Skip to content

Commit

Permalink
Restore validation to setloantoken (#1268)
Browse files Browse the repository at this point in the history
Co-authored-by: Prasanna Loganathar <[email protected]>
  • Loading branch information
Bushstar and prasannavl authored May 23, 2022
1 parent ff90867 commit 507dcc9
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 43 deletions.
5 changes: 4 additions & 1 deletion src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,10 @@ Res ATTRIBUTES::Apply(CCustomCSView & mnview, const uint32_t height)
if (aggregatePrice) {
fixedIntervalPrice.priceRecord[1] = aggregatePrice;
}
mnview.SetFixedIntervalPrice(fixedIntervalPrice);
const auto res = mnview.SetFixedIntervalPrice(fixedIntervalPrice);
if (!res) {
return res;
}
} else {
return Res::Err("Unrecognised value for FixedIntervalPriceId");
}
Expand Down
3 changes: 0 additions & 3 deletions src/masternodes/loan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ Res CLoanView::SetLoanToken(CLoanSetLoanTokenImpl const & loanToken, DCT_ID cons
if (GetLoanTokenByID(id))
return Res::Err("setLoanToken with creation tx %s already exists!", loanToken.creationTx.GetHex());

if (loanToken.interest < 0)
return Res::Err("interest rate cannot be less than 0!");

WriteBy<LoanSetLoanTokenKey>(id, loanToken);
WriteBy<LoanSetLoanTokenCreationTx>(loanToken.creationTx, id);

Expand Down
64 changes: 26 additions & 38 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2383,29 +2383,32 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
if (!HasFoundationAuth())
return Res::Err("tx not from foundation member!");

if (obj.interest < 0) {
return Res::Err("interest rate cannot be less than 0!");
}

CTokenImplementation token;
token.symbol = trim_ws(obj.symbol).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
token.name = trim_ws(obj.name).substr(0, CToken::MAX_TOKEN_NAME_LENGTH);
token.creationTx = tx.GetHash();
token.creationHeight = height;
token.flags = obj.mintable ? static_cast<uint8_t>(CToken::TokenFlags::Default) : static_cast<uint8_t>(CToken::TokenFlags::Tradeable);
token.flags |= static_cast<uint8_t>(CToken::TokenFlags::LoanToken) | static_cast<uint8_t>(CToken::TokenFlags::DAT);

auto tokenId = mnview.CreateToken(token);
if (!tokenId)
return std::move(tokenId);

if (height >= static_cast<uint32_t>(consensus.FortCanningCrunchHeight))
{
CTokenImplementation token;
token.symbol = trim_ws(obj.symbol).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
token.name = trim_ws(obj.name).substr(0, CToken::MAX_TOKEN_NAME_LENGTH);
token.creationTx = tx.GetHash();
token.creationHeight = height;
token.flags = obj.mintable ? static_cast<uint8_t>(CToken::TokenFlags::Default) : static_cast<uint8_t>(CToken::TokenFlags::Tradeable);
token.flags |= (uint8_t)CToken::TokenFlags::LoanToken | (uint8_t)CToken::TokenFlags::DAT;

auto resVal = mnview.CreateToken(token);
if ( !resVal) {
return res;
}

const auto& tokenId = resVal.val->v;
const auto& id = tokenId.val->v;

auto attributes = mnview.GetAttributes();
attributes->time = time;

CDataStructureV0 mintEnabled{AttributeTypes::Token, tokenId, TokenKeys::LoanMintingEnabled};
CDataStructureV0 mintInterest{AttributeTypes::Token, tokenId, TokenKeys::LoanMintingInterest};
CDataStructureV0 pairKey{AttributeTypes::Token, tokenId, TokenKeys::FixedIntervalPriceId};
CDataStructureV0 mintEnabled{AttributeTypes::Token, id, TokenKeys::LoanMintingEnabled};
CDataStructureV0 mintInterest{AttributeTypes::Token, id, TokenKeys::LoanMintingInterest};
CDataStructureV0 pairKey{AttributeTypes::Token, id, TokenKeys::FixedIntervalPriceId};

attributes->SetValue(mintEnabled, obj.mintable);
attributes->SetValue(mintInterest, obj.interest);
Expand All @@ -2428,37 +2431,22 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
loanToken.creationTx = tx.GetHash();
loanToken.creationHeight = height;

CFixedIntervalPrice fixedIntervalPrice;
fixedIntervalPrice.priceFeedId = loanToken.fixedIntervalPriceId;

auto nextPrice = GetAggregatePrice(mnview, loanToken.fixedIntervalPriceId.first, loanToken.fixedIntervalPriceId.second, time);
auto nextPrice = GetAggregatePrice(mnview, obj.fixedIntervalPriceId.first, obj.fixedIntervalPriceId.second, time);
if (!nextPrice)
return Res::Err(nextPrice.msg);

if (!OraclePriceFeed(mnview, obj.fixedIntervalPriceId))
return Res::Err("Price feed %s/%s does not belong to any oracle", obj.fixedIntervalPriceId.first, obj.fixedIntervalPriceId.second);

CFixedIntervalPrice fixedIntervalPrice;
fixedIntervalPrice.priceFeedId = loanToken.fixedIntervalPriceId;
fixedIntervalPrice.priceRecord[1] = nextPrice;
fixedIntervalPrice.timestamp = time;

LogPrint(BCLog::ORACLE,"CLoanSetLoanTokenMessage()->"); /* Continued */
auto resSetFixedPrice = mnview.SetFixedIntervalPrice(fixedIntervalPrice);
if (!resSetFixedPrice)
return Res::Err(resSetFixedPrice.msg);

if (!OraclePriceFeed(mnview, loanToken.fixedIntervalPriceId))
return Res::Err("Price feed %s/%s does not belong to any oracle", loanToken.fixedIntervalPriceId.first, loanToken.fixedIntervalPriceId.second);

CTokenImplementation token;
token.flags = loanToken.mintable ? (uint8_t)CToken::TokenFlags::Default : (uint8_t)CToken::TokenFlags::Tradeable;
token.flags |= (uint8_t)CToken::TokenFlags::LoanToken | (uint8_t)CToken::TokenFlags::DAT;

token.symbol = trim_ws(loanToken.symbol).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
token.name = trim_ws(loanToken.name).substr(0, CToken::MAX_TOKEN_NAME_LENGTH);
token.creationTx = tx.GetHash();
token.creationHeight = height;

auto tokenId = mnview.CreateToken(token);
if (!tokenId)
return std::move(tokenId);

return mnview.SetLoanToken(loanToken, *(tokenId.val));
}

Expand Down
10 changes: 9 additions & 1 deletion test/functional/feature_loan_setloantoken.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from test_framework.test_framework import DefiTestFramework

from test_framework.authproxy import JSONRPCException
from test_framework.util import assert_equal
from test_framework.util import assert_equal,assert_raises_rpc_error

from decimal import Decimal
import calendar
Expand Down Expand Up @@ -153,6 +153,14 @@ def run_test(self):
# Move to fork height
self.nodes[0].generate(110 - self.nodes[0].getblockcount())

assert_raises_rpc_error(-32600, 'token symbol should be non-empty and starts with a letter', self.nodes[0].setloantoken, {
'symbol': "",
'name': "Google",
'fixedIntervalPriceId': "MSFT/USD",
'mintable': True,
'interest': 0.01
})

# Create loan tokens
self.nodes[0].setloantoken({
'symbol': "GOOGL",
Expand Down

0 comments on commit 507dcc9

Please sign in to comment.