From 1b61eb9a976e2afd980376bea6d3a2c8551fd365 Mon Sep 17 00:00:00 2001 From: miketout Date: Sun, 1 May 2022 19:14:49 -0700 Subject: [PATCH] Ensure that reserve transfer payments for ID registration go to correct, enforced transfer keys --- src/pbaas/pbaas.cpp | 29 +++++++++++++++++++++++++++++ src/rpc/pbaasrpc.cpp | 26 +++++++++++++++++++++----- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/pbaas/pbaas.cpp b/src/pbaas/pbaas.cpp index 4fe31804573..7e745e0ef23 100644 --- a/src/pbaas/pbaas.cpp +++ b/src/pbaas/pbaas.cpp @@ -1981,6 +1981,35 @@ bool PrecheckReserveTransfer(const CTransaction &tx, int32_t outNum, CValidation (rt = CReserveTransfer(p.vData[0])).IsValid() && rt.TotalCurrencyOut().valueMap[ASSETCHAINS_CHAINID] == tx.vout[outNum].nValue) { + // reserve transfers must be spendable by the export public / private key + CCcontract_info CC; + CCcontract_info *cp; + + // make a currency definition + cp = CCinit(&CC, EVAL_RESERVE_TRANSFER); + + bool haveRTKey = false; + + CTxDestination RTKey = DecodeDestination(cp->unspendableCCaddr); + for (auto oneKey : p.vKeys) + { + if (oneKey == RTKey) + { + haveRTKey = true; + break; + } + } + COptCCParams master; + if (!haveRTKey || + p.version < p.VERSION_V3 || + p.m != 1 || + p.vData.size() < 2 || + !(master = COptCCParams(p.vData.back())).IsValid() || + master.m > 1) + { + return state.Error("Reserve transfer must be spendable solely by private key of reserve transfer smart transaction " + rt.ToUniValue().write(1,2)); + } + uint160 systemDestID, importCurrencyID; CCurrencyDefinition systemDest, importCurrencyDef; diff --git a/src/rpc/pbaasrpc.cpp b/src/rpc/pbaasrpc.cpp index 2d1f8f39f07..ef78b928ee7 100644 --- a/src/rpc/pbaasrpc.cpp +++ b/src/rpc/pbaasrpc.cpp @@ -8794,7 +8794,7 @@ UniValue definecurrency(const UniValue& params, bool fHelp) cp = CCinit(&CC, EVAL_RESERVE_TRANSFER); CPubKey pk(ParseHex(CC.CChexstr)); - dests = std::vector({pk}); + dests = std::vector({pk.GetID()}); tb.AddTransparentOutput(MakeMofNCCScript(CConditionObj(EVAL_RESERVE_TRANSFER, dests, 1, &rt)), newChain.currencies[i] == thisChainID ? contribution + fee : fee); @@ -8947,7 +8947,7 @@ UniValue definecurrency(const UniValue& params, bool fHelp) cp = CCinit(&CC, EVAL_RESERVE_TRANSFER); CPubKey pk(ParseHex(CC.CChexstr)); - dests = std::vector({pk}); + dests = std::vector({pk.GetID()}); tb.AddTransparentOutput(MakeMofNCCScript(CConditionObj(EVAL_RESERVE_TRANSFER, dests, 1, &rt)), newGatewayConverter.currencies[i] == thisChainID ? contribution + fee : fee); @@ -9908,7 +9908,15 @@ UniValue registeridentity(const UniValue& params, bool fHelp) issuerID, DestinationToTransferDestination(CIdentityID(issuerID))); registrationPaymentOut = outputs.size(); - outputs.push_back({MakeMofNCCScript(CConditionObj(EVAL_RESERVE_TRANSFER, std::vector({CIdentityID(issuerID)}), 1, &rt)), ConnectedChains.ThisChain().IDImportFee(), false}); + + CCcontract_info CC; + CCcontract_info *cp; + cp = CCinit(&CC, EVAL_RESERVE_TRANSFER); + CPubKey pk(ParseHex(CC.CChexstr)); + + std::vector dests = std::vector({pk.GetID()}); + + outputs.push_back({MakeMofNCCScript(CConditionObj(EVAL_RESERVE_TRANSFER, dests, 1, &rt)), ConnectedChains.ThisChain().IDImportFee(), false}); } // add referrals, Verus supports referrals @@ -9999,11 +10007,19 @@ UniValue registeridentity(const UniValue& params, bool fHelp) CReserveTransfer rt(CReserveTransfer::VALID + CReserveTransfer::BURN_CHANGE_PRICE, CCurrencyValueMap(std::vector({issuerID}), std::vector({feeOffer})), ASSETCHAINS_CHAINID, - ConnectedChains.ThisChain().IDImportFee(), + ConnectedChains.ThisChain().GetTransactionTransferFee(), issuerID, DestinationToTransferDestination(CIdentityID(issuerID))); + + CCcontract_info CC; + CCcontract_info *cp; + cp = CCinit(&CC, EVAL_RESERVE_TRANSFER); + CPubKey pk(ParseHex(CC.CChexstr)); + + std::vector dests = std::vector({pk.GetID()}); + outputs[registrationPaymentOut].scriptPubKey = MakeMofNCCScript(CConditionObj(EVAL_RESERVE_TRANSFER, - std::vector({CIdentityID(issuerID)}), + dests, 1, &rt)); }