Skip to content
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

Restore validation to setloantoken #1268

Merged
merged 2 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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