Skip to content

Commit

Permalink
feat: Add flag for OperationValidator at ReserveConfig, add renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmtzinf committed Sep 28, 2021
1 parent 213094c commit 6515d1d
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 28 deletions.
4 changes: 2 additions & 2 deletions contracts/interfaces/IOperationalValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ pragma solidity 0.8.7;
interface IOperationalValidator {
/**
* @notice Returns true if the `borrow` operation is allowed.
* @dev Operation not allowed when sequencer is down or grace period not passed.
* @dev Operation not allowed when PriceOracle is down or grace period not passed.
* @return True if the `borrow` operation is allowed, false otherwise.
*/
function isBorrowAllowed() external view returns (bool);

/**
* @notice Returns true if the `liquidation` operation is allowed.
* @dev Operation not allowed when sequencer is down or grace period not passed.
* @dev Operation not allowed when PriceOracle is down or grace period not passed.
* @dev If the healthfactor is below a minimum threshold, the liquidation is allowed.
* @param healthFactor The health factor of the position to liquidate
* @return True if the `liquidation` operation is allowed, false otherwise.
Expand Down
19 changes: 19 additions & 0 deletions contracts/interfaces/IPoolConfigurator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ interface IPoolConfigurator {
**/
event ReserveUnpaused(address indexed asset);

/**
* @notice Emitted when the OperationalValidator is activated for the reserve
* @param asset The address of the underlying asset of the reserve
**/
event OperationalValidatorActivated(address indexed asset);

/**
* @notice Emitted when the OperationalValidator is deactivated for the reserve
* @param asset The address of the underlying asset of the reserve
**/
event OperationalValidatorDeactivated(address indexed asset);

/**
* @notice Emitted when a reserve is dropped
* @param asset The address of the underlying asset of the reserve
Expand Down Expand Up @@ -343,6 +355,13 @@ interface IPoolConfigurator {
**/
function setReservePause(address asset, bool val) external;

/**
* @notice Set the state of the OperationalValidator for the reserve
* @param asset The address of the underlying asset of the reserve
* @param state True if activating the OperationalValidator, false if deactivating
**/
function setOperationalValidatorActive(address asset, bool state) external;

/**
* @notice Updates the reserve factor of a reserve
* @param asset The address of the underlying asset of the reserve
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/IPriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.7;
/**
* @title IPriceOracle
* @author Aave
* @notice Defines the basic interface for an Price oracles.
* @notice Defines the basic interface for a Price oracle.
**/
interface IPriceOracle {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.7;

interface ISequencerOracle {
/**
* @title IPriceOracleSentinel
* @author Aave
* @notice Defines the basic interface for a Price oracle sentinel.
*/
interface IPriceOracleSentinel {
function setAnswer(bool isDown, uint256 timestamp) external;

function latestAnswer() external view returns (bool, uint256);
Expand Down
13 changes: 12 additions & 1 deletion contracts/misc/AaveProtocolDataProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,21 @@ contract AaveProtocolDataProvider {
usageAsCollateralEnabled = liquidationThreshold > 0;
}

/**
* Returns the state of the OperationValidator of the reserve
* @param asset The address of the underlying asset of the reserve
* @return True if the OperationalValidator is active for the reserve, false otherwise
*/
function getReserveOperationValidatorState(address asset) external view returns (bool) {
DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool())
.getConfiguration(asset);
return configuration.getOperationalValidatorActive();
}

/**
* Returns the efficiency mode category of the reserve
* @param asset The address of the underlying asset of the reserve
* @return eModeCategory The eMode id of the reserve
* @return The eMode id of the reserve
*/
function getReserveEModeCategory(address asset) external view returns (uint256) {
DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
pragma solidity 0.8.7;

import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol';
import {IPriceOracleSentinel} from '../../interfaces/IPriceOracleSentinel.sol';

contract SequencerOracle is Ownable {
contract PriceOracleSentinel is IPriceOracleSentinel, Ownable {
bool internal _isDown;
uint256 internal _timestampGotUp;

function setAnswer(bool isDown, uint256 timestamp) external onlyOwner {
function setAnswer(bool isDown, uint256 timestamp) external override onlyOwner {
_isDown = isDown;
_timestampGotUp = timestamp;
}

function latestAnswer() external view returns (bool, uint256) {
function latestAnswer() external view override returns (bool, uint256) {
return (_isDown, _timestampGotUp);
}
}
16 changes: 8 additions & 8 deletions contracts/protocol/configuration/OperationalValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@ pragma solidity 0.8.7;

import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
import {IOperationalValidator} from '../../interfaces/IOperationalValidator.sol';
import {ISequencerOracle} from '../../interfaces/ISequencerOracle.sol';
import {IPriceOracleSentinel} from '../../interfaces/IPriceOracleSentinel.sol';

/**
* @title OperationalValidator
* @author Aave
* @notice It validates if operations are allowed depending on the Sequencer Health.
* @dev After a Sequencer downtime, users can make their positions healthier during the grace period.
* @notice It validates if operations are allowed depending on the PriceOracle health.
* @dev After a PriceOracle downtime, once it gets up, users can make their positions healthy during a grace period.
*/
contract OperationalValidator is IOperationalValidator {
IPoolAddressesProvider public _addressesProvider;
ISequencerOracle public _sequencerOracle;
IPriceOracleSentinel public _priceOracleSentinel;
uint256 public _gracePeriod;

uint256 public constant MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 0.95 ether;

/**
* @notice Constructor
* @param provider The address of the PoolAddressesProvider
* @param sequencerOracle The address of the Sequencer Health oracle
* @param priceOracleSentinel The address of the PriceOracleSentinel
* @param gracePeriod The duration of the grace period in seconds
*/
constructor(
IPoolAddressesProvider provider,
ISequencerOracle sequencerOracle,
IPriceOracleSentinel priceOracleSentinel,
uint256 gracePeriod
) {
_addressesProvider = provider;
_sequencerOracle = sequencerOracle;
_priceOracleSentinel = priceOracleSentinel;
_gracePeriod = gracePeriod;
}

Expand All @@ -48,7 +48,7 @@ contract OperationalValidator is IOperationalValidator {
}

function _isUpAndGracePeriodPassed() internal view returns (bool) {
(bool isDown, uint256 timestampGotUp) = _sequencerOracle.latestAnswer();
(bool isDown, uint256 timestampGotUp) = _priceOracleSentinel.latestAnswer();
return !isDown && block.timestamp - timestampGotUp > _gracePeriod;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ library ReserveConfiguration {
uint256 constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore
uint256 constant PAUSED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant OPERATIONAL_VALIDATOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
Expand All @@ -35,7 +36,8 @@ library ReserveConfiguration {
uint256 constant BORROWING_ENABLED_START_BIT_POSITION = 58;
uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
uint256 constant IS_PAUSED_START_BIT_POSITION = 60;
/// @dev bits 61 62 63 unused yet
uint256 constant OPERATIONAL_VALIDATOR_ACTIVE_START_BIT_POSITION = 62;
/// @dev bits 61 63 unused yet
uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 constant SUPPLY_CAP_START_BIT_POSITION = 116;
Expand Down Expand Up @@ -219,6 +221,33 @@ library ReserveConfiguration {
return (self.data & ~PAUSED_MASK) != 0;
}

/**
* @notice Sets the state of the operational validator for the reserve
* @param self The reserve configuration
* @param state True if the operational validator is active, false otherwise
**/
function setOperationalValidatorActive(DataTypes.ReserveConfigurationMap memory self, bool state)
internal
pure
{
self.data =
(self.data & OPERATIONAL_VALIDATOR_MASK) |
(uint256(state ? 1 : 0) << OPERATIONAL_VALIDATOR_ACTIVE_START_BIT_POSITION);
}

/**
* @notice Gets the state of the operational validator for the reserve
* @param self The reserve configuration
* @return True if the operational validator is active, false otherwise
**/
function getOperationalValidatorActive(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (bool)
{
return (self.data & ~OPERATIONAL_VALIDATOR_MASK) != 0;
}

/**
* @notice Enables or disables borrowing on the reserve
* @param self The reserve configuration
Expand Down
2 changes: 1 addition & 1 deletion contracts/protocol/libraries/helpers/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,5 @@ library Errors {
string public constant P_CALLER_NOT_BRIDGE = '102';
string public constant RC_INVALID_UNBACKED_MINT_CAP = '103';
string public constant VL_UNBACKED_MINT_CAP_EXCEEDED = '104';
string public constant VL_SEQUENCER_IS_DOWN = '105';
string public constant VL_PRICE_ORACLE_SENTINEL_FAILED = '105';
}
18 changes: 8 additions & 10 deletions contracts/protocol/libraries/logic/ValidationLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,11 @@ library ValidationLogic {

require(vars.borrowingEnabled, Errors.VL_BORROWING_NOT_ENABLED);

if (params.operationalValidator != address(0)) {
require(
require(
!params.reserveCache.reserveConfiguration.getOperationalValidatorActive() ||
IOperationalValidator(params.operationalValidator).isBorrowAllowed(),
Errors.VL_SEQUENCER_IS_DOWN
);
}
Errors.VL_PRICE_ORACLE_SENTINEL_FAILED
);

//validate interest rate mode
require(
Expand Down Expand Up @@ -498,12 +497,11 @@ library ValidationLogic {
)
);

if (params.operationalValidator != address(0)) {
require(
require(
!params.debtReserveCache.reserveConfiguration.getOperationalValidatorActive() ||
IOperationalValidator(params.operationalValidator).isLiquidationAllowed(vars.healthFactor),
Errors.VL_SEQUENCER_IS_DOWN
);
}
Errors.VL_PRICE_ORACLE_SENTINEL_FAILED
);

require(
vars.healthFactor < GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
Expand Down
18 changes: 18 additions & 0 deletions contracts/protocol/pool/PoolConfigurator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,24 @@ contract PoolConfigurator is VersionedInitializable, IPoolConfigurator {
}
}

/// @inheritdoc IPoolConfigurator
function setOperationalValidatorActive(address asset, bool state)
public
override
onlyRiskOrPoolAdmins
{
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setOperationalValidatorActive(state);

_pool.setConfiguration(asset, currentConfig.data);

if (state) {
emit OperationalValidatorActivated(asset);
} else {
emit OperationalValidatorDeactivated(asset);
}
}

/// @inheritdoc IPoolConfigurator
function setReserveFactor(address asset, uint256 reserveFactor)
external
Expand Down

0 comments on commit 6515d1d

Please sign in to comment.