From 787d62c682e06b6ed705acba181bda1ab4217474 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Mon, 4 Aug 2025 16:30:26 +0300 Subject: [PATCH 1/8] refactor: extract interfaces --- .../Comptroller/ComptrollerInterface.sol | 155 +------ contracts/Comptroller/ComptrollerStorage.sol | 124 ++---- contracts/Comptroller/Diamond/Diamond.sol | 6 +- .../Comptroller/Diamond/facets/FacetBase.sol | 18 +- .../Diamond/facets/MarketFacet.sol | 32 +- .../Diamond/facets/PolicyFacet.sol | 34 +- .../Diamond/facets/RewardFacet.sol | 18 +- .../Diamond/facets/SetterFacet.sol | 36 +- .../Diamond/facets/XVSRewardsHelper.sol | 18 +- .../Diamond/interfaces/IFacetBase.sol | 10 +- .../Diamond/interfaces/IMarketFacet.sol | 14 +- .../Diamond/interfaces/IPolicyFacet.sol | 4 +- .../Diamond/interfaces/IRewardFacet.sol | 8 +- .../Diamond/interfaces/ISetterFacet.sol | 18 +- .../Comptroller/UnitrollerAdminStorage.sol | 26 ++ .../Comptroller/interfaces/IComptroller.sol | 15 + .../interfaces/IComptrollerStorage.sol | 139 +++++++ .../interfaces/IUnitrollerAdminStorage.sol | 24 ++ contracts/Lens/ComptrollerLens.sol | 40 +- contracts/Lens/SnapshotLens.sol | 19 +- contracts/Lens/VenusLens.sol | 61 +-- .../interfaces/IComptrollerLens.sol} | 6 +- contracts/Tokens/VAI/VAIController.sol | 19 +- .../Tokens/VAI/VAIControllerInterface.sol | 5 +- contracts/Tokens/VAI/VAIControllerStorage.sol | 5 +- contracts/Tokens/VTokens/VBNB.sol | 8 +- contracts/Tokens/VTokens/VBep20.sol | 12 +- contracts/Tokens/VTokens/VBep20Delegate.sol | 5 +- contracts/Tokens/VTokens/VBep20Delegator.sol | 59 +-- contracts/Tokens/VTokens/VBep20Immutable.sol | 5 +- contracts/Tokens/VTokens/VToken.sol | 20 +- contracts/Tokens/VTokens/VTokenInterfaces.sol | 390 ------------------ contracts/Tokens/VTokens/VTokenStorage.sol | 147 +++++++ contracts/Tokens/VTokens/interfaces/IVBNB.sol | 74 ++++ .../Tokens/VTokens/interfaces/IVBep20.sol | 32 ++ .../Tokens/VTokens/interfaces/IVDelegate.sol | 16 + .../Tokens/VTokens/interfaces/IVDelegator.sol | 21 + .../Tokens/VTokens/interfaces/IVToken.sol | 192 +++++++++ .../VTokens/interfaces/IVTokenStorage.sol | 113 +++++ contracts/VAIVault/IVAIVault.sol | 6 + contracts/test/ComptrollerHarness.sol | 11 +- contracts/test/ComptrollerMock.sol | 2 +- contracts/test/ComptrollerMockR1.sol | 2 +- contracts/test/ComptrollerScenario.sol | 13 +- contracts/test/EvilXDelegator.sol | 18 +- contracts/test/EvilXToken.sol | 9 +- contracts/test/MockVBNB.sol | 2 +- contracts/test/VAIControllerHarness.sol | 3 +- contracts/test/VBep20Harness.sol | 15 +- contracts/test/VBep20MockDelegate.sol | 12 +- 50 files changed, 1137 insertions(+), 904 deletions(-) create mode 100644 contracts/Comptroller/UnitrollerAdminStorage.sol create mode 100644 contracts/Comptroller/interfaces/IComptroller.sol create mode 100644 contracts/Comptroller/interfaces/IComptrollerStorage.sol create mode 100644 contracts/Comptroller/interfaces/IUnitrollerAdminStorage.sol rename contracts/{Comptroller/ComptrollerLensInterface.sol => Lens/interfaces/IComptrollerLens.sol} (82%) delete mode 100644 contracts/Tokens/VTokens/VTokenInterfaces.sol create mode 100644 contracts/Tokens/VTokens/VTokenStorage.sol create mode 100644 contracts/Tokens/VTokens/interfaces/IVBNB.sol create mode 100644 contracts/Tokens/VTokens/interfaces/IVBep20.sol create mode 100644 contracts/Tokens/VTokens/interfaces/IVDelegate.sol create mode 100644 contracts/Tokens/VTokens/interfaces/IVDelegator.sol create mode 100644 contracts/Tokens/VTokens/interfaces/IVToken.sol create mode 100644 contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol create mode 100644 contracts/VAIVault/IVAIVault.sol diff --git a/contracts/Comptroller/ComptrollerInterface.sol b/contracts/Comptroller/ComptrollerInterface.sol index f0d83af46..d7baef4cb 100644 --- a/contracts/Comptroller/ComptrollerInterface.sol +++ b/contracts/Comptroller/ComptrollerInterface.sol @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; - -import { VToken } from "../Tokens/VTokens/VToken.sol"; -import { VAIControllerInterface } from "../Tokens/VAI/VAIControllerInterface.sol"; - enum Action { MINT, REDEEM, @@ -16,152 +12,3 @@ enum Action { ENTER_MARKET, EXIT_MARKET } - -interface ComptrollerInterface { - /// @notice Indicator that this is a Comptroller contract (for inspection) - function isComptroller() external pure returns (bool); - - /*** Assets You Are In ***/ - - function enterMarkets(address[] calldata vTokens) external returns (uint[] memory); - - function exitMarket(address vToken) external returns (uint); - - /*** Policy Hooks ***/ - - function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint); - - function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external; - - function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint); - - function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external; - - function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint); - - function borrowVerify(address vToken, address borrower, uint borrowAmount) external; - - function repayBorrowAllowed( - address vToken, - address payer, - address borrower, - uint repayAmount - ) external returns (uint); - - function repayBorrowVerify( - address vToken, - address payer, - address borrower, - uint repayAmount, - uint borrowerIndex - ) external; - - function liquidateBorrowAllowed( - address vTokenBorrowed, - address vTokenCollateral, - address liquidator, - address borrower, - uint repayAmount - ) external returns (uint); - - function liquidateBorrowVerify( - address vTokenBorrowed, - address vTokenCollateral, - address liquidator, - address borrower, - uint repayAmount, - uint seizeTokens - ) external; - - function seizeAllowed( - address vTokenCollateral, - address vTokenBorrowed, - address liquidator, - address borrower, - uint seizeTokens - ) external returns (uint); - - function seizeVerify( - address vTokenCollateral, - address vTokenBorrowed, - address liquidator, - address borrower, - uint seizeTokens - ) external; - - function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint); - - function transferVerify(address vToken, address src, address dst, uint transferTokens) external; - - /*** Liquidity/Liquidation Calculations ***/ - - function liquidateCalculateSeizeTokens( - address vTokenBorrowed, - address vTokenCollateral, - uint repayAmount - ) external view returns (uint, uint); - - function setMintedVAIOf(address owner, uint amount) external returns (uint); - - function liquidateVAICalculateSeizeTokens( - address vTokenCollateral, - uint repayAmount - ) external view returns (uint, uint); - - function getXVSAddress() external view returns (address); - - function markets(address) external view returns (bool, uint); - - function oracle() external view returns (ResilientOracleInterface); - - function getAccountLiquidity(address) external view returns (uint, uint, uint); - - function getAssetsIn(address) external view returns (VToken[] memory); - - function claimVenus(address) external; - - function venusAccrued(address) external view returns (uint); - - function venusSupplySpeeds(address) external view returns (uint); - - function venusBorrowSpeeds(address) external view returns (uint); - - function getAllMarkets() external view returns (VToken[] memory); - - function venusSupplierIndex(address, address) external view returns (uint); - - function venusInitialIndex() external view returns (uint224); - - function venusBorrowerIndex(address, address) external view returns (uint); - - function venusBorrowState(address) external view returns (uint224, uint32); - - function venusSupplyState(address) external view returns (uint224, uint32); - - function approvedDelegates(address borrower, address delegate) external view returns (bool); - - function vaiController() external view returns (VAIControllerInterface); - - function liquidationIncentiveMantissa() external view returns (uint); - - function protocolPaused() external view returns (bool); - - function actionPaused(address market, Action action) external view returns (bool); - - function mintedVAIs(address user) external view returns (uint); - - function vaiMintRate() external view returns (uint); -} - -interface IVAIVault { - function updatePendingRewards() external; -} - -interface IComptroller { - function liquidationIncentiveMantissa() external view returns (uint); - - /*** Treasury Data ***/ - function treasuryAddress() external view returns (address); - - function treasuryPercent() external view returns (uint); -} diff --git a/contracts/Comptroller/ComptrollerStorage.sol b/contracts/Comptroller/ComptrollerStorage.sol index c94447ff5..db7b0fb3b 100644 --- a/contracts/Comptroller/ComptrollerStorage.sol +++ b/contracts/Comptroller/ComptrollerStorage.sol @@ -1,37 +1,49 @@ // SPDX-License-Identifier: BSD-3-Clause - pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; -import { VToken } from "../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; import { VAIControllerInterface } from "../Tokens/VAI/VAIControllerInterface.sol"; -import { ComptrollerLensInterface } from "./ComptrollerLensInterface.sol"; +import { IComptrollerLens } from "../Lens/interfaces/IComptrollerLens.sol"; import { IPrime } from "../Tokens/Prime/IPrime.sol"; -contract UnitrollerAdminStorage { - /** - * @notice Administrator for this contract - */ - address public admin; +import { IComptrollerStorage } from "./interfaces/IComptrollerStorage.sol"; +import { UnitrollerAdminStorage } from "./UnitrollerAdminStorage.sol"; - /** - * @notice Pending administrator for this contract - */ - address public pendingAdmin; +contract ComptrollerStorage is IComptrollerStorage, UnitrollerAdminStorage { + struct Market { + /// @notice Whether or not this market is listed + bool isListed; + /** + * @notice Multiplier representing the most one can borrow against their collateral in this market. + * For instance, 0.9 to allow borrowing 90% of collateral value. + * Must be between 0 and 1, and stored as a mantissa. + */ + uint256 collateralFactorMantissa; + /// @notice Per-market mapping of "accounts in this asset" + mapping(address => bool) accountMembership; + /// @notice Whether or not this market receives XVS + bool isVenus; + } - /** - * @notice Active brains of Unitroller - */ - address public comptrollerImplementation; + struct VenusMarketState { + /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex + uint224 index; + /// @notice The block number the index was last updated at + uint32 block; + } - /** - * @notice Pending brains of Unitroller - */ - address public pendingComptrollerImplementation; -} + struct FacetAddressAndPosition { + address facetAddress; + uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array + } + + struct FacetFunctionSelectors { + bytes4[] functionSelectors; + uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array + } -contract ComptrollerV1Storage is UnitrollerAdminStorage { /** * @notice Oracle which gives the price of any given asset */ @@ -55,22 +67,7 @@ contract ComptrollerV1Storage is UnitrollerAdminStorage { /** * @notice Per-account mapping of "assets you are in", capped by maxAssets */ - mapping(address => VToken[]) public accountAssets; - - struct Market { - /// @notice Whether or not this market is listed - bool isListed; - /** - * @notice Multiplier representing the most one can borrow against their collateral in this market. - * For instance, 0.9 to allow borrowing 90% of collateral value. - * Must be between 0 and 1, and stored as a mantissa. - */ - uint256 collateralFactorMantissa; - /// @notice Per-market mapping of "accounts in this asset" - mapping(address => bool) accountMembership; - /// @notice Whether or not this market receives XVS - bool isVenus; - } + mapping(address => IVToken[]) public accountAssets; /** * @notice Official mapping of vTokens -> Market metadata @@ -96,15 +93,8 @@ contract ComptrollerV1Storage is UnitrollerAdminStorage { /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused) mapping(address => bool) internal borrowGuardianPaused; - struct VenusMarketState { - /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex - uint224 index; - /// @notice The block number the index was last updated at - uint32 block; - } - /// @notice A list of all markets - VToken[] public allMarkets; + IVToken[] public allMarkets; /// @notice The rate at which the flywheel distributes XVS, per block uint256 internal venusRate; @@ -149,9 +139,7 @@ contract ComptrollerV1Storage is UnitrollerAdminStorage { /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated) uint256 private venusVAIRate; -} -contract ComptrollerV2Storage is ComptrollerV1Storage { /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block uint256 public venusVAIVaultRate; @@ -163,17 +151,13 @@ contract ComptrollerV2Storage is ComptrollerV1Storage { // minimum release amount to VAI Vault uint256 public minReleaseAmount; -} -contract ComptrollerV3Storage is ComptrollerV2Storage { /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market. address public borrowCapGuardian; /// @notice Borrow caps enforced by borrowAllowed for each vToken address. mapping(address => uint256) public borrowCaps; -} -contract ComptrollerV4Storage is ComptrollerV3Storage { /// @notice Treasury Guardian address address public treasuryGuardian; @@ -182,85 +166,51 @@ contract ComptrollerV4Storage is ComptrollerV3Storage { /// @notice Fee percent of accrued interest with decimal 18 uint256 public treasuryPercent; -} -contract ComptrollerV5Storage is ComptrollerV4Storage { /// @notice The portion of XVS that each contributor receives per block (deprecated) mapping(address => uint256) private venusContributorSpeeds; /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated) mapping(address => uint256) private lastContributorBlock; -} -contract ComptrollerV6Storage is ComptrollerV5Storage { address public liquidatorContract; -} -contract ComptrollerV7Storage is ComptrollerV6Storage { - ComptrollerLensInterface public comptrollerLens; -} + IComptrollerLens public comptrollerLens; -contract ComptrollerV8Storage is ComptrollerV7Storage { /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed mapping(address => uint256) public supplyCaps; -} -contract ComptrollerV9Storage is ComptrollerV8Storage { /// @notice AccessControlManager address address internal accessControl; /// @notice True if a certain action is paused on a certain market mapping(address => mapping(uint256 => bool)) internal _actionPaused; -} -contract ComptrollerV10Storage is ComptrollerV9Storage { /// @notice The rate at which venus is distributed to the corresponding borrow market (per block) mapping(address => uint256) public venusBorrowSpeeds; /// @notice The rate at which venus is distributed to the corresponding supply market (per block) mapping(address => uint256) public venusSupplySpeeds; -} -contract ComptrollerV11Storage is ComptrollerV10Storage { /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates; mapping(address => mapping(address => bool)) public approvedDelegates; -} -contract ComptrollerV12Storage is ComptrollerV11Storage { /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market mapping(address => bool) public isForcedLiquidationEnabled; -} - -contract ComptrollerV13Storage is ComptrollerV12Storage { - struct FacetAddressAndPosition { - address facetAddress; - uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array - } - - struct FacetFunctionSelectors { - bytes4[] functionSelectors; - uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array - } mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors; // facet addresses address[] internal _facetAddresses; -} -contract ComptrollerV14Storage is ComptrollerV13Storage { /// @notice Prime token address IPrime public prime; -} -contract ComptrollerV15Storage is ComptrollerV14Storage { /// @notice Whether forced liquidation is enabled for the borrows of a user in a market mapping(address user => mapping(address market => bool)) public isForcedLiquidationEnabledForUser; -} -contract ComptrollerV16Storage is ComptrollerV15Storage { /// @notice The XVS token contract address address internal xvs; diff --git a/contracts/Comptroller/Diamond/Diamond.sol b/contracts/Comptroller/Diamond/Diamond.sol index 7acc303b9..07a195fc4 100644 --- a/contracts/Comptroller/Diamond/Diamond.sol +++ b/contracts/Comptroller/Diamond/Diamond.sol @@ -3,14 +3,14 @@ pragma solidity 0.8.25; import { IDiamondCut } from "./interfaces/IDiamondCut.sol"; -import { Unitroller, ComptrollerV16Storage } from "../Unitroller.sol"; +import { Unitroller, ComptrollerStorage } from "../Unitroller.sol"; /** * @title Diamond * @author Venus * @notice This contract contains functions related to facets */ -contract Diamond is IDiamondCut, ComptrollerV16Storage { +contract Diamond is IDiamondCut, ComptrollerStorage { /// @notice Emitted when functions are added, replaced or removed to facets event DiamondCut(IDiamondCut.FacetCut[] _diamondCut); @@ -71,7 +71,7 @@ contract Diamond is IDiamondCut, ComptrollerV16Storage { */ function facetAddress( bytes4 functionSelector - ) external view returns (ComptrollerV16Storage.FacetAddressAndPosition memory) { + ) external view returns (ComptrollerStorage.FacetAddressAndPosition memory) { return _selectorToFacetAndPosition[functionSelector]; } diff --git a/contracts/Comptroller/Diamond/facets/FacetBase.sol b/contracts/Comptroller/Diamond/facets/FacetBase.sol index 254c202ba..ce2612a65 100644 --- a/contracts/Comptroller/Diamond/facets/FacetBase.sol +++ b/contracts/Comptroller/Diamond/facets/FacetBase.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: BSD-3-Clause - pragma solidity 0.8.25; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol"; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { ComptrollerErrorReporter } from "../../../Utils/ErrorReporter.sol"; import { ExponentialNoError } from "../../../Utils/ExponentialNoError.sol"; -import { IVAIVault, Action } from "../../../Comptroller/ComptrollerInterface.sol"; -import { ComptrollerV16Storage } from "../../../Comptroller/ComptrollerStorage.sol"; +import { IVAIVault } from "../../../VAIVault/IVAIVault.sol"; +import { Action } from "../../../Comptroller/ComptrollerInterface.sol"; +import { ComptrollerStorage } from "../../../Comptroller/ComptrollerStorage.sol"; import { IFacetBase } from "../interfaces/IFacetBase.sol"; /** @@ -18,7 +18,7 @@ import { IFacetBase } from "../interfaces/IFacetBase.sol"; * @author Venus * @notice This facet contract contains functions related to access and checks */ -contract FacetBase is IFacetBase, ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter { +contract FacetBase is IFacetBase, ComptrollerStorage, ExponentialNoError, ComptrollerErrorReporter { using SafeERC20 for IERC20; /// @notice The initial Venus index for a market @@ -31,7 +31,7 @@ contract FacetBase is IFacetBase, ComptrollerV16Storage, ExponentialNoError, Com uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9 /// @notice Emitted when an account enters a market - event MarketEntered(VToken indexed vToken, address indexed account); + event MarketEntered(IVToken indexed vToken, address indexed account); /// @notice Emitted when XVS is distributed to VAI Vault event DistributedVAIVaultVenus(uint256 amount); @@ -146,7 +146,7 @@ contract FacetBase is IFacetBase, ComptrollerV16Storage, ExponentialNoError, Com */ function getHypotheticalAccountLiquidityInternal( address account, - VToken vTokenModify, + IVToken vTokenModify, uint256 redeemTokens, uint256 borrowAmount ) internal view returns (Error, uint256, uint256) { @@ -166,7 +166,7 @@ contract FacetBase is IFacetBase, ComptrollerV16Storage, ExponentialNoError, Com * @param borrower The address of the account to modify * @return Success indicator for whether the market was entered */ - function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) { + function addToMarketInternal(IVToken vToken, address borrower) internal returns (Error) { checkActionPauseState(address(vToken), Action.ENTER_MARKET); Market storage marketToJoin = markets[address(vToken)]; ensureListed(marketToJoin); @@ -207,7 +207,7 @@ contract FacetBase is IFacetBase, ComptrollerV16Storage, ExponentialNoError, Com /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */ (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal( redeemer, - VToken(vToken), + IVToken(vToken), redeemTokens, 0 ); diff --git a/contracts/Comptroller/Diamond/facets/MarketFacet.sol b/contracts/Comptroller/Diamond/facets/MarketFacet.sol index af32eadbc..9ca2648fb 100644 --- a/contracts/Comptroller/Diamond/facets/MarketFacet.sol +++ b/contracts/Comptroller/Diamond/facets/MarketFacet.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.25; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { Action } from "../../ComptrollerInterface.sol"; import { IMarketFacet } from "../interfaces/IMarketFacet.sol"; import { FacetBase } from "./FacetBase.sol"; @@ -15,10 +15,10 @@ import { FacetBase } from "./FacetBase.sol"; */ contract MarketFacet is IMarketFacet, FacetBase { /// @notice Emitted when an admin supports a market - event MarketListed(VToken indexed vToken); + event MarketListed(IVToken indexed vToken); /// @notice Emitted when an account exits a market - event MarketExited(VToken indexed vToken, address indexed account); + event MarketExited(IVToken indexed vToken, address indexed account); /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account event DelegateUpdated(address indexed approver, address indexed delegate, bool approved); @@ -36,12 +36,12 @@ contract MarketFacet is IMarketFacet, FacetBase { * @param account The address of the account to pull assets for * @return A dynamic list with the assets the account has entered */ - function getAssetsIn(address account) external view returns (VToken[] memory) { + function getAssetsIn(address account) external view returns (IVToken[] memory) { uint256 len; - VToken[] memory _accountAssets = accountAssets[account]; + IVToken[] memory _accountAssets = accountAssets[account]; uint256 _accountAssetsLength = _accountAssets.length; - VToken[] memory assetsIn = new VToken[](_accountAssetsLength); + IVToken[] memory assetsIn = new IVToken[](_accountAssetsLength); for (uint256 i; i < _accountAssetsLength; ++i) { Market storage market = markets[address(_accountAssets[i])]; @@ -63,7 +63,7 @@ contract MarketFacet is IMarketFacet, FacetBase { * @dev The automatic getter may be used to access an individual market * @return The list of market addresses */ - function getAllMarkets() external view returns (VToken[] memory) { + function getAllMarkets() external view returns (IVToken[] memory) { return allMarkets; } @@ -114,7 +114,7 @@ contract MarketFacet is IMarketFacet, FacetBase { * @param vToken The vToken to check * @return True if the account is in the asset, otherwise false */ - function checkMembership(address account, VToken vToken) external view returns (bool) { + function checkMembership(address account, IVToken vToken) external view returns (bool) { return markets[address(vToken)].accountMembership[account]; } @@ -123,7 +123,7 @@ contract MarketFacet is IMarketFacet, FacetBase { * @param vToken vToken Address for the market to check * @return listed True if listed otherwise false */ - function isMarketListed(VToken vToken) external view returns (bool) { + function isMarketListed(IVToken vToken) external view returns (bool) { return markets[address(vToken)].isListed; } @@ -137,7 +137,7 @@ contract MarketFacet is IMarketFacet, FacetBase { uint256[] memory results = new uint256[](len); for (uint256 i; i < len; ++i) { - results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender)); + results[i] = uint256(addToMarketInternal(IVToken(vTokens[i]), msg.sender)); } return results; @@ -189,7 +189,7 @@ contract MarketFacet is IMarketFacet, FacetBase { function exitMarket(address vTokenAddress) external returns (uint256) { checkActionPauseState(vTokenAddress, Action.EXIT_MARKET); - VToken vToken = VToken(vTokenAddress); + IVToken vToken = IVToken(vTokenAddress); /* Get sender tokensHeld and amountOwed underlying from the vToken */ (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender); require(oErr == 0, "getAccountSnapshot failed"); // semi-opaque error code @@ -217,7 +217,7 @@ contract MarketFacet is IMarketFacet, FacetBase { /* Delete vToken from the account’s list of assets */ // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1 - VToken[] storage userAssetList = accountAssets[msg.sender]; + IVToken[] storage userAssetList = accountAssets[msg.sender]; uint256 len = userAssetList.length; uint256 i; for (; i < len; ++i) { @@ -241,7 +241,7 @@ contract MarketFacet is IMarketFacet, FacetBase { * @param vToken The address of the market (token) to list * @return uint256 0=success, otherwise a failure. (See enum Error for details) */ - function supportMarket(VToken vToken) external returns (uint256) { + function supportMarket(IVToken vToken) external returns (uint256) { return __supportMarket(vToken); } @@ -251,7 +251,7 @@ contract MarketFacet is IMarketFacet, FacetBase { * @param vToken The address of the market (token) to list * @return uint256 0=success, otherwise a failure. (See enum Error for details) */ - function _supportMarket(VToken vToken) external returns (uint256) { + function _supportMarket(IVToken vToken) external returns (uint256) { return __supportMarket(vToken); } @@ -277,7 +277,7 @@ contract MarketFacet is IMarketFacet, FacetBase { emit DelegateUpdated(approver, delegate, approved); } - function _addMarketInternal(VToken vToken) internal { + function _addMarketInternal(IVToken vToken) internal { uint256 allMarketsLength = allMarkets.length; for (uint256 i; i < allMarketsLength; ++i) { require(allMarkets[i] != vToken, "already added"); @@ -310,7 +310,7 @@ contract MarketFacet is IMarketFacet, FacetBase { supplyState.block = borrowState.block = blockNumber; } - function __supportMarket(VToken vToken) internal returns (uint256) { + function __supportMarket(IVToken vToken) internal returns (uint256) { ensureAllowed("_supportMarket(address)"); if (markets[address(vToken)].isListed) { diff --git a/contracts/Comptroller/Diamond/facets/PolicyFacet.sol b/contracts/Comptroller/Diamond/facets/PolicyFacet.sol index c163f0617..04ac8b87a 100644 --- a/contracts/Comptroller/Diamond/facets/PolicyFacet.sol +++ b/contracts/Comptroller/Diamond/facets/PolicyFacet.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.25; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { Action } from "../../ComptrollerInterface.sol"; import { IPolicyFacet } from "../interfaces/IPolicyFacet.sol"; @@ -16,10 +16,10 @@ import { XVSRewardsHelper } from "./XVSRewardsHelper.sol"; */ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { /// @notice Emitted when a new borrow-side XVS speed is calculated for a market - event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed); + event VenusBorrowSpeedUpdated(IVToken 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); + event VenusSupplySpeedUpdated(IVToken indexed vToken, uint256 newSpeed); /** * @notice Checks if the account should be allowed to mint tokens in the given market @@ -37,8 +37,8 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { uint256 supplyCap = supplyCaps[vToken]; require(supplyCap != 0, "market supply cap is 0"); - uint256 vTokenSupply = VToken(vToken).totalSupply(); - Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() }); + uint256 vTokenSupply = IVToken(vToken).totalSupply(); + Exp memory exchangeRate = Exp({ mantissa: IVToken(vToken).exchangeRateStored() }); uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount); require(nextTotalSupply <= supplyCap, "market supply cap reached"); @@ -121,7 +121,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { require(msg.sender == vToken, "sender must be vToken"); // attempt to add borrower to the market - Error err = addToMarketInternal(VToken(vToken), borrower); + Error err = addToMarketInternal(IVToken(vToken), borrower); if (err != Error.NO_ERROR) { return uint256(err); } @@ -131,12 +131,12 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { return uint256(Error.PRICE_ERROR); } - uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount); + uint256 nextTotalBorrows = add_(IVToken(vToken).totalBorrows(), borrowAmount); require(nextTotalBorrows <= borrowCap, "market borrow cap reached"); (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal( borrower, - VToken(vToken), + IVToken(vToken), 0, borrowAmount ); @@ -148,7 +148,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { } // Keep the flywheel moving - Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() }); + Exp memory borrowIndex = Exp({ mantissa: IVToken(vToken).borrowIndex() }); updateVenusBorrowIndex(vToken, borrowIndex); distributeBorrowerVenus(vToken, borrower, borrowIndex); @@ -187,7 +187,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { ensureListed(markets[vToken]); // Keep the flywheel moving - Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() }); + Exp memory borrowIndex = Exp({ mantissa: IVToken(vToken).borrowIndex() }); updateVenusBorrowIndex(vToken, borrowIndex); distributeBorrowerVenus(vToken, borrower, borrowIndex); @@ -242,7 +242,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { uint256 borrowBalance; if (address(vTokenBorrowed) != address(vaiController)) { ensureListed(markets[vTokenBorrowed]); - borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower); + borrowBalance = IVToken(vTokenBorrowed).borrowBalanceStored(borrower); } else { borrowBalance = vaiController.getVAIRepayAmount(borrower); } @@ -255,7 +255,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { } /* The borrower must have shortfall in order to be liquidatable */ - (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0); + (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, IVToken(address(0)), 0, 0); if (err != Error.NO_ERROR) { return uint256(err); } @@ -327,7 +327,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { ensureListed(markets[vTokenBorrowed]); } - if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) { + if (IVToken(vTokenCollateral).comptroller() != IVToken(vTokenBorrowed).comptroller()) { return uint256(Error.COMPTROLLER_MISMATCH); } @@ -448,7 +448,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { ) external view returns (uint256, uint256, uint256) { (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal( account, - VToken(vTokenModify), + IVToken(vTokenModify), redeemTokens, borrowAmount ); @@ -464,7 +464,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { * @param borrowSpeeds New XVS speed for borrow */ function _setVenusSpeeds( - VToken[] calldata vTokens, + IVToken[] calldata vTokens, uint256[] calldata supplySpeeds, uint256[] calldata borrowSpeeds ) external { @@ -482,7 +482,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { function _getAccountLiquidity(address account) internal view returns (uint256, uint256, uint256) { (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal( account, - VToken(address(0)), + IVToken(address(0)), 0, 0 ); @@ -490,7 +490,7 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { return (uint256(err), liquidity, shortfall); } - function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal { + function setVenusSpeedInternal(IVToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal { ensureListed(markets[address(vToken)]); if (venusSupplySpeeds[address(vToken)] != supplySpeed) { diff --git a/contracts/Comptroller/Diamond/facets/RewardFacet.sol b/contracts/Comptroller/Diamond/facets/RewardFacet.sol index bcaf30115..163323704 100644 --- a/contracts/Comptroller/Diamond/facets/RewardFacet.sol +++ b/contracts/Comptroller/Diamond/facets/RewardFacet.sol @@ -5,10 +5,10 @@ pragma solidity 0.8.25; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { IRewardFacet } from "../interfaces/IRewardFacet.sol"; import { XVSRewardsHelper } from "./XVSRewardsHelper.sol"; -import { VBep20Interface } from "../../../Tokens/VTokens/VTokenInterfaces.sol"; +import { IVBep20 } from "../../../Tokens/VTokens/interfaces/IVBep20.sol"; /** * @title RewardFacet @@ -38,7 +38,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { * @param holder The address to claim XVS for * @param vTokens The list of markets to claim XVS in */ - function claimVenus(address holder, VToken[] memory vTokens) public { + function claimVenus(address holder, IVToken[] memory vTokens) public { address[] memory holders = new address[](1); holders[0] = holder; claimVenus(holders, vTokens, true, true); @@ -51,7 +51,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { * @param borrowers Whether or not to claim XVS earned by borrowing * @param suppliers Whether or not to claim XVS earned by supplying */ - function claimVenus(address[] memory holders, VToken[] memory vTokens, bool borrowers, bool suppliers) public { + function claimVenus(address[] memory holders, IVToken[] memory vTokens, bool borrowers, bool suppliers) public { claimVenus(holders, vTokens, borrowers, suppliers, false); } @@ -110,7 +110,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { xvs_.safeApprove(xvsVToken_, 0); xvs_.safeApprove(xvsVToken_, amount); - require(VBep20Interface(xvsVToken_).mintBehalf(user, amount) == uint256(Error.NO_ERROR), "mint behalf error"); + require(IVBep20(xvsVToken_).mintBehalf(user, amount) == uint256(Error.NO_ERROR), "mint behalf error"); // set venusAccrued[user] to 0 return 0; @@ -176,7 +176,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { */ function claimVenus( address[] memory holders, - VToken[] memory vTokens, + IVToken[] memory vTokens, bool borrowers, bool suppliers, bool collateral @@ -189,7 +189,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { // If there is a positive shortfall, the XVS reward is accrued, // but won't be granted to this holder - (, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(holder, VToken(address(0)), 0, 0); + (, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(holder, IVToken(address(0)), 0, 0); uint256 value = venusAccrued[holder]; delete venusAccrued[holder]; @@ -212,7 +212,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { */ function updateAndDistributeRewardsInternal( address[] memory holders, - VToken[] memory vTokens, + IVToken[] memory vTokens, bool borrowers, bool suppliers ) internal { @@ -221,7 +221,7 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { uint256 vTokensLength = vTokens.length; for (uint256 i; i < vTokensLength; ++i) { - VToken vToken = vTokens[i]; + IVToken vToken = vTokens[i]; ensureListed(markets[address(vToken)]); if (borrowers) { Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() }); diff --git a/contracts/Comptroller/Diamond/facets/SetterFacet.sol b/contracts/Comptroller/Diamond/facets/SetterFacet.sol index db415c367..d97928834 100644 --- a/contracts/Comptroller/Diamond/facets/SetterFacet.sol +++ b/contracts/Comptroller/Diamond/facets/SetterFacet.sol @@ -4,9 +4,9 @@ pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { Action } from "../../ComptrollerInterface.sol"; -import { ComptrollerLensInterface } from "../../ComptrollerLensInterface.sol"; +import { IComptrollerLens } from "../../../Lens/interfaces/IComptrollerLens.sol"; import { VAIControllerInterface } from "../../../Tokens/VAI/VAIControllerInterface.sol"; import { IPrime } from "../../../Tokens/Prime/IPrime.sol"; import { ISetterFacet } from "../interfaces/ISetterFacet.sol"; @@ -24,7 +24,7 @@ contract SetterFacet is ISetterFacet, FacetBase { /// @notice Emitted when a collateral factor is changed by admin event NewCollateralFactor( - VToken indexed vToken, + IVToken indexed vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa ); @@ -36,7 +36,7 @@ contract SetterFacet is ISetterFacet, FacetBase { event NewPriceOracle(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle); /// @notice Emitted when borrow cap for a vToken is changed - event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap); + event NewBorrowCap(IVToken indexed vToken, uint256 newBorrowCap); /// @notice Emitted when VAIController is changed event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController); @@ -63,7 +63,7 @@ contract SetterFacet is ISetterFacet, FacetBase { event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens); /// @notice Emitted when supply cap for a vToken is changed - event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap); + event NewSupplyCap(IVToken indexed vToken, uint256 newSupplyCap); /// @notice Emitted when access control address is changed by admin event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress); @@ -72,7 +72,7 @@ contract SetterFacet is ISetterFacet, FacetBase { event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian); /// @notice Emitted when an action is paused on a market - event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState); + event ActionPausedMarket(IVToken indexed vToken, Action indexed action, bool pauseState); /// @notice Emitted when VAI Vault info is changed event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_); @@ -182,7 +182,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details) */ function setCollateralFactor( - VToken vToken, + IVToken vToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa ) external returns (uint256) { @@ -200,7 +200,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details) */ - function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256) { + function _setCollateralFactor(IVToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256) { return __setCollateralFactor(vToken, newCollateralFactorMantissa); } @@ -267,7 +267,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param vTokens The addresses of the markets (tokens) to change the borrow caps for * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed */ - function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external { + function setMarketBorrowCaps(IVToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external { __setMarketBorrowCaps(vTokens, newBorrowCaps); } @@ -277,7 +277,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param vTokens The addresses of the markets (tokens) to change the borrow caps for * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed */ - function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external { + function _setMarketBorrowCaps(IVToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external { __setMarketBorrowCaps(vTokens, newBorrowCaps); } @@ -286,7 +286,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param vTokens The addresses of the markets (tokens) to change the supply caps for * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed */ - function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external { + function setMarketSupplyCaps(IVToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external { __setMarketSupplyCaps(vTokens, newSupplyCaps); } @@ -296,7 +296,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param vTokens The addresses of the markets (tokens) to change the supply caps for * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed */ - function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external { + function _setMarketSupplyCaps(IVToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external { __setMarketSupplyCaps(vTokens, newSupplyCaps); } @@ -344,7 +344,7 @@ contract SetterFacet is ISetterFacet, FacetBase { function setActionPausedInternal(address market, Action action, bool paused) internal { ensureListed(markets[market]); _actionPaused[market][uint256(action)] = paused; - emit ActionPausedMarket(VToken(market), action, paused); + emit ActionPausedMarket(IVToken(market), action, paused); } /** @@ -444,7 +444,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _setComptrollerLens( - ComptrollerLensInterface comptrollerLens_ + IComptrollerLens comptrollerLens_ ) external virtual compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) { ensureAdmin(); ensureNonzeroAddress(address(comptrollerLens_)); @@ -569,7 +569,7 @@ contract SetterFacet is ISetterFacet, FacetBase { ensureAdmin(); ensureNonzeroAddress(xvsVToken_); - address underlying = VToken(xvsVToken_).underlying(); + address underlying = IVToken(xvsVToken_).underlying(); require(underlying == xvs, "invalid xvs vtoken address"); emit NewXVSVToken(xvsVToken, xvsVToken_); @@ -636,7 +636,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @return uint256 0=success, otherwise reverted */ function __setCollateralFactor( - VToken vToken, + IVToken vToken, uint256 newCollateralFactorMantissa ) internal @@ -702,7 +702,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param vTokens The markets to set the borrow caps on * @param newBorrowCaps The new borrow caps to be set */ - function __setMarketBorrowCaps(VToken[] memory vTokens, uint256[] memory newBorrowCaps) internal { + function __setMarketBorrowCaps(IVToken[] memory vTokens, uint256[] memory newBorrowCaps) internal { ensureAllowed("_setMarketBorrowCaps(address[],uint256[])"); uint256 numMarkets = vTokens.length; @@ -721,7 +721,7 @@ contract SetterFacet is ISetterFacet, FacetBase { * @param vTokens The markets to set the supply caps on * @param newSupplyCaps The new supply caps to be set */ - function __setMarketSupplyCaps(VToken[] memory vTokens, uint256[] memory newSupplyCaps) internal { + function __setMarketSupplyCaps(IVToken[] memory vTokens, uint256[] memory newSupplyCaps) internal { ensureAllowed("_setMarketSupplyCaps(address[],uint256[])"); uint256 numMarkets = vTokens.length; diff --git a/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol b/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol index 5e0d5f961..e2c18e403 100644 --- a/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol +++ b/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.25; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { FacetBase } from "./FacetBase.sol"; /** @@ -14,7 +14,7 @@ import { FacetBase } from "./FacetBase.sol"; contract XVSRewardsHelper is FacetBase { /// @notice Emitted when XVS is distributed to a borrower event DistributedBorrowerVenus( - VToken indexed vToken, + IVToken indexed vToken, address indexed borrower, uint256 venusDelta, uint256 venusBorrowIndex @@ -22,7 +22,7 @@ contract XVSRewardsHelper is FacetBase { /// @notice Emitted when XVS is distributed to a supplier event DistributedSupplierVenus( - VToken indexed vToken, + IVToken indexed vToken, address indexed supplier, uint256 venusDelta, uint256 venusSupplyIndex @@ -38,7 +38,7 @@ contract XVSRewardsHelper is FacetBase { uint32 blockNumber = getBlockNumberAsUint32(); uint256 deltaBlocks = sub_(blockNumber, borrowState.block); if (deltaBlocks != 0 && borrowSpeed != 0) { - uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex); + uint256 borrowAmount = div_(IVToken(vToken).totalBorrows(), marketBorrowIndex); uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed); Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 }); borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, "224"); @@ -59,7 +59,7 @@ contract XVSRewardsHelper is FacetBase { uint256 deltaBlocks = sub_(blockNumber, supplyState.block); if (deltaBlocks != 0 && supplySpeed != 0) { - uint256 supplyTokens = VToken(vToken).totalSupply(); + uint256 supplyTokens = IVToken(vToken).totalSupply(); uint256 accruedVenus = mul_(deltaBlocks, supplySpeed); Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 }); supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, "224"); @@ -91,10 +91,10 @@ contract XVSRewardsHelper is FacetBase { // Calculate change in the cumulative sum of the XVS per vToken accrued Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) }); // Multiply of supplierTokens and supplierDelta - uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex); + uint256 supplierDelta = mul_(IVToken(vToken).balanceOf(supplier), deltaIndex); // Addition of supplierAccrued and supplierDelta venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta); - emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex); + emit DistributedSupplierVenus(IVToken(vToken), supplier, supplierDelta, supplyIndex); } /** @@ -119,8 +119,8 @@ contract XVSRewardsHelper is FacetBase { } // Calculate change in the cumulative sum of the XVS per borrowed unit accrued Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) }); - uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex); + uint256 borrowerDelta = mul_(div_(IVToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex); venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta); - emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex); + emit DistributedBorrowerVenus(IVToken(vToken), borrower, borrowerDelta, borrowIndex); } } diff --git a/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol b/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol index 0b291c15d..0a75f2a00 100644 --- a/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol +++ b/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol @@ -2,15 +2,7 @@ pragma solidity 0.8.25; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol"; - -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; -import { ComptrollerErrorReporter } from "../../../Utils/ErrorReporter.sol"; -import { ExponentialNoError } from "../../../Utils/ExponentialNoError.sol"; -import { IVAIVault, Action } from "../../../Comptroller/ComptrollerInterface.sol"; -import { ComptrollerV16Storage } from "../../../Comptroller/ComptrollerStorage.sol"; +import { Action } from "../../ComptrollerInterface.sol"; interface IFacetBase { /** diff --git a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol index 44c75f32c..5789d272b 100644 --- a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.25; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; interface IMarketFacet { function isComptroller() external pure returns (bool); @@ -18,21 +18,21 @@ interface IMarketFacet { uint256 actualRepayAmount ) external view returns (uint256, uint256); - function checkMembership(address account, VToken vToken) external view returns (bool); + function checkMembership(address account, IVToken vToken) external view returns (bool); function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory); function exitMarket(address vToken) external returns (uint256); - function _supportMarket(VToken vToken) external returns (uint256); + function _supportMarket(IVToken vToken) external returns (uint256); - function supportMarket(VToken vToken) external returns (uint256); + function supportMarket(IVToken vToken) external returns (uint256); - function isMarketListed(VToken vToken) external view returns (bool); + function isMarketListed(IVToken vToken) external view returns (bool); - function getAssetsIn(address account) external view returns (VToken[] memory); + function getAssetsIn(address account) external view returns (IVToken[] memory); - function getAllMarkets() external view returns (VToken[] memory); + function getAllMarkets() external view returns (IVToken[] memory); function updateDelegate(address delegate, bool allowBorrows) external; diff --git a/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol b/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol index b79c79a30..e67081a89 100644 --- a/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.25; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; interface IPolicyFacet { function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256); @@ -84,7 +84,7 @@ interface IPolicyFacet { ) external view returns (uint256, uint256, uint256); function _setVenusSpeeds( - VToken[] calldata vTokens, + IVToken[] calldata vTokens, uint256[] calldata supplySpeeds, uint256[] calldata borrowSpeeds ) external; diff --git a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol index ad5df00e0..476392e01 100644 --- a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol @@ -2,16 +2,16 @@ pragma solidity 0.8.25; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { Action } from "../../ComptrollerInterface.sol"; import { IFacetBase } from "./IFacetBase.sol"; interface IRewardFacet is IFacetBase { function claimVenus(address holder) external; - function claimVenus(address holder, VToken[] calldata vTokens) external; + function claimVenus(address holder, IVToken[] calldata vTokens) external; - function claimVenus(address[] calldata holders, VToken[] calldata vTokens, bool borrowers, bool suppliers) external; + function claimVenus(address[] calldata holders, IVToken[] calldata vTokens, bool borrowers, bool suppliers) external; function claimVenusAsCollateral(address holder) external; @@ -21,7 +21,7 @@ interface IRewardFacet is IFacetBase { function claimVenus( address[] calldata holders, - VToken[] calldata vTokens, + IVToken[] calldata vTokens, bool borrowers, bool suppliers, bool collateral diff --git a/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol b/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol index 38553d824..c0db8dcd0 100644 --- a/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol @@ -3,10 +3,10 @@ pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; -import { VToken } from "../../../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { Action } from "../../ComptrollerInterface.sol"; import { VAIControllerInterface } from "../../../Tokens/VAI/VAIControllerInterface.sol"; -import { ComptrollerLensInterface } from "../../../Comptroller/ComptrollerLensInterface.sol"; +import { IComptrollerLens } from "../../../Lens/interfaces/IComptrollerLens.sol"; import { IPrime } from "../../../Tokens/Prime/IPrime.sol"; interface ISetterFacet { @@ -21,12 +21,12 @@ interface ISetterFacet { function _setAccessControl(address newAccessControlAddress) external returns (uint256); function setCollateralFactor( - VToken vToken, + IVToken vToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa ) external returns (uint256); - function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256); + function _setCollateralFactor(IVToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256); function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256); @@ -36,13 +36,13 @@ interface ISetterFacet { function _setPauseGuardian(address newPauseGuardian) external returns (uint256); - function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external; + function setMarketBorrowCaps(IVToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external; - function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external; + function _setMarketBorrowCaps(IVToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external; - function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external; + function setMarketSupplyCaps(IVToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external; - function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external; + function _setMarketSupplyCaps(IVToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external; function _setProtocolPaused(bool state) external returns (bool); @@ -62,7 +62,7 @@ interface ISetterFacet { uint256 newTreasuryPercent ) external returns (uint256); - function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256); + function _setComptrollerLens(IComptrollerLens comptrollerLens_) external returns (uint256); function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external; diff --git a/contracts/Comptroller/UnitrollerAdminStorage.sol b/contracts/Comptroller/UnitrollerAdminStorage.sol new file mode 100644 index 000000000..6321fbbf6 --- /dev/null +++ b/contracts/Comptroller/UnitrollerAdminStorage.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { IUnitrollerAdminStorage } from "./interfaces/IUnitrollerAdminStorage.sol"; + +contract UnitrollerAdminStorage is IUnitrollerAdminStorage { + /** + * @notice Administrator for this contract + */ + address public admin; + + /** + * @notice Pending administrator for this contract + */ + address public pendingAdmin; + + /** + * @notice Active brains of Unitroller + */ + address public comptrollerImplementation; + + /** + * @notice Pending brains of Unitroller + */ + address public pendingComptrollerImplementation; +} diff --git a/contracts/Comptroller/interfaces/IComptroller.sol b/contracts/Comptroller/interfaces/IComptroller.sol new file mode 100644 index 000000000..86eded1e0 --- /dev/null +++ b/contracts/Comptroller/interfaces/IComptroller.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; + +import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; +import { VAIControllerInterface } from "../../Tokens/VAI/VAIControllerInterface.sol"; +import { IFacetBase } from "../Diamond/interfaces/IFacetBase.sol"; +import { IMarketFacet } from "../Diamond/interfaces/IMarketFacet.sol"; +import { IPolicyFacet } from "../Diamond/interfaces/IPolicyFacet.sol"; +import { IRewardFacet } from "../Diamond/interfaces/IRewardFacet.sol"; +import { ISetterFacet } from "../Diamond/interfaces/ISetterFacet.sol"; +import { IComptrollerStorage } from "./IComptrollerStorage.sol"; + +interface IComptroller is IComptrollerStorage, IFacetBase, IMarketFacet, IPolicyFacet, IRewardFacet, ISetterFacet {} diff --git a/contracts/Comptroller/interfaces/IComptrollerStorage.sol b/contracts/Comptroller/interfaces/IComptrollerStorage.sol new file mode 100644 index 000000000..d063c195d --- /dev/null +++ b/contracts/Comptroller/interfaces/IComptrollerStorage.sol @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; + +import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; +import { VAIControllerInterface } from "../../Tokens/VAI/VAIControllerInterface.sol"; +import { IPrime } from "../../Tokens/Prime/IPrime.sol"; +import { IComptrollerLens } from "../../Lens/interfaces/IComptrollerLens.sol"; + +import { IUnitrollerAdminStorage } from "./IUnitrollerAdminStorage.sol"; + +interface IComptrollerStorage is IUnitrollerAdminStorage { + /** + * @notice Oracle which gives the price of any given asset + */ + function oracle() external view returns (ResilientOracleInterface); + + /** + * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow + */ + function closeFactorMantissa() external view returns (uint256); + + /** + * @notice Multiplier representing the discount on collateral that a liquidator receives + */ + function liquidationIncentiveMantissa() external view returns (uint256); + + /** + * @notice Max number of assets a single account can participate in (borrow or use as collateral) + */ + function maxAssets() external view returns (uint256); + + /** + * @notice Per-account mapping of "assets you are in", capped by maxAssets + */ + function accountAssets(address, uint256) external view returns (IVToken); + + /** + * @notice Official mapping of vTokens -> Market metadata + * @dev Used e.g. to determine if a market is supported + */ + function markets(address) external view returns (bool isListed, uint256 collateralFactorMantissa, bool _unused); + + /** + * @notice The Pause Guardian can pause certain actions as a safety mechanism. + */ + function pauseGuardian() external view returns (address); + + /// @notice A list of all markets + function allMarkets(uint256) external view returns (IVToken); + + /// @notice The Venus market supply state for each market + function venusSupplyState(address) external view returns (uint224, uint32); + + /// @notice The Venus market borrow state for each market + function venusBorrowState(address) external view returns (uint224, uint32); + + /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS + function venusSupplierIndex(address, address) external view returns (uint256); + + /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS + function venusBorrowerIndex(address, address) external view returns (uint256); + + /// @notice The XVS accrued but not yet transferred to each user + function venusAccrued(address) external view returns (uint256); + + /// @notice The Address of VAIController + function vaiController() external view returns (VAIControllerInterface); + + /// @notice The minted VAI amount to each user + function mintedVAIs(address) external view returns (uint256); + + /// @notice VAI Mint Rate as a percentage + function vaiMintRate() external view returns (uint256); + + /** + * @notice The Pause Guardian can pause certain actions as a safety mechanism. + */ + function mintVAIGuardianPaused() external view returns (bool); + function repayVAIGuardianPaused() external view returns (bool); + + /** + * @notice Pause/Unpause whole protocol actions + */ + function protocolPaused() external view returns (bool); + + /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block + function venusVAIVaultRate() external view returns (uint256); + + // @notice address of VAI Vault + function vaiVaultAddress() external view returns (address); + + // @notice start block of release to VAI Vault + function releaseStartBlock() external view returns (uint256); + + // minimum release amount to VAI Vault + function minReleaseAmount() external view returns (uint256); + + /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market. + function borrowCapGuardian() external view returns (address); + + /// @notice Borrow caps enforced by borrowAllowed for each vToken address. + function borrowCaps(address) external view returns (uint256); + + /// @notice Treasury Guardian address + function treasuryGuardian() external view returns (address); + + /// @notice Treasury address + function treasuryAddress() external view returns (address); + + /// @notice Fee percent of accrued interest with decimal 18 + function treasuryPercent() external view returns (uint256); + + function liquidatorContract() external view returns (address); + + function comptrollerLens() external view returns (IComptrollerLens); + + /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed + function supplyCaps(address) external view returns (uint256); + + /// @notice The rate at which venus is distributed to the corresponding borrow market (per block) + function venusBorrowSpeeds(address) external view returns (uint256); + + /// @notice The rate at which venus is distributed to the corresponding supply market (per block) + function venusSupplySpeeds(address) external view returns (uint256); + + /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user + function approvedDelegates(address user, address delegate) external view returns (bool); + + /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market + function isForcedLiquidationEnabled(address vTokenBorrowed) external view returns (bool); + + /// @notice Prime token address + function prime() external view returns (IPrime); + + /// @notice Whether forced liquidation is enabled for the borrows of a user in a market + function isForcedLiquidationEnabledForUser(address user, address vTokenBorrowed) external view returns (bool); +} diff --git a/contracts/Comptroller/interfaces/IUnitrollerAdminStorage.sol b/contracts/Comptroller/interfaces/IUnitrollerAdminStorage.sol new file mode 100644 index 000000000..b07ffb400 --- /dev/null +++ b/contracts/Comptroller/interfaces/IUnitrollerAdminStorage.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +interface IUnitrollerAdminStorage { + /** + * @notice Administrator for this contract + */ + function admin() external view returns (address); + + /** + * @notice Pending administrator for this contract + */ + function pendingAdmin() external view returns (address); + + /** + * @notice Active brains of Unitroller + */ + function comptrollerImplementation() external view returns (address); + + /** + * @notice Pending brains of Unitroller + */ + function pendingComptrollerImplementation() external view returns (address); +} diff --git a/contracts/Lens/ComptrollerLens.sol b/contracts/Lens/ComptrollerLens.sol index c07f88bfd..67c11b8e5 100644 --- a/contracts/Lens/ComptrollerLens.sol +++ b/contracts/Lens/ComptrollerLens.sol @@ -1,14 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; -import "../Tokens/VTokens/VBep20.sol"; -import { VToken } from "../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; import { ExponentialNoError } from "../Utils/ExponentialNoError.sol"; -import "../Utils/ErrorReporter.sol"; -import "../Comptroller/ComptrollerInterface.sol"; -import "../Comptroller/ComptrollerLensInterface.sol"; -import "../Tokens/VAI/VAIControllerInterface.sol"; +import { ComptrollerErrorReporter } from "../Utils/ErrorReporter.sol"; +import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; +import { IComptrollerLens } from "./interfaces/IComptrollerLens.sol"; +import { VAIControllerInterface } from "../Tokens/VAI/VAIControllerInterface.sol"; /** * @title ComptrollerLens Contract @@ -16,7 +16,7 @@ import "../Tokens/VAI/VAIControllerInterface.sol"; * @notice The ComptrollerLens contract has functions to get the number of tokens that * can be seized through liquidation, hypothetical account liquidity and shortfall of an account. */ -contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, ExponentialNoError { +contract ComptrollerLens is IComptrollerLens, ComptrollerErrorReporter, ExponentialNoError { /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. * Note that `vTokenBalance` is the number of vTokens the account owns in the market, @@ -50,8 +50,8 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, uint actualRepayAmount ) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ - uint priceBorrowedMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(vTokenBorrowed); - uint priceCollateralMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(vTokenCollateral); + uint priceBorrowedMantissa = IComptroller(comptroller).oracle().getUnderlyingPrice(vTokenBorrowed); + uint priceCollateralMantissa = IComptroller(comptroller).oracle().getUnderlyingPrice(vTokenCollateral); if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -62,14 +62,14 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, * seizeTokens = seizeAmount / exchangeRate * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = IVToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; Exp memory ratio; numerator = mul_( - Exp({ mantissa: ComptrollerInterface(comptroller).liquidationIncentiveMantissa() }), + Exp({ mantissa: IComptroller(comptroller).liquidationIncentiveMantissa() }), Exp({ mantissa: priceBorrowedMantissa }) ); denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa })); @@ -94,7 +94,7 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, ) external view returns (uint, uint) { /* Read oracle prices for borrowed and collateral markets */ uint priceBorrowedMantissa = 1e18; // Note: this is VAI - uint priceCollateralMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(vTokenCollateral); + uint priceCollateralMantissa = IComptroller(comptroller).oracle().getUnderlyingPrice(vTokenCollateral); if (priceCollateralMantissa == 0) { return (uint(Error.PRICE_ERROR), 0); } @@ -105,14 +105,14 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, * seizeTokens = seizeAmount / exchangeRate * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate) */ - uint exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error + uint exchangeRateMantissa = IVToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error uint seizeTokens; Exp memory numerator; Exp memory denominator; Exp memory ratio; numerator = mul_( - Exp({ mantissa: ComptrollerInterface(comptroller).liquidationIncentiveMantissa() }), + Exp({ mantissa: IComptroller(comptroller).liquidationIncentiveMantissa() }), Exp({ mantissa: priceBorrowedMantissa }) ); denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa })); @@ -136,7 +136,7 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, function getHypotheticalAccountLiquidity( address comptroller, address account, - VToken vTokenModify, + IVToken vTokenModify, uint redeemTokens, uint borrowAmount ) external view returns (uint, uint, uint) { @@ -144,10 +144,10 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, uint oErr; // For each asset the account is in - VToken[] memory assets = ComptrollerInterface(comptroller).getAssetsIn(account); + IVToken[] memory assets = IComptroller(comptroller).getAssetsIn(account); uint assetsCount = assets.length; for (uint i = 0; i < assetsCount; ++i) { - VToken asset = assets[i]; + IVToken asset = assets[i]; // Read the balances and exchange rate from the vToken (oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot( @@ -157,12 +157,12 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades return (uint(Error.SNAPSHOT_ERROR), 0, 0); } - (, uint collateralFactorMantissa) = ComptrollerInterface(comptroller).markets(address(asset)); + (, uint collateralFactorMantissa, ) = IComptroller(comptroller).markets(address(asset)); vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa }); vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa }); // Get the normalized price of the asset - vars.oraclePriceMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(address(asset)); + vars.oraclePriceMantissa = IComptroller(comptroller).oracle().getUnderlyingPrice(address(asset)); if (vars.oraclePriceMantissa == 0) { return (uint(Error.PRICE_ERROR), 0, 0); } @@ -201,7 +201,7 @@ contract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, } } - VAIControllerInterface vaiController = ComptrollerInterface(comptroller).vaiController(); + VAIControllerInterface vaiController = IComptroller(comptroller).vaiController(); if (address(vaiController) != address(0)) { vars.sumBorrowPlusEffects = add_(vars.sumBorrowPlusEffects, vaiController.getVAIRepayAmount(account)); diff --git a/contracts/Lens/SnapshotLens.sol b/contracts/Lens/SnapshotLens.sol index d14ec712a..d0017d0e8 100644 --- a/contracts/Lens/SnapshotLens.sol +++ b/contracts/Lens/SnapshotLens.sol @@ -1,11 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import { VToken } from "../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; import { ExponentialNoError } from "../Utils/ExponentialNoError.sol"; -import { ComptrollerInterface } from "../Comptroller/ComptrollerInterface.sol"; -import { VBep20 } from "../Tokens/VTokens/VBep20.sol"; +import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; +import { IVBep20 } from "../Tokens/VTokens/interfaces/IVBep20.sol"; contract SnapshotLens is ExponentialNoError { struct AccountSnapshot { @@ -53,7 +54,7 @@ contract SnapshotLens is ExponentialNoError { address comptrollerAddress ) public returns (AccountSnapshot[] memory) { // For each asset the account is in - VToken[] memory assets = ComptrollerInterface(comptrollerAddress).getAllMarkets(); + IVToken[] memory assets = IComptroller(comptrollerAddress).getAllMarkets(); AccountSnapshot[] memory accountSnapshots = new AccountSnapshot[](assets.length); for (uint256 i = 0; i < assets.length; ++i) { accountSnapshots[i] = getAccountSnapshot(account, comptrollerAddress, assets[i]); @@ -62,7 +63,7 @@ contract SnapshotLens is ExponentialNoError { } function isACollateral(address account, address asset, address comptrollerAddress) public view returns (bool) { - VToken[] memory assetsAsCollateral = ComptrollerInterface(comptrollerAddress).getAssetsIn(account); + IVToken[] memory assetsAsCollateral = IComptroller(comptrollerAddress).getAssetsIn(account); for (uint256 j = 0; j < assetsAsCollateral.length; ++j) { if (address(assetsAsCollateral[j]) == asset) { return true; @@ -75,7 +76,7 @@ contract SnapshotLens is ExponentialNoError { function getAccountSnapshot( address payable account, address comptrollerAddress, - VToken vToken + IVToken vToken ) public returns (AccountSnapshot memory) { AccountSnapshotLocalVars memory vars; // Holds all our calculation results uint oErr; @@ -85,11 +86,11 @@ contract SnapshotLens is ExponentialNoError { require(oErr == 0, "Snapshot Error"); vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa }); - (, uint collateralFactorMantissa) = ComptrollerInterface(comptrollerAddress).markets(address(vToken)); + (, uint collateralFactorMantissa, ) = IComptroller(comptrollerAddress).markets(address(vToken)); vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa }); // Get the normalized price of the asset - vars.oraclePriceMantissa = ComptrollerInterface(comptrollerAddress).oracle().getUnderlyingPrice( + vars.oraclePriceMantissa = IComptroller(comptrollerAddress).oracle().getUnderlyingPrice( address(vToken) ); vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa }); @@ -112,7 +113,7 @@ contract SnapshotLens is ExponentialNoError { underlyingAssetAddress = address(0); underlyingDecimals = 18; } else { - VBep20 vBep20 = VBep20(address(vToken)); + IVBep20 vBep20 = IVBep20(address(vToken)); underlyingAssetAddress = vBep20.underlying(); underlyingDecimals = IERC20Metadata(vBep20.underlying()).decimals(); } diff --git a/contracts/Lens/VenusLens.sol b/contracts/Lens/VenusLens.sol index 3ec77b8b3..6ae55180d 100644 --- a/contracts/Lens/VenusLens.sol +++ b/contracts/Lens/VenusLens.sol @@ -4,9 +4,10 @@ import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/I import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; import { ExponentialNoError } from "../Utils/ExponentialNoError.sol"; -import { VBep20 } from "../Tokens/VTokens/VBep20.sol"; -import { VToken } from "../Tokens/VTokens/VToken.sol"; -import { ComptrollerInterface, Action } from "../Comptroller/ComptrollerInterface.sol"; +import { IVBep20 } from "../Tokens/VTokens/interfaces/IVBep20.sol"; +import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; +import { Action } from "../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; import { IXVS } from "../Tokens/XVS/IXVS.sol"; contract VenusLens is ExponentialNoError { @@ -58,7 +59,7 @@ contract VenusLens is ExponentialNoError { } struct AccountLimits { - VToken[] markets; + IVToken[] markets; uint liquidity; uint shortfall; } @@ -112,11 +113,11 @@ contract VenusLens is ExponentialNoError { * @param vToken The address of the vToken to fetch VTokenMetadata * @return VTokenMetadata struct with vToken supply and borrow information. */ - function vTokenMetadata(VToken vToken) public returns (VTokenMetadata memory) { + function vTokenMetadata(IVToken vToken) public returns (VTokenMetadata memory) { uint exchangeRateCurrent = vToken.exchangeRateCurrent(); address comptrollerAddress = address(vToken.comptroller()); - ComptrollerInterface comptroller = ComptrollerInterface(comptrollerAddress); - (bool isListed, uint collateralFactorMantissa) = comptroller.markets(address(vToken)); + IComptroller comptroller = IComptroller(comptrollerAddress); + (bool isListed, uint collateralFactorMantissa,) = comptroller.markets(address(vToken)); address underlyingAssetAddress; uint underlyingDecimals; @@ -124,7 +125,7 @@ contract VenusLens is ExponentialNoError { underlyingAssetAddress = address(0); underlyingDecimals = 18; } else { - VBep20 vBep20 = VBep20(address(vToken)); + IVBep20 vBep20 = IVBep20(address(vToken)); underlyingAssetAddress = vBep20.underlying(); underlyingDecimals = IERC20Metadata(vBep20.underlying()).decimals(); } @@ -168,7 +169,7 @@ contract VenusLens is ExponentialNoError { * @param vTokens Array of vToken addresses to fetch VTokenMetadata * @return Array of structs with vToken supply and borrow information. */ - function vTokenMetadataAll(VToken[] calldata vTokens) external returns (VTokenMetadata[] memory) { + function vTokenMetadataAll(IVToken[] calldata vTokens) external returns (VTokenMetadata[] memory) { uint vTokenCount = vTokens.length; VTokenMetadata[] memory res = new VTokenMetadata[](vTokenCount); for (uint i = 0; i < vTokenCount; i++) { @@ -184,12 +185,12 @@ contract VenusLens is ExponentialNoError { * @return Amount of XVS distributed daily to an account */ function getDailyXVS(address payable account, address comptrollerAddress) external returns (uint) { - ComptrollerInterface comptrollerInstance = ComptrollerInterface(comptrollerAddress); - VToken[] memory vTokens = comptrollerInstance.getAllMarkets(); + IComptroller comptrollerInstance = IComptroller(comptrollerAddress); + IVToken[] memory vTokens = comptrollerInstance.getAllMarkets(); uint dailyXvsPerAccount = 0; for (uint i = 0; i < vTokens.length; i++) { - VToken vToken = vTokens[i]; + IVToken vToken = vTokens[i]; if (!compareStrings(vToken.symbol(), "vUST") && !compareStrings(vToken.symbol(), "vLUNA")) { VTokenMetadata memory metaDataItem = vTokenMetadata(vToken); @@ -232,7 +233,7 @@ contract VenusLens is ExponentialNoError { * @param account Account address to fetch the balance of * @return VTokenBalances with token balance information */ - function vTokenBalances(VToken vToken, address payable account) public returns (VTokenBalances memory) { + function vTokenBalances(IVToken vToken, address payable account) public returns (VTokenBalances memory) { uint balanceOf = vToken.balanceOf(account); uint borrowBalanceCurrent = vToken.borrowBalanceCurrent(account); uint balanceOfUnderlying = vToken.balanceOfUnderlying(account); @@ -243,7 +244,7 @@ contract VenusLens is ExponentialNoError { tokenBalance = account.balance; tokenAllowance = account.balance; } else { - VBep20 vBep20 = VBep20(address(vToken)); + IVBep20 vBep20 = IVBep20(address(vToken)); IERC20Metadata underlying = IERC20Metadata(vBep20.underlying()); tokenBalance = underlying.balanceOf(account); tokenAllowance = underlying.allowance(account, address(vToken)); @@ -267,7 +268,7 @@ contract VenusLens is ExponentialNoError { * @return VTokenBalances Array with token balance information */ function vTokenBalancesAll( - VToken[] calldata vTokens, + IVToken[] calldata vTokens, address payable account ) external returns (VTokenBalances[] memory) { uint vTokenCount = vTokens.length; @@ -283,8 +284,8 @@ contract VenusLens is ExponentialNoError { * @param vToken address of the vToken * @return response struct with underlyingPrice info of vToken */ - function vTokenUnderlyingPrice(VToken vToken) public view returns (VTokenUnderlyingPrice memory) { - ComptrollerInterface comptroller = ComptrollerInterface(address(vToken.comptroller())); + function vTokenUnderlyingPrice(IVToken vToken) public view returns (VTokenUnderlyingPrice memory) { + IComptroller comptroller = IComptroller(address(vToken.comptroller())); ResilientOracleInterface priceOracle = comptroller.oracle(); return @@ -300,7 +301,7 @@ contract VenusLens is ExponentialNoError { * @return array of response structs with underlying price information of vTokens */ function vTokenUnderlyingPriceAll( - VToken[] calldata vTokens + IVToken[] calldata vTokens ) external view returns (VTokenUnderlyingPrice[] memory) { uint vTokenCount = vTokens.length; VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount); @@ -317,7 +318,7 @@ contract VenusLens is ExponentialNoError { * @return Struct with markets user has entered, liquidity, and shortfall of the account */ function getAccountLimits( - ComptrollerInterface comptroller, + IComptroller comptroller, address account ) public view returns (AccountLimits memory) { (uint errorCode, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(account); @@ -350,7 +351,7 @@ contract VenusLens is ExponentialNoError { */ function getXVSBalanceMetadataExt( IXVS xvs, - ComptrollerInterface comptroller, + IComptroller comptroller, address account ) external returns (XVSBalanceMetadataExt memory) { uint balance = xvs.balanceOf(account); @@ -400,13 +401,13 @@ contract VenusLens is ExponentialNoError { function updateVenusSupplyIndex( VenusMarketState memory supplyState, address vToken, - ComptrollerInterface comptroller + IComptroller comptroller ) internal view { uint supplySpeed = comptroller.venusSupplySpeeds(vToken); uint blockNumber = block.number; uint deltaBlocks = sub_(blockNumber, uint(supplyState.block)); if (deltaBlocks > 0 && supplySpeed > 0) { - uint supplyTokens = VToken(vToken).totalSupply(); + uint supplyTokens = IVToken(vToken).totalSupply(); uint venusAccrued = mul_(deltaBlocks, supplySpeed); Double memory ratio = supplyTokens > 0 ? fraction(venusAccrued, supplyTokens) : Double({ mantissa: 0 }); Double memory index = add_(Double({ mantissa: supplyState.index }), ratio); @@ -427,13 +428,13 @@ contract VenusLens is ExponentialNoError { VenusMarketState memory borrowState, address vToken, Exp memory marketBorrowIndex, - ComptrollerInterface comptroller + IComptroller comptroller ) internal view { uint borrowSpeed = comptroller.venusBorrowSpeeds(vToken); uint blockNumber = block.number; uint deltaBlocks = sub_(blockNumber, uint(borrowState.block)); if (deltaBlocks > 0 && borrowSpeed > 0) { - uint borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex); + uint borrowAmount = div_(IVToken(vToken).totalBorrows(), marketBorrowIndex); uint venusAccrued = mul_(deltaBlocks, borrowSpeed); Double memory ratio = borrowAmount > 0 ? fraction(venusAccrued, borrowAmount) : Double({ mantissa: 0 }); Double memory index = add_(Double({ mantissa: borrowState.index }), ratio); @@ -456,7 +457,7 @@ contract VenusLens is ExponentialNoError { VenusMarketState memory supplyState, address vToken, address supplier, - ComptrollerInterface comptroller + IComptroller comptroller ) internal view returns (uint) { Double memory supplyIndex = Double({ mantissa: supplyState.index }); Double memory supplierIndex = Double({ mantissa: comptroller.venusSupplierIndex(vToken, supplier) }); @@ -465,7 +466,7 @@ contract VenusLens is ExponentialNoError { } Double memory deltaIndex = sub_(supplyIndex, supplierIndex); - uint supplierTokens = VToken(vToken).balanceOf(supplier); + uint supplierTokens = IVToken(vToken).balanceOf(supplier); uint supplierDelta = mul_(supplierTokens, deltaIndex); return supplierDelta; } @@ -484,13 +485,13 @@ contract VenusLens is ExponentialNoError { address vToken, address borrower, Exp memory marketBorrowIndex, - ComptrollerInterface comptroller + IComptroller comptroller ) internal view returns (uint) { Double memory borrowIndex = Double({ mantissa: borrowState.index }); Double memory borrowerIndex = Double({ mantissa: comptroller.venusBorrowerIndex(vToken, borrower) }); if (borrowerIndex.mantissa > 0) { Double memory deltaIndex = sub_(borrowIndex, borrowerIndex); - uint borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex); + uint borrowerAmount = div_(IVToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex); uint borrowerDelta = mul_(borrowerAmount, deltaIndex); return borrowerDelta; } @@ -505,9 +506,9 @@ contract VenusLens is ExponentialNoError { */ function pendingRewards( address holder, - ComptrollerInterface comptroller + IComptroller comptroller ) external view returns (RewardSummary memory) { - VToken[] memory vTokens = comptroller.getAllMarkets(); + IVToken[] memory vTokens = comptroller.getAllMarkets(); ClaimVenusLocalVariables memory vars; RewardSummary memory rewardSummary; rewardSummary.distributorAddress = address(comptroller); diff --git a/contracts/Comptroller/ComptrollerLensInterface.sol b/contracts/Lens/interfaces/IComptrollerLens.sol similarity index 82% rename from contracts/Comptroller/ComptrollerLensInterface.sol rename to contracts/Lens/interfaces/IComptrollerLens.sol index f55cd8a29..84996ee92 100644 --- a/contracts/Comptroller/ComptrollerLensInterface.sol +++ b/contracts/Lens/interfaces/IComptrollerLens.sol @@ -1,8 +1,8 @@ pragma solidity 0.8.25; -import "../Tokens/VTokens/VToken.sol"; +import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; -interface ComptrollerLensInterface { +interface IComptrollerLens { function liquidateCalculateSeizeTokens( address comptroller, address vTokenBorrowed, @@ -19,7 +19,7 @@ interface ComptrollerLensInterface { function getHypotheticalAccountLiquidity( address comptroller, address account, - VToken vTokenModify, + IVToken vTokenModify, uint redeemTokens, uint borrowAmount ) external view returns (uint, uint, uint); diff --git a/contracts/Tokens/VAI/VAIController.sol b/contracts/Tokens/VAI/VAIController.sol index 64bcaf2f1..4ad68c65c 100644 --- a/contracts/Tokens/VAI/VAIController.sol +++ b/contracts/Tokens/VAI/VAIController.sol @@ -5,13 +5,12 @@ import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interf import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol"; import { VAIControllerErrorReporter } from "../../Utils/ErrorReporter.sol"; import { Exponential } from "../../Utils/Exponential.sol"; -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; -import { VToken } from "../VTokens/VToken.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { VAIUnitroller, VAIControllerStorageG4 } from "./VAIUnitroller.sol"; import { VAIControllerInterface } from "./VAIControllerInterface.sol"; import { IVAI } from "./IVAI.sol"; import { IPrime } from "../Prime/IPrime.sol"; -import { VTokenInterface } from "../VTokens/VTokenInterfaces.sol"; +import { IVToken } from "../VTokens/interfaces/IVToken.sol"; /** * @title VAI Comptroller @@ -23,7 +22,7 @@ contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAICon uint256 public constant INITIAL_VAI_MINT_INDEX = 1e18; /// @notice Emitted when Comptroller is changed - event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller); + event NewComptroller(IComptroller oldComptroller, IComptroller newComptroller); /// @notice Emitted when mint for prime holder is changed event MintOnlyForPrimeHolder(bool previousMintEnabledOnlyForPrimeHolder, bool newMintEnabledOnlyForPrimeHolder); @@ -250,7 +249,7 @@ contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAICon function liquidateVAI( address borrower, uint256 repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) external nonReentrant returns (uint256, uint256) { _ensureNotPaused(); @@ -279,7 +278,7 @@ contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAICon address liquidator, address borrower, uint256 repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) internal returns (uint256, uint256) { if (address(comptroller) != address(0)) { accrueVAIInterest(); @@ -370,13 +369,13 @@ contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAICon * @dev Admin function to set a new comptroller * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function _setComptroller(ComptrollerInterface comptroller_) external returns (uint256) { + function _setComptroller(IComptroller comptroller_) external returns (uint256) { // Check caller is admin if (msg.sender != admin) { return fail(Error.UNAUTHORIZED, FailureInfo.SET_COMPTROLLER_OWNER_CHECK); } - ComptrollerInterface oldComptroller = comptroller; + IComptroller oldComptroller = comptroller; comptroller = comptroller_; emit NewComptroller(oldComptroller, comptroller_); @@ -452,7 +451,7 @@ contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAICon } ResilientOracleInterface oracle = comptroller.oracle(); - VToken[] memory enteredMarkets = comptroller.getAssetsIn(minter); + IVToken[] memory enteredMarkets = comptroller.getAssetsIn(minter); AccountAmountLocalVars memory vars; // Holds all our calculation results @@ -491,7 +490,7 @@ contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAICon return (uint256(Error.MATH_ERROR), 0); } - (, uint256 collateralFactorMantissa) = comptroller.markets(address(enteredMarkets[i])); + (, uint256 collateralFactorMantissa,) = comptroller.markets(address(enteredMarkets[i])); (vars.mErr, vars.marketSupply) = mulUInt(vars.marketSupply, collateralFactorMantissa); if (vars.mErr != MathError.NO_ERROR) { return (uint256(Error.MATH_ERROR), 0); diff --git a/contracts/Tokens/VAI/VAIControllerInterface.sol b/contracts/Tokens/VAI/VAIControllerInterface.sol index bc0b6455b..8997e49b9 100644 --- a/contracts/Tokens/VAI/VAIControllerInterface.sol +++ b/contracts/Tokens/VAI/VAIControllerInterface.sol @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { VTokenInterface } from "../VTokens/VTokenInterfaces.sol"; +import { IVToken } from "../VTokens/interfaces/IVToken.sol"; interface VAIControllerInterface { function mintVAI(uint256 mintVAIAmount) external returns (uint256); @@ -12,7 +13,7 @@ interface VAIControllerInterface { function liquidateVAI( address borrower, uint256 repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) external returns (uint256, uint256); function getMintableVAI(address minter) external view returns (uint256, uint256); diff --git a/contracts/Tokens/VAI/VAIControllerStorage.sol b/contracts/Tokens/VAI/VAIControllerStorage.sol index 535a8d7c3..bb9f3643a 100644 --- a/contracts/Tokens/VAI/VAIControllerStorage.sol +++ b/contracts/Tokens/VAI/VAIControllerStorage.sol @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; contract VAIUnitrollerAdminStorage { /** @@ -25,7 +26,7 @@ contract VAIUnitrollerAdminStorage { } contract VAIControllerStorageG1 is VAIUnitrollerAdminStorage { - ComptrollerInterface public comptroller; + IComptroller public comptroller; struct VenusVAIState { /// @notice The last updated venusVAIMintIndex diff --git a/contracts/Tokens/VTokens/VBNB.sol b/contracts/Tokens/VTokens/VBNB.sol index b569dc0ae..ed21d90d1 100644 --- a/contracts/Tokens/VTokens/VBNB.sol +++ b/contracts/Tokens/VTokens/VBNB.sol @@ -1,7 +1,9 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; +import { IVToken } from "./interfaces/IVToken.sol"; import { VToken } from "./VToken.sol"; /** @@ -21,7 +23,7 @@ contract VBNB is VToken { * @param admin_ Address of the administrator of this token */ constructor( - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -124,7 +126,7 @@ contract VBNB is VToken { * @param vTokenCollateral The market in which to seize collateral from the borrower */ // @custom:event Emit LiquidateBorrow event on success - function liquidateBorrow(address borrower, VToken vTokenCollateral) external payable { + function liquidateBorrow(address borrower, IVToken vTokenCollateral) external payable { (uint err, ) = liquidateBorrowInternal(borrower, msg.value, vTokenCollateral); requireNoError(err, "liquidateBorrow failed"); } diff --git a/contracts/Tokens/VTokens/VBep20.sol b/contracts/Tokens/VTokens/VBep20.sol index 461189013..72534a64a 100644 --- a/contracts/Tokens/VTokens/VBep20.sol +++ b/contracts/Tokens/VTokens/VBep20.sol @@ -1,11 +1,13 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; -import { VBep20Interface, VTokenInterface } from "./VTokenInterfaces.sol"; +import { IVBep20 } from "./interfaces/IVBep20.sol"; +import { IVToken } from "./interfaces/IVToken.sol"; import { VToken } from "./VToken.sol"; /** @@ -13,7 +15,7 @@ import { VToken } from "./VToken.sol"; * @notice vTokens which wrap an ERC-20 underlying * @author Venus */ -contract VBep20 is VToken, VBep20Interface { +contract VBep20 is VToken, IVBep20 { using SafeERC20 for IERC20; /*** User Interface ***/ @@ -163,7 +165,7 @@ contract VBep20 is VToken, VBep20Interface { function liquidateBorrow( address borrower, uint repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) external returns (uint) { (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral); return err; @@ -191,7 +193,7 @@ contract VBep20 is VToken, VBep20Interface { */ function initialize( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, diff --git a/contracts/Tokens/VTokens/VBep20Delegate.sol b/contracts/Tokens/VTokens/VBep20Delegate.sol index 478d8158c..a8bed4ada 100644 --- a/contracts/Tokens/VTokens/VBep20Delegate.sol +++ b/contracts/Tokens/VTokens/VBep20Delegate.sol @@ -1,14 +1,15 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { VBep20 } from "./VBep20.sol"; -import { VDelegateInterface } from "./VTokenInterfaces.sol"; +import { IVDelegate } from "./interfaces/IVDelegate.sol"; /** * @title Venus's VBep20Delegate Contract * @notice VTokens which wrap an EIP-20 underlying and are delegated to * @author Venus */ -contract VBep20Delegate is VBep20, VDelegateInterface { +contract VBep20Delegate is IVDelegate, VBep20 { /** * @notice Construct an empty delegate */ diff --git a/contracts/Tokens/VTokens/VBep20Delegator.sol b/contracts/Tokens/VTokens/VBep20Delegator.sol index 11df7b38c..e53b5dbc7 100644 --- a/contracts/Tokens/VTokens/VBep20Delegator.sol +++ b/contracts/Tokens/VTokens/VBep20Delegator.sol @@ -1,15 +1,18 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; -import { VTokenInterface, VBep20Interface, VDelegatorInterface } from "./VTokenInterfaces.sol"; +import { IVDelegator } from "./interfaces/IVDelegator.sol"; +import { IVToken } from "./interfaces/IVToken.sol"; +import { VTokenStorage } from "./VTokenStorage.sol"; /** * @title Venus's VBep20Delegator Contract * @notice vTokens which wrap an EIP-20 underlying and delegate to an implementation * @author Venus */ -contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterface { +contract VBep20Delegator is IVDelegator, VTokenStorage { /** * @notice Construct a new money market * @param underlying_ The address of the underlying asset @@ -25,7 +28,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac */ constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -174,7 +177,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac function liquidateBorrow( address borrower, uint repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) external returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("liquidateBorrow(address,uint256,address)", borrower, repayAmount, vTokenCollateral) @@ -188,7 +191,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ - function transfer(address dst, uint amount) external override returns (bool) { + function transfer(address dst, uint amount) external returns (bool) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("transfer(address,uint256)", dst, amount)); return abi.decode(data, (bool)); } @@ -200,7 +203,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ - function transferFrom(address src, address dst, uint256 amount) external override returns (bool) { + function transferFrom(address src, address dst, uint256 amount) external returns (bool) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("transferFrom(address,address,uint256)", src, dst, amount) ); @@ -215,7 +218,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param amount The number of tokens that are approved (-1 means infinite) * @return Whether or not the approval succeeded */ - function approve(address spender, uint256 amount) external override returns (bool) { + function approve(address spender, uint256 amount) external returns (bool) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("approve(address,uint256)", spender, amount) ); @@ -228,7 +231,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param owner The address of the account to query * @return The amount of underlying owned by `owner` */ - function balanceOfUnderlying(address owner) external override returns (uint) { + function balanceOfUnderlying(address owner) external returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("balanceOfUnderlying(address)", owner)); return abi.decode(data, (uint)); } @@ -237,7 +240,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @notice Returns the current total borrows plus accrued interest * @return The total borrows with interest */ - function totalBorrowsCurrent() external override returns (uint) { + function totalBorrowsCurrent() external returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("totalBorrowsCurrent()")); return abi.decode(data, (uint)); } @@ -247,7 +250,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param account The address whose balance should be calculated after updating borrowIndex * @return The calculated balance */ - function borrowBalanceCurrent(address account) external override returns (uint) { + function borrowBalanceCurrent(address account) external returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("borrowBalanceCurrent(address)", account)); return abi.decode(data, (uint)); } @@ -261,7 +264,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param seizeTokens The number of vTokens to seize * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function seize(address liquidator, address borrower, uint seizeTokens) external override returns (uint) { + function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("seize(address,address,uint256)", liquidator, borrower, seizeTokens) ); @@ -276,7 +279,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param newPendingAdmin New pending admin. * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function _setPendingAdmin(address payable newPendingAdmin) external override returns (uint) { + function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("_setPendingAdmin(address)", newPendingAdmin) ); @@ -288,7 +291,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @dev Admin function to accrue interest and set a new reserve factor * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function _setReserveFactor(uint newReserveFactorMantissa) external override returns (uint) { + function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("_setReserveFactor(uint256)", newReserveFactorMantissa) ); @@ -300,7 +303,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @dev Admin function for pending admin to accept role and update admin * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function _acceptAdmin() external override returns (uint) { + function _acceptAdmin() external returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("_acceptAdmin()")); return abi.decode(data, (uint)); } @@ -320,7 +323,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param reduceAmount Amount of reduction to reserves * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function _reduceReserves(uint reduceAmount) external override returns (uint) { + function _reduceReserves(uint reduceAmount) external returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("_reduceReserves(uint256)", reduceAmount)); return abi.decode(data, (uint)); } @@ -329,7 +332,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @notice Get cash balance of this vToken in the underlying asset * @return The quantity of underlying asset owned by this contract */ - function getCash() external view override returns (uint) { + function getCash() external view returns (uint) { bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("getCash()")); return abi.decode(data, (uint)); } @@ -340,7 +343,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param spender The address of the account which may transfer tokens * @return The number of tokens allowed to be spent (-1 means infinite) */ - function allowance(address owner, address spender) external view override returns (uint) { + function allowance(address owner, address spender) external view returns (uint) { bytes memory data = delegateToViewImplementation( abi.encodeWithSignature("allowance(address,address)", owner, spender) ); @@ -352,7 +355,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param owner The address of the account to query * @return The number of tokens owned by `owner` */ - function balanceOf(address owner) external view override returns (uint) { + function balanceOf(address owner) external view returns (uint) { bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("balanceOf(address)", owner)); return abi.decode(data, (uint)); } @@ -363,7 +366,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param account Address of the account to snapshot * @return (possible error, token balance, borrow balance, exchange rate mantissa) */ - function getAccountSnapshot(address account) external view override returns (uint, uint, uint, uint) { + function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) { bytes memory data = delegateToViewImplementation( abi.encodeWithSignature("getAccountSnapshot(address)", account) ); @@ -374,7 +377,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @notice Returns the current per-block borrow interest rate for this vToken * @return The borrow interest rate per block, scaled by 1e18 */ - function borrowRatePerBlock() external view override returns (uint) { + function borrowRatePerBlock() external view returns (uint) { bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("borrowRatePerBlock()")); return abi.decode(data, (uint)); } @@ -383,7 +386,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @notice Returns the current per-block supply interest rate for this vToken * @return The supply interest rate per block, scaled by 1e18 */ - function supplyRatePerBlock() external view override returns (uint) { + function supplyRatePerBlock() external view returns (uint) { bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("supplyRatePerBlock()")); return abi.decode(data, (uint)); } @@ -418,7 +421,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @notice Accrue interest then return the up-to-date exchange rate * @return Calculated exchange rate scaled by 1e18 */ - function exchangeRateCurrent() public override returns (uint) { + function exchangeRateCurrent() public returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("exchangeRateCurrent()")); return abi.decode(data, (uint)); } @@ -428,7 +431,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @dev This calculates interest accrued from the last checkpointed block * up to the current block and writes new checkpoint to storage. */ - function accrueInterest() public override returns (uint) { + function accrueInterest() public returns (uint) { bytes memory data = delegateToImplementation(abi.encodeWithSignature("accrueInterest()")); return abi.decode(data, (uint)); } @@ -438,7 +441,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @dev Admin function to set a new comptroller * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function _setComptroller(ComptrollerInterface newComptroller) public override returns (uint) { + function _setComptroller(IComptroller newComptroller) public returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("_setComptroller(address)", newComptroller) ); @@ -451,7 +454,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param newInterestRateModel The new interest rate model to use * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) public override returns (uint) { + function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) public returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("_setInterestRateModel(address)", newInterestRateModel) ); @@ -492,7 +495,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @param account The address whose balance should be calculated * @return The calculated balance */ - function borrowBalanceStored(address account) public view override returns (uint) { + function borrowBalanceStored(address account) public view returns (uint) { bytes memory data = delegateToViewImplementation( abi.encodeWithSignature("borrowBalanceStored(address)", account) ); @@ -504,7 +507,7 @@ contract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterfac * @dev This function does not accrue interest before calculating the exchange rate * @return Calculated exchange rate scaled by 1e18 */ - function exchangeRateStored() public view override returns (uint) { + function exchangeRateStored() public view returns (uint) { bytes memory data = delegateToViewImplementation(abi.encodeWithSignature("exchangeRateStored()")); return abi.decode(data, (uint)); } diff --git a/contracts/Tokens/VTokens/VBep20Immutable.sol b/contracts/Tokens/VTokens/VBep20Immutable.sol index 9a43e186a..b62820c15 100644 --- a/contracts/Tokens/VTokens/VBep20Immutable.sol +++ b/contracts/Tokens/VTokens/VBep20Immutable.sol @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; import { VBep20 } from "./VBep20.sol"; @@ -23,7 +24,7 @@ contract VBep20Immutable is VBep20 { */ constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, diff --git a/contracts/Tokens/VTokens/VToken.sol b/contracts/Tokens/VTokens/VToken.sol index 3c00e82d9..879bd172a 100644 --- a/contracts/Tokens/VTokens/VToken.sol +++ b/contracts/Tokens/VTokens/VToken.sol @@ -1,19 +1,21 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol"; import { IProtocolShareReserve } from "../../external/IProtocolShareReserve.sol"; -import { ComptrollerInterface, IComptroller } from "../../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { TokenErrorReporter } from "../../Utils/ErrorReporter.sol"; import { Exponential } from "../../Utils/Exponential.sol"; import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; -import { VTokenInterface } from "./VTokenInterfaces.sol"; +import { IVToken } from "./interfaces/IVToken.sol"; +import { VTokenStorage } from "./VTokenStorage.sol"; /** * @title Venus's vToken Contract * @notice Abstract base for vTokens * @author Venus */ -abstract contract VToken is VTokenInterface, Exponential, TokenErrorReporter { +abstract contract VToken is IVToken, VTokenStorage, Exponential, TokenErrorReporter { struct MintLocalVars { MathError mathErr; uint exchangeRateMantissa; @@ -50,6 +52,8 @@ abstract contract VToken is VTokenInterface, Exponential, TokenErrorReporter { uint actualRepayAmount; } + bool public constant isVToken = true; + /*** Reentrancy Guard ***/ /** @@ -359,7 +363,7 @@ abstract contract VToken is VTokenInterface, Exponential, TokenErrorReporter { * @param decimals_ EIP-20 decimal precision of this token */ function initialize( - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -536,11 +540,11 @@ abstract contract VToken is VTokenInterface, Exponential, TokenErrorReporter { * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ // @custom:event Emits NewComptroller event - function _setComptroller(ComptrollerInterface newComptroller) public override returns (uint) { + function _setComptroller(IComptroller newComptroller) public override returns (uint) { // Check caller is admin ensureAdmin(msg.sender); - ComptrollerInterface oldComptroller = comptroller; + IComptroller oldComptroller = comptroller; // Ensure invoke comptroller.isComptroller() returns true require(newComptroller.isComptroller(), "marker method returned false"); @@ -1241,7 +1245,7 @@ abstract contract VToken is VTokenInterface, Exponential, TokenErrorReporter { function liquidateBorrowInternal( address borrower, uint repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) internal nonReentrant returns (uint, uint) { uint error = accrueInterest(); if (error != uint(Error.NO_ERROR)) { @@ -1273,7 +1277,7 @@ abstract contract VToken is VTokenInterface, Exponential, TokenErrorReporter { address liquidator, address borrower, uint repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) internal returns (uint, uint) { /* Fail if liquidate not allowed */ uint allowed = comptroller.liquidateBorrowAllowed( diff --git a/contracts/Tokens/VTokens/VTokenInterfaces.sol b/contracts/Tokens/VTokens/VTokenInterfaces.sol deleted file mode 100644 index 9dc6d4f4e..000000000 --- a/contracts/Tokens/VTokens/VTokenInterfaces.sol +++ /dev/null @@ -1,390 +0,0 @@ -pragma solidity 0.8.25; - -import { ComptrollerInterface } from "../../Comptroller/ComptrollerInterface.sol"; -import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; - -contract VTokenStorageBase { - /** - * @notice Container for borrow balance information - * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action - * @member interestIndex Global borrowIndex as of the most recent balance-changing action - */ - struct BorrowSnapshot { - uint principal; - uint interestIndex; - } - - /** - * @dev Guard variable for re-entrancy checks - */ - bool internal _notEntered; - - /** - * @notice EIP-20 token name for this token - */ - string public name; - - /** - * @notice EIP-20 token symbol for this token - */ - string public symbol; - - /** - * @notice EIP-20 token decimals for this token - */ - uint8 public decimals; - - /** - * @notice Maximum borrow rate that can ever be applied (.0005% / block) - */ - - uint internal constant borrowRateMaxMantissa = 0.0005e16; - - /** - * @notice Maximum fraction of interest that can be set aside for reserves - */ - uint internal constant reserveFactorMaxMantissa = 1e18; - - /** - * @notice Administrator for this contract - */ - address payable public admin; - - /** - * @notice Pending administrator for this contract - */ - address payable public pendingAdmin; - - /** - * @notice Contract which oversees inter-vToken operations - */ - ComptrollerInterface public comptroller; - - /** - * @notice Model which tells what the current interest rate should be - */ - InterestRateModelV8 public interestRateModel; - - /** - * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0) - */ - uint internal initialExchangeRateMantissa; - - /** - * @notice Fraction of interest currently set aside for reserves - */ - uint public reserveFactorMantissa; - - /** - * @notice Block number that interest was last accrued at - */ - uint public accrualBlockNumber; - - /** - * @notice Accumulator of the total earned interest rate since the opening of the market - */ - uint public borrowIndex; - - /** - * @notice Total amount of outstanding borrows of the underlying in this market - */ - uint public totalBorrows; - - /** - * @notice Total amount of reserves of the underlying held in this market - */ - uint public totalReserves; - - /** - * @notice Total number of tokens in circulation - */ - uint public totalSupply; - - /** - * @notice Official record of token balances for each account - */ - mapping(address => uint) internal accountTokens; - - /** - * @notice Approved token transfer amounts on behalf of others - */ - mapping(address => mapping(address => uint)) internal transferAllowances; - - /** - * @notice Mapping of account addresses to outstanding borrow balances - */ - mapping(address => BorrowSnapshot) internal accountBorrows; - - /** - * @notice Underlying asset for this VToken - */ - address public underlying; - - /** - * @notice Implementation address for this contract - */ - address public implementation; - - /** - * @notice delta block after which reserves will be reduced - */ - uint public reduceReservesBlockDelta; - - /** - * @notice last block number at which reserves were reduced - */ - uint public reduceReservesBlockNumber; - - /** - * @notice address of protocol share reserve contract - */ - address payable public protocolShareReserve; - - /** - * @notice address of accessControlManager - */ - - address public accessControlManager; -} - -contract VTokenStorage is VTokenStorageBase { - /** - * @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[50] private __gap; -} - -abstract contract VTokenInterface is VTokenStorage { - /** - * @notice Indicator that this is a vToken contract (for inspection) - */ - bool public constant isVToken = true; - - /*** Market Events ***/ - - /** - * @notice Event emitted when interest is accrued - */ - event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows); - - /** - * @notice Event emitted when tokens are minted - */ - event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply); - - /** - * @notice Event emitted when tokens are minted behalf by payer to receiver - */ - event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply); - - /** - * @notice Event emitted when tokens are redeemed - */ - event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply); - - /** - * @notice Event emitted when tokens are redeemed and fee is transferred - */ - event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens); - - /** - * @notice Event emitted when underlying is borrowed - */ - event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows); - - /** - * @notice Event emitted when a borrow is repaid - */ - event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows); - - /** - * @notice Event emitted when a borrow is liquidated - */ - event LiquidateBorrow( - address liquidator, - address borrower, - uint repayAmount, - address vTokenCollateral, - uint seizeTokens - ); - - /*** Admin Events ***/ - - /** - * @notice Event emitted when pendingAdmin is changed - */ - event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); - - /** - * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated - */ - event NewAdmin(address oldAdmin, address newAdmin); - - /** - * @notice Event emitted when comptroller is changed - */ - event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller); - - /** - * @notice Event emitted when interestRateModel is changed - */ - event NewMarketInterestRateModel( - InterestRateModelV8 oldInterestRateModel, - InterestRateModelV8 newInterestRateModel - ); - - /** - * @notice Event emitted when the reserve factor is changed - */ - event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa); - - /** - * @notice Event emitted when the reserves are added - */ - event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves); - - /** - * @notice Event emitted when the reserves are reduced - */ - event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves); - - /** - * @notice EIP20 Transfer event - */ - event Transfer(address indexed from, address indexed to, uint amount); - - /** - * @notice EIP20 Approval event - */ - event Approval(address indexed owner, address indexed spender, uint amount); - - /** - * @notice Event emitted when block delta for reduce reserves get updated - */ - event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta); - - /** - * @notice Event emitted when address of ProtocolShareReserve contract get updated - */ - event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve); - - /// @notice Emitted when access control address is changed by admin - event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress); - - /*** User Interface ***/ - - function transfer(address dst, uint amount) external virtual returns (bool); - - function transferFrom(address src, address dst, uint amount) external virtual returns (bool); - - function approve(address spender, uint amount) external virtual returns (bool); - - function balanceOfUnderlying(address owner) external virtual returns (uint); - - function totalBorrowsCurrent() external virtual returns (uint); - - function borrowBalanceCurrent(address account) external virtual returns (uint); - - function seize(address liquidator, address borrower, uint seizeTokens) external virtual returns (uint); - - /*** Admin Function ***/ - function _setPendingAdmin(address payable newPendingAdmin) external virtual returns (uint); - - /*** Admin Function ***/ - function _acceptAdmin() external virtual returns (uint); - - /*** Admin Function ***/ - function _setReserveFactor(uint newReserveFactorMantissa) external virtual returns (uint); - - /*** Admin Function ***/ - function _reduceReserves(uint reduceAmount) external virtual returns (uint); - - function balanceOf(address owner) external view virtual returns (uint); - - function allowance(address owner, address spender) external view virtual returns (uint); - - function getAccountSnapshot(address account) external view virtual returns (uint, uint, uint, uint); - - function borrowRatePerBlock() external view virtual returns (uint); - - function supplyRatePerBlock() external view virtual returns (uint); - - function getCash() external view virtual returns (uint); - - function exchangeRateCurrent() public virtual returns (uint); - - function accrueInterest() public virtual returns (uint); - - /*** Admin Function ***/ - function _setComptroller(ComptrollerInterface newComptroller) public virtual returns (uint); - - /*** Admin Function ***/ - function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) public virtual returns (uint); - - function borrowBalanceStored(address account) public view virtual returns (uint); - - function exchangeRateStored() public view virtual returns (uint); -} - -interface VBep20Interface { - /*** User Interface ***/ - - function mint(uint mintAmount) external returns (uint); - - function mintBehalf(address receiver, uint mintAmount) external returns (uint); - - function redeem(uint redeemTokens) external returns (uint); - - function redeemUnderlying(uint redeemAmount) external returns (uint); - - function borrow(uint borrowAmount) external returns (uint); - - function repayBorrow(uint repayAmount) external returns (uint); - - function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); - - function liquidateBorrow( - address borrower, - uint repayAmount, - VTokenInterface vTokenCollateral - ) external returns (uint); - - /*** Admin Functions ***/ - - function _addReserves(uint addAmount) external returns (uint); -} - -interface VDelegatorInterface { - /** - * @notice Emitted when implementation is changed - */ - event NewImplementation(address oldImplementation, address newImplementation); - - /** - * @notice Called by the admin to update the implementation of the delegator - * @param implementation_ The address of the new implementation for delegation - * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation - * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation - */ - function _setImplementation( - address implementation_, - bool allowResign, - bytes memory becomeImplementationData - ) external; -} - -interface VDelegateInterface { - /** - * @notice Called by the delegator on a delegate to initialize it for duty - * @dev Should revert if any issues arise which make it unfit for delegation - * @param data The encoded bytes data for any initialization - */ - function _becomeImplementation(bytes memory data) external; - - /** - * @notice Called by the delegator on a delegate to forfeit its responsibility - */ - function _resignImplementation() external; -} diff --git a/contracts/Tokens/VTokens/VTokenStorage.sol b/contracts/Tokens/VTokens/VTokenStorage.sol new file mode 100644 index 000000000..a5b6b1adc --- /dev/null +++ b/contracts/Tokens/VTokens/VTokenStorage.sol @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; +import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; +import { IVTokenStorage } from "./interfaces/IVTokenStorage.sol"; + +contract VTokenStorage is IVTokenStorage { + /** + * @dev Guard variable for re-entrancy checks + */ + bool internal _notEntered; + + /** + * @notice EIP-20 token name for this token + */ + string public name; + + /** + * @notice EIP-20 token symbol for this token + */ + string public symbol; + + /** + * @notice EIP-20 token decimals for this token + */ + uint8 public decimals; + + /** + * @notice Maximum borrow rate that can ever be applied (.0005% / block) + */ + + uint internal constant borrowRateMaxMantissa = 0.0005e16; + + /** + * @notice Maximum fraction of interest that can be set aside for reserves + */ + uint internal constant reserveFactorMaxMantissa = 1e18; + + /** + * @notice Administrator for this contract + */ + address payable public admin; + + /** + * @notice Pending administrator for this contract + */ + address payable public pendingAdmin; + + /** + * @notice Contract which oversees inter-vToken operations + */ + IComptroller public comptroller; + + /** + * @notice Model which tells what the current interest rate should be + */ + InterestRateModelV8 public interestRateModel; + + /** + * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0) + */ + uint internal initialExchangeRateMantissa; + + /** + * @notice Fraction of interest currently set aside for reserves + */ + uint public reserveFactorMantissa; + + /** + * @notice Block number that interest was last accrued at + */ + uint public accrualBlockNumber; + + /** + * @notice Accumulator of the total earned interest rate since the opening of the market + */ + uint public borrowIndex; + + /** + * @notice Total amount of outstanding borrows of the underlying in this market + */ + uint public totalBorrows; + + /** + * @notice Total amount of reserves of the underlying held in this market + */ + uint public totalReserves; + + /** + * @notice Total number of tokens in circulation + */ + uint public totalSupply; + + /** + * @notice Official record of token balances for each account + */ + mapping(address => uint) internal accountTokens; + + /** + * @notice Approved token transfer amounts on behalf of others + */ + mapping(address => mapping(address => uint)) internal transferAllowances; + + /** + * @notice Mapping of account addresses to outstanding borrow balances + */ + mapping(address => BorrowSnapshot) internal accountBorrows; + + /** + * @notice Underlying asset for this VToken + */ + address public underlying; + + /** + * @notice Implementation address for this contract + */ + address public implementation; + + /** + * @notice delta block after which reserves will be reduced + */ + uint public reduceReservesBlockDelta; + + /** + * @notice last block number at which reserves were reduced + */ + uint public reduceReservesBlockNumber; + + /** + * @notice address of protocol share reserve contract + */ + address payable public protocolShareReserve; + + /** + * @notice address of accessControlManager + */ + + address public accessControlManager; + + /** + * @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[50] private __gap; +} diff --git a/contracts/Tokens/VTokens/interfaces/IVBNB.sol b/contracts/Tokens/VTokens/interfaces/IVBNB.sol new file mode 100644 index 000000000..0ad2dd835 --- /dev/null +++ b/contracts/Tokens/VTokens/interfaces/IVBNB.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { IVToken } from "./IVToken.sol"; + +interface IVBNB { + /** + * @notice Send BNB to VBNB to mint + */ + receive() external payable; + + /** + * @notice Sender supplies assets into the market and receives vTokens in exchange + * @dev Reverts upon any failure + * @custom:event Emits Transfer event + * @custom:event Emits Mint event + */ + function mint() external payable; + + /** + * @notice Sender redeems vTokens in exchange for the underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemTokens The number of vTokens to redeem into underlying + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). + * @custom:event Emits Redeem event on success + * @custom:event Emits Transfer event on success + * @custom:event Emits RedeemFee when fee is charged by the treasury + */ + function redeem(uint256 redeemTokens) external returns (uint256); + + /** + * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemAmount The amount of underlying to redeem + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). + * @custom:event Emits Redeem event on success + * @custom:event Emits Transfer event on success + * @custom:event Emits RedeemFee when fee is charged by the treasury + */ + function redeemUnderlying(uint256 redeemAmount) external returns (uint256); + + /** + * @notice Sender borrows assets from the protocol to their own address + * @param borrowAmount The amount of the underlying asset to borrow + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). + * @custom:event Emits Borrow event on success + */ + function borrow(uint256 borrowAmount) external returns (uint256); + + /** + * @notice Sender repays their own borrow + * @dev Reverts upon any failure + * @custom:event Emits RepayBorrow event on success + */ + function repayBorrow() external payable; + + /** + * @notice Sender repays a borrow belonging to borrower + * @dev Reverts upon any failure + * @param borrower The account with the debt being payed off + * @custom:event Emits RepayBorrow event on success + */ + function repayBorrowBehalf(address borrower) external payable; + + /** + * @notice The sender liquidates the borrowers collateral. + * The collateral seized is transferred to the liquidator. + * @dev Reverts upon any failure + * @param borrower The borrower of this vToken to be liquidated + * @param vTokenCollateral The market in which to seize collateral from the borrower + * @custom:event Emit LiquidateBorrow event on success + */ + function liquidateBorrow(address borrower, IVToken vTokenCollateral) external payable; +} \ No newline at end of file diff --git a/contracts/Tokens/VTokens/interfaces/IVBep20.sol b/contracts/Tokens/VTokens/interfaces/IVBep20.sol new file mode 100644 index 000000000..fb5b919be --- /dev/null +++ b/contracts/Tokens/VTokens/interfaces/IVBep20.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { IVToken } from "./IVToken.sol"; + +interface IVBep20 is IVToken { + /*** User Interface ***/ + + function mint(uint mintAmount) external returns (uint); + + function mintBehalf(address receiver, uint mintAmount) external returns (uint); + + function redeem(uint redeemTokens) external returns (uint); + + function redeemUnderlying(uint redeemAmount) external returns (uint); + + function borrow(uint borrowAmount) external returns (uint); + + function repayBorrow(uint repayAmount) external returns (uint); + + function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); + + function liquidateBorrow( + address borrower, + uint repayAmount, + IVToken vTokenCollateral + ) external returns (uint); + + /*** Admin Functions ***/ + + function _addReserves(uint addAmount) external returns (uint); +} diff --git a/contracts/Tokens/VTokens/interfaces/IVDelegate.sol b/contracts/Tokens/VTokens/interfaces/IVDelegate.sol new file mode 100644 index 000000000..66d2fbd04 --- /dev/null +++ b/contracts/Tokens/VTokens/interfaces/IVDelegate.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +interface IVDelegate { + /** + * @notice Called by the delegator on a delegate to initialize it for duty + * @dev Should revert if any issues arise which make it unfit for delegation + * @param data The encoded bytes data for any initialization + */ + function _becomeImplementation(bytes memory data) external; + + /** + * @notice Called by the delegator on a delegate to forfeit its responsibility + */ + function _resignImplementation() external; +} diff --git a/contracts/Tokens/VTokens/interfaces/IVDelegator.sol b/contracts/Tokens/VTokens/interfaces/IVDelegator.sol new file mode 100644 index 000000000..e0af5435a --- /dev/null +++ b/contracts/Tokens/VTokens/interfaces/IVDelegator.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +interface IVDelegator { + /** + * @notice Emitted when implementation is changed + */ + event NewImplementation(address oldImplementation, address newImplementation); + + /** + * @notice Called by the admin to update the implementation of the delegator + * @param implementation_ The address of the new implementation for delegation + * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation + * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation + */ + function _setImplementation( + address implementation_, + bool allowResign, + bytes memory becomeImplementationData + ) external; +} diff --git a/contracts/Tokens/VTokens/interfaces/IVToken.sol b/contracts/Tokens/VTokens/interfaces/IVToken.sol new file mode 100644 index 000000000..ed70075bd --- /dev/null +++ b/contracts/Tokens/VTokens/interfaces/IVToken.sol @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { IComptroller } from "../../../Comptroller/interfaces/IComptroller.sol"; +import { InterestRateModelV8 } from "../../../InterestRateModels/InterestRateModelV8.sol"; +import { IVTokenStorage } from "./IVTokenStorage.sol"; + +interface IVToken is IVTokenStorage { + /*** Market Events ***/ + + /** + * @notice Event emitted when interest is accrued + */ + event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows); + + /** + * @notice Event emitted when tokens are minted + */ + event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply); + + /** + * @notice Event emitted when tokens are minted behalf by payer to receiver + */ + event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply); + + /** + * @notice Event emitted when tokens are redeemed + */ + event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply); + + /** + * @notice Event emitted when tokens are redeemed and fee is transferred + */ + event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens); + + /** + * @notice Event emitted when underlying is borrowed + */ + event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows); + + /** + * @notice Event emitted when a borrow is repaid + */ + event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows); + + /** + * @notice Event emitted when a borrow is liquidated + */ + event LiquidateBorrow( + address liquidator, + address borrower, + uint repayAmount, + address vTokenCollateral, + uint seizeTokens + ); + + /*** Admin Events ***/ + + /** + * @notice Event emitted when pendingAdmin is changed + */ + event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); + + /** + * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated + */ + event NewAdmin(address oldAdmin, address newAdmin); + + /** + * @notice Event emitted when comptroller is changed + */ + event NewComptroller(IComptroller oldComptroller, IComptroller newComptroller); + + /** + * @notice Event emitted when interestRateModel is changed + */ + event NewMarketInterestRateModel( + InterestRateModelV8 oldInterestRateModel, + InterestRateModelV8 newInterestRateModel + ); + + /** + * @notice Event emitted when the reserve factor is changed + */ + event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa); + + /** + * @notice Event emitted when the reserves are added + */ + event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves); + + /** + * @notice Event emitted when the reserves are reduced + */ + event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves); + + /** + * @notice EIP20 Transfer event + */ + event Transfer(address indexed from, address indexed to, uint amount); + + /** + * @notice EIP20 Approval event + */ + event Approval(address indexed owner, address indexed spender, uint amount); + + /** + * @notice Event emitted when block delta for reduce reserves get updated + */ + event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta); + + /** + * @notice Event emitted when address of ProtocolShareReserve contract get updated + */ + event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve); + + /// @notice Emitted when access control address is changed by admin + event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress); + + /*** User Interface ***/ + + /** + * @notice Indicator that this is a vToken contract (for inspection) + */ + function isVToken() external pure returns (bool); + + function transfer(address dst, uint amount) external returns (bool); + + function transferFrom(address src, address dst, uint amount) external returns (bool); + + function approve(address spender, uint amount) external returns (bool); + + function balanceOfUnderlying(address owner) external returns (uint); + + function totalBorrowsCurrent() external returns (uint); + + function borrowBalanceCurrent(address account) external returns (uint); + + function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint); + + function exchangeRateCurrent() external returns (uint); + + function accrueInterest() external returns (uint); + + /*** Admin Function ***/ + function _setPendingAdmin(address payable newPendingAdmin) external returns (uint); + + /*** Admin Function ***/ + function _acceptAdmin() external returns (uint); + + /*** Admin Function ***/ + function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint); + + /*** Admin Function ***/ + function _reduceReserves(uint reduceAmount) external returns (uint); + + /*** Admin Function ***/ + function _setComptroller(IComptroller newComptroller) external returns (uint); + + /*** Admin Function ***/ + function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) external returns (uint); + + function balanceOf(address owner) external view returns (uint); + + function allowance(address owner, address spender) external view returns (uint); + + function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint); + + function borrowRatePerBlock() external view returns (uint); + + function supplyRatePerBlock() external view returns (uint); + + function getCash() external view returns (uint); + + function borrowBalanceStored(address account) external view returns (uint); + + function exchangeRateStored() external view returns (uint); +} + +interface VDelegateInterface { + /** + * @notice Called by the delegator on a delegate to initialize it for duty + * @dev Should revert if any issues arise which make it unfit for delegation + * @param data The encoded bytes data for any initialization + */ + function _becomeImplementation(bytes memory data) external; + + /** + * @notice Called by the delegator on a delegate to forfeit its responsibility + */ + function _resignImplementation() external; +} diff --git a/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol b/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol new file mode 100644 index 000000000..66068c699 --- /dev/null +++ b/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +import { IComptroller } from "../../../Comptroller/interfaces/IComptroller.sol"; +import { InterestRateModelV8 } from "../../../InterestRateModels/InterestRateModelV8.sol"; + + +interface IVTokenStorage { + /** + * @notice Container for borrow balance information + * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action + * @member interestIndex Global borrowIndex as of the most recent balance-changing action + */ + struct BorrowSnapshot { + uint principal; + uint interestIndex; + } + + /** + * @notice EIP-20 token name for this token + */ + function name() external view returns (string memory); + + /** + * @notice EIP-20 token symbol for this token + */ + function symbol() external view returns (string memory); + + /** + * @notice EIP-20 token decimals for this token + */ + function decimals() external view returns (uint8); + + /** + * @notice Administrator for this contract + */ + function admin() external view returns (address payable); + + /** + * @notice Pending administrator for this contract + */ + function pendingAdmin() external view returns (address payable); + + /** + * @notice Contract which oversees inter-vToken operations + */ + function comptroller() external view returns (IComptroller); + + /** + * @notice Model which tells what the current interest rate should be + */ + function interestRateModel() external view returns (InterestRateModelV8); + + /** + * @notice Fraction of interest currently set aside for reserves + */ + function reserveFactorMantissa() external view returns (uint256); + + /** + * @notice Block number that interest was last accrued at + */ + function accrualBlockNumber() external view returns (uint256); + + /** + * @notice Accumulator of the total earned interest rate since the opening of the market + */ + function borrowIndex() external view returns (uint256); + + /** + * @notice Total amount of outstanding borrows of the underlying in this market + */ + function totalBorrows() external view returns (uint256); + + /** + * @notice Total amount of reserves of the underlying held in this market + */ + function totalReserves() external view returns (uint256); + + /** + * @notice Total number of tokens in circulation + */ + function totalSupply() external view returns (uint256); + + /** + * @notice Underlying asset for this VToken + */ + function underlying() external view returns (address); + + /** + * @notice Implementation address for this contract + */ + function implementation() external view returns (address); + + /** + * @notice Delta block after which reserves will be reduced + */ + function reduceReservesBlockDelta() external view returns (uint256); + + /** + * @notice Last block number at which reserves were reduced + */ + function reduceReservesBlockNumber() external view returns (uint256); + + /** + * @notice Address of protocol share reserve contract + */ + function protocolShareReserve() external view returns (address payable); + + /** + * @notice Address of accessControlManager + */ + function accessControlManager() external view returns (address); +} diff --git a/contracts/VAIVault/IVAIVault.sol b/contracts/VAIVault/IVAIVault.sol new file mode 100644 index 000000000..83ce747d2 --- /dev/null +++ b/contracts/VAIVault/IVAIVault.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: BSD-3-Clause +pragma solidity 0.8.25; + +interface IVAIVault { + function updatePendingRewards() external; +} diff --git a/contracts/test/ComptrollerHarness.sol b/contracts/test/ComptrollerHarness.sol index 10dd4811e..a290a7651 100644 --- a/contracts/test/ComptrollerHarness.sol +++ b/contracts/test/ComptrollerHarness.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import "./ComptrollerMock.sol"; @@ -44,10 +45,10 @@ contract ComptrollerHarness is ComptrollerMock { * @notice Recalculate and update XVS speeds for all XVS markets */ function harnessRefreshVenusSpeeds() public { - VToken[] memory allMarkets_ = allMarkets; + IVToken[] memory allMarkets_ = allMarkets; for (uint i = 0; i < allMarkets_.length; i++) { - VToken vToken = allMarkets_[i]; + IVToken vToken = allMarkets_[i]; Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() }); updateVenusSupplyIndex(address(vToken)); updateVenusBorrowIndex(address(vToken), borrowIndex); @@ -56,7 +57,7 @@ contract ComptrollerHarness is ComptrollerMock { Exp memory totalUtility = Exp({ mantissa: 0 }); Exp[] memory utilities = new Exp[](allMarkets_.length); for (uint i = 0; i < allMarkets_.length; i++) { - VToken vToken = allMarkets_[i]; + IVToken vToken = allMarkets_[i]; if (venusSpeeds[address(vToken)] > 0) { Exp memory assetPrice = Exp({ mantissa: oracle.getUnderlyingPrice(address(vToken)) }); Exp memory utility = mul_(assetPrice, vToken.totalBorrows()); @@ -66,7 +67,7 @@ contract ComptrollerHarness is ComptrollerMock { } for (uint i = 0; i < allMarkets_.length; i++) { - VToken vToken = allMarkets[i]; + IVToken vToken = allMarkets[i]; uint newSpeed = totalUtility.mantissa > 0 ? mul_(venusRate, div_(utilities[i], totalUtility)) : 0; setVenusSpeedInternal(vToken, newSpeed, newSpeed); } @@ -120,7 +121,7 @@ contract ComptrollerHarness is ComptrollerMock { function harnessAddVenusMarkets(address[] memory vTokens) public { for (uint i = 0; i < vTokens.length; i++) { // temporarily set venusSpeed to 1 (will be fixed by `harnessRefreshVenusSpeeds`) - setVenusSpeedInternal(VToken(vTokens[i]), 1, 1); + setVenusSpeedInternal(IVToken(vTokens[i]), 1, 1); } } diff --git a/contracts/test/ComptrollerMock.sol b/contracts/test/ComptrollerMock.sol index 538c7da78..52d6672eb 100644 --- a/contracts/test/ComptrollerMock.sol +++ b/contracts/test/ComptrollerMock.sol @@ -18,7 +18,7 @@ contract ComptrollerMock is MarketFacet, PolicyFacet, RewardFacet, SetterFacet { require(unitroller._acceptImplementation() == 0, "not authorized"); } - function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external override returns (uint) { + function _setComptrollerLens(IComptrollerLens comptrollerLens_) external override returns (uint) { ensureAdmin(); ensureNonzeroAddress(address(comptrollerLens_)); address oldComptrollerLens = address(comptrollerLens); diff --git a/contracts/test/ComptrollerMockR1.sol b/contracts/test/ComptrollerMockR1.sol index 8561217c3..856e473eb 100644 --- a/contracts/test/ComptrollerMockR1.sol +++ b/contracts/test/ComptrollerMockR1.sol @@ -23,7 +23,7 @@ contract ComptrollerMockR1 is MarketFacet, PolicyFacet, RewardFacet, SetterFacet require(unitroller._acceptImplementation() == 0, "not authorized"); } - function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external override returns (uint) { + function _setComptrollerLens(IComptrollerLens comptrollerLens_) external override returns (uint) { ensureAdmin(); ensureNonzeroAddress(address(comptrollerLens_)); address oldComptrollerLens = address(comptrollerLens); diff --git a/contracts/test/ComptrollerScenario.sol b/contracts/test/ComptrollerScenario.sol index 735a5760c..791a571ac 100644 --- a/contracts/test/ComptrollerScenario.sol +++ b/contracts/test/ComptrollerScenario.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import "./ComptrollerMock.sol"; @@ -25,7 +26,7 @@ contract ComptrollerScenario is ComptrollerMock { return vaiAddress; } - function membershipLength(VToken vToken) public view returns (uint) { + function membershipLength(IVToken vToken) public view returns (uint) { return accountAssets[address(vToken)].length; } @@ -62,7 +63,7 @@ contract ComptrollerScenario is ComptrollerMock { return venusMarkets; } - function unlist(VToken vToken) public { + function unlist(IVToken vToken) public { markets[address(vToken)].isListed = false; } @@ -70,10 +71,10 @@ contract ComptrollerScenario is ComptrollerMock { * @notice Recalculate and update XVS speeds for all XVS markets */ function refreshVenusSpeeds() public { - VToken[] memory allMarkets_ = allMarkets; + IVToken[] memory allMarkets_ = allMarkets; for (uint i = 0; i < allMarkets_.length; i++) { - VToken vToken = allMarkets_[i]; + IVToken vToken = allMarkets_[i]; Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() }); updateVenusSupplyIndex(address(vToken)); updateVenusBorrowIndex(address(vToken), borrowIndex); @@ -82,7 +83,7 @@ contract ComptrollerScenario is ComptrollerMock { Exp memory totalUtility = Exp({ mantissa: 0 }); Exp[] memory utilities = new Exp[](allMarkets_.length); for (uint i = 0; i < allMarkets_.length; i++) { - VToken vToken = allMarkets_[i]; + IVToken vToken = allMarkets_[i]; if (venusSpeeds[address(vToken)] > 0) { Exp memory assetPrice = Exp({ mantissa: oracle.getUnderlyingPrice(address(vToken)) }); Exp memory utility = mul_(assetPrice, vToken.totalBorrows()); @@ -92,7 +93,7 @@ contract ComptrollerScenario is ComptrollerMock { } for (uint i = 0; i < allMarkets_.length; i++) { - VToken vToken = allMarkets[i]; + IVToken vToken = allMarkets[i]; uint newSpeed = totalUtility.mantissa > 0 ? mul_(venusRate, div_(utilities[i], totalUtility)) : 0; setVenusSpeedInternal(vToken, newSpeed, newSpeed); } diff --git a/contracts/test/EvilXDelegator.sol b/contracts/test/EvilXDelegator.sol index 36bdbc33e..b2866367a 100644 --- a/contracts/test/EvilXDelegator.sol +++ b/contracts/test/EvilXDelegator.sol @@ -1,15 +1,21 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { InterestRateModelV8 } from "../InterestRateModels/InterestRateModelV8.sol"; -import { ComptrollerInterface } from "../Comptroller/ComptrollerInterface.sol"; -import { VTokenInterface, VBep20Interface, VDelegatorInterface } from "../Tokens/VTokens/VTokenInterfaces.sol"; +import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; +import { VTokenStorage } from "../Tokens/VTokens/VTokenStorage.sol"; +import { IVBep20 } from "../Tokens/VTokens/interfaces/IVBep20.sol"; +import { IVDelegator } from "../Tokens/VTokens/interfaces/IVDelegator.sol"; +import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; /** * @title Venus's VBep20Delegator Contract * @notice VTokens which wrap an EIP-20 underlying and delegate to an implementation * @author Venus */ -contract EvilXDelegator is VTokenInterface, VBep20Interface, VDelegatorInterface { +contract EvilXDelegator is VTokenStorage, IVBep20, IVDelegator { + bool public constant isVToken = true; + /** * @notice Construct a new money market * @param underlying_ The address of the underlying asset @@ -25,7 +31,7 @@ contract EvilXDelegator is VTokenInterface, VBep20Interface, VDelegatorInterface */ constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint256 initialExchangeRateMantissa_, string memory name_, @@ -177,7 +183,7 @@ contract EvilXDelegator is VTokenInterface, VBep20Interface, VDelegatorInterface function liquidateBorrow( address borrower, uint256 repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) external returns (uint256) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("liquidateBorrow(address,uint256,address)", borrower, repayAmount, vTokenCollateral) @@ -395,7 +401,7 @@ contract EvilXDelegator is VTokenInterface, VBep20Interface, VDelegatorInterface * @dev Admin function to set a new comptroller * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function _setComptroller(ComptrollerInterface newComptroller) public override returns (uint256) { + function _setComptroller(IComptroller newComptroller) public override returns (uint256) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("_setComptroller(address)", newComptroller) ); diff --git a/contracts/test/EvilXToken.sol b/contracts/test/EvilXToken.sol index abbcba555..36f4c4875 100644 --- a/contracts/test/EvilXToken.sol +++ b/contracts/test/EvilXToken.sol @@ -1,15 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import "../Tokens/VTokens/VBep20Immutable.sol"; import "../Tokens/VTokens/VBep20Delegator.sol"; import "../Tokens/VTokens/VBep20Delegate.sol"; import "./ComptrollerScenario.sol"; -import "../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; contract VBep20Scenario is VBep20Immutable { constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -75,7 +76,7 @@ contract EvilXToken is VBep20Delegate { // Checking the Liquidity of the user after the tranfer. // solhint-disable-next-line no-unused-vars - (uint errorCode, uint liquidity, uint shortfall) = ComptrollerInterface(comptrollerAddress).getAccountLiquidity( + (uint errorCode, uint liquidity, uint shortfall) = IComptroller(comptrollerAddress).getAccountLiquidity( msg.sender ); emit LogLiquidity(liquidity); @@ -181,7 +182,7 @@ contract EvilXToken is VBep20Delegate { address liquidator, address borrower, uint repayAmount, - VToken vTokenCollateral + IVToken vTokenCollateral ) public returns (uint) { (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral); return err; diff --git a/contracts/test/MockVBNB.sol b/contracts/test/MockVBNB.sol index a61dee4ff..78f42458b 100644 --- a/contracts/test/MockVBNB.sol +++ b/contracts/test/MockVBNB.sol @@ -19,7 +19,7 @@ contract MockVBNB is VToken { * @param admin_ Address of the administrator of this token */ constructor( - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, diff --git a/contracts/test/VAIControllerHarness.sol b/contracts/test/VAIControllerHarness.sol index b2111bdfa..632a71d91 100644 --- a/contracts/test/VAIControllerHarness.sol +++ b/contracts/test/VAIControllerHarness.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import "../Tokens/VAI/VAIController.sol"; @@ -32,7 +33,7 @@ contract VAIControllerHarness is VAIController { address liquidator, address borrower, uint repayAmount, - VToken vTokenCollateral + IVToken vTokenCollateral ) public returns (uint) { (uint err, ) = liquidateVAIFresh(liquidator, borrower, repayAmount, vTokenCollateral); return err; diff --git a/contracts/test/VBep20Harness.sol b/contracts/test/VBep20Harness.sol index b9c39d27d..69e5f30f8 100644 --- a/contracts/test/VBep20Harness.sol +++ b/contracts/test/VBep20Harness.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import "../Tokens/VTokens/VBep20Immutable.sol"; @@ -14,7 +15,7 @@ contract VBep20Harness is VBep20Immutable { constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -141,7 +142,7 @@ contract VBep20Harness is VBep20Immutable { address liquidator, address borrower, uint repayAmount, - VToken vTokenCollateral + IVToken vTokenCollateral ) public returns (uint) { (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral); return err; @@ -171,7 +172,7 @@ contract VBep20Harness is VBep20Immutable { contract VBep20Scenario is VBep20Immutable { constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -208,7 +209,7 @@ contract VBep20Scenario is VBep20Immutable { contract VEvil is VBep20Scenario { constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -228,7 +229,7 @@ contract VEvil is VBep20Scenario { ) {} - function evilSeize(VToken treasure, address liquidator, address borrower, uint seizeTokens) public returns (uint) { + function evilSeize(IVToken treasure, address liquidator, address borrower, uint seizeTokens) public returns (uint) { return treasure.seize(liquidator, borrower, seizeTokens); } } @@ -236,7 +237,7 @@ contract VEvil is VBep20Scenario { contract VBep20DelegatorScenario is VBep20Delegator { constructor( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -390,7 +391,7 @@ contract VBep20DelegateHarness is VBep20Delegate { address liquidator, address borrower, uint repayAmount, - VToken vTokenCollateral + IVToken vTokenCollateral ) public returns (uint) { (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral); return err; diff --git a/contracts/test/VBep20MockDelegate.sol b/contracts/test/VBep20MockDelegate.sol index 026f15caf..850a57cd6 100644 --- a/contracts/test/VBep20MockDelegate.sol +++ b/contracts/test/VBep20MockDelegate.sol @@ -3,18 +3,20 @@ pragma solidity 0.8.25; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { ComptrollerInterface } from "../Comptroller/ComptrollerInterface.sol"; +import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { VToken } from "../Tokens/VTokens/VToken.sol"; import { InterestRateModelV8 } from "../InterestRateModels/InterestRateModelV8.sol"; -import { VBep20Interface, VTokenInterface } from "../Tokens/VTokens/VTokenInterfaces.sol"; +import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; +import { IVBep20 } from "../Tokens/VTokens/interfaces/IVBep20.sol"; +import { IVDelegate } from "../Tokens/VTokens/interfaces/IVDelegate.sol"; /** * @title Venus's VBep20 Contract * @notice VTokens which wrap an EIP-20 underlying * @author Venus */ -contract VBep20MockDelegate is VToken, VBep20Interface { +contract VBep20MockDelegate is VToken, IVBep20, IVDelegate { using SafeERC20 for IERC20; uint internal blockNumber = 100000; @@ -31,7 +33,7 @@ contract VBep20MockDelegate is VToken, VBep20Interface { */ function initialize( address underlying_, - ComptrollerInterface comptroller_, + IComptroller comptroller_, InterestRateModelV8 interestRateModel_, uint initialExchangeRateMantissa_, string memory name_, @@ -164,7 +166,7 @@ contract VBep20MockDelegate is VToken, VBep20Interface { function liquidateBorrow( address borrower, uint repayAmount, - VTokenInterface vTokenCollateral + IVToken vTokenCollateral ) external returns (uint) { (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral); return err; From 9791a857e06056db84269ef57b76ad5e16be8a81 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Mon, 4 Aug 2025 16:30:48 +0300 Subject: [PATCH 2/8] fix: add missing awaits in tests --- .../Comptroller/Diamond/comptrollerTest.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts b/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts index a31a6f034..135a602d6 100644 --- a/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts +++ b/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts @@ -444,7 +444,7 @@ describe("Comptroller", () => { beforeEach(async () => { ({ comptroller, vToken, accessControl } = await loadFixture(deploy)); - configureVToken(vToken, comptroller); + await configureVToken(vToken, comptroller); }); it("fails if asset is not listed", async () => { @@ -509,7 +509,7 @@ describe("Comptroller", () => { beforeEach(async () => { ({ comptroller, vToken, accessControl } = await loadFixture(deploy)); - configureVToken(vToken, comptroller); + await configureVToken(vToken, comptroller); }); it("fails if asset is not listed", async () => { @@ -583,8 +583,8 @@ describe("Comptroller", () => { beforeEach(async () => { ({ comptroller, oracle, vToken1, vToken2, token } = await loadFixture(deploy)); configureOracle(oracle); - configureVToken(vToken1, unitroller); - configureVToken(vToken2, unitroller); + await configureVToken(vToken1, unitroller); + await configureVToken(vToken2, unitroller); }); it("fails if asset is not a VToken", async () => { @@ -670,13 +670,13 @@ describe("Comptroller", () => { beforeEach(async () => { ({ comptroller, vToken } = await loadFixture(deploy)); - configureVToken(vToken, unitroller); + await configureVToken(vToken, unitroller); }); describe("mintAllowed", () => { beforeEach(async () => { ({ comptroller, vToken } = await loadFixture(deploy)); - configureVToken(vToken, unitroller); + await configureVToken(vToken, unitroller); }); it("allows minting if cap is not reached", async () => { @@ -905,8 +905,7 @@ describe("Comptroller", () => { beforeEach(async () => { const contracts = await loadFixture(deploy); comptrollerLens = contracts.comptrollerLens; - // ({ comptroller, oracle, vToken } = await loadFixture(deploy)); - configureVToken(contracts.vToken, contracts.unitroller); + await configureVToken(contracts.vToken, contracts.unitroller); configureOracle(contracts.oracle); }); From c974cf206a7fc31c5b03ee5f46f4d94228c62d12 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 7 Aug 2025 14:57:06 +0300 Subject: [PATCH 3/8] docs: add missing natspec to interfaces --- .../Diamond/facets/RewardFacet.sol | 2 +- .../Diamond/interfaces/IMarketFacet.sol | 88 +++++++ .../Diamond/interfaces/IPolicyFacet.sol | 152 ++++++++++- .../Diamond/interfaces/IRewardFacet.sol | 53 ++++ .../Diamond/interfaces/ISetterFacet.sol | 188 ++++++++++++++ contracts/Tokens/VTokens/VBNB.sol | 3 +- contracts/Tokens/VTokens/interfaces/IVBNB.sol | 2 +- .../Tokens/VTokens/interfaces/IVBep20.sol | 59 ++++- .../Tokens/VTokens/interfaces/IVToken.sol | 236 +++++++++++++----- 9 files changed, 707 insertions(+), 76 deletions(-) diff --git a/contracts/Comptroller/Diamond/facets/RewardFacet.sol b/contracts/Comptroller/Diamond/facets/RewardFacet.sol index 163323704..962aa9503 100644 --- a/contracts/Comptroller/Diamond/facets/RewardFacet.sol +++ b/contracts/Comptroller/Diamond/facets/RewardFacet.sol @@ -133,8 +133,8 @@ contract RewardFacet is IRewardFacet, XVSRewardsHelper { } /** - * @dev Seize XVS tokens from the specified holders and transfer to recipient * @notice Seize XVS rewards allocated to holders + * @dev Seize XVS tokens from the specified holders and transfer to recipient * @param holders Addresses of the XVS holders * @param recipient Address of the XVS token recipient * @return The total amount of XVS tokens seized and transferred to recipient diff --git a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol index 5789d272b..7cd98d3c0 100644 --- a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol @@ -4,37 +4,125 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; +/** + * @title IMarketFacet + * @author Venus + * @dev Interface for the MarketFacet which contains all methods related to market management in the pool + * @notice This interface defines functions for managing markets, including listing, entering/exiting markets, + * liquidation calculations, and delegate management + */ interface IMarketFacet { + /** + * @notice Indicator that this is a Comptroller contract (for inspection) + * @return True indicating this is a Comptroller contract + */ function isComptroller() external pure returns (bool); + /** + * @notice Calculate number of tokens of collateral asset to seize given an underlying amount + * @dev Used in liquidation (called in vToken.liquidateBorrowFresh) + * @param vTokenBorrowed The address of the borrowed vToken + * @param vTokenCollateral The address of the collateral vToken + * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens + * @return errorCode The error code (0 for success) + * @return seizeTokens Number of vTokenCollateral tokens to be seized in a liquidation + */ function liquidateCalculateSeizeTokens( address vTokenBorrowed, address vTokenCollateral, uint256 actualRepayAmount ) external view returns (uint256, uint256); + /** + * @notice Calculate number of tokens of collateral asset to seize given an underlying amount for VAI liquidation + * @dev Used in VAI liquidation (called in vToken.liquidateBorrowFresh) + * @param vTokenCollateral The address of the collateral vToken + * @param actualRepayAmount The amount of VAI to convert into vTokenCollateral tokens + * @return errorCode The error code (0 for success) + * @return seizeTokens Number of vTokenCollateral tokens to be seized in a liquidation + */ function liquidateVAICalculateSeizeTokens( address vTokenCollateral, uint256 actualRepayAmount ) external view returns (uint256, uint256); + /** + * @notice Returns whether the given account is entered in the given asset + * @param account The address of the account to check + * @param vToken The vToken to check + * @return True if the account is in the asset, otherwise false + */ function checkMembership(address account, IVToken vToken) external view returns (bool); + /** + * @notice Add assets to be included in account liquidity calculation + * @param vTokens The list of addresses of the vToken markets to be enabled + * @return Success indicator for whether each corresponding market was entered + */ function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory); + /** + * @notice Removes asset from sender's account liquidity calculation + * @dev Sender must not have an outstanding borrow balance in the asset, + * or be providing necessary collateral for an outstanding borrow + * @param vToken The address of the asset to be removed + * @return Whether or not the account successfully exited the market (0 for success) + */ function exitMarket(address vToken) external returns (uint256); + /** + * @notice Add the market to the markets mapping and set it as listed + * @dev Allows a privileged role to add and list markets to the Comptroller + * @param vToken The address of the market (token) to list + * @return uint256 0=success, otherwise a failure. (See enum Error for details) + */ function _supportMarket(IVToken vToken) external returns (uint256); + /** + * @notice Alias to _supportMarket to support the Isolated Lending Comptroller Interface + * @param vToken The address of the market (token) to list + * @return uint256 0=success, otherwise a failure. (See enum Error for details) + */ function supportMarket(IVToken vToken) external returns (uint256); + /** + * @notice Check if a market is marked as listed (active) + * @param vToken vToken Address for the market to check + * @return True if listed otherwise false + */ function isMarketListed(IVToken vToken) external view returns (bool); + /** + * @notice Returns the assets an account has entered + * @param account The address of the account to pull assets for + * @return A dynamic list with the assets the account has entered + */ function getAssetsIn(address account) external view returns (IVToken[] memory); + /** + * @notice Return all of the markets + * @dev The automatic getter may be used to access an individual market + * @return The list of market addresses + */ function getAllMarkets() external view returns (IVToken[] memory); + /** + * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account + * @dev If allowed, the delegate will be able to borrow funds on behalf of the sender. + * Upon a delegated borrow, the delegate will receive the funds, and the borrower + * will see the debt on their account. + * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver + * will see a deduction in his vToken balance + * @param delegate The address to update the rights for + * @param allowBorrows Whether to grant (true) or revoke (false) the borrowing or redeeming rights + */ function updateDelegate(address delegate, bool allowBorrows) external; + /** + * @notice Unlist a market by setting isListed to false + * @dev Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0 + * @param market The address of the market (vToken) to unlist + * @return uint256 0=success, otherwise a failure. (See enum Error for details) + */ function unlistMarket(address market) external returns (uint256); } diff --git a/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol b/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol index e67081a89..e8f89cc25 100644 --- a/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol @@ -4,19 +4,74 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; +/** + * @title IPolicyFacet + * @author Venus + * @dev Interface for the PolicyFacet which contains all the hooks used while transferring assets + * @notice This interface defines all the external pre-hook functions related to vToken operations + */ interface IPolicyFacet { + /** + * @notice Checks if the account should be allowed to mint tokens in the given market + * @param vToken The market to verify the mint against + * @param minter The account which would get the minted tokens + * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens + * @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); - function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external; - + /** + * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vToken Asset being minted + * @param minter The address minting the tokens + * @param actualMintAmount The amount of the underlying asset being minted + * @param mintTokens The number of tokens being minted + */ + function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external; + + /** + * @notice Checks if the account should be allowed to redeem tokens in the given market + * @param vToken The market to verify the redeem against + * @param redeemer The account which would redeem the tokens + * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market + * @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); + /** + * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vToken Asset being redeemed + * @param redeemer The address redeeming the tokens + * @param redeemAmount The amount of the underlying asset being redeemed + * @param redeemTokens The number of tokens being redeemed + */ function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external; + /** + * @notice Checks if the account should be allowed to borrow the underlying asset of the given market + * @param vToken The market to verify the borrow against + * @param borrower The account which would borrow the asset + * @param borrowAmount The amount of underlying the account would borrow + * @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); + /** + * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vToken Asset whose underlying is being borrowed + * @param borrower The address borrowing the underlying + * @param borrowAmount The amount of the underlying asset requested to borrow + */ function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external; + /** + * @notice Checks if the account should be allowed to repay a borrow in the given market + * @param vToken The market to verify the repay against + * @param payer The account which would repay the asset + * @param borrower The account which borrowed the asset + * @param repayAmount The amount of the underlying asset the account would repay + * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ function repayBorrowAllowed( address vToken, address payer, @@ -24,14 +79,31 @@ interface IPolicyFacet { uint256 repayAmount ) external returns (uint256); + /** + * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vToken Asset being repaid + * @param payer The address repaying the borrow + * @param borrower The address of the borrower + * @param actualRepayAmount The amount of underlying being repaid + * @param borrowerIndex The borrower's index + */ function repayBorrowVerify( address vToken, address payer, address borrower, - uint256 repayAmount, + uint256 actualRepayAmount, uint256 borrowerIndex ) external; + /** + * @notice Checks if the liquidation should be allowed to occur + * @param vTokenBorrowed Asset which was borrowed by the borrower + * @param vTokenCollateral Asset which was used as collateral and will be seized + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param repayAmount The amount of underlying being repaid + * @return 0 if the liquidation is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ function liquidateBorrowAllowed( address vTokenBorrowed, address vTokenCollateral, @@ -40,15 +112,33 @@ interface IPolicyFacet { uint256 repayAmount ) external view returns (uint256); + /** + * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vTokenBorrowed Asset which was borrowed by the borrower + * @param vTokenCollateral Asset which was used as collateral and will be seized + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param actualRepayAmount The amount of underlying being repaid + * @param seizeTokens The amount of collateral token that will be seized + */ function liquidateBorrowVerify( address vTokenBorrowed, address vTokenCollateral, address liquidator, address borrower, - uint256 repayAmount, + uint256 actualRepayAmount, uint256 seizeTokens ) external; + /** + * @notice Checks if the seizing of assets should be allowed to occur + * @param vTokenCollateral Asset which was used as collateral and will be seized + * @param vTokenBorrowed Asset which was borrowed by the borrower + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param seizeTokens The number of collateral tokens to seize + * @return 0 if the seize is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ function seizeAllowed( address vTokenCollateral, address vTokenBorrowed, @@ -57,6 +147,14 @@ interface IPolicyFacet { uint256 seizeTokens ) external returns (uint256); + /** + * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vTokenCollateral Asset which was used as collateral and will be seized + * @param vTokenBorrowed Asset which was borrowed by the borrower + * @param liquidator The address repaying the borrow and seizing the collateral + * @param borrower The address of the borrower + * @param seizeTokens The number of collateral tokens to seize + */ function seizeVerify( address vTokenCollateral, address vTokenBorrowed, @@ -65,6 +163,14 @@ interface IPolicyFacet { uint256 seizeTokens ) external; + /** + * @notice Checks if the account should be allowed to transfer tokens in the given market + * @param vToken The market to verify the transfer against + * @param src The account which sources the tokens + * @param dst The account which receives the tokens + * @param transferTokens The number of vTokens to transfer + * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol) + */ function transferAllowed( address vToken, address src, @@ -72,10 +178,34 @@ interface IPolicyFacet { uint256 transferTokens ) external returns (uint256); + /** + * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs. + * @param vToken Asset being transferred + * @param src The account which sources the tokens + * @param dst The account which receives the tokens + * @param transferTokens The number of vTokens to transfer + */ function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external; + /** + * @notice Determine the current account liquidity wrt collateral requirements + * @param account The account get liquidity for + * @return (possible error code (semi-opaque), + account liquidity in excess of collateral requirements, + * account shortfall below collateral requirements) + */ function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256); + /** + * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed + * @param account The account to determine liquidity for + * @param vTokenModify The market to hypothetically redeem/borrow in + * @param redeemTokens The number of tokens to hypothetically redeem + * @param borrowAmount The amount of underlying to hypothetically borrow + * @return (possible error code (semi-opaque), + hypothetical account liquidity in excess of collateral requirements, + * hypothetical account shortfall below collateral requirements) + */ function getHypotheticalAccountLiquidity( address account, address vTokenModify, @@ -83,12 +213,26 @@ interface IPolicyFacet { uint256 borrowAmount ) external view returns (uint256, uint256, uint256); + /** + * @notice Set XVS speed for a single market + * @dev Allows the contract admin to set XVS speed for a market + * @param vTokens The market whose XVS speed to update + * @param supplySpeeds New XVS speed for supply + * @param borrowSpeeds New XVS speed for borrow + */ function _setVenusSpeeds( IVToken[] calldata vTokens, uint256[] calldata supplySpeeds, uint256[] calldata borrowSpeeds ) external; + /** + * @notice Alias to getAccountLiquidity to support the Isolated Lending Comptroller Interface + * @param account The account get liquidity for + * @return error possible error code (semi-opaque), + * @return liquidity account liquidity in excess of collateral requirements, + * @return shortfall account shortfall below collateral requirements + */ function getBorrowingPower( address account ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall); diff --git a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol index 476392e01..12b34ac8a 100644 --- a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol @@ -6,19 +6,64 @@ import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { Action } from "../../ComptrollerInterface.sol"; import { IFacetBase } from "./IFacetBase.sol"; +/** + * @title IRewardFacet + * @author Venus + * @dev This interface contains all the methods related to the reward functionality + * @notice This interface provides the external functions related to all claims and rewards of the protocol + */ interface IRewardFacet is IFacetBase { + /** + * @notice Claim all the xvs accrued by holder in all markets and VAI + * @param holder The address to claim XVS for + */ function claimVenus(address holder) external; + /** + * @notice Claim all the xvs accrued by holder in the specified markets + * @param holder The address to claim XVS for + * @param vTokens The list of markets to claim XVS in + */ function claimVenus(address holder, IVToken[] calldata vTokens) external; + /** + * @notice Claim all xvs accrued by the holders + * @param holders The addresses to claim XVS for + * @param vTokens The list of markets to claim XVS in + * @param borrowers Whether or not to claim XVS earned by borrowing + * @param suppliers Whether or not to claim XVS earned by supplying + */ function claimVenus(address[] calldata holders, IVToken[] calldata vTokens, bool borrowers, bool suppliers) external; + /** + * @notice Claim all the xvs accrued by holder in all markets, a shorthand for `claimVenus` with collateral set to `true` + * @param holder The address to claim XVS for + */ function claimVenusAsCollateral(address holder) external; + /** + * @notice Transfer XVS to the recipient + * @dev Allows the contract admin to transfer XVS to any recipient based on the recipient's shortfall + * Note: If there is not enough XVS, we do not perform the transfer all + * @param recipient The address of the recipient to transfer XVS to + * @param amount The amount of XVS to (possibly) transfer + */ function _grantXVS(address recipient, uint256 amount) external; + /** + * @notice Returns the XVS vToken address + * @return The address of XVS vToken + */ function getXVSVTokenAddress() external view returns (address); + /** + * @notice Claim all xvs accrued by the holders + * @param holders The addresses to claim XVS for + * @param vTokens The list of markets to claim XVS in + * @param borrowers Whether or not to claim XVS earned by borrowing + * @param suppliers Whether or not to claim XVS earned by supplying + * @param collateral Whether or not to use XVS earned as collateral, only takes effect when the holder has a shortfall + */ function claimVenus( address[] calldata holders, IVToken[] calldata vTokens, @@ -26,5 +71,13 @@ interface IRewardFacet is IFacetBase { bool suppliers, bool collateral ) external; + + /** + * @notice Seize XVS rewards allocated to holders + * @dev Seize XVS tokens from the specified holders and transfer to recipient + * @param holders Addresses of the XVS holders + * @param recipient Address of the XVS token recipient + * @return The total amount of XVS tokens seized and transferred to recipient + */ function seizeVenus(address[] calldata holders, address recipient) external returns (uint256); } diff --git a/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol b/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol index c0db8dcd0..f1540d824 100644 --- a/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol @@ -9,76 +9,264 @@ import { VAIControllerInterface } from "../../../Tokens/VAI/VAIControllerInterfa import { IComptrollerLens } from "../../../Lens/interfaces/IComptrollerLens.sol"; import { IPrime } from "../../../Tokens/Prime/IPrime.sol"; +/** + * @title ISetterFacet + * @author Venus + * @dev This interface contains all the setters for the states + * @notice This interface contract contains all the configurational setter functions + */ interface ISetterFacet { + /** + * @notice Alias to _setPriceOracle to support the Isolated Lending Comptroller Interface + * @param newOracle The new price oracle to set + * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function setPriceOracle(ResilientOracleInterface newOracle) external returns (uint256); + /** + * @notice Sets a new price oracle for the comptroller + * @dev Allows the contract admin to set a new price oracle used by the Comptroller + * @param newOracle The new price oracle to set + * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function _setPriceOracle(ResilientOracleInterface newOracle) external returns (uint256); + /** + * @notice Alias to _setCloseFactor to support the Isolated Lending Comptroller Interface + * @param newCloseFactorMantissa New close factor, scaled by 1e18 + * @return uint256 0=success, otherwise will revert + */ function setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256); + /** + * @notice Sets the closeFactor used when liquidating borrows + * @dev Allows the contract admin to set the closeFactor used to liquidate borrows + * @param newCloseFactorMantissa New close factor, scaled by 1e18 + * @return uint256 0=success, otherwise will revert + */ function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256); + /** + * @notice Sets the address of the access control of this contract + * @dev Allows the contract admin to set the address of access control of this contract + * @param newAccessControlAddress New address for the access control + * @return uint256 0=success, otherwise will revert + */ function _setAccessControl(address newAccessControlAddress) external returns (uint256); + /** + * @notice Alias to _setCollateralFactor to support the Isolated Lending Comptroller Interface + * @param vToken The market to set the factor on + * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 + * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18 + * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details) + */ function setCollateralFactor( IVToken vToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa ) external returns (uint256); + /** + * @notice Sets the collateralFactor for a market + * @dev Allows a privileged role to set the collateralFactorMantissa + * @param vToken The market to set the factor on + * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18 + * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details) + */ function _setCollateralFactor(IVToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256); + /** + * @notice Alias to _setLiquidationIncentive to support the Isolated Lending Comptroller Interface + * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18 + * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details) + */ function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256); + /** + * @notice Sets liquidationIncentive + * @dev Allows a privileged role to set the liquidationIncentiveMantissa + * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18 + * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details) + */ function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256); + /** + * @notice Update the address of the liquidator contract + * @dev Allows the contract admin to update the address of liquidator contract + * @param newLiquidatorContract_ The new address of the liquidator contract + */ function _setLiquidatorContract(address newLiquidatorContract_) external; + /** + * @notice Admin function to change the Pause Guardian + * @dev Allows the contract admin to change the Pause Guardian + * @param newPauseGuardian The address of the new Pause Guardian + * @return uint256 0=success, otherwise a failure. (See enum Error for details) + */ function _setPauseGuardian(address newPauseGuardian) external returns (uint256); + /** + * @notice Alias to _setMarketBorrowCaps to support the Isolated Lending Comptroller Interface + * @param vTokens The addresses of the markets (tokens) to change the borrow caps for + * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed + */ function setMarketBorrowCaps(IVToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external; + /** + * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert + * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed + * @param vTokens The addresses of the markets (tokens) to change the borrow caps for + * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed + */ function _setMarketBorrowCaps(IVToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external; + /** + * @notice Alias to _setMarketSupplyCaps to support the Isolated Lending Comptroller Interface + * @param vTokens The addresses of the markets (tokens) to change the supply caps for + * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed + */ function setMarketSupplyCaps(IVToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external; + /** + * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert + * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed + * @param vTokens The addresses of the markets (tokens) to change the supply caps for + * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed + */ function _setMarketSupplyCaps(IVToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external; + /** + * @notice Set whole protocol pause/unpause state + * @dev Allows a privileged role to pause/unpause protocol + * @param state The new state (true=paused, false=unpaused) + * @return bool The updated state of the protocol + */ function _setProtocolPaused(bool state) external returns (bool); + /** + * @notice Alias to _setActionsPaused to support the Isolated Lending Comptroller Interface + * @param markets Markets to pause/unpause the actions on + * @param actions List of action ids to pause/unpause + * @param paused The new paused state (true=paused, false=unpaused) + */ function setActionsPaused(address[] calldata markets, Action[] calldata actions, bool paused) external; + /** + * @notice Pause/unpause certain actions + * @dev Allows a privileged role to pause/unpause the protocol action state + * @param markets Markets to pause/unpause the actions on + * @param actions List of action ids to pause/unpause + * @param paused The new paused state (true=paused, false=unpaused) + */ function _setActionsPaused(address[] calldata markets, Action[] calldata actions, bool paused) external; + /** + * @notice Sets a new VAI controller + * @dev Admin function to set a new VAI controller + * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256); + /** + * @notice Set the VAI mint rate + * @param newVAIMintRate The new VAI mint rate to be set + * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256); + /** + * @notice Set the minted VAI amount of the `owner` + * @param owner The address of the account to set + * @param amount The amount of VAI to set to the account + * @return The number of minted VAI by `owner` + */ function setMintedVAIOf(address owner, uint256 amount) external returns (uint256); + /** + * @notice Set the treasury data. + * @param newTreasuryGuardian The new address of the treasury guardian to be set + * @param newTreasuryAddress The new address of the treasury to be set + * @param newTreasuryPercent The new treasury percent to be set + * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function _setTreasuryData( address newTreasuryGuardian, address newTreasuryAddress, uint256 newTreasuryPercent ) external returns (uint256); + /** + * @dev Set ComptrollerLens contract address + * @param comptrollerLens_ The new ComptrollerLens contract address to be set + * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function _setComptrollerLens(IComptrollerLens comptrollerLens_) external returns (uint256); + /** + * @notice Set the amount of XVS distributed per block to VAI Vault + * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault + */ function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external; + /** + * @notice Set the VAI Vault infos + * @param vault_ The address of the VAI Vault + * @param releaseStartBlock_ The start block of release to VAI Vault + * @param minReleaseAmount_ The minimum release amount to VAI Vault + */ function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external; + /** + * @notice Enables forced liquidations for a market. If forced liquidation is enabled, + * borrows in the market may be liquidated regardless of the account liquidity + * @dev Allows a privileged role to set enable/disable forced liquidations + * @param vToken Borrowed vToken + * @param enable Whether to enable forced liquidations + */ function _setForcedLiquidation(address vToken, bool enable) external; + /** + * @notice Alias to _setPrimeToken to support the Isolated Lending Comptroller Interface + * @param _prime The new prime token contract to be set + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function setPrimeToken(IPrime _prime) external returns (uint256); + /** + * @notice Sets the prime token contract for the comptroller + * @param _prime The new prime token contract to be set + * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) + */ function _setPrimeToken(IPrime _prime) external returns (uint); + /** + * @notice Alias to _setForcedLiquidation to support the Isolated Lending Comptroller Interface + * @param vTokenBorrowed Borrowed vToken + * @param enable Whether to enable forced liquidations + */ function setForcedLiquidation(address vTokenBorrowed, bool enable) external; + /** + * @notice Enables forced liquidations for user's borrows in a certain market. If forced + * liquidation is enabled, user's borrows in the market may be liquidated regardless of + * the account liquidity. Forced liquidation may be enabled for a user even if it is not + * enabled for the entire market. + * @param borrower The address of the borrower + * @param vTokenBorrowed Borrowed vToken + * @param enable Whether to enable forced liquidations + */ function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external; + /** + * @notice Set the address of the XVS token + * @param xvs_ The address of the XVS token + */ function _setXVSToken(address xvs_) external; + /** + * @notice Set the address of the XVS vToken + * @param xvsVToken_ The address of the XVS vToken + */ function _setXVSVToken(address xvsVToken_) external; } diff --git a/contracts/Tokens/VTokens/VBNB.sol b/contracts/Tokens/VTokens/VBNB.sol index ed21d90d1..cc069a35e 100644 --- a/contracts/Tokens/VTokens/VBNB.sol +++ b/contracts/Tokens/VTokens/VBNB.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.25; import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../InterestRateModels/InterestRateModelV8.sol"; +import { IVBNB } from "./interfaces/IVBNB.sol"; import { IVToken } from "./interfaces/IVToken.sol"; import { VToken } from "./VToken.sol"; @@ -11,7 +12,7 @@ import { VToken } from "./VToken.sol"; * @notice vToken which wraps BNB * @author Venus */ -contract VBNB is VToken { +contract VBNB is IVBNB, VToken { /** * @notice Construct a new vBNB money market * @param comptroller_ The address of the Comptroller diff --git a/contracts/Tokens/VTokens/interfaces/IVBNB.sol b/contracts/Tokens/VTokens/interfaces/IVBNB.sol index 0ad2dd835..85b4bbb67 100644 --- a/contracts/Tokens/VTokens/interfaces/IVBNB.sol +++ b/contracts/Tokens/VTokens/interfaces/IVBNB.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.25; import { IVToken } from "./IVToken.sol"; -interface IVBNB { +interface IVBNB is IVToken { /** * @notice Send BNB to VBNB to mint */ diff --git a/contracts/Tokens/VTokens/interfaces/IVBep20.sol b/contracts/Tokens/VTokens/interfaces/IVBep20.sol index fb5b919be..a6538401e 100644 --- a/contracts/Tokens/VTokens/interfaces/IVBep20.sol +++ b/contracts/Tokens/VTokens/interfaces/IVBep20.sol @@ -5,21 +5,72 @@ import { IVToken } from "./IVToken.sol"; interface IVBep20 is IVToken { /*** User Interface ***/ - + /** + * @notice Sender supplies assets into the market and receives vTokens in exchange + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param mintAmount The amount of the underlying asset to supply + * @return uint Returns 0 on success, otherwise returns a failure code + */ function mint(uint mintAmount) external returns (uint); + /** + * @notice Sender supplies assets into the market on behalf of another account and receives vTokens in exchange + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param receiver The address that will receive the vTokens + * @param mintAmount The amount of the underlying asset to supply + * @return uint Returns 0 on success, otherwise returns a failure code + */ function mintBehalf(address receiver, uint mintAmount) external returns (uint); + /** + * @notice Sender redeems vTokens in exchange for the underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemTokens The amount of vTokens to redeem + * @return uint Returns the underlying asset received + */ function redeem(uint redeemTokens) external returns (uint); + /** + * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemAmount The amount of underlying asset to receive + * @return uint Returns the vTokens redeemed + */ function redeemUnderlying(uint redeemAmount) external returns (uint); + /** + * @notice Sender borrows assets from the protocol to their own address + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param borrowAmount The amount of the underlying asset to borrow + * @return uint Returns the amount successfully borrowed + */ function borrow(uint borrowAmount) external returns (uint); + /** + * @notice Sender repays their own borrow + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param repayAmount The amount of the underlying asset to repay + * @return uint Returns the remaining borrow amount after repayment + */ function repayBorrow(uint repayAmount) external returns (uint); + /** + * @notice Sender repays a borrow on behalf of another account + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param borrower The address of the borrower + * @param repayAmount The amount of the underlying asset to repay + * @return uint Returns the remaining borrow amount after repayment + */ function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); + /** + * @notice Liquidates a borrowers position + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param borrower The address of the borrower + * @param repayAmount The amount of the underlying asset to repay + * @param vTokenCollateral The address of the vToken collateral + * @return uint Returns the amount successfully liquidated + */ function liquidateBorrow( address borrower, uint repayAmount, @@ -28,5 +79,11 @@ interface IVBep20 is IVToken { /*** Admin Functions ***/ + /** + * @notice Admin function to add reserves to the protocol + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param addAmount The amount of the underlying asset to add + * @return uint Returns the new total reserves + */ function _addReserves(uint addAmount) external returns (uint); } diff --git a/contracts/Tokens/VTokens/interfaces/IVToken.sol b/contracts/Tokens/VTokens/interfaces/IVToken.sol index ed70075bd..4b0980dc2 100644 --- a/contracts/Tokens/VTokens/interfaces/IVToken.sol +++ b/contracts/Tokens/VTokens/interfaces/IVToken.sol @@ -5,47 +5,35 @@ import { IComptroller } from "../../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../../InterestRateModels/InterestRateModelV8.sol"; import { IVTokenStorage } from "./IVTokenStorage.sol"; +/** + * @title Venus VToken Interface + * @author Venus + * @notice Interface for interacting with Venus VTokens + * @dev This interface defines the core functionality of Venus VTokens, which are interest-bearing tokens that represent deposits of underlying assets + */ interface IVToken is IVTokenStorage { - /*** Market Events ***/ - - /** - * @notice Event emitted when interest is accrued - */ + /// @notice Event emitted when interest is accrued event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows); - /** - * @notice Event emitted when tokens are minted - */ + /// @notice Event emitted when tokens are minted event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply); - /** - * @notice Event emitted when tokens are minted behalf by payer to receiver - */ + /// @notice Event emitted when tokens are minted behalf by payer to receiver event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply); - /** - * @notice Event emitted when tokens are redeemed - */ + /// @notice Event emitted when tokens are redeemed event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply); - /** - * @notice Event emitted when tokens are redeemed and fee is transferred - */ + /// @notice Event emitted when tokens are redeemed and fee is transferred event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens); - /** - * @notice Event emitted when underlying is borrowed - */ + /// @notice Event emitted when underlying is borrowed event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows); - /** - * @notice Event emitted when a borrow is repaid - */ + /// @notice Event emitted when a borrow is repaid event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows); - /** - * @notice Event emitted when a borrow is liquidated - */ + /// @notice Event emitted when a borrow is liquidated event LiquidateBorrow( address liquidator, address borrower, @@ -54,126 +42,238 @@ interface IVToken is IVTokenStorage { uint seizeTokens ); - /*** Admin Events ***/ - - /** - * @notice Event emitted when pendingAdmin is changed - */ + /// @notice Event emitted when pendingAdmin is changed event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); - /** - * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated - */ + /// @notice Event emitted when pendingAdmin is accepted, which means admin has been updated event NewAdmin(address oldAdmin, address newAdmin); - /** - * @notice Event emitted when comptroller is changed - */ + /// @notice Event emitted when comptroller is changed event NewComptroller(IComptroller oldComptroller, IComptroller newComptroller); - /** - * @notice Event emitted when interestRateModel is changed - */ + /// @notice Event emitted when interestRateModel is changed event NewMarketInterestRateModel( InterestRateModelV8 oldInterestRateModel, InterestRateModelV8 newInterestRateModel ); - /** - * @notice Event emitted when the reserve factor is changed - */ + /// @notice Event emitted when the reserve factor is changed event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa); - /** - * @notice Event emitted when the reserves are added - */ + /// @notice Event emitted when the reserves are added event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves); - /** - * @notice Event emitted when the reserves are reduced - */ + /// @notice Event emitted when the reserves are reduced event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves); - /** - * @notice EIP20 Transfer event - */ + /// @notice EIP20 Transfer event event Transfer(address indexed from, address indexed to, uint amount); - /** - * @notice EIP20 Approval event - */ + /// @notice EIP20 Approval event event Approval(address indexed owner, address indexed spender, uint amount); - /** - * @notice Event emitted when block delta for reduce reserves get updated - */ + /// @notice Event emitted when block delta for reduce reserves get updated event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta); - /** - * @notice Event emitted when address of ProtocolShareReserve contract get updated - */ + /// @notice Event emitted when address of ProtocolShareReserve contract get updated event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve); /// @notice Emitted when access control address is changed by admin event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress); - /*** User Interface ***/ /** * @notice Indicator that this is a vToken contract (for inspection) */ function isVToken() external pure returns (bool); + /** + * @notice Transfer `amount` tokens from `msg.sender` to `dst` + * @param dst The address of the destination account + * @param amount The number of tokens to transfer + * @return Whether or not the transfer succeeded + * @custom:event Emits Transfer event + */ function transfer(address dst, uint amount) external returns (bool); + /** + * @notice Transfer `amount` tokens from `src` to `dst` + * @param src The address of the source account + * @param dst The address of the destination account + * @param amount The number of tokens to transfer + * @return Whether or not the transfer succeeded + * @custom:event Emits Transfer event + */ function transferFrom(address src, address dst, uint amount) external returns (bool); + /** + * @notice Approve `spender` to transfer up to `amount` from `msg.sender` + * @dev This will overwrite the approval amount for `spender` + * @param spender The address of the account which may transfer tokens + * @param amount The number of tokens that are approved + * @return Whether or not the approval succeeded + * @custom:event Emits Approval event + */ function approve(address spender, uint amount) external returns (bool); + /** + * @notice Get the underlying balance of the `owner` + * @dev This also accrues interest in a transaction + * @param owner The address of the account to query + * @return The amount of underlying owned by `owner` + */ function balanceOfUnderlying(address owner) external returns (uint); + /** + * @notice Returns the current total borrows plus accrued interest + * @return The total borrows with interest + */ function totalBorrowsCurrent() external returns (uint); + /** + * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex + * @param account The address whose balance should be calculated after updating borrowIndex + * @return The calculated balance + */ function borrowBalanceCurrent(address account) external returns (uint); + /** + * @notice Transfers collateral tokens (this market) to the liquidator + * @dev Called only during liquidation + * @param liquidator The account receiving seized collateral + * @param borrower The account having collateral seized + * @param seizeTokens The number of vTokens to seize + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits Transfer event + */ function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint); + /** + * @notice Calculates the current exchange rate from the underlying to the VToken + * @dev This function includes accruing interest + * @return Calculated exchange rate scaled by 1e18 + */ function exchangeRateCurrent() external returns (uint); + /** + * @notice Applies accrued interest to total borrows and reserves + * @dev This calculates interest accrued from the last checkpointed block up to the current block + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits AccrueInterest on success + */ function accrueInterest() external returns (uint); - /*** Admin Function ***/ + /** + * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. + * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. + * @param newPendingAdmin New pending admin. + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits NewPendingAdmin event + * @custom:access Only Governance + */ function _setPendingAdmin(address payable newPendingAdmin) external returns (uint); - /*** Admin Function ***/ + /** + * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin + * @dev Admin function for pending admin to accept role and update admin + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits NewAdmin event + * @custom:event Emits NewPendingAdmin event + * @custom:access Only pending admin + */ function _acceptAdmin() external returns (uint); - /*** Admin Function ***/ + /** + * @notice Sets a new reserve factor for the protocol + * @dev Admin function to set a new reserve factor + * @param newReserveFactorMantissa The new reserve factor, scaled by 1e18 + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits NewReserveFactor event + * @custom:access Controlled by AccessControlManager + */ function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint); - /*** Admin Function ***/ + /** + * @notice Reduces reserves by transferring to protocol share reserve + * @dev Requires fresh interest accrual + * @param reduceAmount Amount of reduction to reserves + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits ReservesReduced event + * @custom:access Controlled by AccessControlManager + */ function _reduceReserves(uint reduceAmount) external returns (uint); - /*** Admin Function ***/ + /** + * @notice Sets a new comptroller for the market + * @dev Admin function to set a new comptroller + * @param newComptroller The new comptroller address + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits NewComptroller event + * @custom:access Only Governance + */ function _setComptroller(IComptroller newComptroller) external returns (uint); - /*** Admin Function ***/ + /** + * @notice Sets a new interest rate model for the market + * @dev Admin function to set a new interest rate model + * @param newInterestRateModel The new interest rate model address + * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details) + * @custom:event Emits NewMarketInterestRateModel event + * @custom:access Controlled by AccessControlManager + */ function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) external returns (uint); + /** + * @notice Get the token balance of the `owner` + * @param owner The address of the account to query + * @return The number of tokens owned by `owner` + */ function balanceOf(address owner) external view returns (uint); + /** + * @notice Get the current allowance from `owner` for `spender` + * @param owner The address of the account which owns the tokens + * @param spender The address of the account which may transfer tokens + * @return The number of tokens allowed to be spent + */ function allowance(address owner, address spender) external view returns (uint); + /** + * @notice Get various information about an account in this market + * @param account The address of the account to query + * @return (possible error, token balance, borrow balance, exchange rate mantissa) + */ function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint); + /** + * @notice Get the current borrow interest rate per block + * @return The borrow interest rate per block, scaled by 1e18 + */ function borrowRatePerBlock() external view returns (uint); + /** + * @notice Get the current supply interest rate per block + * @return The supply interest rate per block, scaled by 1e18 + */ function supplyRatePerBlock() external view returns (uint); + /** + * @notice Get the amount of tokens held by this contract + * @return The number of tokens held by this contract + */ function getCash() external view returns (uint); + /** + * @notice Get the borrow balance of account based on stored data + * @param account The address whose balance should be calculated + * @return The calculated balance + */ function borrowBalanceStored(address account) external view returns (uint); + /** + * @notice Get the current exchange rate from the underlying to the VToken + * @return The current exchange rate from the underlying to the VToken, scaled by 1e18 + */ function exchangeRateStored() external view returns (uint); } From 14bca613f53afb0f7d8fc6506f1fd4d46333b73a Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 7 Aug 2025 16:03:41 +0300 Subject: [PATCH 4/8] fixup! refactor: extract interfaces --- contracts/Comptroller/ComptrollerInterface.sol | 14 -------------- contracts/Comptroller/ComptrollerStorage.sol | 4 ++-- contracts/Comptroller/Diamond/facets/FacetBase.sol | 3 +-- .../Comptroller/Diamond/facets/MarketFacet.sol | 2 +- .../Comptroller/Diamond/facets/PolicyFacet.sol | 2 +- .../Comptroller/Diamond/facets/SetterFacet.sol | 10 +++++----- .../Comptroller/Diamond/interfaces/IFacetBase.sol | 12 +++++++++++- .../Diamond/interfaces/IMarketFacet.sol | 3 ++- .../Diamond/interfaces/IPolicyFacet.sol | 3 ++- .../Diamond/interfaces/IRewardFacet.sol | 3 +-- .../Diamond/interfaces/ISetterFacet.sol | 8 ++++---- contracts/Comptroller/interfaces/IComptroller.sol | 4 ---- .../Comptroller/interfaces/IComptrollerStorage.sol | 4 ++-- contracts/Lens/ComptrollerLens.sol | 6 ++---- contracts/Lens/VenusLens.sol | 2 +- contracts/Lens/interfaces/IComptrollerLens.sol | 1 + contracts/Tokens/VAI/{ => interfaces}/IVAI.sol | 0 .../IVAIController.sol} | 9 +++++++-- 18 files changed, 43 insertions(+), 47 deletions(-) delete mode 100644 contracts/Comptroller/ComptrollerInterface.sol rename contracts/Tokens/VAI/{ => interfaces}/IVAI.sol (100%) rename contracts/Tokens/VAI/{VAIControllerInterface.sol => interfaces/IVAIController.sol} (77%) diff --git a/contracts/Comptroller/ComptrollerInterface.sol b/contracts/Comptroller/ComptrollerInterface.sol deleted file mode 100644 index d7baef4cb..000000000 --- a/contracts/Comptroller/ComptrollerInterface.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity 0.8.25; - -enum Action { - MINT, - REDEEM, - BORROW, - REPAY, - SEIZE, - LIQUIDATE, - TRANSFER, - ENTER_MARKET, - EXIT_MARKET -} diff --git a/contracts/Comptroller/ComptrollerStorage.sol b/contracts/Comptroller/ComptrollerStorage.sol index db7b0fb3b..90ca2ff24 100644 --- a/contracts/Comptroller/ComptrollerStorage.sol +++ b/contracts/Comptroller/ComptrollerStorage.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; -import { VAIControllerInterface } from "../Tokens/VAI/VAIControllerInterface.sol"; +import { IVAIController } from "../Tokens/VAI/interfaces/IVAIController.sol"; import { IComptrollerLens } from "../Lens/interfaces/IComptrollerLens.sol"; import { IPrime } from "../Tokens/Prime/IPrime.sol"; @@ -118,7 +118,7 @@ contract ComptrollerStorage is IComptrollerStorage, UnitrollerAdminStorage { mapping(address => uint256) public venusAccrued; /// @notice The Address of VAIController - VAIControllerInterface public vaiController; + IVAIController public vaiController; /// @notice The minted VAI amount to each user mapping(address => uint256) public mintedVAIs; diff --git a/contracts/Comptroller/Diamond/facets/FacetBase.sol b/contracts/Comptroller/Diamond/facets/FacetBase.sol index ce2612a65..2371544e2 100644 --- a/contracts/Comptroller/Diamond/facets/FacetBase.sol +++ b/contracts/Comptroller/Diamond/facets/FacetBase.sol @@ -9,9 +9,8 @@ import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; import { ComptrollerErrorReporter } from "../../../Utils/ErrorReporter.sol"; import { ExponentialNoError } from "../../../Utils/ExponentialNoError.sol"; import { IVAIVault } from "../../../VAIVault/IVAIVault.sol"; -import { Action } from "../../../Comptroller/ComptrollerInterface.sol"; import { ComptrollerStorage } from "../../../Comptroller/ComptrollerStorage.sol"; -import { IFacetBase } from "../interfaces/IFacetBase.sol"; +import { IFacetBase, Action } from "../interfaces/IFacetBase.sol"; /** * @title FacetBase diff --git a/contracts/Comptroller/Diamond/facets/MarketFacet.sol b/contracts/Comptroller/Diamond/facets/MarketFacet.sol index 9ca2648fb..5c874652f 100644 --- a/contracts/Comptroller/Diamond/facets/MarketFacet.sol +++ b/contracts/Comptroller/Diamond/facets/MarketFacet.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; -import { Action } from "../../ComptrollerInterface.sol"; +import { Action } from "../interfaces/IFacetBase.sol"; import { IMarketFacet } from "../interfaces/IMarketFacet.sol"; import { FacetBase } from "./FacetBase.sol"; diff --git a/contracts/Comptroller/Diamond/facets/PolicyFacet.sol b/contracts/Comptroller/Diamond/facets/PolicyFacet.sol index 04ac8b87a..5f378b888 100644 --- a/contracts/Comptroller/Diamond/facets/PolicyFacet.sol +++ b/contracts/Comptroller/Diamond/facets/PolicyFacet.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; -import { Action } from "../../ComptrollerInterface.sol"; +import { Action } from "../interfaces/IFacetBase.sol"; import { IPolicyFacet } from "../interfaces/IPolicyFacet.sol"; import { XVSRewardsHelper } from "./XVSRewardsHelper.sol"; diff --git a/contracts/Comptroller/Diamond/facets/SetterFacet.sol b/contracts/Comptroller/Diamond/facets/SetterFacet.sol index d97928834..bc1c89842 100644 --- a/contracts/Comptroller/Diamond/facets/SetterFacet.sol +++ b/contracts/Comptroller/Diamond/facets/SetterFacet.sol @@ -5,9 +5,9 @@ pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; -import { Action } from "../../ComptrollerInterface.sol"; +import { Action } from "../interfaces/IFacetBase.sol"; import { IComptrollerLens } from "../../../Lens/interfaces/IComptrollerLens.sol"; -import { VAIControllerInterface } from "../../../Tokens/VAI/VAIControllerInterface.sol"; +import { IVAIController } from "../../../Tokens/VAI/interfaces/IVAIController.sol"; import { IPrime } from "../../../Tokens/Prime/IPrime.sol"; import { ISetterFacet } from "../interfaces/ISetterFacet.sol"; import { FacetBase } from "./FacetBase.sol"; @@ -39,7 +39,7 @@ contract SetterFacet is ISetterFacet, FacetBase { event NewBorrowCap(IVToken indexed vToken, uint256 newBorrowCap); /// @notice Emitted when VAIController is changed - event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController); + event NewVAIController(IVAIController oldVAIController, IVAIController newVAIController); /// @notice Emitted when VAI mint rate is changed by admin event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate); @@ -353,13 +353,13 @@ contract SetterFacet is ISetterFacet, FacetBase { * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function _setVAIController( - VAIControllerInterface vaiController_ + IVAIController vaiController_ ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) { // Check caller is admin ensureAdmin(); ensureNonzeroAddress(address(vaiController_)); - VAIControllerInterface oldVaiController = vaiController; + IVAIController oldVaiController = vaiController; vaiController = vaiController_; emit NewVAIController(oldVaiController, vaiController_); diff --git a/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol b/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol index 0a75f2a00..472964ed4 100644 --- a/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol +++ b/contracts/Comptroller/Diamond/interfaces/IFacetBase.sol @@ -2,7 +2,17 @@ pragma solidity 0.8.25; -import { Action } from "../../ComptrollerInterface.sol"; +enum Action { + MINT, + REDEEM, + BORROW, + REPAY, + SEIZE, + LIQUIDATE, + TRANSFER, + ENTER_MARKET, + EXIT_MARKET +} interface IFacetBase { /** diff --git a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol index 7cd98d3c0..60e214a3f 100644 --- a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; +import { IFacetBase } from "./IFacetBase.sol"; /** * @title IMarketFacet @@ -11,7 +12,7 @@ import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; * @notice This interface defines functions for managing markets, including listing, entering/exiting markets, * liquidation calculations, and delegate management */ -interface IMarketFacet { +interface IMarketFacet is IFacetBase { /** * @notice Indicator that this is a Comptroller contract (for inspection) * @return True indicating this is a Comptroller contract diff --git a/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol b/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol index e8f89cc25..4a98382d0 100644 --- a/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; +import { IFacetBase } from "./IFacetBase.sol"; /** * @title IPolicyFacet @@ -10,7 +11,7 @@ import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; * @dev Interface for the PolicyFacet which contains all the hooks used while transferring assets * @notice This interface defines all the external pre-hook functions related to vToken operations */ -interface IPolicyFacet { +interface IPolicyFacet is IFacetBase { /** * @notice Checks if the account should be allowed to mint tokens in the given market * @param vToken The market to verify the mint against diff --git a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol index 12b34ac8a..896cd7fe9 100644 --- a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol @@ -3,8 +3,7 @@ pragma solidity 0.8.25; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; -import { Action } from "../../ComptrollerInterface.sol"; -import { IFacetBase } from "./IFacetBase.sol"; +import { IFacetBase, Action } from "./IFacetBase.sol"; /** * @title IRewardFacet diff --git a/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol b/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol index f1540d824..36f76ec5f 100644 --- a/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol @@ -4,8 +4,8 @@ pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; import { IVToken } from "../../../Tokens/VTokens/interfaces/IVToken.sol"; -import { Action } from "../../ComptrollerInterface.sol"; -import { VAIControllerInterface } from "../../../Tokens/VAI/VAIControllerInterface.sol"; +import { IFacetBase, Action } from "./IFacetBase.sol"; +import { IVAIController } from "../../../Tokens/VAI/interfaces/IVAIController.sol"; import { IComptrollerLens } from "../../../Lens/interfaces/IComptrollerLens.sol"; import { IPrime } from "../../../Tokens/Prime/IPrime.sol"; @@ -15,7 +15,7 @@ import { IPrime } from "../../../Tokens/Prime/IPrime.sol"; * @dev This interface contains all the setters for the states * @notice This interface contract contains all the configurational setter functions */ -interface ISetterFacet { +interface ISetterFacet is IFacetBase { /** * @notice Alias to _setPriceOracle to support the Isolated Lending Comptroller Interface * @param newOracle The new price oracle to set @@ -166,7 +166,7 @@ interface ISetterFacet { * @dev Admin function to set a new VAI controller * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256); + function _setVAIController(IVAIController vaiController_) external returns (uint256); /** * @notice Set the VAI mint rate diff --git a/contracts/Comptroller/interfaces/IComptroller.sol b/contracts/Comptroller/interfaces/IComptroller.sol index 86eded1e0..3d5893c26 100644 --- a/contracts/Comptroller/interfaces/IComptroller.sol +++ b/contracts/Comptroller/interfaces/IComptroller.sol @@ -1,10 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; - -import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; -import { VAIControllerInterface } from "../../Tokens/VAI/VAIControllerInterface.sol"; import { IFacetBase } from "../Diamond/interfaces/IFacetBase.sol"; import { IMarketFacet } from "../Diamond/interfaces/IMarketFacet.sol"; import { IPolicyFacet } from "../Diamond/interfaces/IPolicyFacet.sol"; diff --git a/contracts/Comptroller/interfaces/IComptrollerStorage.sol b/contracts/Comptroller/interfaces/IComptrollerStorage.sol index d063c195d..382b5219e 100644 --- a/contracts/Comptroller/interfaces/IComptrollerStorage.sol +++ b/contracts/Comptroller/interfaces/IComptrollerStorage.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.25; import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; -import { VAIControllerInterface } from "../../Tokens/VAI/VAIControllerInterface.sol"; +import { IVAIController } from "../../Tokens/VAI/interfaces/IVAIController.sol"; import { IPrime } from "../../Tokens/Prime/IPrime.sol"; import { IComptrollerLens } from "../../Lens/interfaces/IComptrollerLens.sol"; @@ -66,7 +66,7 @@ interface IComptrollerStorage is IUnitrollerAdminStorage { function venusAccrued(address) external view returns (uint256); /// @notice The Address of VAIController - function vaiController() external view returns (VAIControllerInterface); + function vaiController() external view returns (IVAIController); /// @notice The minted VAI amount to each user function mintedVAIs(address) external view returns (uint256); diff --git a/contracts/Lens/ComptrollerLens.sol b/contracts/Lens/ComptrollerLens.sol index 67c11b8e5..64497f16e 100644 --- a/contracts/Lens/ComptrollerLens.sol +++ b/contracts/Lens/ComptrollerLens.sol @@ -1,14 +1,12 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol"; - import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; import { ExponentialNoError } from "../Utils/ExponentialNoError.sol"; import { ComptrollerErrorReporter } from "../Utils/ErrorReporter.sol"; import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; import { IComptrollerLens } from "./interfaces/IComptrollerLens.sol"; -import { VAIControllerInterface } from "../Tokens/VAI/VAIControllerInterface.sol"; +import { IVAIController } from "../Tokens/VAI/interfaces/IVAIController.sol"; /** * @title ComptrollerLens Contract @@ -201,7 +199,7 @@ contract ComptrollerLens is IComptrollerLens, ComptrollerErrorReporter, Exponent } } - VAIControllerInterface vaiController = IComptroller(comptroller).vaiController(); + IVAIController vaiController = IComptroller(comptroller).vaiController(); if (address(vaiController) != address(0)) { vars.sumBorrowPlusEffects = add_(vars.sumBorrowPlusEffects, vaiController.getVAIRepayAmount(account)); diff --git a/contracts/Lens/VenusLens.sol b/contracts/Lens/VenusLens.sol index 6ae55180d..143a512dd 100644 --- a/contracts/Lens/VenusLens.sol +++ b/contracts/Lens/VenusLens.sol @@ -6,7 +6,7 @@ import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interf import { ExponentialNoError } from "../Utils/ExponentialNoError.sol"; import { IVBep20 } from "../Tokens/VTokens/interfaces/IVBep20.sol"; import { IVToken } from "../Tokens/VTokens/interfaces/IVToken.sol"; -import { Action } from "../Comptroller/ComptrollerInterface.sol"; +import { Action } from "../Comptroller/Diamond/interfaces/IFacetBase.sol"; import { IComptroller } from "../Comptroller/interfaces/IComptroller.sol"; import { IXVS } from "../Tokens/XVS/IXVS.sol"; diff --git a/contracts/Lens/interfaces/IComptrollerLens.sol b/contracts/Lens/interfaces/IComptrollerLens.sol index 84996ee92..dbf16aaa2 100644 --- a/contracts/Lens/interfaces/IComptrollerLens.sol +++ b/contracts/Lens/interfaces/IComptrollerLens.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; diff --git a/contracts/Tokens/VAI/IVAI.sol b/contracts/Tokens/VAI/interfaces/IVAI.sol similarity index 100% rename from contracts/Tokens/VAI/IVAI.sol rename to contracts/Tokens/VAI/interfaces/IVAI.sol diff --git a/contracts/Tokens/VAI/VAIControllerInterface.sol b/contracts/Tokens/VAI/interfaces/IVAIController.sol similarity index 77% rename from contracts/Tokens/VAI/VAIControllerInterface.sol rename to contracts/Tokens/VAI/interfaces/IVAIController.sol index 8997e49b9..4dbfcc803 100644 --- a/contracts/Tokens/VAI/VAIControllerInterface.sol +++ b/contracts/Tokens/VAI/interfaces/IVAIController.sol @@ -1,15 +1,20 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.25; -import { IVToken } from "../VTokens/interfaces/IVToken.sol"; +import { IVToken } from "../../VTokens/interfaces/IVToken.sol"; -interface VAIControllerInterface { +interface IVAIController { function mintVAI(uint256 mintVAIAmount) external returns (uint256); function repayVAI(uint256 amount) external returns (uint256, uint256); function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256); + /** + * @notice Accrue interest on outstanding minted VAI + */ + function accrueVAIInterest() external; + function liquidateVAI( address borrower, uint256 repayAmount, From b1cbdadf4823e0d1007ae88db55da943a1617c4e Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 7 Aug 2025 16:04:08 +0300 Subject: [PATCH 5/8] fixup! docs: add missing natspec to interfaces --- contracts/VAIVault/IVAIVault.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/VAIVault/IVAIVault.sol b/contracts/VAIVault/IVAIVault.sol index 83ce747d2..80f2e6d95 100644 --- a/contracts/VAIVault/IVAIVault.sol +++ b/contracts/VAIVault/IVAIVault.sol @@ -2,5 +2,9 @@ pragma solidity 0.8.25; interface IVAIVault { + /** + * @notice Updates pending rewards for all users + * @dev This function must be called before any operation that changes user balances or reward parameters + */ function updatePendingRewards() external; } From da1bbf350080d16893fe7ec443a3eff3bff2963e Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 7 Aug 2025 16:05:19 +0300 Subject: [PATCH 6/8] fixup! refactor: extract interfaces --- contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol | 5 ++++- contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol | 7 ++++++- contracts/Tokens/VAI/VAIController.sol | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol b/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol index e2c18e403..f818cf014 100644 --- a/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol +++ b/contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol @@ -119,7 +119,10 @@ contract XVSRewardsHelper is FacetBase { } // Calculate change in the cumulative sum of the XVS per borrowed unit accrued Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) }); - uint256 borrowerDelta = mul_(div_(IVToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex); + uint256 borrowerDelta = mul_( + div_(IVToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), + deltaIndex + ); venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta); emit DistributedBorrowerVenus(IVToken(vToken), borrower, borrowerDelta, borrowIndex); } diff --git a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol index 896cd7fe9..3147afd83 100644 --- a/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol @@ -32,7 +32,12 @@ interface IRewardFacet is IFacetBase { * @param borrowers Whether or not to claim XVS earned by borrowing * @param suppliers Whether or not to claim XVS earned by supplying */ - function claimVenus(address[] calldata holders, IVToken[] calldata vTokens, bool borrowers, bool suppliers) external; + function claimVenus( + address[] calldata holders, + IVToken[] calldata vTokens, + bool borrowers, + bool suppliers + ) external; /** * @notice Claim all the xvs accrued by holder in all markets, a shorthand for `claimVenus` with collateral set to `true` diff --git a/contracts/Tokens/VAI/VAIController.sol b/contracts/Tokens/VAI/VAIController.sol index 4ad68c65c..93355c392 100644 --- a/contracts/Tokens/VAI/VAIController.sol +++ b/contracts/Tokens/VAI/VAIController.sol @@ -7,8 +7,8 @@ import { VAIControllerErrorReporter } from "../../Utils/ErrorReporter.sol"; import { Exponential } from "../../Utils/Exponential.sol"; import { IComptroller } from "../../Comptroller/interfaces/IComptroller.sol"; import { VAIUnitroller, VAIControllerStorageG4 } from "./VAIUnitroller.sol"; -import { VAIControllerInterface } from "./VAIControllerInterface.sol"; -import { IVAI } from "./IVAI.sol"; +import { IVAIController } from "./interfaces/IVAIController.sol"; +import { IVAI } from "./interfaces/IVAI.sol"; import { IPrime } from "../Prime/IPrime.sol"; import { IVToken } from "../VTokens/interfaces/IVToken.sol"; @@ -17,7 +17,7 @@ import { IVToken } from "../VTokens/interfaces/IVToken.sol"; * @author Venus * @notice This is the implementation contract for the VAIUnitroller proxy */ -contract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAIControllerErrorReporter, Exponential { +contract VAIController is IVAIController, VAIControllerStorageG4, VAIControllerErrorReporter, Exponential { /// @notice Initial index used in interest computations uint256 public constant INITIAL_VAI_MINT_INDEX = 1e18; From e6e58b8ad574d84d58dcfb5d79bdfa8d61809f9f Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 7 Aug 2025 16:41:54 +0300 Subject: [PATCH 7/8] fixup! refactor: extract interfaces --- contracts/Lens/SnapshotLens.sol | 4 +--- contracts/Lens/VenusLens.sol | 12 +++--------- contracts/Tokens/VAI/VAIController.sol | 2 +- contracts/Tokens/VTokens/VBep20.sol | 6 +----- contracts/Tokens/VTokens/VBep20Delegator.sol | 6 +----- contracts/Tokens/VTokens/interfaces/IVBNB.sol | 2 +- contracts/Tokens/VTokens/interfaces/IVBep20.sol | 6 +----- contracts/Tokens/VTokens/interfaces/IVToken.sol | 1 - .../Tokens/VTokens/interfaces/IVTokenStorage.sol | 1 - contracts/test/VBep20MockDelegate.sol | 6 +----- 10 files changed, 10 insertions(+), 36 deletions(-) diff --git a/contracts/Lens/SnapshotLens.sol b/contracts/Lens/SnapshotLens.sol index d0017d0e8..6ce1024bd 100644 --- a/contracts/Lens/SnapshotLens.sol +++ b/contracts/Lens/SnapshotLens.sol @@ -90,9 +90,7 @@ contract SnapshotLens is ExponentialNoError { vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa }); // Get the normalized price of the asset - vars.oraclePriceMantissa = IComptroller(comptrollerAddress).oracle().getUnderlyingPrice( - address(vToken) - ); + vars.oraclePriceMantissa = IComptroller(comptrollerAddress).oracle().getUnderlyingPrice(address(vToken)); vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa }); // Pre-compute a conversion factor from tokens -> bnb (normalized price value) diff --git a/contracts/Lens/VenusLens.sol b/contracts/Lens/VenusLens.sol index 143a512dd..77634d048 100644 --- a/contracts/Lens/VenusLens.sol +++ b/contracts/Lens/VenusLens.sol @@ -117,7 +117,7 @@ contract VenusLens is ExponentialNoError { uint exchangeRateCurrent = vToken.exchangeRateCurrent(); address comptrollerAddress = address(vToken.comptroller()); IComptroller comptroller = IComptroller(comptrollerAddress); - (bool isListed, uint collateralFactorMantissa,) = comptroller.markets(address(vToken)); + (bool isListed, uint collateralFactorMantissa, ) = comptroller.markets(address(vToken)); address underlyingAssetAddress; uint underlyingDecimals; @@ -317,10 +317,7 @@ contract VenusLens is ExponentialNoError { * @param account Address of the account to query * @return Struct with markets user has entered, liquidity, and shortfall of the account */ - function getAccountLimits( - IComptroller comptroller, - address account - ) public view returns (AccountLimits memory) { + function getAccountLimits(IComptroller comptroller, address account) public view returns (AccountLimits memory) { (uint errorCode, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(account); require(errorCode == 0, "account liquidity error"); @@ -504,10 +501,7 @@ contract VenusLens is ExponentialNoError { * @param comptroller Address of the comptroller * @return Reward object contraining the totalRewards and pending rewards for each market */ - function pendingRewards( - address holder, - IComptroller comptroller - ) external view returns (RewardSummary memory) { + function pendingRewards(address holder, IComptroller comptroller) external view returns (RewardSummary memory) { IVToken[] memory vTokens = comptroller.getAllMarkets(); ClaimVenusLocalVariables memory vars; RewardSummary memory rewardSummary; diff --git a/contracts/Tokens/VAI/VAIController.sol b/contracts/Tokens/VAI/VAIController.sol index 93355c392..d84a2e992 100644 --- a/contracts/Tokens/VAI/VAIController.sol +++ b/contracts/Tokens/VAI/VAIController.sol @@ -490,7 +490,7 @@ contract VAIController is IVAIController, VAIControllerStorageG4, VAIControllerE return (uint256(Error.MATH_ERROR), 0); } - (, uint256 collateralFactorMantissa,) = comptroller.markets(address(enteredMarkets[i])); + (, uint256 collateralFactorMantissa, ) = comptroller.markets(address(enteredMarkets[i])); (vars.mErr, vars.marketSupply) = mulUInt(vars.marketSupply, collateralFactorMantissa); if (vars.mErr != MathError.NO_ERROR) { return (uint256(Error.MATH_ERROR), 0); diff --git a/contracts/Tokens/VTokens/VBep20.sol b/contracts/Tokens/VTokens/VBep20.sol index 72534a64a..f0275b3bd 100644 --- a/contracts/Tokens/VTokens/VBep20.sol +++ b/contracts/Tokens/VTokens/VBep20.sol @@ -162,11 +162,7 @@ contract VBep20 is VToken, IVBep20 { * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ // @custom:event Emit LiquidateBorrow event on success - function liquidateBorrow( - address borrower, - uint repayAmount, - IVToken vTokenCollateral - ) external returns (uint) { + function liquidateBorrow(address borrower, uint repayAmount, IVToken vTokenCollateral) external returns (uint) { (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral); return err; } diff --git a/contracts/Tokens/VTokens/VBep20Delegator.sol b/contracts/Tokens/VTokens/VBep20Delegator.sol index e53b5dbc7..c7d5ca0f9 100644 --- a/contracts/Tokens/VTokens/VBep20Delegator.sol +++ b/contracts/Tokens/VTokens/VBep20Delegator.sol @@ -174,11 +174,7 @@ contract VBep20Delegator is IVDelegator, VTokenStorage { * @param repayAmount The amount of the underlying borrowed asset to repay * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details). */ - function liquidateBorrow( - address borrower, - uint repayAmount, - IVToken vTokenCollateral - ) external returns (uint) { + function liquidateBorrow(address borrower, uint repayAmount, IVToken vTokenCollateral) external returns (uint) { bytes memory data = delegateToImplementation( abi.encodeWithSignature("liquidateBorrow(address,uint256,address)", borrower, repayAmount, vTokenCollateral) ); diff --git a/contracts/Tokens/VTokens/interfaces/IVBNB.sol b/contracts/Tokens/VTokens/interfaces/IVBNB.sol index 85b4bbb67..8ccba8795 100644 --- a/contracts/Tokens/VTokens/interfaces/IVBNB.sol +++ b/contracts/Tokens/VTokens/interfaces/IVBNB.sol @@ -71,4 +71,4 @@ interface IVBNB is IVToken { * @custom:event Emit LiquidateBorrow event on success */ function liquidateBorrow(address borrower, IVToken vTokenCollateral) external payable; -} \ No newline at end of file +} diff --git a/contracts/Tokens/VTokens/interfaces/IVBep20.sol b/contracts/Tokens/VTokens/interfaces/IVBep20.sol index a6538401e..1c4e0a8c1 100644 --- a/contracts/Tokens/VTokens/interfaces/IVBep20.sol +++ b/contracts/Tokens/VTokens/interfaces/IVBep20.sol @@ -71,11 +71,7 @@ interface IVBep20 is IVToken { * @param vTokenCollateral The address of the vToken collateral * @return uint Returns the amount successfully liquidated */ - function liquidateBorrow( - address borrower, - uint repayAmount, - IVToken vTokenCollateral - ) external returns (uint); + function liquidateBorrow(address borrower, uint repayAmount, IVToken vTokenCollateral) external returns (uint); /*** Admin Functions ***/ diff --git a/contracts/Tokens/VTokens/interfaces/IVToken.sol b/contracts/Tokens/VTokens/interfaces/IVToken.sol index 4b0980dc2..f8add6389 100644 --- a/contracts/Tokens/VTokens/interfaces/IVToken.sol +++ b/contracts/Tokens/VTokens/interfaces/IVToken.sol @@ -81,7 +81,6 @@ interface IVToken is IVTokenStorage { /// @notice Emitted when access control address is changed by admin event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress); - /** * @notice Indicator that this is a vToken contract (for inspection) */ diff --git a/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol b/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol index 66068c699..c9fdd0477 100644 --- a/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol +++ b/contracts/Tokens/VTokens/interfaces/IVTokenStorage.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.25; import { IComptroller } from "../../../Comptroller/interfaces/IComptroller.sol"; import { InterestRateModelV8 } from "../../../InterestRateModels/InterestRateModelV8.sol"; - interface IVTokenStorage { /** * @notice Container for borrow balance information diff --git a/contracts/test/VBep20MockDelegate.sol b/contracts/test/VBep20MockDelegate.sol index 850a57cd6..b530282c2 100644 --- a/contracts/test/VBep20MockDelegate.sol +++ b/contracts/test/VBep20MockDelegate.sol @@ -163,11 +163,7 @@ contract VBep20MockDelegate is VToken, IVBep20, IVDelegate { * @param vTokenCollateral The market in which to seize collateral from the borrower * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function liquidateBorrow( - address borrower, - uint repayAmount, - IVToken vTokenCollateral - ) external returns (uint) { + function liquidateBorrow(address borrower, uint repayAmount, IVToken vTokenCollateral) external returns (uint) { (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral); return err; } From 3b998cac131a08f0ed4e4cc18d715981661ac5da Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Thu, 7 Aug 2025 19:40:35 +0300 Subject: [PATCH 8/8] fixup! docs: add missing natspec to interfaces --- .../Lens/interfaces/IComptrollerLens.sol | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/contracts/Lens/interfaces/IComptrollerLens.sol b/contracts/Lens/interfaces/IComptrollerLens.sol index dbf16aaa2..946da6ab3 100644 --- a/contracts/Lens/interfaces/IComptrollerLens.sol +++ b/contracts/Lens/interfaces/IComptrollerLens.sol @@ -4,6 +4,14 @@ pragma solidity 0.8.25; import { IVToken } from "../../Tokens/VTokens/interfaces/IVToken.sol"; interface IComptrollerLens { + /** + * @notice Computes the number of collateral tokens to be seized in a liquidation event + * @param comptroller Address of comptroller + * @param vTokenBorrowed Address of the borrowed vToken + * @param vTokenCollateral Address of collateral for the borrow + * @param actualRepayAmount Repayment amount i.e amount to be repaid of total borrowed amount + * @return A tuple of error code, and tokens to seize + */ function liquidateCalculateSeizeTokens( address comptroller, address vTokenBorrowed, @@ -11,12 +19,28 @@ interface IComptrollerLens { uint actualRepayAmount ) external view returns (uint, uint); + /** + * @notice Computes the number of VAI tokens to be seized in a liquidation event + * @param comptroller Address of comptroller + * @param vTokenCollateral Address of collateral for vToken + * @param actualRepayAmount Repayment amount i.e amount to be repaid of the total borrowed amount + * @return A tuple of error code, and tokens to seize + */ function liquidateVAICalculateSeizeTokens( address comptroller, address vTokenCollateral, uint actualRepayAmount ) external view returns (uint, uint); + /** + * @notice Determine the current account liquidity wrt collateral requirements + * @param comptroller Address of comptroller + * @param account The account to determine liquidity for + * @param vTokenModify The market to hypothetically modify + * @param redeemTokens The number of tokens to hypothetically redeem + * @param borrowAmount The amount of underlying to hypothetically borrow + * @return A tuple of error code, liquidity, and shortfall + */ function getHypotheticalAccountLiquidity( address comptroller, address account,