From ac40ab54ed0676a50d57dd2a7b5782c7edd825c1 Mon Sep 17 00:00:00 2001 From: q1q0 Date: Sun, 1 Oct 2023 14:58:40 -0400 Subject: [PATCH 1/4] feat: update resolver --- .../protocols/mainnet/crvusd/helpers.sol | 3 + .../protocols/mainnet/crvusd/interfaces.sol | 19 ++++++ contracts/protocols/mainnet/crvusd/main.sol | 59 +++++++++++++++++++ test/mainnet/crv_usd.test.ts | 24 ++++++++ 4 files changed, 105 insertions(+) diff --git a/contracts/protocols/mainnet/crvusd/helpers.sol b/contracts/protocols/mainnet/crvusd/helpers.sol index 8bc4772..f8a319c 100644 --- a/contracts/protocols/mainnet/crvusd/helpers.sol +++ b/contracts/protocols/mainnet/crvusd/helpers.sol @@ -42,6 +42,9 @@ contract CRVHelpers is DSMath { config.borrowable = IERC20(CRV_USD).balanceOf(address(controller)); config.basePrice = I_LLAMMA(AMM).get_base_price(); config.A = I_LLAMMA(AMM).A(); + config.minBand = I_LLAMMA(AMM).min_band(); + config.maxBand = I_LLAMMA(AMM).max_band(); + try IMonetary(monetary).rate(address(controller)) returns (uint256 rate) { config.fractionPerSecond = rate; } catch { diff --git a/contracts/protocols/mainnet/crvusd/interfaces.sol b/contracts/protocols/mainnet/crvusd/interfaces.sol index e5e3bb5..04d3aec 100644 --- a/contracts/protocols/mainnet/crvusd/interfaces.sol +++ b/contracts/protocols/mainnet/crvusd/interfaces.sol @@ -9,6 +9,7 @@ struct PositionData { uint256 health; UserPrices prices; uint256 loanId; + int256[2] userTickNumber; // calculating for user band range } struct UserPrices { @@ -39,6 +40,8 @@ struct MarketConfig { address monetary; uint256 borrowable; Coins coins; // factors for total collaterals + int256 minBand; + int256 maxBand; } interface IControllerFactory { @@ -71,6 +74,16 @@ interface IController { function amm_price() external view returns (uint256); function monetary_policy() external view returns (address); + + function max_borrowable(uint256 collateral, uint256 N) external view returns (uint256); + + function min_collateral(uint256 debt, uint256 N) external view returns (uint256); + + function calculate_debt_n1( + uint256 collateral, + uint256 debt, + uint256 N + ) external view returns (int256); } interface I_LLAMMA { @@ -81,6 +94,12 @@ interface I_LLAMMA { function coins(uint256 i) external view returns (address); function get_base_price() external view returns (uint256); + + function read_user_tick_numbers(address user) external view returns (int256[2] memory); + + function min_band() external view returns (int256); + + function max_band() external view returns (int256); } interface IMonetary { diff --git a/contracts/protocols/mainnet/crvusd/main.sol b/contracts/protocols/mainnet/crvusd/main.sol index b90f3bc..a02631b 100644 --- a/contracts/protocols/mainnet/crvusd/main.sol +++ b/contracts/protocols/mainnet/crvusd/main.sol @@ -23,6 +23,8 @@ contract CurveUSDResolver is CRVHelpers { ) public view returns (PositionData memory positionData, MarketConfig memory marketConfig) { IController controller = getController(market, index); uint256[4] memory res = controller.user_state(user); + address AMM = controller.amm(); + positionData.userTickNumber = I_LLAMMA(AMM).read_user_tick_numbers(user); positionData.borrow = res[2]; positionData.supply = res[0]; positionData.N = res[3]; @@ -92,6 +94,63 @@ contract CurveUSDResolver is CRVHelpers { marketConfig[i] = getMarketConfig(markets[i], indexes[i]); } } + + /** + *@dev get max debt amount with given collateral. + *@param market Addresse of the market + *@param version This is used for getting controller. + *@return debt Max debt amount. + */ + function getMaxDebt( + address market, + uint256 version, + uint256 collateralAmount, + uint256 bandNumber + ) public view returns (uint256 debt) { + IController controller = getController(market, version); + return controller.max_borrowable(collateralAmount, bandNumber); + } + + /** + *@dev get min collateral amount with given debt. + *@param market Addresse of the market + *@param version This is used for getting controller. + *@return collateral Min collateral amount. + */ + function getMinCollateral( + address market, + uint256 version, + uint256 debt, + uint256 bandNumber + ) public view returns (uint256 collateral) { + IController controller = getController(market, version); + return controller.max_borrowable(debt, bandNumber); + } + + /** + *@dev get band range according to given collateral, debt and bandNumber. + *@param market Addresse of the market + *@param version This is used for getting controller. + *@param collateral collateral amount. + *@param debt debt amount. + *@return range Band range. + */ + function getCalculateBandRange( + address market, + uint256 version, + uint256 collateral, + uint256 debt, + uint256 bandNumber + ) public view returns (int256[2] memory range) { + IController controller = getController(market, version); + address AMM = controller.amm(); + int256 minBand = I_LLAMMA(AMM).min_band(); + int256 maxBand = I_LLAMMA(AMM).max_band(); + require(int256(bandNumber) >= minBand && int256(bandNumber) <= maxBand); + + range[0] = controller.calculate_debt_n1(collateral, debt, bandNumber); + range[1] = range[0] + int256(bandNumber) - 1; + } } contract InstaCurveUSDResolver is CurveUSDResolver { diff --git a/test/mainnet/crv_usd.test.ts b/test/mainnet/crv_usd.test.ts index 7b4d7dc..e8415c2 100644 --- a/test/mainnet/crv_usd.test.ts +++ b/test/mainnet/crv_usd.test.ts @@ -59,6 +59,8 @@ describe("CRV-USD Resolvers", () => { console.log(`Coin1 token decimals: ${market.coins.coin1Decimals}`); console.log(`Coin0 balance: ${market.coins.coin0Amount}`); console.log(`Coin1 balance: ${market.coins.coin1Amount}`); + console.log(`min Band: ${market.minBand}`); + console.log(`max Band: ${market.maxBand}`); console.log("======================================================"); } }); @@ -77,8 +79,30 @@ describe("CRV-USD Resolvers", () => { console.log(`Use loan ID: ${position.loanId}`); console.log(`User upper price: ${position.prices.upper}`); console.log(`User lower price: ${position.prices.lower}`); + console.log(`User userTickNumber: ${position.userTickNumber}`); console.log("-----------------------------------------------------------"); } }); + + it("Returns max debt amount", async () => { + const maxDebt = await resolver.getMaxDebt(markets[0], 0, "1000000000000000000", 12); + console.log("maxDebt amount: ", maxDebt); + }); + + it("Returns min collateral amount", async () => { + const minCollateral = await resolver.getMinCollateral(markets[0], 0, "500000000000000000000", 10); + console.log("maxDebt amount: ", minCollateral); + }); + + it("Returns Band range", async () => { + const minCollateral = await resolver.getCalculateBandRange( + markets[0], + 0, + "2205663198573977494528", + "2589469072122129017791488", + 21, + ); + console.log("maxDebt amount: ", minCollateral); + }); }); }); From 9a69a79900dce7e73a35d96849cfe614747d8f06 Mon Sep 17 00:00:00 2001 From: q1q0 Date: Sun, 1 Oct 2023 15:14:56 -0400 Subject: [PATCH 2/4] fix: update function name --- contracts/protocols/mainnet/crvusd/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/protocols/mainnet/crvusd/main.sol b/contracts/protocols/mainnet/crvusd/main.sol index a02631b..28a0ed1 100644 --- a/contracts/protocols/mainnet/crvusd/main.sol +++ b/contracts/protocols/mainnet/crvusd/main.sol @@ -135,7 +135,7 @@ contract CurveUSDResolver is CRVHelpers { *@param debt debt amount. *@return range Band range. */ - function getCalculateBandRange( + function getBandRange( address market, uint256 version, uint256 collateral, From cf3a37cab1296659b00f8ff4aab1c9b3a7cc693b Mon Sep 17 00:00:00 2001 From: q1q0 Date: Sun, 1 Oct 2023 16:51:36 -0400 Subject: [PATCH 3/4] feat: add liquidation range calculation --- contracts/protocols/mainnet/crvusd/interfaces.sol | 4 ++++ contracts/protocols/mainnet/crvusd/main.sol | 7 +++++-- test/mainnet/crv_usd.test.ts | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/contracts/protocols/mainnet/crvusd/interfaces.sol b/contracts/protocols/mainnet/crvusd/interfaces.sol index 04d3aec..98a1718 100644 --- a/contracts/protocols/mainnet/crvusd/interfaces.sol +++ b/contracts/protocols/mainnet/crvusd/interfaces.sol @@ -100,6 +100,10 @@ interface I_LLAMMA { function min_band() external view returns (int256); function max_band() external view returns (int256); + + function p_oracle_up(int256 bandNumber0) external view returns (uint256); + + function p_oracle_down(int256 bandNumber1) external view returns (uint256); } interface IMonetary { diff --git a/contracts/protocols/mainnet/crvusd/main.sol b/contracts/protocols/mainnet/crvusd/main.sol index 28a0ed1..e43a6d7 100644 --- a/contracts/protocols/mainnet/crvusd/main.sol +++ b/contracts/protocols/mainnet/crvusd/main.sol @@ -134,14 +134,15 @@ contract CurveUSDResolver is CRVHelpers { *@param collateral collateral amount. *@param debt debt amount. *@return range Band range. + *@return liquidation liquidation price range. */ - function getBandRange( + function getBandRangeAndLiquidationRange( address market, uint256 version, uint256 collateral, uint256 debt, uint256 bandNumber - ) public view returns (int256[2] memory range) { + ) public view returns (int256[2] memory range, uint256[2] memory liquidation) { IController controller = getController(market, version); address AMM = controller.amm(); int256 minBand = I_LLAMMA(AMM).min_band(); @@ -150,6 +151,8 @@ contract CurveUSDResolver is CRVHelpers { range[0] = controller.calculate_debt_n1(collateral, debt, bandNumber); range[1] = range[0] + int256(bandNumber) - 1; + liquidation[0] = I_LLAMMA(AMM).p_oracle_up(range[0]); + liquidation[1] = I_LLAMMA(AMM).p_oracle_down(range[1]); } } diff --git a/test/mainnet/crv_usd.test.ts b/test/mainnet/crv_usd.test.ts index e8415c2..84f4bee 100644 --- a/test/mainnet/crv_usd.test.ts +++ b/test/mainnet/crv_usd.test.ts @@ -95,7 +95,7 @@ describe("CRV-USD Resolvers", () => { }); it("Returns Band range", async () => { - const minCollateral = await resolver.getCalculateBandRange( + const minCollateral = await resolver.getBandRangeAndLiquidationRange( markets[0], 0, "2205663198573977494528", From fb576205cc7badc8611cbc765ca01abca5dfb153 Mon Sep 17 00:00:00 2001 From: Shriya Tyagi Date: Wed, 4 Oct 2023 18:07:20 +0530 Subject: [PATCH 4/4] feat: minor updates --- contracts/protocols/mainnet/crvusd/helpers.sol | 2 +- contracts/protocols/mainnet/crvusd/interfaces.sol | 2 +- contracts/protocols/mainnet/crvusd/main.sol | 10 +++++----- test/mainnet/crv_usd.test.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/protocols/mainnet/crvusd/helpers.sol b/contracts/protocols/mainnet/crvusd/helpers.sol index f8a319c..2e579fb 100644 --- a/contracts/protocols/mainnet/crvusd/helpers.sol +++ b/contracts/protocols/mainnet/crvusd/helpers.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity ^0.8.6; import "./interfaces.sol"; import { DSMath } from "../../../utils/dsmath.sol"; diff --git a/contracts/protocols/mainnet/crvusd/interfaces.sol b/contracts/protocols/mainnet/crvusd/interfaces.sol index 98a1718..d453fd4 100644 --- a/contracts/protocols/mainnet/crvusd/interfaces.sol +++ b/contracts/protocols/mainnet/crvusd/interfaces.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity ^0.8.0; struct PositionData { uint256 supply; diff --git a/contracts/protocols/mainnet/crvusd/main.sol b/contracts/protocols/mainnet/crvusd/main.sol index e43a6d7..21e8064 100644 --- a/contracts/protocols/mainnet/crvusd/main.sol +++ b/contracts/protocols/mainnet/crvusd/main.sol @@ -98,7 +98,7 @@ contract CurveUSDResolver is CRVHelpers { /** *@dev get max debt amount with given collateral. *@param market Addresse of the market - *@param version This is used for getting controller. + *@param version Latest controller version *@return debt Max debt amount. */ function getMaxDebt( @@ -114,7 +114,7 @@ contract CurveUSDResolver is CRVHelpers { /** *@dev get min collateral amount with given debt. *@param market Addresse of the market - *@param version This is used for getting controller. + *@param version Latest controller version *@return collateral Min collateral amount. */ function getMinCollateral( @@ -124,13 +124,13 @@ contract CurveUSDResolver is CRVHelpers { uint256 bandNumber ) public view returns (uint256 collateral) { IController controller = getController(market, version); - return controller.max_borrowable(debt, bandNumber); + return controller.min_collateral(debt, bandNumber); } /** *@dev get band range according to given collateral, debt and bandNumber. *@param market Addresse of the market - *@param version This is used for getting controller. + *@param version Latest controller version *@param collateral collateral amount. *@param debt debt amount. *@return range Band range. @@ -147,7 +147,7 @@ contract CurveUSDResolver is CRVHelpers { address AMM = controller.amm(); int256 minBand = I_LLAMMA(AMM).min_band(); int256 maxBand = I_LLAMMA(AMM).max_band(); - require(int256(bandNumber) >= minBand && int256(bandNumber) <= maxBand); + require(int256(bandNumber) >= minBand && int256(bandNumber) <= maxBand, "Invalid band number"); range[0] = controller.calculate_debt_n1(collateral, debt, bandNumber); range[1] = range[0] + int256(bandNumber) - 1; diff --git a/test/mainnet/crv_usd.test.ts b/test/mainnet/crv_usd.test.ts index 84f4bee..be6933b 100644 --- a/test/mainnet/crv_usd.test.ts +++ b/test/mainnet/crv_usd.test.ts @@ -91,7 +91,7 @@ describe("CRV-USD Resolvers", () => { it("Returns min collateral amount", async () => { const minCollateral = await resolver.getMinCollateral(markets[0], 0, "500000000000000000000", 10); - console.log("maxDebt amount: ", minCollateral); + console.log("minCollateral amount: ", minCollateral); }); it("Returns Band range", async () => {