From d49c032cddd34a79468c658b6f45d523c3533d35 Mon Sep 17 00:00:00 2001 From: Beepidibop <63800471+beepidibop@users.noreply.github.com> Date: Sun, 30 Jan 2022 00:22:16 -0800 Subject: [PATCH 1/4] Added collateralGuardianPaused for V6 Addition to the Pause Guardian storage slots in V2. Appended as V6 to avoid introducing storage slot conflicts. --- contracts/ComptrollerStorage.sol | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/contracts/ComptrollerStorage.sol b/contracts/ComptrollerStorage.sol index 7f0a7e674..f99887aba 100644 --- a/contracts/ComptrollerStorage.sol +++ b/contracts/ComptrollerStorage.sol @@ -143,3 +143,17 @@ contract ComptrollerV5Storage is ComptrollerV4Storage { /// @notice Last block at which a contributor's COMP rewards have been allocated mapping(address => uint) public lastContributorBlock; } + +//New code +contract ComptrollerV6Storage is ComptrollerV5Storage { + + /** + * @notice Addition to the Pause Guardian storage slots in V2. + * Appended as V6 to avoid introducing storage slot conflicts. + */ + + + /// @notice Whether a cToken is paused for borrowing or not + mapping(address => bool) public collateralGuardianPaused; +} + From 7377563f5ad3616f09be2b6c57e7403ba3d2a3a0 Mon Sep 17 00:00:00 2001 From: Beepidibop <63800471+beepidibop@users.noreply.github.com> Date: Sun, 30 Jan 2022 00:24:08 -0800 Subject: [PATCH 2/4] Add COLLATERAL_PAUSED Added new error COLLATERAL_PAUSED for when a collateral is paused and someone tries to borrow with paused collateral. --- contracts/ErrorReporter.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/ErrorReporter.sol b/contracts/ErrorReporter.sol index 33cc775f5..2d01e60a3 100644 --- a/contracts/ErrorReporter.sol +++ b/contracts/ErrorReporter.sol @@ -19,7 +19,8 @@ contract ComptrollerErrorReporter { REJECTION, SNAPSHOT_ERROR, TOO_MANY_ASSETS, - TOO_MUCH_REPAY + TOO_MUCH_REPAY, + COLLATERAL_PAUSED } enum FailureInfo { @@ -204,4 +205,4 @@ contract TokenErrorReporter { return uint(err); } -} \ No newline at end of file +} From 29a73d667782483b452f5e17fb2100c3fc4e9068 Mon Sep 17 00:00:00 2001 From: Beepidibop <63800471+beepidibop@users.noreply.github.com> Date: Sun, 30 Jan 2022 00:28:50 -0800 Subject: [PATCH 3/4] Update Comptroller to allow pausing collaterals Added _setCollateralPaused(), changed getHypotheticalAccountLiquidityInternal() to reflect new error. --- contracts/Comptroller.sol | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 15810720d..63b8d8432 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -12,7 +12,7 @@ import "./Governance/IINV.sol"; * @title Compound's Comptroller Contract * @author Compound */ -contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError { +contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerErrorReporter, ExponentialNoError { /// @notice Emitted when an admin supports a market event MarketListed(CToken cToken); @@ -721,6 +721,13 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE if (oErr != 0) { // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (Error.SNAPSHOT_ERROR, 0, 0); } + + // New code + // Check if the collateral is paused, only for borrowing + if (collateralGuardianPaused[address(asset)] == true && borrowAmount>0){ + return (Error.COLLATERAL_PAUSED, 0, 0); + } + vars.collateralFactor = Exp({mantissa: markets[address(asset)].collateralFactorMantissa}); vars.exchangeRate = Exp({mantissa: vars.exchangeRateMantissa}); @@ -1037,6 +1044,17 @@ contract Comptroller is ComptrollerV5Storage, ComptrollerInterface, ComptrollerE return state; } + //New code + function _setCollateralPaused(CToken cToken, bool state) public returns (bool) { + require(markets[address(cToken)].isListed, "cannot pause a market that is not listed"); + require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause"); + require(msg.sender == admin || state == true, "only admin can unpause"); + + collateralGuardianPaused[address(cToken)] = state; + emit ActionPaused(cToken, "Collateral", state); + return state; + } + function _become(Unitroller unitroller) public { require(msg.sender == unitroller.admin(), "only unitroller admin can change brains"); require(unitroller._acceptImplementation() == 0, "change not authorized"); From 748c9763998540a853938da3f0b0e8e297fc79cf Mon Sep 17 00:00:00 2001 From: Beepidibop <63800471+beepidibop@users.noreply.github.com> Date: Sun, 30 Jan 2022 12:44:24 -0800 Subject: [PATCH 4/4] added checks for cTokenBalance > 0 Allows users to borrow even if they're in a market where the collateral is paused if they have 0 cTokenBalance (In market, but not supplied. Happens when someone borrows but don't supply the same token) --- contracts/Comptroller.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 63b8d8432..340d8cc2e 100644 --- a/contracts/Comptroller.sol +++ b/contracts/Comptroller.sol @@ -724,7 +724,7 @@ contract Comptroller is ComptrollerV6Storage, ComptrollerInterface, ComptrollerE // New code // Check if the collateral is paused, only for borrowing - if (collateralGuardianPaused[address(asset)] == true && borrowAmount>0){ + if (collateralGuardianPaused[address(asset)] == true && borrowAmount > 0 && vars.cTokenBalance > 0){ return (Error.COLLATERAL_PAUSED, 0, 0); }