diff --git a/contracts/Comptroller.sol b/contracts/Comptroller.sol index 15810720d..340d8cc2e 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 && vars.cTokenBalance > 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"); 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; +} + 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 +}