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

DFI2203 Futures #1155

Merged
merged 12 commits into from
Mar 28, 2022
4 changes: 4 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ class CMainParams : public CChainParams {

consensus.smartContracts.clear();
consensus.smartContracts[SMART_CONTRACT_DFIP_2201] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})));
consensus.smartContracts[SMART_CONTRACT_DFIP_2203] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1})));

// owner base58, operator base58
vMasternodes.push_back({"8PuErAcazqccCVzRcc8vJ3wFaZGm4vFbLe", "8J846CKFF83Jcj5m4EReJmxiaJ6Jy1Y6Ea"});
Expand Down Expand Up @@ -462,6 +463,7 @@ class CTestNetParams : public CChainParams {

consensus.smartContracts.clear();
consensus.smartContracts[SMART_CONTRACT_DFIP_2201] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})));
consensus.smartContracts[SMART_CONTRACT_DFIP_2203] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1})));

// owner base58, operator base58
vMasternodes.push_back({"7LMorkhKTDjbES6DfRxX2RiNMbeemUkxmp", "7KEu9JMKCx6aJ9wyg138W3p42rjg19DR5D"});
Expand Down Expand Up @@ -644,6 +646,7 @@ class CDevNetParams : public CChainParams {

consensus.smartContracts.clear();
consensus.smartContracts[SMART_CONTRACT_DFIP_2201] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})));
consensus.smartContracts[SMART_CONTRACT_DFIP_2203] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1})));

// owner base58, operator base58
vMasternodes.push_back({"7M3g9CSERjLdXisE5pv2qryDbURUj9Vpi1", "7Grgx69MZJ4wDKRx1bBxLqTnU9T3quKW7n"});
Expand Down Expand Up @@ -832,6 +835,7 @@ class CRegTestParams : public CChainParams {

consensus.smartContracts.clear();
consensus.smartContracts[SMART_CONTRACT_DFIP_2201] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})));
consensus.smartContracts[SMART_CONTRACT_DFIP_2203] = GetScriptForDestination(CTxDestination(WitnessV0KeyHash(std::vector<unsigned char>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1})));

// owner base58, operator base58
vMasternodes.push_back({"mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU", "mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy"});
Expand Down
1 change: 1 addition & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class CChainParams
};

const auto SMART_CONTRACT_DFIP_2201 = "DFIP2201";
const auto SMART_CONTRACT_DFIP_2203 = "DFIP2203";

/**
* Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
Expand Down
15 changes: 15 additions & 0 deletions src/masternodes/accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,18 @@ uint32_t CAccountsView::GetBalancesHeight(CScript const & owner)
bool ok = ReadBy<ByHeightKey>(owner, height);
return ok ? height : 0;
}

Res CAccountsView::StoreFuturesUserValues(const CFuturesUserKey& key, const CFuturesUserValue& futures)
{
if (!WriteBy<ByFuturesKey>(key, futures)) {
return Res::Err("Failed to store futures");
}

return Res::Ok();
}

void CAccountsView::ForEachFuturesUserValues(std::function<bool(const CFuturesUserKey&, const CFuturesUserValue&)> callback, const CFuturesUserKey& start)
{
ForEach<ByFuturesKey, CFuturesUserKey, CFuturesUserValue>(callback, start);
}

42 changes: 42 additions & 0 deletions src/masternodes/accounts.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,44 @@
#include <amount.h>
#include <script/script.h>

struct CFuturesUserKey {
uint32_t height;
CScript owner;
uint32_t txn;

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
if (ser_action.ForRead()) {
READWRITE(WrapBigEndian(height));
height = ~height;
READWRITE(owner);
READWRITE(WrapBigEndian(txn));
txn = ~txn;
} else {
uint32_t height_ = ~height;
READWRITE(WrapBigEndian(height_));
READWRITE(owner);
uint32_t txn_ = ~txn;
READWRITE(WrapBigEndian(txn_));
}
}
};

struct CFuturesUserValue {
CTokenAmount source{};
uint32_t destination{};

ADD_SERIALIZE_METHODS;

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

class CAccountsView : public virtual CStorageView
{
public:
Expand All @@ -27,9 +65,13 @@ class CAccountsView : public virtual CStorageView
uint32_t GetBalancesHeight(CScript const & owner);
Res UpdateBalancesHeight(CScript const & owner, uint32_t height);

Res StoreFuturesUserValues(const CFuturesUserKey& key, const CFuturesUserValue& futures);
void ForEachFuturesUserValues(std::function<bool(const CFuturesUserKey&, const CFuturesUserValue&)> callback, const CFuturesUserKey& start = {});

// tags
struct ByBalanceKey { static constexpr uint8_t prefix() { return 'a'; } };
struct ByHeightKey { static constexpr uint8_t prefix() { return 'b'; } };
struct ByFuturesKey { static constexpr uint8_t prefix() { return 'J'; } };

private:
Res SetBalance(CScript const & owner, CTokenAmount amount);
Expand Down
15 changes: 15 additions & 0 deletions src/masternodes/balances.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,21 @@ struct CSmartContractMessage {
}
};

struct CDFIP2203Message {
CScript owner;
CTokenAmount source{};
uint32_t destination{};

ADD_SERIALIZE_METHODS;

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

inline CBalances SumAllTransfers(CAccounts const & to) {
CBalances sum;
for (const auto& kv : to) {
Expand Down
78 changes: 64 additions & 14 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,16 @@ const std::map<uint8_t, std::string>& ATTRIBUTES::displayTypes() {

const std::map<std::string, uint8_t>& ATTRIBUTES::allowedParamIDs() {
static const std::map<std::string, uint8_t> params{
{"dfip2201", ParamIDs::DFIP2201}
{"dfip2201", ParamIDs::DFIP2201},
{"dfip2203", ParamIDs::DFIP2203},
};
return params;
}

const std::map<uint8_t, std::string>& ATTRIBUTES::displayParamsIDs() {
static const std::map<uint8_t, std::string> params{
{ParamIDs::DFIP2201, "dfip2201"},
{ParamIDs::DFIP2203, "dfip2203"},
{ParamIDs::Economy, "economy"},
};
return params;
Expand All @@ -91,6 +93,7 @@ const std::map<uint8_t, std::map<std::string, uint8_t>>& ATTRIBUTES::allowedKeys
{"loan_payback_fee_pct",TokenKeys::LoanPaybackFeePCT},
{"dex_in_fee_pct", TokenKeys::DexInFeePct},
{"dex_out_fee_pct", TokenKeys::DexOutFeePct},
{"dfip2203_disabled", TokenKeys::DFIP2203Disabled},
Jouzo marked this conversation as resolved.
Show resolved Hide resolved
}
},
{
Expand All @@ -101,9 +104,11 @@ const std::map<uint8_t, std::map<std::string, uint8_t>>& ATTRIBUTES::allowedKeys
},
{
AttributeTypes::Param, {
{"active", DFIP2201Keys::Active},
{"minswap", DFIP2201Keys::MinSwap},
{"premium", DFIP2201Keys::Premium},
{"active", DFIPKeys::Active},
{"minswap", DFIPKeys::MinSwap},
{"premium", DFIPKeys::Premium},
{"reward_pct", DFIPKeys::RewardPct},
{"block_period", DFIPKeys::BlockPeriod},
}
},
};
Expand All @@ -120,6 +125,7 @@ const std::map<uint8_t, std::map<uint8_t, std::string>>& ATTRIBUTES::displayKeys
{TokenKeys::LoanPaybackFeePCT,"loan_payback_fee_pct"},
{TokenKeys::DexInFeePct, "dex_in_fee_pct"},
{TokenKeys::DexOutFeePct, "dex_out_fee_pct"},
{TokenKeys::DFIP2203Disabled, "dfip2203_disabled"},
}
},
{
Expand All @@ -130,14 +136,17 @@ const std::map<uint8_t, std::map<uint8_t, std::string>>& ATTRIBUTES::displayKeys
},
{
AttributeTypes::Param, {
{DFIP2201Keys::Active, "active"},
{DFIP2201Keys::Premium, "premium"},
{DFIP2201Keys::MinSwap, "minswap"},
{DFIPKeys::Active, "active"},
{DFIPKeys::Premium, "premium"},
{DFIPKeys::MinSwap, "minswap"},
{DFIPKeys::RewardPct, "reward_pct"},
{DFIPKeys::BlockPeriod, "block_period"},
}
},
{
AttributeTypes::Live, {
{EconomyKeys::PaybackDFITokens, "dfi_payback_tokens"},
{EconomyKeys::DFIP2203Tokens, "dfip_tokens"},
}
},
};
Expand All @@ -147,11 +156,19 @@ const std::map<uint8_t, std::map<uint8_t, std::string>>& ATTRIBUTES::displayKeys
static ResVal<int32_t> VerifyInt32(const std::string& str) {
Bushstar marked this conversation as resolved.
Show resolved Hide resolved
int32_t int32;
if (!ParseInt32(str, &int32) || int32 < 0) {
return Res::Err("Identifier must be a positive integer");
return Res::Err("Value must be a positive integer");
}
return {int32, Res::Ok()};
}

static ResVal<CAttributeValue> VerifyPositiveInt64(const std::string& str) {
CAmount int64;
if (!ParseInt64(str, &int64) || int64 < 0) {
return Res::Err("Value must be a positive integer");
}
return {int64, Res::Ok()};
}

static ResVal<CAttributeValue> VerifyFloat(const std::string& str) {
CAmount amount = 0;
if (!ParseFixedPoint(str, 8, &amount) || amount < 0) {
Expand Down Expand Up @@ -191,6 +208,7 @@ const std::map<uint8_t, std::map<uint8_t,
{TokenKeys::LoanPaybackFeePCT,VerifyPct},
{TokenKeys::DexInFeePct, VerifyPct},
{TokenKeys::DexOutFeePct, VerifyPct},
{TokenKeys::DFIP2203Disabled, VerifyBool},
}
},
{
Expand All @@ -201,9 +219,11 @@ const std::map<uint8_t, std::map<uint8_t,
},
{
AttributeTypes::Param, {
{DFIP2201Keys::Active, VerifyBool},
{DFIP2201Keys::Premium, VerifyPct},
{DFIP2201Keys::MinSwap, VerifyFloat},
{DFIPKeys::Active, VerifyBool},
{DFIPKeys::Premium, VerifyPct},
{DFIPKeys::MinSwap, VerifyFloat},
{DFIPKeys::RewardPct, VerifyPct},
{DFIPKeys::BlockPeriod, VerifyPositiveInt64},
}
},
};
Expand Down Expand Up @@ -282,6 +302,20 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value

auto typeKey = itype->second;

if (type == AttributeTypes::Param) {
if (typeId == ParamIDs::DFIP2201) {
if (typeKey == DFIPKeys::RewardPct ||
typeKey == DFIPKeys::BlockPeriod) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this block in general is prepared for other typeIds etc. Why check here for the "other" values?
This if needs to be adapted whenever a new typeId (with new typeKeys) come along. Would be better to check here for the wanted values and return the error if typeKey is not a wanted one, right?

return Res::Err("Unsupported type for DFIP2201 {%d}", typeKey);
}
} else {
Bushstar marked this conversation as resolved.
Show resolved Hide resolved
if (typeKey == DFIPKeys::Premium ||
typeKey == DFIPKeys::MinSwap) {
return Res::Err("Unsupported type for DFIP2203 {%d}", typeKey);
}
}
}

CDataStructureV0 attrV0{type, typeId, typeKey};

if (attrV0.IsExtendedSize()) {
Expand Down Expand Up @@ -375,8 +409,12 @@ UniValue ATTRIBUTES::Export() const {
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()));
if (attrV0->typeId == DFIP2203 && attrV0->key == DFIPKeys::BlockPeriod) {
ret.pushKV(key, KeyBuilder(*amount));
} else {
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)) {
Expand Down Expand Up @@ -432,6 +470,14 @@ Res ATTRIBUTES::Validate(const CCustomCSView & view) const
return Res::Err("No such token (%d)", attrV0->typeId);
}
break;
case TokenKeys::DFIP2203Disabled:
if (view.GetLastHeight() < Params().GetConsensus().FortCanningRoadHeight) {
return Res::Err("Cannot be set before FortCanningRoad");
}
if (!view.GetLoanTokenByID(DCT_ID{attrV0->typeId})) {
return Res::Err("No such loan token (%d)", attrV0->typeId);
}
break;
default:
return Res::Err("Unsupported key");
}
Expand All @@ -454,7 +500,11 @@ Res ATTRIBUTES::Validate(const CCustomCSView & view) const
break;

case AttributeTypes::Param:
if (attrV0->typeId != ParamIDs::DFIP2201) {
if (attrV0->typeId == ParamIDs::DFIP2203) {
if (view.GetLastHeight() < Params().GetConsensus().FortCanningRoadHeight) {
return Res::Err("Cannot be set before FortCanningRoad");
}
} else if (attrV0->typeId != ParamIDs::DFIP2201) {
return Res::Err("Unrecognised param id");
}
break;
Expand Down
19 changes: 15 additions & 4 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,22 @@ enum AttributeTypes : uint8_t {

enum ParamIDs : uint8_t {
DFIP2201 = 'a',
DFIP2203 = 'b',
Economy = 'e',
};

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

enum DFIP2201Keys : uint8_t {
Active = 'a',
Premium = 'b',
MinSwap = 'c',
enum DFIPKeys : uint8_t {
Active = 'a',
Premium = 'b',
MinSwap = 'c',
RewardPct = 'd',
BlockPeriod = 'e',
};

enum TokenKeys : uint8_t {
Expand All @@ -43,6 +47,7 @@ enum TokenKeys : uint8_t {
LoanPaybackFeePCT = 'd',
DexInFeePct = 'e',
DexOutFeePct = 'f',
DFIP2203Disabled = 'g',
};

enum PoolKeys : uint8_t {
Expand Down Expand Up @@ -135,6 +140,12 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
return std::move(value);
}

template<typename K>
[[nodiscard]] bool CheckKey(const K& key) const {
static_assert(std::is_convertible_v<K, CAttributeType>);
return attributes.count(key) > 0;
}

ADD_OVERRIDE_VECTOR_SERIALIZE_METHODS
ADD_OVERRIDE_SERIALIZE_METHODS(CDataStream)

Expand Down
4 changes: 2 additions & 2 deletions src/masternodes/masternodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,15 +363,15 @@ class CCustomCSView
CFoundationsDebtView :: Debt,
CAnchorRewardsView :: BtcTx,
CTokensView :: ID, Symbol, CreationTx, LastDctId,
CAccountsView :: ByBalanceKey, ByHeightKey,
CAccountsView :: ByBalanceKey, ByHeightKey, ByFuturesKey,
CCommunityBalancesView :: ById,
CUndosView :: ByUndoKey,
CPoolPairView :: ByID, ByPair, ByShare, ByIDPair, ByPoolSwap, ByReserves, ByRewardPct, ByRewardLoanPct,
ByPoolReward, ByDailyReward, ByCustomReward, ByTotalLiquidity, ByDailyLoanReward,
ByPoolLoanReward, ByTokenDexFeePct,
CGovView :: ByName, ByHeightVars,
CAnchorConfirmsView :: BtcTx,
COracleView :: ByName, FixedIntervalBlockKey, FixedIntervalPriceKey, PriceDeviation,
COracleView :: ByName, FixedIntervalBlockKey, FixedIntervalPriceKey, PriceDeviation, FuturesPriceKey,
CICXOrderView :: ICXOrderCreationTx, ICXMakeOfferCreationTx, ICXSubmitDFCHTLCCreationTx,
ICXSubmitEXTHTLCCreationTx, ICXClaimDFCHTLCCreationTx, ICXCloseOrderCreationTx,
ICXCloseOfferCreationTx, ICXOrderOpenKey, ICXOrderCloseKey, ICXMakeOfferOpenKey,
Expand Down
Loading