Skip to content

Commit

Permalink
Refactor gov attributes value (#1055)
Browse files Browse the repository at this point in the history
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
  • Loading branch information
bvbfan authored and prasannavl committed Jan 24, 2022
1 parent f0f620e commit b76c95c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 102 deletions.
44 changes: 17 additions & 27 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,20 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
UniValue univalue;
auto typeKey = itype->second;

CValueV0 valueV0;
CAttributeValue attribValue;

if (type == AttributeTypes::Token) {
if (typeKey == TokenKeys::PaybackDFI) {
if (value != "true" && value != "false") {
return Res::Err("Payback DFI value must be either \"true\" or \"false\"");
}
valueV0 = value == "true";
attribValue = value == "true";
} else if (typeKey == TokenKeys::PaybackDFIFeePCT) {
auto res = VerifyPct(value);
if (!res) {
return std::move(res);
}
valueV0 = *res.val;
attribValue = *res.val;
} else {
return Res::Err("Unrecognised key");
}
Expand All @@ -157,7 +157,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
if (!res) {
return std::move(res);
}
valueV0 = *res.val;
attribValue = *res.val;
} else {
return Res::Err("Unrecognised key");
}
Expand All @@ -167,19 +167,19 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
if (value != "true" && value != "false") {
return Res::Err("DFIP2201 actve value must be either \"true\" or \"false\"");
}
valueV0 = value == "true";
attribValue = value == "true";
} else if (typeKey == DFIP2201Keys::Premium) {
auto res = VerifyPct(value);
if (!res) {
return std::move(res);
}
valueV0 = *res.val;
attribValue = *res.val;
} else if (typeKey == DFIP2201Keys::MinSwap) {
auto res = VerifyFloat(value);
if (!res) {
return std::move(res);
}
valueV0 = *res.val;
attribValue = *res.val;
} else {
return Res::Err("Unrecognised key");
}
Expand All @@ -189,7 +189,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
}

if (applyVariable) {
return applyVariable(CDataStructureV0{type, typeId, typeKey}, valueV0);
return applyVariable(CDataStructureV0{type, typeId, typeKey}, attribValue);
}
return Res::Ok();
}
Expand Down Expand Up @@ -223,20 +223,16 @@ UniValue ATTRIBUTES::Export() const {
if (!attrV0) {
continue;
}
auto valV0 = boost::get<const CValueV0>(&attribute.second);
if (!valV0) {
continue;
}
try {
const std::string id = attrV0->type == AttributeTypes::Param ? displayParamsIDs.at(attrV0->typeId) : KeyBuilder(attrV0->typeId);
auto key = KeyBuilder(displayVersions.at(VersionTypes::v0),
displayTypes.at(attrV0->type),
id,
displayKeys.at(attrV0->type).at(attrV0->key));

if (auto bool_val = boost::get<const bool>(valV0)) {
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>(valV0)) {
} else if (auto amount = boost::get<const CAmount>(&attribute.second)) {
auto uvalue = ValueFromAmount(*amount);
ret.pushKV(key, KeyBuilder(uvalue.get_real()));
}
Expand All @@ -257,30 +253,26 @@ Res ATTRIBUTES::Validate(const CCustomCSView & view) const
if (!attrV0) {
return Res::Err("Unsupported version");
}
auto valV0 = boost::get<const CValueV0>(&attribute.second);
if (!valV0) {
return Res::Err("Unsupported value");
}
if (attrV0->type == AttributeTypes::Token) {
uint32_t tokenId = attrV0->typeId;
if (!view.GetLoanTokenByID(DCT_ID{tokenId})) {
return Res::Err("No such loan token (%d)", tokenId);
}
if (attrV0->key == TokenKeys::PaybackDFI) {
if (!boost::get<const bool>(valV0)) {
if (!boost::get<const bool>(&attribute.second)) {
return Res::Err("Unsupported value");
}
continue;
}
if (attrV0->key == TokenKeys::PaybackDFIFeePCT) {
if (!boost::get<const CAmount>(valV0)) {
if (!boost::get<const CAmount>(&attribute.second)) {
return Res::Err("Unsupported value");
}
continue;
}
}
if (attrV0->type == AttributeTypes::Poolpairs) {
if (!boost::get<const CAmount>(valV0)) {
if (!boost::get<const CAmount>(&attribute.second)) {
return Res::Err("Unsupported value");
}
uint32_t poolId = attrV0->typeId;
Expand Down Expand Up @@ -317,12 +309,10 @@ Res ATTRIBUTES::Apply(CCustomCSView & mnview, const uint32_t height)
auto tokenId = attrV0->key == PoolKeys::TokenAFeePCT ?
pool->idTokenA : pool->idTokenB;

if (auto valV0 = boost::get<const CValueV0>(&attribute.second)) {
auto valuePct = boost::get<const CAmount>(*valV0);
auto res = mnview.SetDexFeePct(DCT_ID{poolId}, tokenId, valuePct);
if (!res) {
return res;
}
auto valuePct = boost::get<const CAmount>(attribute.second);
auto res = mnview.SetDexFeePct(DCT_ID{poolId}, tokenId, valuePct);
if (!res) {
return res;
}
}
}
Expand Down
22 changes: 12 additions & 10 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ enum PoolKeys : uint8_t {
TokenBFeePCT = 'b',
};

using CValueV0 = boost::variant<bool, CAmount>;

struct CDataStructureV0 {
uint8_t type;
uint32_t typeId;
Expand Down Expand Up @@ -71,15 +69,8 @@ struct CDataStructureV1 {
bool operator<(const CDataStructureV1& o) const { return false; }
};

struct CValueV1 {
ADD_SERIALIZE_METHODS;

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

using CAttributeType = boost::variant<CDataStructureV0, CDataStructureV1>;
using CAttributeValue = boost::variant<CValueV0, CValueV1>;
using CAttributeValue = boost::variant<bool, CAmount>;

class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRIBUTES>
{
Expand All @@ -98,6 +89,17 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
static constexpr char const * TypeName() { return "ATTRIBUTES"; }
static GovVariable * Create() { return new ATTRIBUTES(); }

template<typename T>
T GetValue(const CAttributeType& key, T value) {
auto it = attributes.find(key);
if (it != attributes.end()) {
if (auto val = boost::get<const T>(&it->second)) {
value = *val;
}
}
return std::move(value);
}

ADD_OVERRIDE_VECTOR_SERIALIZE_METHODS
ADD_OVERRIDE_SERIALIZE_METHODS(CDataStream)

Expand Down
79 changes: 14 additions & 65 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,26 +1344,13 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
}

Res operator()(const CSmartContractMessage& obj) const {
const auto pAttributes = mnview.GetAttributes();
if (!pAttributes) {
const auto attributes = mnview.GetAttributes();
if (!attributes) {
return Res::Err("DFIP2201 smart contract is not enabled");
}

const auto& attrs = pAttributes->attributes;
CDataStructureV0 activeKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Active};
try {
const auto& value = attrs.at(activeKey);
auto valueV0 = boost::get<const CValueV0>(&value);

if (!valueV0) {
throw std::out_of_range("");
}

const auto active = boost::get<const bool>(valueV0);
if (!active || !*active) {
throw std::out_of_range("");
}
} catch (const std::out_of_range&) {
if (!attributes->GetValue(activeKey, false)) {
return Res::Err("DFIP2201 smart contract is not enabled");
}

Expand Down Expand Up @@ -1393,16 +1380,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
}

CDataStructureV0 minSwapKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::MinSwap};
CAmount minSwap{0};
try {
const auto& value = attrs.at(minSwapKey);
auto valueV0 = boost::get<const CValueV0>(&value);
if (valueV0) {
if (auto storedMinSwap = boost::get<const CAmount>(valueV0)) {
minSwap = *storedMinSwap;
}
}
} catch (const std::out_of_range&) {}
auto minSwap = attributes->GetValue(minSwapKey, CAmount{0});

if (minSwap && amount < minSwap) {
return Res::Err("Below minimum swapable amount, must be at least " + ValueFromAmount(minSwap).getValStr() + " BTC");
Expand Down Expand Up @@ -1431,26 +1409,17 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
return std::move(resVal);
}

CDataStructureV0 feePctKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Premium};
CAmount feePct{2500000};
try {
const auto& value = attrs.at(feePctKey);
auto valueV0 = boost::get<const CValueV0>(&value);
if (valueV0) {
if (auto storedFeePct = boost::get<const CAmount>(valueV0)) {
feePct = *storedFeePct;
}
}
} catch (const std::out_of_range&) {}
CDataStructureV0 premiumKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Premium};
auto premium = attributes->GetValue(premiumKey, CAmount{2500000});

const auto& btcPrice = MultiplyAmounts(resVal.val.get(), feePct + COIN);
const auto& btcPrice = MultiplyAmounts(*resVal.val, premium + COIN);

resVal = mnview.GetValidatedIntervalPrice(dfiUsd, useNextPrice, requireLivePrice);
if (!resVal) {
return std::move(resVal);
}

const auto totalDFI = MultiplyAmounts(DivideAmounts(btcPrice, resVal.val.get()), amount);
const auto totalDFI = MultiplyAmounts(DivideAmounts(btcPrice, *resVal.val), amount);

res = mnview.SubBalance(Params().GetConsensus().smartContracts.begin()->second, {{0}, totalDFI});
if (!res) {
Expand Down Expand Up @@ -2828,22 +2797,10 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
auto allowDFIPayback = false;
std::map<CAttributeType, CAttributeValue> attrs;
auto tokenDUSD = mnview.GetToken("DUSD");
if (tokenDUSD) {
const auto pAttributes = mnview.GetAttributes();
if (pAttributes) {
attrs = pAttributes->attributes;
CDataStructureV0 activeKey{AttributeTypes::Token, tokenDUSD->first.v, TokenKeys::PaybackDFI};
try {
const auto& value = attrs.at(activeKey);
auto valueV0 = boost::get<const CValueV0>(&value);
if (valueV0) {
const auto active = boost::get<const bool>(valueV0);
if (active != nullptr && *active) {
allowDFIPayback = true;
}
}
} catch (const std::out_of_range&) {}
}
auto attributes = mnview.GetAttributes();
if (tokenDUSD && attributes) {
CDataStructureV0 activeKey{AttributeTypes::Token, tokenDUSD->first.v, TokenKeys::PaybackDFI};
allowDFIPayback = attributes->GetValue(activeKey, false);
}

for (const auto& kv : obj.amounts.balances)
Expand All @@ -2867,17 +2824,9 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
}

// Apply penalty
CAmount penalty{99000000}; // Update from Gov var
CDataStructureV0 penaltyKey{AttributeTypes::Token, tokenDUSD->first.v, TokenKeys::PaybackDFIFeePCT};
try {
const auto& value = attrs.at(penaltyKey);
auto valueV0 = boost::get<const CValueV0>(&value);
if (valueV0) {
if (auto storedPenalty = boost::get<const CAmount>(valueV0)) {
penalty = COIN - *storedPenalty;
}
}
} catch (const std::out_of_range&) {}
auto penalty = COIN - attributes->GetValue(penaltyKey, COIN / 100);

dfiUSDPrice = MultiplyAmounts(*resVal.val, penalty);

// Set tokenId to DUSD
Expand Down

0 comments on commit b76c95c

Please sign in to comment.