diff --git a/src/dfi/rpc_poolpair.cpp b/src/dfi/rpc_poolpair.cpp index 381bb9307a..c1dd0858e4 100644 --- a/src/dfi/rpc_poolpair.cpp +++ b/src/dfi/rpc_poolpair.cpp @@ -1,6 +1,7 @@ #include #include +#include UniValue poolToJSON(const CCustomCSView &view, DCT_ID const &id, @@ -1430,13 +1431,48 @@ UniValue listloantokenliquidity(const JSONRPCRequest &request) { LOCK(cs_main); - UniValue ret(UniValue::VOBJ); + UniValue ret(UniValue::VARR); + const auto height = ::ChainActive().Height(); + + const auto attributes = pcustomcsview->GetAttributes(); + + CDataStructureV0 averageKey{AttributeTypes::Param, ParamIDs::DFIP2211F, DFIPKeys::AverageLiquidityPercentage}; + const auto averageLiquidityPercentage = attributes->GetValue(averageKey, DEFAULT_AVERAGE_LIQUIDITY_PERCENTAGE); + + const auto dusdToken = pcustomcsview->GetToken("DUSD"); + if (!dusdToken) { + return ret; + } + + const auto dusdId = dusdToken->first.v; + pcustomcsview->ForEachTokenAverageLiquidity([&](const LoanTokenAverageLiquidityKey &key, const uint64_t liquidity) { const auto sourceToken = pcustomcsview->GetToken(DCT_ID{key.sourceID}); const auto destToken = pcustomcsview->GetToken(DCT_ID{key.destID}); + if (sourceToken && destToken) { - ret.pushKV(sourceToken->symbol + '-' + destToken->symbol, GetDecimalString(liquidity)); + arith_uint256 totalSwapAmount{}; + pcustomcsview->ForEachFuturesUserValues( + [&](const CFuturesUserKey &, const CFuturesUserValue &futuresValues) { + const auto destination = futuresValues.destination ? futuresValues.destination : dusdId; + if (futuresValues.source.nTokenId.v == key.sourceID && destination == key.destID) { + totalSwapAmount += futuresValues.source.nValue; + } + return true; + }, + {static_cast(height), {}, std::numeric_limits::max()}); + + const auto liquidityLimit = MultiplyAmounts(liquidity, averageLiquidityPercentage); + + UniValue poolRes(UniValue::VOBJ); + UniValue limitRes(UniValue::VOBJ); + limitRes.pushKV("liquidity", GetDecimalString(liquidity)); + limitRes.pushKV("limit", GetDecimalString(liquidityLimit)); + limitRes.pushKV("remaining", GetDecimalString(liquidityLimit - totalSwapAmount.GetLow64())); + poolRes.pushKV(sourceToken->symbol + '-' + destToken->symbol, limitRes); + ret.push_back(poolRes); } + return true; }); diff --git a/test/functional/feature_future_swap_limitation.py b/test/functional/feature_future_swap_limitation.py index 5f208dcbcf..e82a003efd 100755 --- a/test/functional/feature_future_swap_limitation.py +++ b/test/functional/feature_future_swap_limitation.py @@ -312,7 +312,22 @@ def test_future_swap_limitation(self): # Check liquidity data assert_equal( self.nodes[0].listloantokenliquidity(), - {"META-DUSD": "100.00000000", "DUSD-META": "100.00000000"}, + [ + { + "META-DUSD": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "10.00000000", + } + }, + { + "DUSD-META": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "10.00000000", + } + }, + ], ) # Try and swap above limit @@ -347,11 +362,81 @@ def test_future_swap_limitation(self): ) self.nodes[0].generate(1) - # Swap the max limit + # Swap half the limit self.nodes[0].futureswap(self.address, "5.00000000@META") + self.nodes[0].generate(1) + + # Check liquidity data + assert_equal( + self.nodes[0].listloantokenliquidity(), + [ + { + "META-DUSD": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "5.00000000", + } + }, + { + "DUSD-META": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "10.00000000", + } + }, + ], + ) + + # Swap the max limit self.nodes[0].futureswap(self.address, "5.00000000@META") self.nodes[0].generate(1) + # Check liquidity data + assert_equal( + self.nodes[0].listloantokenliquidity(), + [ + { + "META-DUSD": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "0.00000000", + } + }, + { + "DUSD-META": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "10.00000000", + } + }, + ], + ) + + # Swap the max limit in the other direction + self.nodes[0].futureswap(self.address, "10.00000000@DUSD", "META") + self.nodes[0].generate(1) + + # Check liquidity data + assert_equal( + self.nodes[0].listloantokenliquidity(), + [ + { + "META-DUSD": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "0.00000000", + } + }, + { + "DUSD-META": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "0.00000000", + } + }, + ], + ) + # Try and swap above limit assert_raises_rpc_error( -32600, @@ -367,7 +452,22 @@ def test_future_swap_limitation(self): # Check liquidity data changed assert_equal( self.nodes[0].listloantokenliquidity(), - {"META-DUSD": "69.98499472", "DUSD-META": "160.00000000"}, + [ + { + "META-DUSD": { + "liquidity": "69.98499472", + "limit": "6.99849947", + "remaining": "6.99849947", + } + }, + { + "DUSD-META": { + "liquidity": "160.00000000", + "limit": "16.00000000", + "remaining": "16.00000000", + } + }, + ], ) # Try and swap above new limit @@ -415,7 +515,7 @@ def test_future_swap_limitation(self): self.nodes[0].generate(1) # Check liquidity data empty - assert_equal(self.nodes[0].listloantokenliquidity(), {}) + assert_equal(self.nodes[0].listloantokenliquidity(), []) def test_longer_fs_limit_period(self): @@ -464,7 +564,22 @@ def test_longer_fs_limit_period(self): # Check minimum liquidity assert_equal( self.nodes[0].listloantokenliquidity(), - {"META-DUSD": "100.00000000", "DUSD-META": "100.00000000"}, + [ + { + "META-DUSD": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "10.00000000", + } + }, + { + "DUSD-META": { + "liquidity": "100.00000000", + "limit": "10.00000000", + "remaining": "10.00000000", + } + }, + ], )