Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bench/duplicate_inputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static void DuplicateInputs(benchmark::State& state)
coinbaseTx.vin[0].prevout.SetNull();
coinbaseTx.vout.resize(1);
coinbaseTx.vout[0].scriptPubKey = SCRIPT_PUB;
coinbaseTx.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus());
coinbaseTx.vout[0].nValue = GetBlockSubsidy(*pcustomcsview, nHeight, chainparams.GetConsensus());
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;


Expand Down
5 changes: 4 additions & 1 deletion src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <chain.h>

#include <dfi/govvariables/attributes.h>
#include <dfi/masternodes.h>

/**
* CChain implementation
*/
Expand Down Expand Up @@ -144,7 +147,7 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr
r = from.nChainWork - to.nChainWork;
sign = -1;
}
r = r * arith_uint256(params.pos.nTargetSpacing) / GetBlockProof(tip);
r = r * arith_uint256(GetTargetSpacing(*pcustomcsview)) / GetBlockProof(tip);
if (r.bits() > 63) {
return sign * std::numeric_limits<int64_t>::max();
}
Expand Down
15 changes: 0 additions & 15 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,6 @@ struct Params {
};
PoS pos;

uint32_t blocksPerDay() const {
static const uint32_t blocks = 60 * 60 * 24 / pos.nTargetSpacing;
return blocks;
}

uint32_t blocksCollateralizationRatioCalculation() const {
static const uint32_t blocks = 15 * 60 / pos.nTargetSpacing;
return blocks;
}

uint32_t blocksCollateralAuction() const {
static const uint32_t blocks = 6 * 60 * 60 / pos.nTargetSpacing;
return blocks;
}

/**
* Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,
* (nTargetTimespan / nTargetSpacing) which is also used for BIP9 deployments.
Expand Down
2 changes: 1 addition & 1 deletion src/dfi/consensus/masternodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Res CMasternodesConsensus::CheckMasternodeCreationTx() const {
const auto height = txCtx.GetHeight();
const auto &tx = txCtx.GetTransaction();

if (tx.vout.size() < 2 || tx.vout[0].nValue < GetMnCreationFee(height) || tx.vout[0].nTokenId != DCT_ID{0} ||
if (tx.vout.size() < 2 || tx.vout[0].nValue < GetMnCreationFee() || tx.vout[0].nTokenId != DCT_ID{0} ||
tx.vout[1].nValue != GetMnCollateralAmount(height) || tx.vout[1].nTokenId != DCT_ID{0}) {
return Res::Err("malformed tx vouts (wrong creation fee or collateral amount)");
}
Expand Down
6 changes: 6 additions & 0 deletions src/dfi/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@ class DeFiErrors {
return Res::Err("Unsupported key for Rules {%d}", type);
}

static Res GovVarVariableUnsupportedBlockTimeType(const unsigned char type) {
return Res::Err("Unsupported key for BlockTime {%d}", type);
}

static Res GovVarVariableUnsupportedParamType() { return Res::Err("Unsupported Param ID"); }

static Res GovVarVariableUnsupportedGovType() { return Res::Err("Unsupported Governance ID"); }
Expand All @@ -264,6 +268,8 @@ class DeFiErrors {

static Res GovVarValidateDF23Height() { return Res::Err("Cannot be set before DF23Height"); }

static Res GovVarValidateDF24Height() { return Res::Err("Cannot be set before DF24Height"); }

static Res GovVarValidateToken(const uint32_t token) { return Res::Err("No such token (%d)", token); }

static Res GovVarValidateTokenExist(const uint32_t token) { return Res::Err("Token (%d) does not exist", token); }
Expand Down
71 changes: 70 additions & 1 deletion src/dfi/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ const std::map<std::string, uint8_t> &ATTRIBUTES::allowedParamIDs() {
{"dfip2211f", ParamIDs::DFIP2211F },
{"feature", ParamIDs::Feature },
{"foundation", ParamIDs::Foundation},
{"block_time", ParamIDs::BlockTime },
};
return params;
}
Expand All @@ -119,6 +120,7 @@ const std::map<uint8_t, std::string> &ATTRIBUTES::allowedExportParamsIDs() {
{ParamIDs::DFIP2211F, "dfip2211f" },
{ParamIDs::Feature, "feature" },
{ParamIDs::Foundation, "foundation"},
{ParamIDs::BlockTime, "block_time"},
};
return params;
}
Expand Down Expand Up @@ -283,6 +285,9 @@ const std::map<uint8_t, std::map<std::string, uint8_t>> &ATTRIBUTES::allowedKeys
{"transferdomain", DFIPKeys::TransferDomain},
{"liquidity_calc_sampling_period", DFIPKeys::LiquidityCalcSamplingPeriod},
{"average_liquidity_percentage", DFIPKeys::AverageLiquidityPercentage},
{"emission_reduction", DFIPKeys::EmissionReduction},
{"target_spacing", DFIPKeys::TargetSpacing},
{"target_timespan", DFIPKeys::TargetTimespam},
}},
{AttributeTypes::EVMType,
{
Expand Down Expand Up @@ -388,6 +393,9 @@ const std::map<uint8_t, std::map<uint8_t, std::string>> &ATTRIBUTES::displayKeys
{DFIPKeys::TransferDomain, "transferdomain"},
{DFIPKeys::LiquidityCalcSamplingPeriod, "liquidity_calc_sampling_period"},
{DFIPKeys::AverageLiquidityPercentage, "average_liquidity_percentage"},
{DFIPKeys::EmissionReduction, "emission_reduction"},
{DFIPKeys::TargetSpacing, "target_spacing"},
{DFIPKeys::TargetTimespam, "target_timespan"},
}},
{AttributeTypes::EVMType,
{
Expand Down Expand Up @@ -491,6 +499,18 @@ static ResVal<CAttributeValue> VerifyUInt64(const std::string &str) {
return {x, Res::Ok()};
}

static ResVal<CAttributeValue> VerifyMoreThenZeroUInt32(const std::string &str) {
auto resVal = VerifyUInt32(str);
if (!resVal) {
return resVal;
}
const auto value = std::get<uint32_t>(*resVal.val);
if (value == 0) {
return DeFiErrors::GovVarVerifyFactor();
}
return resVal;
}

static ResVal<CAttributeValue> VerifyMoreThenZeroUInt64(const std::string &str) {
auto resVal = VerifyUInt64(str);
if (!resVal) {
Expand Down Expand Up @@ -817,6 +837,9 @@ const std::map<uint8_t, std::map<uint8_t, std::function<ResVal<CAttributeValue>(
{DFIPKeys::TransferDomain, VerifyBool},
{DFIPKeys::LiquidityCalcSamplingPeriod, VerifyMoreThenZeroInt64},
{DFIPKeys::AverageLiquidityPercentage, VerifyPctInt64},
{DFIPKeys::EmissionReduction, VerifyMoreThenZeroUInt32},
{DFIPKeys::TargetSpacing, VerifyMoreThenZeroInt64},
{DFIPKeys::TargetTimespam, VerifyMoreThenZeroInt64},
Comment thread
prasannavl marked this conversation as resolved.
Outdated
}},
{AttributeTypes::Locks,
{
Expand Down Expand Up @@ -994,6 +1017,11 @@ static Res CheckValidAttrV0Key(const uint8_t type, const uint32_t typeId, const
if (typeKey != DFIPKeys::Members) {
return DeFiErrors::GovVarVariableUnsupportedFoundationType(typeKey);
}
} else if (typeId == ParamIDs::BlockTime) {
if (typeKey != DFIPKeys::EmissionReduction && typeKey != DFIPKeys::TargetSpacing &&
typeKey != DFIPKeys::TargetTimespam) {
return DeFiErrors::GovVarVariableUnsupportedBlockTimeType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedParamType();
}
Expand Down Expand Up @@ -2083,6 +2111,10 @@ Res ATTRIBUTES::Validate(const CCustomCSView &view) const {
return DeFiErrors::GovVarValidateBlockPeriod();
}
}
} else if (attrV0->typeId == ParamIDs::BlockTime) {
if (view.GetLastHeight() < Params().GetConsensus().DF24Height) {
return DeFiErrors::GovVarValidateDF24Height();
}
} else if (attrV0->typeId != ParamIDs::DFIP2201) {
return Res::Err("Unrecognised param id");
}
Expand Down Expand Up @@ -2421,7 +2453,7 @@ Res ATTRIBUTES::Apply(CCustomCSView &mnview, const uint32_t height) {
return DeFiErrors::GovVarApplyAutoNoToken(split);
}

const auto startHeight = attrV0->key - Params().GetConsensus().blocksPerDay() / 2;
const auto startHeight = attrV0->key - BlocksPerDay(mnview) / 2;
if (height < startHeight) {
auto var = GovVariable::Create("ATTRIBUTES");
if (!var) {
Expand Down Expand Up @@ -2510,3 +2542,40 @@ Res ATTRIBUTES::Erase(CCustomCSView &mnview, uint32_t, const std::vector<std::st

return Res::Ok();
}

int64_t GetTargetSpacing(const CCustomCSView &view) {
const auto attributes = view.GetAttributes();
CDataStructureV0 key{AttributeTypes::Param, ParamIDs::BlockTime, DFIPKeys::TargetSpacing};
return attributes->GetValue(key, Params().GetConsensus().pos.nTargetSpacing);
}

int64_t GetTargetTimespan(const CCustomCSView &view) {
const auto attributes = view.GetAttributes();
CDataStructureV0 key{AttributeTypes::Param, ParamIDs::BlockTime, DFIPKeys::TargetTimespam};
return attributes->GetValue(key, Params().GetConsensus().pos.nTargetTimespanV2);
}

int64_t DifficultyAdjustment(const CCustomCSView &view) {
return GetTargetTimespan(view) / GetTargetSpacing(view);
}

int32_t GetEmissionReduction(const CCustomCSView &view) {
const auto attributes = view.GetAttributes();
CDataStructureV0 key{AttributeTypes::Param, ParamIDs::BlockTime, DFIPKeys::EmissionReduction};
return attributes->GetValue(key, Params().GetConsensus().emissionReductionPeriod);
}

uint32_t BlocksPerDay(const CCustomCSView &view) {
uint32_t blocks = 60 * 60 * 24 / GetTargetSpacing(view);
return blocks;
}

uint32_t BlocksCollateralizationRatioCalculation(const CCustomCSView &view) {
uint32_t blocks = 15 * 60 / GetTargetSpacing(view);
return blocks;
}

uint32_t BlocksCollateralAuction(const CCustomCSView &view) {
uint32_t blocks = 6 * 60 * 60 / GetTargetSpacing(view);
return blocks;
}
12 changes: 12 additions & 0 deletions src/dfi/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum ParamIDs : uint8_t {
Auction = 'i',
Foundation = 'j',
DFIP2211F = 'k',
BlockTime = 'l',
};

enum OracleIDs : uint8_t {
Expand Down Expand Up @@ -124,6 +125,9 @@ enum DFIPKeys : uint8_t {
TransferDomain = 'w',
LiquidityCalcSamplingPeriod = 'x',
AverageLiquidityPercentage = 'y',
EmissionReduction = 'z',
TargetSpacing = 'A',
TargetTimespam = 'B',
};

enum GovernanceKeys : uint8_t {
Expand Down Expand Up @@ -401,6 +405,14 @@ bool IsEVMEnabled(const std::shared_ptr<ATTRIBUTES> attributes);
bool IsEVMEnabled(const CCustomCSView &view);
Res StoreGovVars(const CGovernanceHeightMessage &obj, CCustomCSView &view);

int64_t GetTargetSpacing(const CCustomCSView &view);
int64_t GetTargetTimespan(const CCustomCSView &view);
int64_t DifficultyAdjustment(const CCustomCSView &view);
int32_t GetEmissionReduction(const CCustomCSView &view);
uint32_t BlocksPerDay(const CCustomCSView &view);
uint32_t BlocksCollateralizationRatioCalculation(const CCustomCSView &view);
uint32_t BlocksCollateralAuction(const CCustomCSView &view);

enum GovVarsFilter {
All,
NoAttributes,
Expand Down
59 changes: 39 additions & 20 deletions src/dfi/loan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,23 +197,32 @@ std::optional<CInterestRateV3> CLoanView::GetInterestRate(const CVaultId &vaultI

// Precision 64bit
template <typename T>
inline T InterestPerBlockCalculationV1(CAmount amount, CAmount tokenInterest, CAmount schemeInterest) {
inline T InterestPerBlockCalculationV1(const CCustomCSView &view,
CAmount amount,
CAmount tokenInterest,
CAmount schemeInterest) {
const auto netInterest = (tokenInterest + schemeInterest) / 100; // in %
static const auto blocksPerYear = T(365) * Params().GetConsensus().blocksPerDay();
static const auto blocksPerYear = T(365) * BlocksPerDay(view);
return MultiplyAmounts(netInterest, amount) / blocksPerYear;
}

// Precision 128bit
inline base_uint<128> InterestPerBlockCalculationV2(CAmount amount, CAmount tokenInterest, CAmount schemeInterest) {
inline base_uint<128> InterestPerBlockCalculationV2(const CCustomCSView &view,
CAmount amount,
CAmount tokenInterest,
CAmount schemeInterest) {
const auto netInterest = (tokenInterest + schemeInterest) / 100; // in %
static const auto blocksPerYear = 365 * Params().GetConsensus().blocksPerDay();
static const auto blocksPerYear = 365 * BlocksPerDay(view);
return arith_uint256(amount) * netInterest * COIN / blocksPerYear;
}

// Precision 128bit with negative interest
CInterestAmount InterestPerBlockCalculationV3(CAmount amount, CAmount tokenInterest, CAmount schemeInterest) {
CInterestAmount InterestPerBlockCalculationV3(const CCustomCSView &view,
CAmount amount,
CAmount tokenInterest,
CAmount schemeInterest) {
const auto netInterest = (tokenInterest + schemeInterest) / 100; // in %
static const auto blocksPerYear = 365 * Params().GetConsensus().blocksPerDay();
static const auto blocksPerYear = 365 * BlocksPerDay(view);
return {netInterest < 0 && amount > 0, arith_uint256(amount) * std::abs(netInterest) * COIN / blocksPerYear};
}

Expand Down Expand Up @@ -324,21 +333,24 @@ Res CLoanView::IncreaseInterest(const uint32_t height,

// Use argument token interest as update from Gov var TX will not be applied to GetLoanTokenByID at this point
// in time.
rate.interestPerBlock = InterestPerBlockCalculationV3(amounts.balances[id], tokenInterest, scheme->rate);
rate.interestPerBlock = InterestPerBlockCalculationV3(
*static_cast<CCustomCSView *>(this), amounts.balances[id], tokenInterest, scheme->rate);

} else if (height >= static_cast<uint32_t>(Params().GetConsensus().DF14FortCanningHillHeight)) {
CBalances amounts;
ReadBy<LoanTokenAmount>(vaultId, amounts);
rate.interestPerBlock = {false,
InterestPerBlockCalculationV2(amounts.balances[id], token->interest, scheme->rate)};
rate.interestPerBlock = {
false,
InterestPerBlockCalculationV2(
*static_cast<CCustomCSView *>(this), amounts.balances[id], token->interest, scheme->rate)};
} else if (height >= static_cast<uint32_t>(Params().GetConsensus().DF12FortCanningMuseumHeight)) {
CAmount interestPerBlock = rate.interestPerBlock.amount.GetLow64();
interestPerBlock +=
std::ceil(InterestPerBlockCalculationV1<float>(loanIncreased, token->interest, scheme->rate));
interestPerBlock += std::ceil(InterestPerBlockCalculationV1<float>(
*static_cast<CCustomCSView *>(this), loanIncreased, token->interest, scheme->rate));
rate.interestPerBlock = {false, interestPerBlock};
} else {
rate.interestPerBlock.amount +=
InterestPerBlockCalculationV1<CAmount>(loanIncreased, token->interest, scheme->rate);
rate.interestPerBlock.amount += InterestPerBlockCalculationV1<CAmount>(
*static_cast<CCustomCSView *>(this), loanIncreased, token->interest, scheme->rate);
}

WriteInterestRate(std::make_pair(vaultId, id), rate, height);
Expand Down Expand Up @@ -387,19 +399,23 @@ Res CLoanView::DecreaseInterest(const uint32_t height,
if (height >= static_cast<uint32_t>(Params().GetConsensus().DF18FortCanningGreatWorldHeight)) {
CBalances amounts;
ReadBy<LoanTokenAmount>(vaultId, amounts);
rate.interestPerBlock = InterestPerBlockCalculationV3(amounts.balances[id], token->interest, scheme->rate);
rate.interestPerBlock = InterestPerBlockCalculationV3(
*static_cast<CCustomCSView *>(this), amounts.balances[id], token->interest, scheme->rate);
} else if (height >= static_cast<uint32_t>(Params().GetConsensus().DF14FortCanningHillHeight)) {
CBalances amounts;
ReadBy<LoanTokenAmount>(vaultId, amounts);
rate.interestPerBlock = {false,
InterestPerBlockCalculationV2(amounts.balances[id], token->interest, scheme->rate)};
rate.interestPerBlock = {
false,
InterestPerBlockCalculationV2(
*static_cast<CCustomCSView *>(this), amounts.balances[id], token->interest, scheme->rate)};
} else if (height >= static_cast<uint32_t>(Params().GetConsensus().DF12FortCanningMuseumHeight)) {
CAmount interestPerBlock = rate.interestPerBlock.amount.GetLow64();
CAmount newInterestPerBlock =
std::ceil(InterestPerBlockCalculationV1<float>(loanDecreased, token->interest, scheme->rate));
CAmount newInterestPerBlock = std::ceil(InterestPerBlockCalculationV1<float>(
*static_cast<CCustomCSView *>(this), loanDecreased, token->interest, scheme->rate));
rate.interestPerBlock = {false, std::max(CAmount{0}, interestPerBlock - newInterestPerBlock)};
} else {
auto interestPerBlock = InterestPerBlockCalculationV1<CAmount>(loanDecreased, token->interest, scheme->rate);
auto interestPerBlock = InterestPerBlockCalculationV1<CAmount>(
*static_cast<CCustomCSView *>(this), loanDecreased, token->interest, scheme->rate);
rate.interestPerBlock = rate.interestPerBlock.amount < interestPerBlock
? CInterestAmount{false, 0}
: CInterestAmount{false, rate.interestPerBlock.amount - interestPerBlock};
Expand All @@ -423,7 +439,10 @@ void CLoanView::ResetInterest(const uint32_t height,
ReadBy<LoanTokenAmount>(vaultId, amounts);

const CInterestRateV3 rate{
height, InterestPerBlockCalculationV3(amounts.balances[id], token->interest, scheme->rate), {false, 0}
height,
InterestPerBlockCalculationV3(
*static_cast<CCustomCSView *>(this), amounts.balances[id], token->interest, scheme->rate),
{false, 0}
};

WriteInterestRate(std::make_pair(vaultId, id), rate, height);
Expand Down
8 changes: 6 additions & 2 deletions src/dfi/loan.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <flushablestorage.h>
#include <script/script.h>

class CCustomCSView;

class CLoanSetCollateralToken {
public:
DCT_ID idToken{UINT_MAX};
Expand Down Expand Up @@ -335,8 +337,10 @@ CAmount CeilInterest(const base_uint<128> &value, uint32_t height);
std::string GetInterestPerBlockHighPrecisionString(const CInterestAmount &value);
std::optional<std::string> TryGetInterestPerBlockHighPrecisionString(const CInterestAmount &value);

base_uint<128> InterestPerBlockCalculationV2(CAmount amount, CAmount tokenInterest, CAmount schemeInterest);
CInterestAmount InterestPerBlockCalculationV3(CAmount amount, CAmount tokenInterest, CAmount schemeInterest);
CInterestAmount InterestPerBlockCalculationV3(const CCustomCSView &view,
CAmount amount,
CAmount tokenInterest,
CAmount schemeInterest);

class CLoanTakeLoanMessage {
public:
Expand Down
Loading