-
Notifications
You must be signed in to change notification settings - Fork 22
Liquidation Improvements based on Health-Factor #535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Debugger022
wants to merge
51
commits into
develop
Choose a base branch
from
feat/Liquidation-improvement
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 46 commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
d2f5cd0
feat: add new vars in AccountLiquiditySnapshot
Debugger022 1f2d92b
feat: modify comptroller interface
Debugger022 a2ac784
feat: add dynamic close factor and liquidation incentive
Debugger022 39c970d
feat: add contract-sizer in hardhat config
Debugger022 5aac9d2
chore: update yarn.lock
Debugger022 083a1f7
feat: move liquidation logic to Liquidation library
Debugger022 8c964fa
feat: update comptroller to use Liquidation library functions
Debugger022 7c65f24
feat: add maximum liquidation incentive per asset
Debugger022 32bf187
feat: update liquidation library
Debugger022 2716fec
refactor: remove pool liquidation Incentive reference
Debugger022 e1f58da
feat: moved reward updates logic to Rewards library
Debugger022 0921fce
refactor: removed liquidation Incentive mapping
Debugger022 dec2414
refactor: reduced comptroller size
Debugger022 f2ef6fd
fix: minor fix
Debugger022 27cf44c
fix: adjust heal account tests for dynamic factors
Debugger022 47ba38e
fix: adjust liquidate account tests for dynamic factors
Debugger022 876e44e
refactor: add zero checks in snapshot calculations
Debugger022 5860efe
test: fix hooks and setters test
Debugger022 fc9c6a7
test: fix seize tokens test
Debugger022 691c424
refactor: moved rewards logic to internal functions
Debugger022 bebf45d
test: fix pool lens test
Debugger022 2811258
test: fix tests
Debugger022 8876c29
feat: getter for liquidation incentive per market
Debugger022 e6e906f
fix: fixed vTokens test
Debugger022 749dbb6
test: fix NativeToken gateway test
Debugger022 e8ea512
fix: Average liquidation incentive calculation
Debugger022 c4a5768
refactor: corrected addPool signature
Debugger022 fe24745
refactor: adjust computation in calculateIncentiveAdjustedDebt
Debugger022 bfd294f
test: fixed integration tests
Debugger022 232421a
fix: fix Pool lens test
Debugger022 fbde27d
fix: corrected averageLT calculation
Debugger022 438695d
feat: add Toxic liquidation check
Debugger022 58e2678
feat: update comptroller interface
Debugger022 2413962
test: refactored integration tests
Debugger022 c5564d9
fix: fixed references for averageLT
Debugger022 525f1cf
fix: fixed storage layout
Debugger022 c825a8e
feat: external Liquidaiton Manager contract instead of library
Debugger022 c907123
feat: Liquidation Manager interface
Debugger022 b6f0e5e
feat: update comptroller interface
Debugger022 d072b0a
feat: add liquidation manager setter and refactor dependencies
Debugger022 d86ccaa
refactor: add MarketListed internal function to reduce comptroller size
Debugger022 ebcd3e4
feat: add natspec comments for reward functions
Debugger022 8451373
fix: fix tests
Debugger022 d8bc0ce
refactor: move order processing back to comptroller
Debugger022 dbf5739
fix: integration test
Debugger022 3177bf8
test: fixed fork tests
Debugger022 ec585af
feat: liquidation Manager for common functionalities of core and IL
Debugger022 1dc088c
feat: IL specific liquidation manager
Debugger022 91c22c3
refactor: using ILLiquidation manager in comptroller
Debugger022 b7ad5ae
refactor: moved some logic to Liquidation Manager
Debugger022 e7285d6
test: refactor tests
Debugger022 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
| pragma solidity ^0.8.10; | ||
|
|
||
| import { VToken } from "./VToken.sol"; | ||
| import { ComptrollerStorage } from "./ComptrollerStorage.sol"; | ||
| import { ComptrollerInterface } from "./ComptrollerInterface.sol"; | ||
| import { Comptroller } from "./Comptroller.sol"; | ||
| import { ExponentialNoError } from "./ExponentialNoError.sol"; | ||
| import { ILiquidationManager } from "./LiquidationManagerInterface.sol"; | ||
| import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; | ||
|
|
||
| contract LiquidationManager is ILiquidationManager, ExponentialNoError { | ||
| /** | ||
| * @notice Calculates incentive-adjusted debt | ||
| */ | ||
| function calculateIncentiveAdjustedDebt( | ||
| address borrower, | ||
| VToken[] memory markets, | ||
| ComptrollerInterface comptroller | ||
| ) external view returns (uint256 weightedBorrowSum) { | ||
| for (uint256 i; i < markets.length; ++i) { | ||
| VToken market = markets[i]; | ||
| (, , uint256 borrowBalance, ) = market.getAccountSnapshot(borrower); | ||
| if (borrowBalance == 0) continue; | ||
|
|
||
| ResilientOracleInterface oracle = comptroller.getOracle(); | ||
| uint256 borrowPrice = oracle.getUnderlyingPrice(address(market)); | ||
| uint256 borrowValueUSD = mul_ScalarTruncate(Exp({ mantissa: borrowPrice }), borrowBalance); | ||
|
|
||
| uint256 marketIncentive = comptroller.getDynamicLiquidationIncentive(borrower, address(market)); | ||
|
|
||
| weightedBorrowSum = ExponentialNoError.add_( | ||
| weightedBorrowSum, | ||
| ExponentialNoError.mul_ScalarTruncate( | ||
| ExponentialNoError.Exp({ mantissa: marketIncentive }), | ||
| borrowValueUSD | ||
| ) | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @notice Processes a single asset for a given account and updates the liquidity snapshot. | ||
| * @dev | ||
| * - Constructs AssetData for the asset and account. | ||
| * - Calculates and applies the asset's effect on the account's liquidity snapshot, including any modifications (redeem/borrow). | ||
| * @param asset The VToken asset to process. | ||
| * @param account The address of the account being evaluated. | ||
| * @param effects Parameters describing any modifications (redeem/borrow) to apply for this asset. | ||
| * @param assetWeight The risk weight of the asset. | ||
| * @param snapshot The current account liquidity snapshot to update. | ||
| * @return The updated AccountLiquiditySnapshot struct. | ||
| */ | ||
| function processAsset( | ||
| VToken asset, | ||
| address account, | ||
| EffectsParams memory effects, | ||
| uint256 assetWeight, | ||
| uint256 underlyingPrice, | ||
| ComptrollerStorage.AccountLiquiditySnapshot memory snapshot | ||
| ) external view returns (ComptrollerStorage.AccountLiquiditySnapshot memory) { | ||
| (, uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = asset.getAccountSnapshot( | ||
| account | ||
| ); | ||
|
|
||
| AssetData memory assetData = AssetData({ | ||
| vTokenBalance: vTokenBalance, | ||
| borrowBalance: borrowBalance, | ||
| exchangeRateMantissa: exchangeRateMantissa, | ||
| underlyingPrice: underlyingPrice, | ||
| assetWeight: assetWeight, | ||
| vTokenAddress: address(asset) | ||
| }); | ||
|
|
||
| return _calculateAssetValues(assetData, snapshot, effects); | ||
| } | ||
|
|
||
| /** | ||
| * @notice Finalizes the account liquidity snapshot by calculating weighted averages, health factors, and liquidity/shortfall. | ||
| * @dev | ||
| * - Computes the average weight. | ||
| * - Calculates the sum of borrows and effects. | ||
| * - Determines the health factor as the ratio of weighted collateral to total borrow plus effects. | ||
| * - Sets the health factor threshold using the weighted average and liquidation incentive. | ||
| * - Calculates liquidity and shortfall based on the comparison of weighted collateral and borrow plus effects. | ||
| * @param snapshot The account liquidity snapshot to be finalized. | ||
| * @return The finalized account liquidity snapshot with updated fields. | ||
| */ | ||
| function finalizeSnapshot( | ||
| ComptrollerStorage.AccountLiquiditySnapshot memory snapshot | ||
| ) external pure returns (ComptrollerStorage.AccountLiquiditySnapshot memory) { | ||
| if (snapshot.totalCollateral > 0) { | ||
| snapshot.averageLT = div_(snapshot.averageLT, snapshot.totalCollateral); | ||
| } | ||
| uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects; | ||
|
|
||
| if (borrowPlusEffects > 0) { | ||
| snapshot.healthFactor = div_(snapshot.weightedCollateral, borrowPlusEffects); | ||
| } | ||
| snapshot.healthFactorThreshold = div_(snapshot.averageLT * (1e18 + snapshot.liquidationIncentiveAvg), 1e18); | ||
|
|
||
| unchecked { | ||
| if (snapshot.weightedCollateral > borrowPlusEffects) { | ||
| snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects; | ||
| snapshot.shortfall = 0; | ||
| } else { | ||
| snapshot.liquidity = 0; | ||
| snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral; | ||
| } | ||
| } | ||
|
|
||
| return snapshot; | ||
| } | ||
|
|
||
| /** | ||
| * @notice Calculates and updates the liquidity snapshot values for a given asset. | ||
| * @dev Computes weighted collateral, total collateral, and borrow values using asset data and price information. | ||
| * If the asset is being modified (redeemed or borrowed), applies the effects to the snapshot as well. | ||
| * @param asset The asset data struct containing balances, prices, and weights. | ||
| * @param snapshot The current account liquidity snapshot to update. | ||
| * @param effectsParams Parameters describing any modifications (redeem/borrow) to apply for this asset. | ||
| * @return The updated AccountLiquiditySnapshot struct. | ||
| */ | ||
| function _calculateAssetValues( | ||
| AssetData memory asset, | ||
| ComptrollerStorage.AccountLiquiditySnapshot memory snapshot, | ||
| EffectsParams memory effectsParams | ||
| ) internal pure returns (ComptrollerStorage.AccountLiquiditySnapshot memory) { | ||
| Exp memory oraclePrice = Exp({ mantissa: asset.underlyingPrice }); | ||
| Exp memory vTokenPrice = mul_(Exp({ mantissa: asset.exchangeRateMantissa }), oraclePrice); | ||
| Exp memory weightedVTokenPrice = mul_(Exp({ mantissa: asset.assetWeight }), vTokenPrice); | ||
|
|
||
| // Core calculations | ||
| snapshot.weightedCollateral = mul_ScalarTruncateAddUInt( | ||
| weightedVTokenPrice, | ||
| asset.vTokenBalance, | ||
| snapshot.weightedCollateral | ||
| ); | ||
| snapshot.totalCollateral = mul_ScalarTruncateAddUInt( | ||
| vTokenPrice, | ||
| asset.vTokenBalance, | ||
| snapshot.totalCollateral | ||
| ); | ||
| snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, asset.borrowBalance, snapshot.borrows); | ||
| uint256 vTokenBalanceUSD = mul_ScalarTruncate(vTokenPrice, asset.vTokenBalance); | ||
| snapshot.averageLT += mul_(asset.assetWeight, vTokenBalanceUSD); | ||
|
|
||
| // Handle modified asset effects | ||
| if (address(asset.vTokenAddress) == address(effectsParams.vTokenModify)) { | ||
| snapshot.effects = mul_ScalarTruncateAddUInt( | ||
| weightedVTokenPrice, | ||
| effectsParams.redeemTokens, | ||
| snapshot.effects | ||
| ); | ||
| snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, effectsParams.borrowAmount, snapshot.effects); | ||
| } | ||
|
|
||
| return snapshot; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
| pragma solidity ^0.8.10; | ||
|
|
||
| import { VToken } from "./VToken.sol"; | ||
| import { ComptrollerStorage } from "./ComptrollerStorage.sol"; | ||
| import { ComptrollerInterface } from "./ComptrollerInterface.sol"; | ||
|
|
||
| interface ILiquidationManager { | ||
| struct AssetData { | ||
| uint256 vTokenBalance; | ||
| uint256 borrowBalance; | ||
| uint256 exchangeRateMantissa; | ||
| uint256 underlyingPrice; | ||
| uint256 assetWeight; | ||
| address vTokenAddress; | ||
| } | ||
|
|
||
| struct EffectsParams { | ||
| VToken vTokenModify; | ||
| uint256 redeemTokens; | ||
| uint256 borrowAmount; | ||
| } | ||
|
|
||
| function calculateIncentiveAdjustedDebt( | ||
| address borrower, | ||
| VToken[] memory markets, | ||
| ComptrollerInterface comptroller | ||
| ) external view returns (uint256 weightedBorrowSum); | ||
|
|
||
| function processAsset( | ||
| VToken asset, | ||
| address account, | ||
| EffectsParams memory effects, | ||
| uint256 assetWeight, | ||
| uint256 underlyingPrice, | ||
| ComptrollerStorage.AccountLiquiditySnapshot memory snapshot | ||
| ) external view returns (ComptrollerStorage.AccountLiquiditySnapshot memory); | ||
|
|
||
| function finalizeSnapshot( | ||
| ComptrollerStorage.AccountLiquiditySnapshot memory snapshot | ||
| ) external pure returns (ComptrollerStorage.AccountLiquiditySnapshot memory); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would avoid changes in the VToken contract, if it's doable. Because vBNB cannot be upgraded |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maintain the attribute, to not break the storage layout. Simply rename it to "deprecatedLiquidationIncentiveMantissa"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
525f1cf