Skip to content
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

[VEN-2323] Unlist Market #349

Merged
merged 41 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9999eda
fix: added unlist function
web3rover Jan 22, 2024
99e8dd8
fix: updates getAssetsIn
web3rover Jan 22, 2024
bba744b
fix: fixed compile error
web3rover Jan 22, 2024
8ad5761
fix: tests for unlist
web3rover Jan 22, 2024
ac789d2
fix: deployed comptroller in bsctestnet
web3rover Jan 25, 2024
5959aed
feat: updating deployment files
Narayanprusty Jan 25, 2024
e36b799
fix: deployed on sepolia and opbnb testnet
web3rover Jan 25, 2024
f4d2f23
Merge branch 'feat/unlist-market' of github.com:VenusProtocol/isolate…
web3rover Jan 25, 2024
6ee64eb
feat: updating deployment files
Narayanprusty Jan 25, 2024
622cb17
fix: added indexed to event
web3rover Jan 29, 2024
dddcd83
fix: fix CI
web3rover Jan 30, 2024
1b21f05
fix: resolved conflict
web3rover Jan 30, 2024
7e1902a
fix: optimised getAssetsIn
web3rover Feb 19, 2024
6dacce2
fix: rebased
web3rover Mar 4, 2024
b03cb62
fix: fixed yarn.lock
web3rover Mar 4, 2024
0b3a26b
fix: only unlist without updating state
web3rover Mar 4, 2024
f038e3e
fix: VPB-05
web3rover Mar 14, 2024
9fd7543
fix: CVP-01
web3rover Mar 14, 2024
144cb97
fix: VPB-01
web3rover Mar 18, 2024
9584519
fix: change storage to memory
web3rover Mar 21, 2024
f85f96e
fix: resolved conflict
web3rover Mar 29, 2024
97871b8
fix: test description
web3rover Mar 29, 2024
cb1826e
fix: removed unwanted deployment file
web3rover Mar 29, 2024
3e957f1
fix: fixed lint
web3rover Mar 29, 2024
d2a0403
fix: updated yarn lock
web3rover Mar 29, 2024
a4d470c
feat: updating deployment files
Narayanprusty Mar 29, 2024
5fd036c
fix: removed deployments
web3rover Mar 29, 2024
26070c2
fix: resolved conflict
web3rover Jun 6, 2024
ebed4aa
fix: deployment on testnets - wip
web3rover Jun 6, 2024
43cda83
feat: updating deployment files
Narayanprusty Jun 6, 2024
e25fc16
fix: deployed on arb sepolia
web3rover Jun 6, 2024
ae3c021
Merge branch 'feat/unlist-market' of github.com:VenusProtocol/isolate…
web3rover Jun 6, 2024
2e64131
feat: updating deployment files
Narayanprusty Jun 6, 2024
0d4f2e3
fix: added missing solcinputs
web3rover Jun 10, 2024
e2d1bf8
Merge branch 'feat/unlist-market' of github.com:VenusProtocol/isolate…
web3rover Jun 10, 2024
89dc5f4
fix: resolved conflict
web3rover Aug 28, 2024
54ad9ee
fix: resolved conflict
web3rover Aug 28, 2024
03519d6
fix: redeployed contracts
web3rover Aug 30, 2024
7d25caf
feat: updating deployment files
Narayanprusty Aug 30, 2024
c5d4db7
fix: deployed on ethereum and arbitrumone
web3rover Sep 2, 2024
581c592
feat: updating deployment files
Narayanprusty Sep 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "solhint:recommended",
"rules": {
"code-complexity": ["error", 9],
"code-complexity": ["error", 15],
"compiler-version": ["error", ">=0.5.0"],
"const-name-snakecase": "error",
"constructor-syntax": "error",
Expand Down
164 changes: 149 additions & 15 deletions contracts/Comptroller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
{
// PoolRegistry, immutable to save on gas
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address public immutable poolRegistry;

Check warning on line 50 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Immutable variables name are set to be in capitalized SNAKE_CASE

/// @notice Emitted when an account enters a market
event MarketEntered(VToken indexed vToken, address indexed account);
Expand Down Expand Up @@ -98,6 +98,8 @@
/// @notice Emitted when forced liquidation is enabled or disabled for a market
event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);

/// @notice Emitted when a market is unlisted
event MarketUnlisted(address indexed vToken);
/// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account
event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);

Expand Down Expand Up @@ -125,6 +127,42 @@
/// @notice Thrown when user is not member of market
error MarketNotCollateral(address vToken, address user);

/// @notice Thrown when borrow action is not paused
error BorrowActionNotPaused();

/// @notice Thrown when mint action is not paused
error MintActionNotPaused();

/// @notice Thrown when redeem action is not paused
error RedeemActionNotPaused();

/// @notice Thrown when repay action is not paused
error RepayActionNotPaused();

/// @notice Thrown when seize action is not paused
error SeizeActionNotPaused();

/// @notice Thrown when exit market action is not paused
error ExitMarketActionNotPaused();

/// @notice Thrown when transfer action is not paused
error TransferActionNotPaused();

/// @notice Thrown when enter market action is not paused
error EnterMarketActionNotPaused();

/// @notice Thrown when liquidate action is not paused
error LiquidateActionNotPaused();

/// @notice Thrown when borrow cap is not zero
error BorrowCapIsNotZero();

/// @notice Thrown when supply cap is not zero
error SupplyCapIsNotZero();

/// @notice Thrown when collateral factor is not zero
error CollateralFactorIsNotZero();

/**
* @notice Thrown during the liquidation if user's total collateral amount is lower than
* a predefined threshold. In this case only batch liquidations (either liquidateAccount
Expand Down Expand Up @@ -205,6 +243,86 @@
return results;
}

/**
* @notice Unlist a market by setting isListed to false
* @dev Checks if all actions are paused, borrow/supply caps is set to 0 and collateral factor is to 0.
* @param market The address of the market (token) to unlist
* @return uint256 Always NO_ERROR for compatibility with Venus core tooling
* @custom:event MarketUnlisted is emitted on success
* @custom:error MarketNotListed error is thrown when the market is not listed
* @custom:error BorrowActionNotPaused error is thrown if borrow action is not paused
* @custom:error MintActionNotPaused error is thrown if mint action is not paused
* @custom:error RedeemActionNotPaused error is thrown if redeem action is not paused
* @custom:error RepayActionNotPaused error is thrown if repay action is not paused
* @custom:error EnterMarketActionNotPaused error is thrown if enter market action is not paused
* @custom:error LiquidateActionNotPaused error is thrown if liquidate action is not paused
* @custom:error BorrowCapIsNotZero error is thrown if borrow cap is not zero
* @custom:error SupplyCapIsNotZero error is thrown if supply cap is not zero
* @custom:error CollateralFactorIsNotZero error is thrown if collateral factor is not zero
*/
function unlistMarket(address market) external returns (uint256) {
_checkAccessAllowed("unlistMarket(address)");

Market storage _market = markets[market];

if (!_market.isListed) {
revert MarketNotListed(market);
}

if (!actionPaused(market, Action.BORROW)) {
revert BorrowActionNotPaused();
}

if (!actionPaused(market, Action.MINT)) {
revert MintActionNotPaused();
}

if (!actionPaused(market, Action.REDEEM)) {
revert RedeemActionNotPaused();
}

if (!actionPaused(market, Action.REPAY)) {
revert RepayActionNotPaused();
}

if (!actionPaused(market, Action.SEIZE)) {
revert SeizeActionNotPaused();
}

if (!actionPaused(market, Action.ENTER_MARKET)) {
revert EnterMarketActionNotPaused();
}

if (!actionPaused(market, Action.LIQUIDATE)) {
revert LiquidateActionNotPaused();
}

if (!actionPaused(market, Action.TRANSFER)) {
revert TransferActionNotPaused();
}

if (!actionPaused(market, Action.EXIT_MARKET)) {
revert ExitMarketActionNotPaused();
}

if (borrowCaps[market] != 0) {
revert BorrowCapIsNotZero();
}

if (supplyCaps[market] != 0) {
revert SupplyCapIsNotZero();
}

if (_market.collateralFactorMantissa != 0) {
revert CollateralFactorIsNotZero();
}

_market.isListed = false;
emit MarketUnlisted(market);

return NO_ERROR;
}

/**
* @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account
* If allowed, the delegate will be able to borrow funds on behalf of the sender
Expand Down Expand Up @@ -382,7 +500,7 @@
* @param redeemAmount The amount of the underlying asset being redeemed
* @param redeemTokens The number of tokens being redeemed
*/
function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {

Check warning on line 503 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Variable "redeemAmount" is unused

Check warning on line 503 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Variable "redeemTokens" is unused
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(redeemer, vToken);
}
Expand Down Expand Up @@ -749,7 +867,7 @@
* @custom:access Not restricted
*/
function healAccount(address user) external {
VToken[] memory userAssets = accountAssets[user];
VToken[] memory userAssets = getAssetsIn(user);
uint256 userAssetsCount = userAssets.length;

address liquidator = msg.sender;
Expand Down Expand Up @@ -860,12 +978,12 @@
);
}

VToken[] memory borrowMarkets = accountAssets[borrower];
VToken[] memory borrowMarkets = getAssetsIn(borrower);
uint256 marketsCount = borrowMarkets.length;

for (uint256 i; i < marketsCount; ++i) {
(, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);
require(borrowBalance == 0, "Nonzero borrow balance after liquidation");

Check warning on line 986 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements
}
}

Expand All @@ -877,8 +995,8 @@
*/
function setCloseFactor(uint256 newCloseFactorMantissa) external {
_checkAccessAllowed("setCloseFactor(uint256)");
require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, "Close factor greater than maximum close factor");

Check warning on line 998 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements
require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, "Close factor smaller than minimum close factor");

Check warning on line 999 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

uint256 oldCloseFactorMantissa = closeFactorMantissa;
closeFactorMantissa = newCloseFactorMantissa;
Expand Down Expand Up @@ -953,7 +1071,7 @@
* @custom:access Controlled by AccessControlManager
*/
function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {
require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, "liquidation incentive should be greater than 1e18");

Check warning on line 1074 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

_checkAccessAllowed("setLiquidationIncentive(uint256)");

Expand Down Expand Up @@ -981,7 +1099,7 @@
revert MarketAlreadyListed(address(vToken));
}

require(vToken.isVToken(), "Comptroller: Invalid vToken"); // Sanity check to make sure its really a VToken

Check warning on line 1102 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

Market storage newMarket = markets[address(vToken)];
newMarket.isListed = true;
Expand Down Expand Up @@ -1015,7 +1133,7 @@
uint256 numMarkets = vTokens.length;
uint256 numBorrowCaps = newBorrowCaps.length;

require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input");

Check warning on line 1136 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

_ensureMaxLoops(numMarkets);

Expand All @@ -1039,7 +1157,7 @@
_checkAccessAllowed("setMarketSupplyCaps(address[],uint256[])");
uint256 vTokensCount = vTokens.length;

require(vTokensCount != 0, "invalid number of markets");

Check warning on line 1160 in contracts/Comptroller.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements
require(vTokensCount == newSupplyCaps.length, "invalid number of markets");

_ensureMaxLoops(vTokensCount);
Expand Down Expand Up @@ -1244,17 +1362,6 @@

/*** Assets You Are In ***/

/**
* @notice Returns the assets an account has entered
* @param account The address of the account to pull assets for
* @return A list with the assets the account has entered
*/
function getAssetsIn(address account) external view returns (VToken[] memory) {
VToken[] memory assetsIn = accountAssets[account];

return assetsIn;
}

/**
* @notice Returns whether the given account is entered in a given market
* @param account The address of the account to check
Expand Down Expand Up @@ -1346,7 +1453,7 @@
* @param account Address of the account to get associated tokens with
*/
function updatePrices(address account) public {
VToken[] memory vTokens = accountAssets[account];
VToken[] memory vTokens = getAssetsIn(account);
uint256 vTokensCount = vTokens.length;

ResilientOracleInterface oracle_ = oracle;
Expand All @@ -1366,6 +1473,33 @@
return _actionPaused[market][action];
}

/**
* @notice Returns the assets an account has entered
* @param account The address of the account to pull assets for
* @return A list with the assets the account has entered
*/
function getAssetsIn(address account) public view returns (VToken[] memory) {
uint256 len;
VToken[] memory _accountAssets = accountAssets[account];
uint256 _accountAssetsLength = _accountAssets.length;

VToken[] memory assetsIn = new VToken[](_accountAssetsLength);

for (uint256 i; i < _accountAssetsLength; ++i) {
Market storage market = markets[address(_accountAssets[i])];
Debugger022 marked this conversation as resolved.
Show resolved Hide resolved
if (market.isListed) {
assetsIn[len] = _accountAssets[i];
++len;
}
}

assembly {
mstore(assetsIn, len)
}

return assetsIn;
}

/**
* @notice Add the market to the borrower's "assets in" for liquidity calculations
* @param vToken The market to enter
Expand Down Expand Up @@ -1495,7 +1629,7 @@
function(VToken) internal view returns (Exp memory) weight
) internal view returns (AccountLiquiditySnapshot memory snapshot) {
// For each asset the account is in
VToken[] memory assets = accountAssets[account];
VToken[] memory assets = getAssetsIn(account);
uint256 assetsCount = assets.length;

for (uint256 i; i < assetsCount; ++i) {
Expand Down
Loading
Loading