Skip to content

Commit

Permalink
Implement Keyring cred check
Browse files Browse the repository at this point in the history
  • Loading branch information
fdemiramon committed Feb 18, 2025
1 parent f22c95a commit c194050
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
68 changes: 67 additions & 1 deletion contracts/Comptroller/Diamond/facets/PolicyFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.5.16;

import { VToken } from "../../../Tokens/VTokens/VToken.sol";
import { IPolicyFacet } from "../interfaces/IPolicyFacet.sol";

import { IKeyringChecker } from "../../../KeyringChecker/IKeyringChecker.sol";
import { XVSRewardsHelper } from "./XVSRewardsHelper.sol";

/**
Expand All @@ -14,12 +14,31 @@ import { XVSRewardsHelper } from "./XVSRewardsHelper.sol";
* @notice This facet contract contains all the external pre-hook functions related to vToken
*/
contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
/// @notice The address of the Keyring contract.
/// @dev This could have been immutable, but not possible in upgradeable contracts.
/// @dev Consumes one storage slot.
IKeyringChecker public keyringChecker;

/// @notice The policyId to use with the Keyring contract.
/// @dev This could have been immutable, but not possible in upgradeable contracts.
/// @dev Consumes one storage slot.
uint32 public keyringPolicyId;

/// @notice Whether the keyring guard is enabled.
bool public keyringGuardEnabled;

/// @notice Emitted when a new borrow-side XVS speed is calculated for a market
event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);

/// @notice Emitted when a new supply-side XVS speed is calculated for a market
event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);

/// @notice Emitted when the keyring configuration is updated.
event KeyringConfigurationUpdated(address keyringChecker, uint32 keyringPolicyId);

/// @notice Emitted when the keyring guard is enabled.
event KeyringGuardEnabled(bool enabled);

/**
* @notice Checks if the account should be allowed to mint tokens in the given market
* @param vToken The market to verify the mint against
Expand All @@ -28,6 +47,8 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
* @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)
*/
function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {
ensureUserAllowed(minter);

// Pausing is a very serious situation - we revert to sound the alarms
checkProtocolPauseState();
checkActionPauseState(vToken, Action.MINT);
Expand Down Expand Up @@ -57,6 +78,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
*/
// solhint-disable-next-line no-unused-vars
function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {
ensureUserAllowed(minter);
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(minter, vToken);
}
Expand All @@ -70,6 +92,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
* @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)
*/
function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {
ensureUserAllowed(redeemer);
checkProtocolPauseState();
checkActionPauseState(vToken, Action.REDEEM);

Expand All @@ -93,6 +116,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
* @param redeemTokens The number of tokens being redeemed
*/
function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {
ensureUserAllowed(redeemer);
require(redeemTokens != 0 || redeemAmount == 0, "redeemTokens zero");
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(redeemer, vToken);
Expand All @@ -107,6 +131,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
* @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)
*/
function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {
ensureUserAllowed(borrower);
// Pausing is a very serious situation - we revert to sound the alarms
checkProtocolPauseState();
checkActionPauseState(vToken, Action.BORROW);
Expand Down Expand Up @@ -162,6 +187,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
*/
// solhint-disable-next-line no-unused-vars
function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {
ensureUserAllowed(borrower);
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(borrower, vToken);
}
Expand All @@ -181,6 +207,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
address borrower,
uint256 repayAmount // solhint-disable-line no-unused-vars
) external returns (uint256) {
ensureUserAllowed(payer);
checkProtocolPauseState();
checkActionPauseState(vToken, Action.REPAY);
ensureListed(markets[vToken]);
Expand All @@ -207,6 +234,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
uint256 actualRepayAmount, // solhint-disable-line no-unused-vars
uint256 borrowerIndex // solhint-disable-line no-unused-vars
) external {
ensureUserAllowed(payer);
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(borrower, vToken);
}
Expand All @@ -227,6 +255,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
address borrower,
uint256 repayAmount
) external view returns (uint256) {
ensureUserAllowed(liquidator);
checkProtocolPauseState();

// if we want to pause liquidating to vTokenCollateral, we should pause seizing
Expand Down Expand Up @@ -288,6 +317,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
uint256 actualRepayAmount, // solhint-disable-line no-unused-vars
uint256 seizeTokens // solhint-disable-line no-unused-vars
) external {
ensureUserAllowed(liquidator);
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);
prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);
Expand All @@ -309,6 +339,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
address borrower,
uint256 seizeTokens // solhint-disable-line no-unused-vars
) external returns (uint256) {
ensureUserAllowed(liquidator);
// Pausing is a very serious situation - we revert to sound the alarms
checkProtocolPauseState();
checkActionPauseState(vTokenCollateral, Action.SEIZE);
Expand Down Expand Up @@ -353,6 +384,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
address borrower,
uint256 seizeTokens // solhint-disable-line no-unused-vars
) external {
ensureUserAllowed(liquidator);
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);
prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);
Expand All @@ -373,6 +405,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
address dst,
uint256 transferTokens
) external returns (uint256) {
ensureUserAllowed(src);
// Pausing is a very serious situation - we revert to sound the alarms
checkProtocolPauseState();
checkActionPauseState(vToken, Action.TRANSFER);
Expand Down Expand Up @@ -401,6 +434,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
*/
// solhint-disable-next-line no-unused-vars
function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {
ensureUserAllowed(src);
if (address(prime) != address(0)) {
prime.accrueInterestAndUpdateScore(src, vToken);
prime.accrueInterestAndUpdateScore(dst, vToken);
Expand Down Expand Up @@ -499,4 +533,36 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper {
emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);
}
}
/// @notice Sets the keyring configuration.
/// @param _keyringChecker The address of the keyring checker.
/// @param _keyringPolicyId The policy id of the keyring.
function setKeyringConfiguration(address _keyringChecker, uint32 _keyringPolicyId) public {
ensureAdmin(msg.sender);
if (address(_keyringChecker) == address(0) || _keyringPolicyId == 0) {
revert InvalidKeyringConfiguration(address(_keyringChecker), _keyringPolicyId);
}
keyringChecker = IKeyringChecker(_keyringChecker);
keyringPolicyId = _keyringPolicyId;
emit KeyringConfigurationUpdated(address(_keyringChecker), _keyringPolicyId);
}

/// @notice Enables or disables the keyring guard.
/// @param _enabled Whether to enable or disable the keyring guard.
function enableKeyringGuard(bool _enabled) public {
ensureAdmin(msg.sender);
keyringGuardEnabled = _enabled;
emit KeyringGuardEnabled(_enabled);
}

/// @notice Checks if the user satisfies the policy.
/// @param _entity The address of the entity to check.
/// @return result True if the user satisfies the policy, false otherwise.
function isUserAllowed(address _entity) public view returns (bool) {
return !keyringGuardEnabled || keyringChecker.checkCredential(keyringPolicyId, _entity);
}

/// @notice Ensures that the user satisfies the policy.
function ensureUserAllowed(address _entity) public view {
require(isUserAllowed(_entity), "User does not have Keyring credential");
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity =0.8.19;

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

/// @title Mocked Keyring Checker
/// @notice A mock implementation of IKeyringChecker for testing purposes
Expand Down

0 comments on commit c194050

Please sign in to comment.