From e16559ae82f0f24c3dc29693c444f40d676ebff9 Mon Sep 17 00:00:00 2001 From: Mikael <26343374+0xmikko@users.noreply.github.com> Date: Wed, 6 Dec 2023 10:26:41 +0100 Subject: [PATCH] fix: quota min value fixed to proper formula --- contracts/libraries/CollateralLogic.sol | 2 +- .../test/unit/core/PriceOracleV3.unit.t.sol | 2 - .../unit/credit/CreditManagerV3.unit.t.sol | 2 +- .../unit/libraries/CollateralLogic.unit.t.sol | 52 +++++++++---------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/contracts/libraries/CollateralLogic.sol b/contracts/libraries/CollateralLogic.sol index 8d8fde5b..dee618b1 100644 --- a/contracts/libraries/CollateralLogic.sol +++ b/contracts/libraries/CollateralLogic.sol @@ -263,7 +263,7 @@ library CollateralLogic { unchecked { valueUSD = convertToUSDFn(priceOracle, balance - 1, token); // U:[CLL-1] } - weightedValueUSD = Math.min(valueUSD, quotaUSD) * liquidationThreshold / PERCENTAGE_FACTOR; // U:[CLL-1] + weightedValueUSD = Math.min(valueUSD * liquidationThreshold / PERCENTAGE_FACTOR, quotaUSD); // U:[CLL-1] nonZeroBalance = true; // U:[CLL-1] } } diff --git a/contracts/test/unit/core/PriceOracleV3.unit.t.sol b/contracts/test/unit/core/PriceOracleV3.unit.t.sol index 26a66caa..6884dc42 100644 --- a/contracts/test/unit/core/PriceOracleV3.unit.t.sol +++ b/contracts/test/unit/core/PriceOracleV3.unit.t.sol @@ -37,7 +37,6 @@ contract PriceOracleV3UnitTest is Test, IPriceOracleV3Events { // ----------------------- // /// @notice U:[PO-1]: `_getPrice` works as expected - /// forge-config: default.fuzz.runs = 5000 function test_U_PO_01_getPrice_works_as_expected( int256 answer, uint256 updatedAt, @@ -77,7 +76,6 @@ contract PriceOracleV3UnitTest is Test, IPriceOracleV3Events { } /// @notice U:[PO-2]: `_getPriceFeedParams` works as expected - /// forge-config: default.fuzz.runs = 5000 function test_U_PO_02_getPriceFeedParams_works_as_expected(address token, PriceFeedParams memory expectedParams) public { diff --git a/contracts/test/unit/credit/CreditManagerV3.unit.t.sol b/contracts/test/unit/credit/CreditManagerV3.unit.t.sol index 48adf1ae..efd22450 100644 --- a/contracts/test/unit/credit/CreditManagerV3.unit.t.sol +++ b/contracts/test/unit/credit/CreditManagerV3.unit.t.sol @@ -1825,7 +1825,7 @@ contract CreditManagerV3UnitTest is TestHelper, ICreditManagerV3Events, BalanceH stEthBalance: 0, usdcBalance: 0, expectedTotalValueUSD: 2 * vars.get("LINK_QUOTA_IN_USD"), - expectedTwvUSD: vars.get("LINK_QUOTA_IN_USD") * vars.get("LINK_LT") / PERCENTAGE_FACTOR, + expectedTwvUSD: vars.get("LINK_QUOTA_IN_USD"), expectedEnabledTokensMask: LINK_TOKEN_MASK }), CollateralCalcTestCase({ diff --git a/contracts/test/unit/libraries/CollateralLogic.unit.t.sol b/contracts/test/unit/libraries/CollateralLogic.unit.t.sol index 581115ea..a27fe7ec 100644 --- a/contracts/test/unit/libraries/CollateralLogic.unit.t.sol +++ b/contracts/test/unit/libraries/CollateralLogic.unit.t.sol @@ -96,7 +96,7 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { quotaUSD: 40_00, // expectedValueUSD: (5_000 - 1) * 2, - expectedWeightedValueUSD: 40_00 * 80_00 / PERCENTAGE_FACTOR, + expectedWeightedValueUSD: 40_00, expectedNonZeroBalance: true, priceOracleCalled: true }) @@ -383,28 +383,28 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000})), target: type(uint256).max, expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR, + expectedTwvUSD: (5_000 - 1) * prices[Tokens.DAI], expectedOrder: arrayOf(Tokens.USDT) }), CalcQuotedTokenCollateralTestCase({ name: "Two token calc, no target, one twv quota", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000}), B({t: Tokens.LINK, balance: 1_000})), + balances: arrayOf(B({t: Tokens.USDT, balance: 70_000}), B({t: Tokens.LINK, balance: 1_000})), quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000}), Q({t: Tokens.LINK, quota: 20_000})), target: type(uint256).max, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT] + (1_000 - 1) * prices[Tokens.LINK], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR + expectedTotalValueUSD: (70_000 - 1) * prices[Tokens.USDT] + (1_000 - 1) * prices[Tokens.LINK], + expectedTwvUSD: 5_000 * prices[Tokens.DAI] + (1_000 - 1) * prices[Tokens.LINK] * lts[Tokens.LINK] / PERCENTAGE_FACTOR, expectedOrder: arrayOf(Tokens.USDT, Tokens.LINK) }), CalcQuotedTokenCollateralTestCase({ name: "Stops when target reached", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000})), + balances: arrayOf(B({t: Tokens.USDT, balance: 20_000})), quotas: arrayOf( Q({t: Tokens.USDT, quota: 5_000}), Q({t: Tokens.WETH, quota: 50}), Q({t: Tokens.LINK, quota: 50_000}) ), - target: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR, + target: 5_000 * prices[Tokens.DAI], + expectedTotalValueUSD: (20_000 - 1) * prices[Tokens.USDT], + expectedTwvUSD: 5_000 * prices[Tokens.DAI], expectedOrder: arrayOf(Tokens.USDT) }) ]; @@ -500,8 +500,8 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { expectedOrder: arrayOf(Tokens.USDT) }), CalcCollateralTestCase({ - name: "One quoted token calc, no target, no hints, value < quota", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000})), + name: "One quoted token calc, no target, no hints, value > quota", + balances: arrayOf(B({t: Tokens.USDT, balance: 20_000})), quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000})), enabledTokensMask: getTokenMask(arrayOf(Tokens.USDT)), quotedTokensMask: getTokenMask(arrayOf(Tokens.USDT)), @@ -509,14 +509,14 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { minHealthFactor: PERCENTAGE_FACTOR, collateralHints: new uint256[](0), totalDebtUSD: 0, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR, + expectedTotalValueUSD: (20_000 - 1) * prices[Tokens.USDT], + expectedTwvUSD: 5_000 * prices[Tokens.DAI], expectedTokensToDisable: 0, expectedOrder: arrayOf(Tokens.USDT) }), CalcCollateralTestCase({ name: "It removes non-quoted tokens with 0 and 1 balances", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000}), B({t: Tokens.LINK, balance: 1})), + balances: arrayOf(B({t: Tokens.USDT, balance: 20_000}), B({t: Tokens.LINK, balance: 1})), quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000})), enabledTokensMask: getTokenMask(arrayOf(Tokens.USDT, Tokens.LINK, Tokens.DAI)), quotedTokensMask: getTokenMask(arrayOf(Tokens.USDT)), @@ -524,29 +524,29 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { minHealthFactor: PERCENTAGE_FACTOR, collateralHints: new uint256[](0), totalDebtUSD: 0, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR, + expectedTotalValueUSD: (20_000 - 1) * prices[Tokens.USDT], + expectedTwvUSD: 5_000 * prices[Tokens.DAI], expectedTokensToDisable: getTokenMask(arrayOf(Tokens.LINK, Tokens.DAI)), expectedOrder: arrayOf(Tokens.USDT, Tokens.DAI, Tokens.LINK) }), CalcCollateralTestCase({ name: "It stops if target reached during quoted token collateral computation", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000}), B({t: Tokens.LINK, balance: 1})), + balances: arrayOf(B({t: Tokens.USDT, balance: 20_000}), B({t: Tokens.LINK, balance: 1})), quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000}), Q({t: Tokens.WETH, quota: 5_000})), enabledTokensMask: getTokenMask(arrayOf(Tokens.USDT, Tokens.WETH, Tokens.LINK, Tokens.DAI)), quotedTokensMask: getTokenMask(arrayOf(Tokens.USDT, Tokens.WETH)), lazy: true, minHealthFactor: 2 * PERCENTAGE_FACTOR, collateralHints: new uint256[](0), - totalDebtUSD: (5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR) / 2, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR, + totalDebtUSD: 5_000 * prices[Tokens.DAI] / 2, + expectedTotalValueUSD: (20_000 - 1) * prices[Tokens.USDT], + expectedTwvUSD: 5_000 * prices[Tokens.DAI], expectedTokensToDisable: 0, expectedOrder: arrayOf(Tokens.USDT) }), CalcCollateralTestCase({ name: "It stops if target reached during non-quoted token collateral computation, and updates target properly after quoted calc", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000}), B({t: Tokens.DAI, balance: 8_000})), + balances: arrayOf(B({t: Tokens.USDT, balance: 20_000}), B({t: Tokens.DAI, balance: 8_000})), quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000}), Q({t: Tokens.WETH, quota: 5_000})), enabledTokensMask: getTokenMask(arrayOf(Tokens.USDT, Tokens.WETH, Tokens.LINK, Tokens.DAI)), quotedTokensMask: getTokenMask(arrayOf(Tokens.USDT, Tokens.WETH)), @@ -555,15 +555,15 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { collateralHints: new uint256[](0), totalDebtUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR + (8_000 - 1) * prices[Tokens.DAI] * lts[Tokens.DAI] / PERCENTAGE_FACTOR, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT] + (8_000 - 1) * prices[Tokens.DAI], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR + expectedTotalValueUSD: (20_000 - 1) * prices[Tokens.USDT] + (8_000 - 1) * prices[Tokens.DAI], + expectedTwvUSD: 5_000 * prices[Tokens.DAI] + (8_000 - 1) * prices[Tokens.DAI] * lts[Tokens.DAI] / PERCENTAGE_FACTOR, expectedTokensToDisable: 0, expectedOrder: arrayOf(Tokens.USDT, Tokens.WETH, Tokens.DAI) }), CalcCollateralTestCase({ name: "Collateral hints work for non-quoted tokens", - balances: arrayOf(B({t: Tokens.USDT, balance: 10_000}), B({t: Tokens.DAI, balance: 8_000})), + balances: arrayOf(B({t: Tokens.USDT, balance: 20_000}), B({t: Tokens.DAI, balance: 8_000})), quotas: arrayOf(Q({t: Tokens.USDT, quota: 5_000})), enabledTokensMask: getTokenMask(arrayOf(Tokens.USDT, Tokens.WETH, Tokens.LINK, Tokens.DAI)), quotedTokensMask: getTokenMask(arrayOf(Tokens.USDT)), @@ -572,8 +572,8 @@ contract CollateralLogicUnitTest is TestHelper, CollateralLogicHelper { collateralHints: getHints(arrayOf(Tokens.WETH, Tokens.LINK)), totalDebtUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR + (8_000 - 1) * prices[Tokens.DAI] * lts[Tokens.DAI] / PERCENTAGE_FACTOR, - expectedTotalValueUSD: (10_000 - 1) * prices[Tokens.USDT] + (8_000 - 1) * prices[Tokens.DAI], - expectedTwvUSD: 5_000 * prices[Tokens.DAI] * lts[Tokens.USDT] / PERCENTAGE_FACTOR + expectedTotalValueUSD: (20_000 - 1) * prices[Tokens.USDT] + (8_000 - 1) * prices[Tokens.DAI], + expectedTwvUSD: 5_000 * prices[Tokens.DAI] + (8_000 - 1) * prices[Tokens.DAI] * lts[Tokens.DAI] / PERCENTAGE_FACTOR, expectedTokensToDisable: getTokenMask(arrayOf(Tokens.WETH, Tokens.LINK)), expectedOrder: arrayOf(Tokens.USDT, Tokens.WETH, Tokens.LINK, Tokens.DAI)