Skip to content

Commit

Permalink
Merge branch 'master' into fix/bogus_vault_ratio_calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
bvbfan authored Mar 22, 2022
2 parents eec61a9 + 2a236bb commit d7f6a0c
Show file tree
Hide file tree
Showing 13 changed files with 1,181 additions and 174 deletions.
61 changes: 59 additions & 2 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
return Res::Err("Unsupported version");
}

if (keys.size() != 4 || keys[1].empty() || keys[2].empty() || keys[3].empty()) {
if (keys.size() < 4 || keys[1].empty() || keys[2].empty() || keys[3].empty()) {
return Res::Err("Incorrect key for <type>. Object of ['<version>/<type>/ID/<key>','value'] expected");
}

Expand Down Expand Up @@ -135,6 +135,8 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
UniValue univalue;
auto typeKey = itype->second;

uint32_t typeKeyId = 0;

CAttributeValue attribValue;

if (type == AttributeTypes::Token) {
Expand All @@ -149,6 +151,28 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
return std::move(res);
}
attribValue = *res.val;
} else if (typeKey == TokenKeys::LoanPayback
|| typeKey == TokenKeys::LoanPaybackFeePCT) {
if (keys.size() != 5 || keys[4].empty()) {
return Res::Err("Exact 5 keys are required {%d}", keys.size());
}
auto id = VerifyInt32(keys[4]);
if (!id) {
return std::move(id);
}
typeKeyId = *id.val;
if (typeKey == TokenKeys::LoanPayback) {
if (value != "true" && value != "false") {
return Res::Err("Payback token value must be either \"true\" or \"false\"");
}
attribValue = value == "true";
} else {
auto res = VerifyPct(value);
if (!res) {
return std::move(res);
}
attribValue = *res.val;
}
} else {
return Res::Err("Unrecognised key");
}
Expand Down Expand Up @@ -191,7 +215,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
}

if (applyVariable) {
return applyVariable(CDataStructureV0{type, typeId, typeKey}, attribValue);
return applyVariable(CDataStructureV0{type, typeId, typeKey, typeKeyId}, attribValue);
}
return Res::Ok();
}
Expand All @@ -211,6 +235,17 @@ Res ATTRIBUTES::Import(const UniValue & val) {
if (attrV0->type == AttributeTypes::Live) {
return Res::Err("Live attribute cannot be set externally");
}
// applay DFI via old keys
if (attrV0->IsExtendedSize() && attrV0->keyId == 0) {
auto newAttr = *attrV0;
if (attrV0->key == TokenKeys::LoanPayback) {
newAttr.key = TokenKeys::PaybackDFI;
} else {
newAttr.key = TokenKeys::PaybackDFIFeePCT;
}
attributes[newAttr] = value;
return Res::Ok();
}
}
attributes[attribute] = value;
return Res::Ok();
Expand Down Expand Up @@ -241,13 +276,22 @@ UniValue ATTRIBUTES::Export() const {
id,
displayKeys.at(attrV0->type).at(attrV0->key));

if (attrV0->IsExtendedSize()) {
key = KeyBuilder(key, attrV0->keyId);
}

if (auto bool_val = boost::get<const bool>(&attribute.second)) {
ret.pushKV(key, *bool_val ? "true" : "false");
} else if (auto amount = boost::get<const CAmount>(&attribute.second)) {
auto uvalue = ValueFromAmount(*amount);
ret.pushKV(key, KeyBuilder(uvalue.get_real()));
} else if (auto balances = boost::get<const CBalances>(&attribute.second)) {
ret.pushKV(key, AmountsToJSON(balances->balances));
} else if (auto paybacks = boost::get<const CTokenPayback>(&attribute.second)) {
UniValue result(UniValue::VOBJ);
result.pushKV("paybackfees", AmountsToJSON(paybacks->tokensFee.balances));
result.pushKV("paybacktokens", AmountsToJSON(paybacks->tokensPayback.balances));
ret.pushKV(key, result);
}
} catch (const std::out_of_range&) {
// Should not get here, that's mean maps are mismatched
Expand All @@ -274,6 +318,19 @@ Res ATTRIBUTES::Validate(const CCustomCSView & view) const
if (!view.GetLoanTokenByID(DCT_ID{tokenId})) {
return Res::Err("No such loan token (%d)", tokenId);
}
} else if (attrV0->key == TokenKeys::LoanPayback
|| attrV0->key == TokenKeys::LoanPaybackFeePCT) {
if (view.GetLastHeight() < Params().GetConsensus().FortCanningRoadHeight) {
return Res::Err("Cannot be set before FortCanningRoad");
}
uint32_t loanTokenId = attrV0->typeId;
if (!view.GetLoanTokenByID(DCT_ID{loanTokenId})) {
return Res::Err("No such loan token (%d)", loanTokenId);
}
uint32_t tokenId = attrV0->keyId;
if (!view.GetToken(DCT_ID{tokenId})) {
return Res::Err("No such token (%d)", tokenId);
}
} else {
return Res::Err("Unsupported key");
}
Expand Down
41 changes: 37 additions & 4 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum ParamIDs : uint8_t {

enum EconomyKeys : uint8_t {
PaybackDFITokens = 'a',
PaybackTokens = 'b',
};

enum DFIP2201Keys : uint8_t {
Expand All @@ -36,8 +37,10 @@ enum DFIP2201Keys : uint8_t {
};

enum TokenKeys : uint8_t {
PaybackDFI = 'a',
PaybackDFIFeePCT = 'b',
PaybackDFI = 'a',
PaybackDFIFeePCT = 'b',
LoanPayback = 'c',
LoanPaybackFeePCT = 'd',
};

enum PoolKeys : uint8_t {
Expand All @@ -49,6 +52,7 @@ struct CDataStructureV0 {
uint8_t type;
uint32_t typeId;
uint8_t key;
uint32_t keyId;

ADD_SERIALIZE_METHODS;

Expand All @@ -57,10 +61,21 @@ struct CDataStructureV0 {
READWRITE(type);
READWRITE(typeId);
READWRITE(key);
if (IsExtendedSize()) {
READWRITE(keyId);
} else {
keyId = 0;
}
}

bool IsExtendedSize() const {
return type == AttributeTypes::Token
&& (key == TokenKeys::LoanPayback
|| key == TokenKeys::LoanPaybackFeePCT);
}

bool operator<(const CDataStructureV0& o) const {
return std::tie(type, typeId, key) < std::tie(o.type, o.typeId, o.key);
return std::tie(type, typeId, key, keyId) < std::tie(o.type, o.typeId, o.key, o.keyId);
}
};

Expand All @@ -74,8 +89,21 @@ struct CDataStructureV1 {
bool operator<(const CDataStructureV1& o) const { return false; }
};

struct CTokenPayback {
CBalances tokensFee;
CBalances tokensPayback;

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(tokensFee);
READWRITE(tokensPayback);
}
};

using CAttributeType = boost::variant<CDataStructureV0, CDataStructureV1>;
using CAttributeValue = boost::variant<bool, CAmount, CBalances>;
using CAttributeValue = boost::variant<bool, CAmount, CBalances, CTokenPayback>;

class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRIBUTES>
{
Expand Down Expand Up @@ -136,6 +164,8 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
AttributeTypes::Token, {
{"payback_dfi", TokenKeys::PaybackDFI},
{"payback_dfi_fee_pct", TokenKeys::PaybackDFIFeePCT},
{"loan_payback", TokenKeys::LoanPayback},
{"loan_payback_fee_pct",TokenKeys::LoanPaybackFeePCT},
}
},
{
Expand Down Expand Up @@ -175,6 +205,8 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
AttributeTypes::Token, {
{TokenKeys::PaybackDFI, "payback_dfi"},
{TokenKeys::PaybackDFIFeePCT, "payback_dfi_fee_pct"},
{TokenKeys::LoanPayback, "loan_payback"},
{TokenKeys::LoanPaybackFeePCT,"loan_payback_fee_pct"},
}
},
{
Expand All @@ -193,6 +225,7 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
{
AttributeTypes::Live, {
{EconomyKeys::PaybackDFITokens, "dfi_payback_tokens"},
{EconomyKeys::PaybackTokens, "payback_tokens"},
}
},
};
Expand Down
17 changes: 17 additions & 0 deletions src/masternodes/loan.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,23 @@ class CLoanPaybackLoanMessage
}
};

class CLoanPaybackLoanV2Message
{
public:
CVaultId vaultId;
CScript from;
std::map<DCT_ID, CBalances> loans;

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(vaultId);
READWRITE(from);
READWRITE(loans);
}
};

class CLoanView : public virtual CStorageView {
public:
using CLoanSetCollateralTokenImpl = CLoanSetCollateralTokenImplementation;
Expand Down
Loading

0 comments on commit d7f6a0c

Please sign in to comment.