From 34d00ad2aa85b4beb43f8d0b8c4ccf63de84f722 Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Wed, 30 Mar 2022 10:37:25 +0100 Subject: [PATCH] Invert DFIP2203 token flag. Fix bug in attrs to refund disabled token. --- src/masternodes/govvariables/attributes.cpp | 15 +++++++---- src/masternodes/govvariables/attributes.h | 2 +- src/masternodes/mn_checks.cpp | 12 ++++----- src/validation.cpp | 6 ++--- test/functional/feature_futures.py | 28 ++++++++++++++++++--- test/functional/feature_setgov.py | 12 ++++----- 6 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/masternodes/govvariables/attributes.cpp b/src/masternodes/govvariables/attributes.cpp index f8af1de9da..f5b2ea9932 100644 --- a/src/masternodes/govvariables/attributes.cpp +++ b/src/masternodes/govvariables/attributes.cpp @@ -96,7 +96,7 @@ const std::map>& ATTRIBUTES::allowedKeys {"loan_payback_fee_pct",TokenKeys::LoanPaybackFeePCT}, {"dex_in_fee_pct", TokenKeys::DexInFeePct}, {"dex_out_fee_pct", TokenKeys::DexOutFeePct}, - {"dfip2203_disabled", TokenKeys::DFIP2203Disabled}, + {"dfip2203", TokenKeys::DFIP2203Enabled}, } }, { @@ -128,7 +128,7 @@ const std::map>& ATTRIBUTES::displayKeys {TokenKeys::LoanPaybackFeePCT,"loan_payback_fee_pct"}, {TokenKeys::DexInFeePct, "dex_in_fee_pct"}, {TokenKeys::DexOutFeePct, "dex_out_fee_pct"}, - {TokenKeys::DFIP2203Disabled, "dfip2203_disabled"}, + {TokenKeys::DFIP2203Enabled, "dfip2203"}, } }, { @@ -212,7 +212,7 @@ const std::maptypeId); } break; - case TokenKeys::DFIP2203Disabled: + case TokenKeys::DFIP2203Enabled: if (view.GetLastHeight() < Params().GetConsensus().FortCanningRoadHeight) { return Res::Err("Cannot be set before FortCanningRoad"); } @@ -633,7 +633,7 @@ Res ATTRIBUTES::Apply(CCustomCSView & mnview, const uint32_t height) return res; } } - if (attrV0->key == TokenKeys::DFIP2203Disabled) { + if (attrV0->key == TokenKeys::DFIP2203Enabled) { // Skip on block period change to avoid refunding and erasing entries. // Block period change will check for conflicting entries, deleting them @@ -642,6 +642,11 @@ Res ATTRIBUTES::Apply(CCustomCSView & mnview, const uint32_t height) continue; } + auto value = boost::get(attribute.second); + if (value) { + continue; + } + const auto token = mnview.GetLoanTokenByID(DCT_ID{attrV0->typeId}); if (!token) { return Res::Err("No such loan token (%d)", attrV0->typeId); diff --git a/src/masternodes/govvariables/attributes.h b/src/masternodes/govvariables/attributes.h index 75cad78450..3ca09e0c98 100644 --- a/src/masternodes/govvariables/attributes.h +++ b/src/masternodes/govvariables/attributes.h @@ -48,7 +48,7 @@ enum TokenKeys : uint8_t { LoanPaybackFeePCT = 'd', DexInFeePct = 'e', DexOutFeePct = 'f', - DFIP2203Disabled = 'g', + DFIP2203Enabled = 'g', }; enum PoolKeys : uint8_t { diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index 15b41802f7..381c970021 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -1497,9 +1497,9 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor } if (source->symbol == "DUSD") { - CDataStructureV0 tokenKey{AttributeTypes::Token, obj.destination, TokenKeys::DFIP2203Disabled}; - const auto disabled = attributes->GetValue(tokenKey, false); - if (disabled) { + CDataStructureV0 tokenKey{AttributeTypes::Token, obj.destination, TokenKeys::DFIP2203Enabled}; + const auto enabled = attributes->GetValue(tokenKey, true); + if (!enabled) { return Res::Err("DFIP2203 currently disabled for token %d", obj.destination); } @@ -1512,9 +1512,9 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor return Res::Err("Destination should not be set when source amount is a dToken"); } - CDataStructureV0 tokenKey{AttributeTypes::Token, obj.source.nTokenId.v, TokenKeys::DFIP2203Disabled}; - const auto disabled = attributes->GetValue(tokenKey, false); - if (disabled) { + CDataStructureV0 tokenKey{AttributeTypes::Token, obj.source.nTokenId.v, TokenKeys::DFIP2203Enabled}; + const auto enabled = attributes->GetValue(tokenKey, true); + if (!enabled) { return Res::Err("DFIP2203 currently disabled for token %s", obj.source.nTokenId.ToString()); } } diff --git a/src/validation.cpp b/src/validation.cpp index 1b1e272a30..bb73081992 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3321,12 +3321,12 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache const auto premium{COIN + rewardPct}; std::map futuresPrices; - CDataStructureV0 tokenKey{AttributeTypes::Token, 0, TokenKeys::DFIP2203Disabled}; + CDataStructureV0 tokenKey{AttributeTypes::Token, 0, TokenKeys::DFIP2203Enabled}; cache.ForEachLoanToken([&](const DCT_ID& id, const CLoanView::CLoanSetLoanTokenImpl& loanToken) { tokenKey.typeId = id.v; - const auto disabled = attributes->GetValue(tokenKey, false); - if (disabled) { + const auto enabled = attributes->GetValue(tokenKey, true); + if (!enabled) { return true; } diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index e5dc4fabc4..cf0349afc5 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -223,12 +223,12 @@ def futures_setup(self): assert_equal(result['v0/params/dfip2203/block_period'], str(self.futures_interval)) # Disable DUSD - self.nodes[0].setgov({"ATTRIBUTES":{f'v0/token/{str(self.idDUSD)}/dfip2203_disabled':'true'}}) + self.nodes[0].setgov({"ATTRIBUTES":{f'v0/token/{str(self.idDUSD)}/dfip2203':'false'}}) self.nodes[0].generate(1) # Verify Gov vars result = self.nodes[0].getgov('ATTRIBUTES')['ATTRIBUTES'] - assert_equal(result[f'v0/token/{self.idDUSD}/dfip2203_disabled'], 'true') + assert_equal(result[f'v0/token/{self.idDUSD}/dfip2203'], 'false') # Check futures block next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) @@ -832,7 +832,7 @@ def check_gov_var_change(self): self.nodes[0].generate(1) # Disable GOOGL - self.nodes[0].setgov({"ATTRIBUTES":{f'v0/token/{str(self.idGOOGL)}/dfip2203_disabled':'true'}}) + self.nodes[0].setgov({"ATTRIBUTES":{f'v0/token/{str(self.idGOOGL)}/dfip2203':'false'}}) self.nodes[0].generate(1) # Only TSLA contract should remain @@ -850,6 +850,26 @@ def check_gov_var_change(self): result = self.nodes[0].getaccount(address_tsla) assert_equal(result, []) + # Enable GOOGL + self.nodes[0].setgov({"ATTRIBUTES":{f'v0/token/{str(self.idGOOGL)}/dfip2203':'true'}}) + self.nodes[0].generate(1) + + # Create user futures contracts + self.nodes[0].futureswap(address_googl, f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}', int(self.idGOOGL)) + self.nodes[0].generate(1) + + # GOOGL balance should be empty + result = self.nodes[0].getaccount(address_googl) + assert_equal(result, []) + + # Disable GOOGL + self.nodes[0].setgov({"ATTRIBUTES":{f'v0/token/{str(self.idGOOGL)}/dfip2203':'false'}}) + self.nodes[0].generate(1) + + # Balance should be restored + result = self.nodes[0].getaccount(address_googl) + assert_equal(result, [f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) + # Move to next futures block next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) @@ -940,7 +960,7 @@ def rpc_history(self): # Check all swap refunds present result = self.nodes[0].listaccounthistory('all', {'txtype':'w'}) - assert_equal(len(result), 7) + assert_equal(len(result), 9) # Check swap by specific address result = self.nodes[0].listaccounthistory(self.list_history[0]['swaps'][0]['address'], {'txtype':'q'}) diff --git a/test/functional/feature_setgov.py b/test/functional/feature_setgov.py index 811f619859..9b35f9e937 100755 --- a/test/functional/feature_setgov.py +++ b/test/functional/feature_setgov.py @@ -445,7 +445,7 @@ def run_test(self): assert_raises_rpc_error(-5, "Empty value", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/15/payback_dfi':''}}) assert_raises_rpc_error(-5, "Incorrect key for . Object of ['//ID/','value'] expected", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/payback_dfi':'true'}}) assert_raises_rpc_error(-5, "Unrecognised type argument provided, valid types are: params, poolpairs, token,", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/unrecognised/5/payback_dfi':'true'}}) - assert_raises_rpc_error(-5, "Unrecognised key argument provided, valid keys are: dex_in_fee_pct, dex_out_fee_pct, dfip2203_disabled, loan_payback, loan_payback_fee_pct, payback_dfi, payback_dfi_fee_pct,", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/unrecognised':'true'}}) + assert_raises_rpc_error(-5, "Unrecognised key argument provided, valid keys are: dex_in_fee_pct, dex_out_fee_pct, dfip2203, loan_payback, loan_payback_fee_pct, payback_dfi, payback_dfi_fee_pct,", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/unrecognised':'true'}}) assert_raises_rpc_error(-5, "Value must be a positive integer", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/not_a_number/payback_dfi':'true'}}) assert_raises_rpc_error(-5, 'Boolean value must be either "true" or "false"', self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/payback_dfi':'not_a_number'}}) assert_raises_rpc_error(-5, 'Boolean value must be either "true" or "false"', self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/payback_dfi':'unrecognised'}}) @@ -465,7 +465,7 @@ def run_test(self): assert_raises_rpc_error(-32600, "ATTRIBUTES: Cannot be set before FortCanningRoad", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/active':'true'}}) assert_raises_rpc_error(-32600, "ATTRIBUTES: Cannot be set before FortCanningRoad", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/reward_pct':'0.05'}}) assert_raises_rpc_error(-32600, "ATTRIBUTES: Cannot be set before FortCanningRoad", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/block_period':'2880'}}) - assert_raises_rpc_error(-32600, "ATTRIBUTES: Cannot be set before FortCanningRoad", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/dfip2203_disabled':'true'}}) + assert_raises_rpc_error(-32600, "ATTRIBUTES: Cannot be set before FortCanningRoad", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/dfip2203':'true'}}) # Setup for loan related tests oracle_address = self.nodes[0].getnewaddress("", "legacy") @@ -566,13 +566,13 @@ def run_test(self): assert_raises_rpc_error(-5, "Percentage exceeds 100%", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/reward_pct':'2'}}) assert_raises_rpc_error(-5, "Value must be a positive integer", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/block_period':'not_a_number'}}) assert_raises_rpc_error(-5, "Value must be a positive integer", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/block_period':'-1'}}) - assert_raises_rpc_error(-5, "Boolean value must be either \"true\" or \"false\"", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/dfip2203_disabled':'not_a_bool'}}) - assert_raises_rpc_error(-32600, "No such loan token", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/4/dfip2203_disabled':'true'}}) + assert_raises_rpc_error(-5, "Boolean value must be either \"true\" or \"false\"", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/5/dfip2203':'not_a_bool'}}) + assert_raises_rpc_error(-32600, "No such loan token", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/token/4/dfip2203':'true'}}) assert_raises_rpc_error(-5, "Unsupported type for DFIP2203", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/premium': '0.025'}}) assert_raises_rpc_error(-5, "Unsupported type for DFIP2203", self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/minswap': '0.025'}}) # Test setting FCR ATTRBIUTES - self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2203/reward_pct':'0.05','v0/params/dfip2203/block_period':'20160','v0/token/5/dfip2203_disabled':'true'}}) + self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2203/reward_pct':'0.05','v0/params/dfip2203/block_period':'20160','v0/token/5/dfip2203':'true'}}) self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2203/active':'true'}}) self.nodes[0].generate(1) @@ -581,7 +581,7 @@ def run_test(self): assert_equal(result['v0/params/dfip2203/active'], 'true') assert_equal(result['v0/params/dfip2203/reward_pct'], '0.05') assert_equal(result['v0/params/dfip2203/block_period'], '20160') - assert_equal(result['v0/token/5/dfip2203_disabled'], 'true') + assert_equal(result['v0/token/5/dfip2203'], 'true') if __name__ == '__main__': GovsetTest ().main ()