Skip to content
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
92 changes: 92 additions & 0 deletions contracts/Interfaces.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.25;

Check warning on line 2 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Found more than One contract per file. 4 contracts found!

import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol";

interface IVToken is IERC20Upgradeable {
function accrueInterest() external returns (uint256);

function redeem(uint256 redeemTokens) external returns (uint256);

function redeemUnderlying(uint256 redeemAmount) external returns (uint256);

function borrowBalanceCurrent(address borrower) external returns (uint256);

function balanceOfUnderlying(address owner) external returns (uint256);

function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);

Check warning on line 18 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Rule is set with explicit type [var/s: uint]

Check warning on line 18 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Rule is set with explicit type [var/s: uint]

function mintBehalf(address receiver, uint mintAmount) external returns (uint);

Check warning on line 20 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Rule is set with explicit type [var/s: uint]

Check warning on line 20 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Rule is set with explicit type [var/s: uint]

function borrowBehalf(address borrower, uint borrowAmount) external returns (uint256);

Check warning on line 22 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Rule is set with explicit type [var/s: uint]

function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint256);

Check warning on line 24 in contracts/Interfaces.sol

View workflow job for this annotation

GitHub Actions / Lint

Rule is set with explicit type [var/s: uint]

function comptroller() external view returns (IComptroller);

function borrowBalanceStored(address account) external view returns (uint256);

function underlying() external view returns (address);
}

interface IVBNB is IVToken {
function repayBorrowBehalf(address borrower) external payable;

function liquidateBorrow(address borrower, IVToken vTokenCollateral) external payable;
}

interface IComptroller {
enum Action {
MINT,
REDEEM,
BORROW,
REPAY,
SEIZE,
LIQUIDATE,
TRANSFER,
ENTER_MARKET,
EXIT_MARKET
}

function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external;

function setCollateralFactor(
IVToken vToken,
uint256 newCollateralFactorMantissa,
uint256 newLiquidationThresholdMantissa
) external returns (uint256);

function setLiquidationIncentive(
address vToken,
uint256 newLiquidationIncentiveMantissa
) external returns (uint256);

function setIsBorrowAllowed(uint96 poolId, address vToken, bool borrowAllowed) external;

function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);

function liquidationIncentiveMantissa() external view returns (uint256);

function vaiController() external view returns (address);

function liquidatorContract() external view returns (address);

function oracle() external view returns (ResilientOracleInterface);

function actionPaused(address market, Action action) external view returns (bool);

function markets(address) external view returns (bool, uint256, bool);

function isForcedLiquidationEnabled(address) external view returns (bool);

function approvedDelegates(address borrower, address delegate) external view returns (bool);

function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);
}

interface IWBNB is IERC20Upgradeable {
function deposit() external payable;

function withdraw(uint256 amount) external;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.25;

import { IComptroller, IVToken } from "../Interfaces.sol";

/**
* @title MarketConfigurationAggregator
* @author Venus
* @notice Executes batches of market configuration updates.
*/
contract MarketConfigurationAggregator {
/// @notice Struct representing parameters to update a market's collateral factor and liquidation threshold
struct CollateralFactorParams {
IVToken vToken;
uint256 newCollateralFactorMantissa;
uint256 newLiquidationThresholdMantissa;
}

/// @notice Struct representing parameters to update a market's liquidation incentive
struct LiquidationIncentiveParams {
address vToken;
uint256 newLiquidationIncentiveMantissa;
}

/// @notice Struct representing parameters to enable or disable borrowing on a market
struct BorrowAllowedParams {
uint96 poolId;
address vToken;
bool borrowAllowed;
}

/// @notice The Comptroller contract
IComptroller public immutable COMPTROLLER;

/**
* @notice Emitted after a batch of collateral factor updates is executed
* @param count The number of updates executed in this batch
*/
event CollateralFactorBatchExecuted(uint256 count);

/**
* @notice Emitted after a batch of liquidation incentive updates is executed
* @param count The number of updates executed in this batch
*/
event LiquidationIncentiveBatchExecuted(uint256 count);

/**
* @notice Emitted after a batch of borrow allowed updates is executed
* @param count The number of updates executed in this batch
*/
event BorrowAllowedBatchExecuted(uint256 count);

/// @notice Error thrown when an zero address is provided
error ZeroAddress();

/// @notice Error thrown when attempting to execute a batch with zero updates
error EmptyBatch();

/**
* @notice Constructor to initialize the MarketConfigurationAggregator with the comptroller
* @param _comptroller Address of the comptroller
* @custom:error Reverts with ZeroAddress if the provided `_comptroller` is the zero address
*/
constructor(address _comptroller) {
if (_comptroller == address(0)) revert ZeroAddress();
COMPTROLLER = IComptroller(_comptroller);
}

/**
* @notice Execute a batch of collateral factor updates
* @param updates Array of collateral factor parameters
* @custom:error Reverts with EmptyBatch if the updates array is empty
* @custom:event Emits CollateralFactorBatchExecuted
*/
function executeCollateralFactorBatch(CollateralFactorParams[] memory updates) external {
uint256 length = updates.length;
if (length == 0) revert EmptyBatch();

for (uint256 i; i < length; ++i) {
CollateralFactorParams memory u = updates[i];
COMPTROLLER.setCollateralFactor(u.vToken, u.newCollateralFactorMantissa, u.newLiquidationThresholdMantissa);
}

emit CollateralFactorBatchExecuted(length);
}

/**
* @notice Execute a batch of liquidation incentive updates
* @param updates Array of liquidation incentive parameters
* @custom:error Reverts with EmptyBatch if the updates array is empty
* @custom:event Emits LiquidationIncentiveBatchExecuted
*/
function executeLiquidationIncentiveBatch(LiquidationIncentiveParams[] memory updates) external {
uint256 length = updates.length;
if (length == 0) revert EmptyBatch();

for (uint256 i; i < length; ++i) {
LiquidationIncentiveParams memory u = updates[i];
COMPTROLLER.setLiquidationIncentive(u.vToken, u.newLiquidationIncentiveMantissa);
}

emit LiquidationIncentiveBatchExecuted(length);
}

/**
* @notice Execute a batch of borrow allowed updates
* @param updates Array of borrow allowed parameters
* @custom:error Reverts with EmptyBatch if the updates array is empty
* @custom:event Emits BorrowAllowedBatchExecuted
*/
function executeBorrowAllowedBatch(BorrowAllowedParams[] memory updates) external {
uint256 length = updates.length;
if (length == 0) revert EmptyBatch();

for (uint256 i; i < length; ++i) {
BorrowAllowedParams memory u = updates[i];
COMPTROLLER.setIsBorrowAllowed(u.poolId, u.vToken, u.borrowAllowed);
}

emit BorrowAllowedBatchExecuted(length);
}
}
21 changes: 21 additions & 0 deletions deploy/000-deploy-market-configuration-aggregator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();
const comptrollerDeployment = await deployments.get("Unitroller");

await deploy("MarketConfigurationAggregator", {
from: deployer,
args: [comptrollerDeployment.address],
log: true,
skipIfAlreadyDeployed: true,
});
};

func.tags = ["marketConfigurator"];
func.skip = async hre => hre.network.name === "hardhat";

export default func;
Loading
Loading