diff --git a/contracts/Comptroller/Diamond/facets/MarketFacet.sol b/contracts/Comptroller/Diamond/facets/MarketFacet.sol index 2ef2d729b..f740f4d7d 100644 --- a/contracts/Comptroller/Diamond/facets/MarketFacet.sol +++ b/contracts/Comptroller/Diamond/facets/MarketFacet.sol @@ -216,7 +216,15 @@ contract MarketFacet is IMarketFacet, FacetBase { require(_market.collateralFactorMantissa == 0, "collateral factor is not 0"); + for (uint96 i = lastPoolId; i > corePoolId; i--) { + PoolMarketId index = getPoolMarketIndex(i, market); + if (_poolMarkets[index].isListed) { + _removePoolMarket(i, market); + } + } + _market.isListed = false; + emit MarketUnlisted(market); return uint256(Error.NO_ERROR); @@ -409,27 +417,7 @@ contract MarketFacet is IMarketFacet, FacetBase { */ function removePoolMarket(uint96 poolId, address vToken) external { ensureAllowed("removePoolMarket(uint96,address)"); - - if (poolId == corePoolId) revert InvalidOperationForCorePool(); - PoolMarketId index = getPoolMarketIndex(poolId, vToken); - if (!_poolMarkets[index].isListed) { - revert PoolMarketNotFound(poolId, vToken); - } - - address[] storage assets = pools[poolId].vTokens; - - uint256 length = assets.length; - for (uint256 i; i < length; i++) { - if (assets[i] == vToken) { - assets[i] = assets[length - 1]; - assets.pop(); - break; - } - } - - delete _poolMarkets[index]; - - emit PoolMarketRemoved(poolId, vToken); + _removePoolMarket(poolId, vToken); } /** @@ -507,7 +495,7 @@ contract MarketFacet is IMarketFacet, FacetBase { * @custom:error PoolDoesNotExist Reverts if the given pool ID do not exist. * @custom:error InvalidOperationForCorePool Reverts if called on the Core Pool. */ - function getPoolVTokens(uint96 poolId) external view returns (address[] memory) { + function getPoolVTokens(uint96 poolId) public view returns (address[] memory) { if (poolId > lastPoolId) revert PoolDoesNotExist(poolId); if (poolId == corePoolId) revert InvalidOperationForCorePool(); return pools[poolId].vTokens; @@ -697,6 +685,29 @@ contract MarketFacet is IMarketFacet, FacetBase { emit PoolMarketInitialized(poolId, vToken); } + function _removePoolMarket(uint96 poolId, address vToken) internal { + if (poolId == corePoolId) revert InvalidOperationForCorePool(); + PoolMarketId index = getPoolMarketIndex(poolId, vToken); + if (!_poolMarkets[index].isListed) { + revert PoolMarketNotFound(poolId, vToken); + } + + address[] storage assets = pools[poolId].vTokens; + + uint256 length = assets.length; + for (uint256 i; i < length; i++) { + if (assets[i] == vToken) { + assets[i] = assets[length - 1]; + assets.pop(); + break; + } + } + + delete _poolMarkets[index]; + + emit PoolMarketRemoved(poolId, vToken); + } + /** * @notice Returns only the core risk parameters (CF, LI, LT) for a vToken in a specific pool. * @dev If the pool is inactive, or if the vToken is not configured in the given pool and diff --git a/tests/hardhat/Comptroller/Diamond/assetListTest.ts b/tests/hardhat/Comptroller/Diamond/assetListTest.ts index a85104aca..53e0fa44d 100644 --- a/tests/hardhat/Comptroller/Diamond/assetListTest.ts +++ b/tests/hardhat/Comptroller/Diamond/assetListTest.ts @@ -142,9 +142,21 @@ describe("Comptroller: assetListTest", () => { expectedError: ComptrollerErrorReporter.Error | null = null, ) { const reply = await comptroller.connect(customer).callStatic.unlistMarket(unlistToken.address); + const lastPoolId = await comptroller.lastPoolId(); + + if (lastPoolId.toNumber() != 0) { + const poolVTokens = await comptroller.getPoolVTokens(lastPoolId); + expect(poolVTokens).to.include(unlistToken.address); + } const receipt = await comptroller.connect(customer).unlistMarket(unlistToken.address); expect(receipt).to.emit(unitroller, "MarketUnlisted"); + expect(receipt).to.emit(unitroller, "PoolMarketRemoved"); + + if (lastPoolId.toNumber() != 0) { + const poolVTokens = await comptroller.getPoolVTokens(lastPoolId); + expect(poolVTokens).to.not.include(unlistToken.address); + } const expectedError_ = expectedError || Error.NO_ERROR; expect(reply).to.equal(expectedError_); @@ -326,6 +338,10 @@ describe("Comptroller: assetListTest", () => { true, ); + const newLabel = "test-pool"; + await comptroller.createPool(newLabel); + await comptroller.addPoolMarkets([1], [OMG.address]); + await unlistAndCheckMarket(OMG, [BAT, ZRX], [OMG, BAT, ZRX]); });