Skip to content

Commit

Permalink
Smart contract exchange of BTC for DFI (#1045)
Browse files Browse the repository at this point in the history
* Smart contract exchange of BTC for DFI

* lint: add new "circular deps"

* Remove redundant COIN from calculations

* Rename error message

Co-authored-by: Prasanna Loganathar <[email protected]>
  • Loading branch information
Bushstar and prasannavl authored Jan 24, 2022
1 parent 8e37286 commit 06b51a7
Show file tree
Hide file tree
Showing 18 changed files with 745 additions and 19 deletions.
12 changes: 12 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ class CMainParams : public CChainParams {
consensus.accountDestruction.insert(GetScriptForDestination(DecodeDestination("dJEbxbfufyPF14SC93yxiquECEfq4YSd9L", *this)));
consensus.accountDestruction.insert(GetScriptForDestination(DecodeDestination("8UAhRuUFCyFUHEPD7qvtj8Zy2HxF5HH5nb", *this)));

consensus.smartContracts.clear();
consensus.smartContracts["DFIP2201"] = 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})));

// owner base58, operator base58
vMasternodes.push_back({"8PuErAcazqccCVzRcc8vJ3wFaZGm4vFbLe", "8J846CKFF83Jcj5m4EReJmxiaJ6Jy1Y6Ea"});
vMasternodes.push_back({"8RPZm7SVUNhGN1RgGY3R92rvRkZBwETrCX", "8bzHwhaF2MaVs4owRvpWtZQVug3mKuJji2"});
Expand Down Expand Up @@ -456,6 +459,9 @@ class CTestNetParams : public CChainParams {
consensus.accountDestruction.insert(GetScriptForDestination(DecodeDestination("trnZD2qPU1c3WryBi8sWX16mEaq9WkGHeg", *this))); // cVUZfDj1B1o7eVhxuZr8FQLh626KceiGQhZ8G6YCUdeW3CAV49ti
consensus.accountDestruction.insert(GetScriptForDestination(DecodeDestination("75jrurn8tkDLhZ3YPyzhk6D9kc1a4hBrmM", *this))); // cSmsVpoR6dSW5hPNKeGwC561gXHXcksdQb2yAFQdjbSp5MUyzZqr

consensus.smartContracts.clear();
consensus.smartContracts["DFIP2201"] = 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})));

// owner base58, operator base58
vMasternodes.push_back({"7LMorkhKTDjbES6DfRxX2RiNMbeemUkxmp", "7KEu9JMKCx6aJ9wyg138W3p42rjg19DR5D"});
vMasternodes.push_back({"7E8Cjn9cqEwnrc3E4zN6c5xKxDSGAyiVUM", "78MWNEcAAJxihddCw1UnZD8T7fMWmUuBro"});
Expand Down Expand Up @@ -634,6 +640,9 @@ class CDevNetParams : public CChainParams {
consensus.foundationMembers.emplace(GetScriptForDestination(DecodeDestination("7M3g9CSERjLdXisE5pv2qryDbURUj9Vpi1", *this)));
consensus.foundationMembers.emplace(GetScriptForDestination(DecodeDestination("7L29itepC13pgho1X2y7mcuf4WjkBi7x2w", *this)));

consensus.smartContracts.clear();
consensus.smartContracts["DFIP2201"] = 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})));

// owner base58, operator base58
vMasternodes.push_back({"7M3g9CSERjLdXisE5pv2qryDbURUj9Vpi1", "7Grgx69MZJ4wDKRx1bBxLqTnU9T3quKW7n"});
vMasternodes.push_back({"7L29itepC13pgho1X2y7mcuf4WjkBi7x2w", "773MiaEtQK2HAwWj55gyuRiU8tSwowRTTW"});
Expand Down Expand Up @@ -818,6 +827,9 @@ class CRegTestParams : public CChainParams {
consensus.accountDestruction.insert(GetScriptForDestination(DecodeDestination("2MxJf6Ak8MGrLoGdekrU6AusW29szZUFphH", *this)));
consensus.accountDestruction.insert(GetScriptForDestination(DecodeDestination("mxiaFfAnCoXEUy4RW8NgsQM7yU5YRCiFSh", *this)));

consensus.smartContracts.clear();
consensus.smartContracts["DFIP2201"] = 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})));

// owner base58, operator base58
vMasternodes.push_back({"mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU", "mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy"});
vMasternodes.push_back({"msER9bmJjyEemRpQoS8YYVL21VyZZrSgQ7", "mps7BdmwEF2vQ9DREDyNPibqsuSRZ8LuwQ"});
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct Params {
uint32_t foundationShare;
std::set<CScript> foundationMembers;
std::set<CScript> accountDestruction;
std::map<std::string, CScript> smartContracts;
/* Block hash that is excepted from BIP16 enforcement */
uint256 BIP16Exception;
/** Block height and hash at which BIP34 becomes active */
Expand Down
13 changes: 13 additions & 0 deletions src/masternodes/balances.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,19 @@ struct CUtxosToAccountMessage {
}
};

struct CSmartContractMessage {
std::string name;
CAccounts accounts;

ADD_SERIALIZE_METHODS;

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

inline CBalances SumAllTransfers(CAccounts const & to) {
CBalances sum;
for (const auto& kv : to) {
Expand Down
68 changes: 59 additions & 9 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,23 @@ static ResVal<int32_t> VerifyInt32(const std::string& str) {
return {int32, Res::Ok()};
}

static ResVal<CAmount> VerifyPct(const std::string& str) {
static ResVal<CAmount> VerifyFloat(const std::string& str) {
CAmount amount = 0;
if (!ParseFixedPoint(str, 8, &amount) || amount < 0) {
return Res::Err("Percentage must be a positive integer or float");
return Res::Err("Amount must be a positive value");
}
return {amount, Res::Ok()};
}

static ResVal<CAmount> VerifyPct(const std::string& str) {
auto resVal = VerifyFloat(str);
if (!resVal) {
return resVal;
}
if (amount > COIN) {
if (*resVal.val > COIN) {
return Res::Err("Percentage exceeds 100%%");
}
return ResVal<CAmount>(amount, Res::Ok());
return resVal;
}

Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value,
Expand Down Expand Up @@ -91,9 +99,21 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value

auto type = itype->second;

auto typeId = VerifyInt32(keys[2]);
if (!typeId) {
return std::move(typeId);
uint32_t typeId{0};
if (type != AttributeTypes::Param) {
auto id = VerifyInt32(keys[2]);
if (!id) {
return std::move(id);
}

typeId = *id.val;
} else {
auto id = allowedParamIDs.find(keys[2]);
if (id == allowedParamIDs.end()) {
return Res::Err("Unsupported ID");
}

typeId = id->second;
}

auto ikey = allowedKeys.find(type);
Expand Down Expand Up @@ -141,12 +161,35 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value
} else {
return Res::Err("Unrecognised key");
}
} else if (type == AttributeTypes::Param) {
if (typeId == ParamIDs::DFIP2201) {
if (typeKey == DFIP2201Keys::Active) {
if (value != "true" && value != "false") {
return Res::Err("DFIP2201 actve value must be either \"true\" or \"false\"");
}
valueV0 = value == "true";
} else if (typeKey == DFIP2201Keys::Premium) {
auto res = VerifyPct(value);
if (!res) {
return std::move(res);
}
valueV0 = *res.val;
} else if (typeKey == DFIP2201Keys::MinSwap) {
auto res = VerifyFloat(value);
if (!res) {
return std::move(res);
}
valueV0 = *res.val;
} else {
return Res::Err("Unrecognised key");
}
}
} else {
return Res::Err("Unrecognised type");
}

if (applyVariable) {
return applyVariable(CDataStructureV0{type, uint32_t(*typeId.val), typeKey}, valueV0);
return applyVariable(CDataStructureV0{type, typeId, typeKey}, valueV0);
}
return Res::Ok();
}
Expand Down Expand Up @@ -185,9 +228,10 @@ UniValue ATTRIBUTES::Export() const {
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),
attrV0->typeId,
id,
displayKeys.at(attrV0->type).at(attrV0->key));

if (auto bool_val = boost::get<const bool>(valV0)) {
Expand Down Expand Up @@ -248,6 +292,12 @@ Res ATTRIBUTES::Validate(const CCustomCSView & view) const
continue;
}
}
if (attrV0->type == AttributeTypes::Param) {
if (attrV0->typeId == ParamIDs::DFIP2201) {
return Res::Ok();
}
return Res::Err("Unrecognised param id");
}
return Res::Err("Unrecognised type");
}

Expand Down
35 changes: 35 additions & 0 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,21 @@ enum VersionTypes : uint8_t {
};

enum AttributeTypes : uint8_t {
Param = 'a',
Token = 't',
Poolpairs = 'p',
};

enum ParamIDs : uint8_t {
DFIP2201 = 'a',
};

enum DFIP2201Keys : uint8_t {
Active = 'a',
Premium = 'b',
MinSwap = 'c',
};

enum TokenKeys : uint8_t {
PaybackDFI = 'a',
PaybackDFIFeePCT = 'b',
Expand Down Expand Up @@ -106,6 +117,11 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
const std::map<std::string, uint8_t> allowedTypes{
{"token", AttributeTypes::Token},
{"poolpairs", AttributeTypes::Poolpairs},
{"params", AttributeTypes::Param},
};

const std::map<std::string, uint8_t> allowedParamIDs{
{"dfip2201", ParamIDs::DFIP2201}
};

const std::map<uint8_t, std::map<std::string, uint8_t>> allowedKeys{
Expand All @@ -121,6 +137,13 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
{"token_b_fee_pct", PoolKeys::TokenBFeePCT},
}
},
{
AttributeTypes::Param, {
{"active", DFIP2201Keys::Active},
{"minswap", DFIP2201Keys::MinSwap},
{"premium", DFIP2201Keys::Premium},
}
},
};

// For formatting in export
Expand All @@ -131,6 +154,11 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
const std::map<uint8_t, std::string> displayTypes{
{AttributeTypes::Token, "token"},
{AttributeTypes::Poolpairs, "poolpairs"},
{AttributeTypes::Param, "params"},
};

const std::map<uint8_t, std::string> displayParamsIDs{
{ParamIDs::DFIP2201, "dfip2201"}
};

const std::map<uint8_t, std::map<uint8_t, std::string>> displayKeys{
Expand All @@ -146,6 +174,13 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
{PoolKeys::TokenBFeePCT, "token_b_fee_pct"},
}
},
{
AttributeTypes::Param, {
{DFIP2201Keys::Active, "active"},
{DFIP2201Keys::Premium, "premium"},
{DFIP2201Keys::MinSwap, "minswap"},
}
},
};

Res ProcessVariable(const std::string& key, const std::string& value,
Expand Down
3 changes: 2 additions & 1 deletion src/masternodes/masternodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,6 @@ class CCustomCSView
private:
Res PopulateLoansData(CCollateralLoans& result, CVaultId const& vaultId, uint32_t height, int64_t blockTime, bool useNextPrice, bool requireLivePrice);
Res PopulateCollateralData(CCollateralLoans& result, CVaultId const& vaultId, CBalances const& collaterals, uint32_t height, int64_t blockTime, bool useNextPrice, bool requireLivePrice);
ResVal<CAmount> GetValidatedIntervalPrice(CTokenCurrencyPair priceFeedId, bool useNextPrice, bool requireLivePrice);

public:
// Increase version when underlaying tables are changed
Expand Down Expand Up @@ -431,6 +430,8 @@ class CCustomCSView

ResVal<CCollateralLoans> GetLoanCollaterals(CVaultId const & vaultId, CBalances const & collaterals, uint32_t height, int64_t blockTime, bool useNextPrice = false, bool requireLivePrice = true);

ResVal<CAmount> GetValidatedIntervalPrice(CTokenCurrencyPair priceFeedId, bool useNextPrice, bool requireLivePrice);

void SetDbVersion(int version);

int GetDbVersion() const;
Expand Down
Loading

0 comments on commit 06b51a7

Please sign in to comment.