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

Feature/upgrade pool pausing #201

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import "../../../libraries/uniswap/FullMath.sol";

import {LenderCommitmentGroupShares} from "./LenderCommitmentGroupShares.sol";

import {LenderPoolPauseableUpgradeable} from "./LenderPoolPauseableUpgradeable.sol";

import {OracleProtectedChild} from "../../../oracleprotection/OracleProtectedChild.sol";

Expand All @@ -49,6 +50,8 @@ import { ILoanRepaymentCallbacks } from "../../../interfaces/ILoanRepaymentCallb

import { IEscrowVault } from "../../../interfaces/IEscrowVault.sol";



import { IPausableTimestamp } from "../../../interfaces/IPausableTimestamp.sol";
import { ILenderCommitmentGroup } from "../../../interfaces/ILenderCommitmentGroup.sol";
import { Payment } from "../../../TellerV2Storage.sol";
Expand Down Expand Up @@ -88,7 +91,7 @@ contract LenderCommitmentGroup_Smart is
Initializable,
OracleProtectedChild,
OwnableUpgradeable,
PausableUpgradeable,
LenderPoolPauseableUpgradeable,
ReentrancyGuardUpgradeable
{
using AddressUpgradeable for address;
Expand Down Expand Up @@ -456,7 +459,7 @@ contract LenderCommitmentGroup_Smart is
uint256 _amount,
address _sharesRecipient,
uint256 _minSharesAmountOut
) external whenForwarderNotPaused whenNotPaused nonReentrant onlyOracleApprovedAllowEOA
) external whenForwarderNotPaused whenPoolNotPaused whenStakingNotPaused nonReentrant onlyOracleApprovedAllowEOA
returns (uint256 sharesAmount_) {

uint256 principalTokenBalanceBefore = principalToken.balanceOf(address(this));
Expand Down Expand Up @@ -526,7 +529,7 @@ contract LenderCommitmentGroup_Smart is
uint256 _collateralTokenId,
uint32 _loanDuration,
uint16 _interestRate
) external onlySmartCommitmentForwarder whenForwarderNotPaused whenNotPaused {
) external onlySmartCommitmentForwarder whenForwarderNotPaused whenPoolNotPaused whenBorrowingNotPaused {

require(
_collateralTokenAddress == address(collateralToken),
Expand Down Expand Up @@ -595,7 +598,7 @@ contract LenderCommitmentGroup_Smart is

function prepareSharesForBurn(
uint256 _amountPoolSharesTokens
) external whenForwarderNotPaused whenNotPaused nonReentrant
) external whenForwarderNotPaused whenPoolNotPaused nonReentrant
returns (bool) {

return poolSharesToken.prepareSharesForBurn(msg.sender, _amountPoolSharesTokens);
Expand All @@ -616,7 +619,7 @@ contract LenderCommitmentGroup_Smart is
uint256 _amountPoolSharesTokens,
address _recipient,
uint256 _minAmountOut
) external whenForwarderNotPaused whenNotPaused nonReentrant onlyOracleApprovedAllowEOA
) external whenForwarderNotPaused whenPoolNotPaused whenStakingNotPaused nonReentrant onlyOracleApprovedAllowEOA
returns (uint256) {


Expand Down Expand Up @@ -658,7 +661,7 @@ contract LenderCommitmentGroup_Smart is
function liquidateDefaultedLoanWithIncentive(
uint256 _bidId,
int256 _tokenAmountDifference
) external whenForwarderNotPaused whenNotPaused bidIsActiveForGroup(_bidId) nonReentrant onlyOracleApprovedAllowEOA {
) external whenForwarderNotPaused whenPoolNotPaused whenLiquidationNotPaused bidIsActiveForGroup(_bidId) nonReentrant onlyOracleApprovedAllowEOA {



Expand Down Expand Up @@ -1002,7 +1005,7 @@ contract LenderCommitmentGroup_Smart is

@dev there is no need to increment totalPrincipalTokensRepaid here as that is accomplished by the repayLoanCallback
*/
function withdrawFromEscrowVault ( uint256 _amount ) external whenForwarderNotPaused whenNotPaused {
function withdrawFromEscrowVault ( uint256 _amount ) external whenForwarderNotPaused whenPoolNotPaused {

address _escrowVault = ITellerV2(TELLER_V2).getEscrowVault();

Expand Down Expand Up @@ -1098,15 +1101,61 @@ contract LenderCommitmentGroup_Smart is
/**
* @notice Lets the DAO/owner of the protocol implement an emergency stop mechanism.
*/
function pauseLendingPool() public virtual onlyProtocolPauser whenNotPaused {
_pause();
function pauseLendingPool() public virtual onlyProtocolPauser whenPoolNotPaused {
_pausePool();
}

/**
* @notice Lets the DAO/owner of the protocol undo a previously implemented emergency stop.
*/
function unpauseLendingPool() public virtual onlyProtocolPauser whenPoolPaused {
setLastUnpausedAt();
_unpausePool();
}


/**
* @notice Lets the DAO/owner of the protocol implement an emergency stop mechanism.
*/
function pauseBorrowing() public virtual onlyProtocolPauser whenBorrowingNotPaused {
_pauseBorrowing();
}

/**
* @notice Lets the DAO/owner of the protocol undo a previously implemented emergency stop.
*/
function unpauseBorrowing() public virtual onlyProtocolPauser whenBorrowingPaused {
_unpauseBorrowing();
}


/**
* @notice Lets the DAO/owner of the protocol implement an emergency stop mechanism.
*/
function pauseStaking() public virtual onlyProtocolPauser whenStakingNotPaused {
_pauseStaking();
}

/**
* @notice Lets the DAO/owner of the protocol undo a previously implemented emergency stop.
*/
function unpauseStaking() public virtual onlyProtocolPauser whenStakingPaused {
_unpauseStaking();
}


/**
* @notice Lets the DAO/owner of the protocol implement an emergency stop mechanism.
*/
function pauseLiquidation() public virtual onlyProtocolPauser whenLiquidationNotPaused {
_pauseLiquidation();
}

/**
* @notice Lets the DAO/owner of the protocol undo a previously implemented emergency stop.
*/
function unpauseLendingPool() public virtual onlyProtocolPauser whenPaused {
function unpauseLiquidation() public virtual onlyProtocolPauser whenLiquidationPaused {
setLastUnpausedAt();
_unpause();
_unpauseLiquidation();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract LenderPoolPauseableUpgradeable is Initializable, ContextUpgradeable {
/**
* @dev Emitted when the pool pause is triggered by `account`.
*/
event PoolPaused(address account);
event PoolUnpaused(address account);

/**
* @dev Emitted when borrowing is paused/unpaused.
*/
event BorrowingPaused(address account);
event BorrowingUnpaused(address account);

/**
* @dev Emitted when staking is paused/unpaused.
*/
event StakingPaused(address account);
event StakingUnpaused(address account);

/**
* @dev Emitted when liquidation is paused/unpaused.
*/
event LiquidationPaused(address account);
event LiquidationUnpaused(address account);


/*
In Solidity, bool values consume 1 byte in storage, even though they technically only need a single bit.
Solidity packs multiple bool values into a single 32-byte (256-bit) storage slot whenever possible.
*/

bool private _poolPaused;

bool private _borrowingPaused;

bool private _stakingPaused;

bool private _liquidationPaused;

/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}

function __Pausable_init_unchained() internal onlyInitializing {
_poolPaused = false;
_borrowingPaused = false;
_stakingPaused = false;
_liquidationPaused = false;
}



// ========================== POOL PAUSE ==========================

modifier whenPoolNotPaused() {
_requirePoolNotPaused();
_;
}

modifier whenPoolPaused() {
_requirePoolPaused();
_;
}

function poolPaused() public view virtual returns (bool) {
return _poolPaused;
}

function _requirePoolNotPaused() internal view virtual {
require(!_poolPaused, "Pausable: Pool is paused");
}

function _requirePoolPaused() internal view virtual {
require(_poolPaused, "Pausable: Pool is not paused");
}

function _pausePool() internal virtual whenPoolNotPaused {
_poolPaused = true;
emit PoolPaused(_msgSender());
}

function _unpausePool() internal virtual whenPoolPaused {
_poolPaused = false;
emit PoolUnpaused(_msgSender());
}

// ========================== BORROWING PAUSE ==========================

modifier whenBorrowingNotPaused() {
_requireBorrowingNotPaused();
_;
}

modifier whenBorrowingPaused() {
_requireBorrowingPaused();
_;
}

function borrowingPaused() public view virtual returns (bool) {
return _borrowingPaused;
}

function _requireBorrowingNotPaused() internal view virtual {
require(!_borrowingPaused, "Pausable: Borrowing is paused");
}

function _requireBorrowingPaused() internal view virtual {
require(_borrowingPaused, "Pausable: Borrowing is not paused");
}

function _pauseBorrowing() internal virtual whenBorrowingNotPaused {
_borrowingPaused = true;
emit BorrowingPaused(_msgSender());
}

function _unpauseBorrowing() internal virtual whenBorrowingPaused {
_borrowingPaused = false;
emit BorrowingUnpaused(_msgSender());
}

// ========================== STAKING PAUSE ==========================

modifier whenStakingNotPaused() {
_requireStakingNotPaused();
_;
}

modifier whenStakingPaused() {
_requireStakingPaused();
_;
}

function stakingPaused() public view virtual returns (bool) {
return _stakingPaused;
}

function _requireStakingNotPaused() internal view virtual {
require(!_stakingPaused, "Pausable: Staking is paused");
}

function _requireStakingPaused() internal view virtual {
require(_stakingPaused, "Pausable: Staking is not paused");
}

function _pauseStaking() internal virtual whenStakingNotPaused {
_stakingPaused = true;
emit StakingPaused(_msgSender());
}

function _unpauseStaking() internal virtual whenStakingPaused {
_stakingPaused = false;
emit StakingUnpaused(_msgSender());
}

// ========================== LIQUIDATION PAUSE ==========================

modifier whenLiquidationNotPaused() {
_requireLiquidationNotPaused();
_;
}

modifier whenLiquidationPaused() {
_requireLiquidationPaused();
_;
}

function liquidationPaused() public view virtual returns (bool) {
return _liquidationPaused;
}

function _requireLiquidationNotPaused() internal view virtual {
require(!_liquidationPaused, "Pausable: Liquidation is paused");
}

function _requireLiquidationPaused() internal view virtual {
require(_liquidationPaused, "Pausable: Liquidation is not paused");
}

function _pauseLiquidation() internal virtual whenLiquidationNotPaused {
_liquidationPaused = true;
emit LiquidationPaused(_msgSender());
}

function _unpauseLiquidation() internal virtual whenLiquidationPaused {
_liquidationPaused = false;
emit LiquidationUnpaused(_msgSender());
}



/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}