From 251e9b7493f920ebc9179e7739f3d8316b8eab3e Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Fri, 4 Nov 2022 19:45:38 +0300 Subject: [PATCH 1/4] refactor!: consolidate VToken contracts Problem: We decided to not use vBNB for isolated lending because it's not upgradeable, error-prone and causes confusion. We still support a wrapped version (WBNB). With vBNB removed, there's no point in keeping separate VBep20. Since we use proxies, there's no need to keep delegator contracts either. With these changes, the inheritance scheme can be simplified greatly. Solution: Get rid of VBep20, VBep20Immutable in favor of VToken; use WithAdminUpgradeable mixin in VToken. BREAKING CHANGES: VBep20, VBep20Immutable no longer exist --- contracts/VBep20.sol | 227 --------------------------- contracts/VBep20Immutable.sol | 59 ------- contracts/VToken.sol | 271 ++++++++++++++++++++------------- contracts/VTokenInterfaces.sol | 195 +++++++----------------- 4 files changed, 220 insertions(+), 532 deletions(-) delete mode 100644 contracts/VBep20.sol delete mode 100644 contracts/VBep20Immutable.sol diff --git a/contracts/VBep20.sol b/contracts/VBep20.sol deleted file mode 100644 index ed6687ded..000000000 --- a/contracts/VBep20.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; - -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "./VToken.sol"; -import "./Governance/AccessControlManager.sol"; - -/** - * @title Venus VBep20 Contract - * @notice VTokens which wrap an EIP-20 underlying - * @author Venus dev team - */ -contract VBep20 is VToken, VBep20Interface { - using SafeERC20 for IERC20; - - /** - * @notice Initialize the new money market - * @param underlying_ The address of the underlying asset - * @param comptroller_ The address of the Comptroller - * @param interestRateModel_ The address of the interest rate model - * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 - * @param name_ ERC-20 name of this token - * @param symbol_ ERC-20 symbol of this token - * @param decimals_ ERC-20 decimal precision of this token - */ - function initialize( - address underlying_, - ComptrollerInterface comptroller_, - InterestRateModel interestRateModel_, - uint256 initialExchangeRateMantissa_, - string memory name_, - string memory symbol_, - uint8 decimals_, - AccessControlManager accessControlManager_, - RiskManagementInit memory riskManagement - ) public { - // VToken initialize does the bulk of the work - super.initialize( - comptroller_, - interestRateModel_, - initialExchangeRateMantissa_, - name_, - symbol_, - decimals_, - accessControlManager_, - riskManagement - ); - - // Set underlying and sanity check it - underlying = underlying_; - IERC20(underlying).totalSupply(); - } - - /*** 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 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function mint(uint256 mintAmount) external override returns (uint256) { - mintInternal(mintAmount); - return NO_ERROR; - } - - /** - * @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 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function redeem(uint256 redeemTokens) external override returns (uint256) { - redeemInternal(redeemTokens); - return NO_ERROR; - } - - /** - * @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 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function redeemUnderlying(uint256 redeemAmount) - external - override - returns (uint256) - { - redeemUnderlyingInternal(redeemAmount); - return NO_ERROR; - } - - /** - * @notice Sender borrows assets from the protocol to their own address - * @param borrowAmount The amount of the underlying asset to borrow - * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function borrow(uint256 borrowAmount) external override returns (uint256) { - borrowInternal(borrowAmount); - return NO_ERROR; - } - - /** - * @notice Sender repays their own borrow - * @param repayAmount The amount to repay, or -1 for the full outstanding amount - * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function repayBorrow(uint256 repayAmount) - external - override - returns (uint256) - { - repayBorrowInternal(repayAmount); - return NO_ERROR; - } - - /** - * @notice Sender repays a borrow belonging to borrower - * @param borrower the account with the debt being payed off - * @param repayAmount The amount to repay, or -1 for the full outstanding amount - * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function repayBorrowBehalf(address borrower, uint256 repayAmount) - external - override - returns (uint256) - { - repayBorrowBehalfInternal(borrower, repayAmount); - return NO_ERROR; - } - - /** - * @notice The sender liquidates the borrowers collateral. - * The collateral seized is transferred to the liquidator. - * @param borrower The borrower of this vToken to be liquidated - * @param repayAmount The amount of the underlying borrowed asset to repay - * @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, - uint256 repayAmount, - VTokenInterface vTokenCollateral - ) external override returns (uint256) { - liquidateBorrowInternal( - msg.sender, - borrower, - repayAmount, - vTokenCollateral, - false - ); - return NO_ERROR; - } - - /** - * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock) - * @param token The address of the ERC-20 token to sweep - */ - function sweepToken(IERC20 token) external override { - require( - msg.sender == admin, - "VBep20::sweepToken: only admin can sweep tokens" - ); - require( - address(token) != underlying, - "VBep20::sweepToken: can not sweep underlying token" - ); - uint256 balance = token.balanceOf(address(this)); - token.safeTransfer(admin, balance); - } - - /** - * @notice The sender adds to reserves. - * @param addAmount The amount fo underlying token to add as reserves - * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function _addReserves(uint256 addAmount) - external - override - returns (uint256) - { - return _addReservesInternal(addAmount); - } - - /*** Safe Token ***/ - - /** - * @notice Gets balance of this contract in terms of the underlying - * @dev This excludes the value of the current message, if any - * @return The quantity of underlying tokens owned by this contract - */ - function getCashPrior() internal view virtual override returns (uint256) { - IERC20 token = IERC20(underlying); - return token.balanceOf(address(this)); - } - - /** - * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees. - * This function returns the actual amount received, - * which may be less than `amount` if there is a fee attached to the transfer. - */ - function doTransferIn(address from, uint256 amount) - internal - virtual - override - returns (uint256) - { - IERC20 token = IERC20(underlying); - uint256 balanceBefore = token.balanceOf(address(this)); - token.safeTransferFrom(from, address(this), amount); - uint256 balanceAfter = token.balanceOf(address(this)); - // Return the amount that was *actually* transferred - return balanceAfter - balanceBefore; - } - - /** - * @dev Just a regular ERC-20 transfer, reverts on failure - */ - function doTransferOut(address payable to, uint256 amount) - internal - virtual - override - { - IERC20 token = IERC20(underlying); - token.safeTransfer(to, amount); - } -} diff --git a/contracts/VBep20Immutable.sol b/contracts/VBep20Immutable.sol deleted file mode 100644 index e2fdbf458..000000000 --- a/contracts/VBep20Immutable.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -pragma solidity ^0.8.10; - -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; - -import "./VBep20.sol"; -import "./Governance/AccessControlManager.sol"; - -/** - * @title Compound's VBep20Immutable Contract - * @notice VTokens which wrap an EIP-20 underlying and are immutable - * @author Compound - */ -contract VBep20Immutable is VBep20, Initializable { - /** - * @notice Construct a new money market - * @param underlying_ The address of the underlying asset - * @param comptroller_ The address of the Comptroller - * @param interestRateModel_ The address of the interest rate model - * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 - * @param name_ ERC-20 name of this token - * @param symbol_ ERC-20 symbol of this token - * @param decimals_ ERC-20 decimal precision of this token - * @param admin_ Address of the administrator of this token - * @param riskManagement Addresses of risk fund contracts - */ - - function initializeVToken( - address underlying_, - ComptrollerInterface comptroller_, - InterestRateModel interestRateModel_, - uint256 initialExchangeRateMantissa_, - string memory name_, - string memory symbol_, - uint8 decimals_, - address payable admin_, - AccessControlManager accessControlManager_, - RiskManagementInit memory riskManagement - ) public initializer { - // Creator of the contract is admin during initialization - admin = payable(msg.sender); - - // Initialize the market - initialize( - underlying_, - comptroller_, - interestRateModel_, - initialExchangeRateMantissa_, - name_, - symbol_, - decimals_, - accessControlManager_, - riskManagement - ); - - // Set the proper admin now that initialization is done - admin = admin_; - } -} diff --git a/contracts/VToken.sol b/contracts/VToken.sol index 077f3be8b..5f8d7db2c 100644 --- a/contracts/VToken.sol +++ b/contracts/VToken.sol @@ -1,6 +1,9 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.10; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +import "./mixins/WithAdminUpgradeable.sol"; import "./ComptrollerInterface.sol"; import "./VTokenInterfaces.sol"; import "./ErrorReporter.sol"; @@ -10,16 +13,63 @@ import "./Governance/AccessControlManager.sol"; /** * @title Venus VToken Contract - * @notice Abstract base for VTokens * @author Venus Dev Team */ -abstract contract VToken is +contract VToken is + WithAdminUpgradeable, VTokenInterface, ExponentialNoError, TokenErrorReporter { + using SafeERC20 for IERC20; + + /** + * @notice Construct a new money market + * @param underlying_ The address of the underlying asset + * @param comptroller_ The address of the Comptroller + * @param interestRateModel_ The address of the interest rate model + * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 + * @param name_ ERC-20 name of this token + * @param symbol_ ERC-20 symbol of this token + * @param decimals_ ERC-20 decimal precision of this token + * @param admin_ Address of the administrator of this token + * @param riskManagement Addresses of risk fund contracts + */ + function initialize( + address underlying_, + ComptrollerInterface comptroller_, + InterestRateModel interestRateModel_, + uint256 initialExchangeRateMantissa_, + string memory name_, + string memory symbol_, + uint8 decimals_, + address payable admin_, + AccessControlManager accessControlManager_, + RiskManagementInit memory riskManagement + ) public initializer { + // Creator of the contract is admin during initialization + admin = payable(msg.sender); + + // Initialize the market + initializeInternal( + underlying_, + comptroller_, + interestRateModel_, + initialExchangeRateMantissa_, + name_, + symbol_, + decimals_, + accessControlManager_, + riskManagement + ); + + // Set the proper admin now that initialization is done + admin = admin_; + } + /** * @notice Initialize the money market + * @param underlying_ The address of the underlying asset * @param comptroller_ The address of the Comptroller * @param interestRateModel_ The address of the interest rate model * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 @@ -27,7 +77,8 @@ abstract contract VToken is * @param symbol_ EIP-20 symbol of this token * @param decimals_ EIP-20 decimal precision of this token */ - function initialize( + function initializeInternal( + address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, uint256 initialExchangeRateMantissa_, @@ -35,8 +86,8 @@ abstract contract VToken is string memory symbol_, uint8 decimals_, AccessControlManager accessControlManager_, - VBep20Interface.RiskManagementInit memory riskManagement - ) public { + VTokenInterface.RiskManagementInit memory riskManagement + ) internal { require(msg.sender == admin, "only admin may initialize the market"); require( accrualBlockNumber == 0 && borrowIndex == 0, @@ -73,6 +124,10 @@ abstract contract VToken is riskFund = riskManagement.riskFund; protocolShareReserve = riskManagement.protocolShareReserve; + // Set underlying and sanity check it + underlying = underlying_; + IERC20(underlying).totalSupply(); + // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund) _notEntered = true; } @@ -516,7 +571,7 @@ abstract contract VToken is * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param mintAmount The amount of the underlying asset to supply */ - function mintInternal(uint256 mintAmount) internal nonReentrant { + function mint(uint256 mintAmount) external override nonReentrant { accrueInterest(); // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to mintFresh(msg.sender, mintAmount); @@ -590,7 +645,7 @@ abstract contract VToken is * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemTokens The number of vTokens to redeem into underlying */ - function redeemInternal(uint256 redeemTokens) internal nonReentrant { + function redeem(uint256 redeemTokens) external override nonReentrant { accrueInterest(); // redeemFresh emits redeem-specific logs on errors, so we don't need to redeemFresh(payable(msg.sender), redeemTokens, 0); @@ -601,8 +656,9 @@ abstract contract VToken is * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemAmount The amount of underlying to receive from redeeming vTokens */ - function redeemUnderlyingInternal(uint256 redeemAmount) - internal + function redeemUnderlying(uint256 redeemAmount) + external + override nonReentrant { accrueInterest(); @@ -707,7 +763,7 @@ abstract contract VToken is * @notice Sender borrows assets from the protocol to their own address * @param borrowAmount The amount of the underlying asset to borrow */ - function borrowInternal(uint256 borrowAmount) internal nonReentrant { + function borrow(uint256 borrowAmount) external override nonReentrant { accrueInterest(); // borrowFresh emits borrow-specific logs on errors, so we don't need to borrowFresh(payable(msg.sender), borrowAmount); @@ -777,7 +833,11 @@ abstract contract VToken is * @notice Sender repays their own borrow * @param repayAmount The amount to repay, or -1 for the full outstanding amount */ - function repayBorrowInternal(uint256 repayAmount) internal nonReentrant { + function repayBorrow(uint256 repayAmount) + external + override + nonReentrant + { accrueInterest(); // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to repayBorrowFresh(msg.sender, msg.sender, repayAmount); @@ -788,8 +848,9 @@ abstract contract VToken is * @param borrower the account with the debt being payed off * @param repayAmount The amount to repay, or -1 for the full outstanding amount */ - function repayBorrowBehalfInternal(address borrower, uint256 repayAmount) - internal + function repayBorrowBehalf(address borrower, uint256 repayAmount) + external + override nonReentrant { accrueInterest(); @@ -871,6 +932,28 @@ abstract contract VToken is return actualRepayAmount; } + + /** + * @notice The sender liquidates the borrowers collateral. + * The collateral seized is transferred to the liquidator. + * @param borrower The borrower of this vToken to be liquidated + * @param repayAmount The amount of the underlying borrowed asset to repay + * @param vTokenCollateral The market in which to seize collateral from the borrower + */ + function liquidateBorrow( + address borrower, + uint256 repayAmount, + VTokenInterface vTokenCollateral + ) external override { + liquidateBorrowInternal( + msg.sender, + borrower, + repayAmount, + vTokenCollateral, + false + ); + } + /** * @notice The sender liquidates the borrowers collateral. * The collateral seized is transferred to the liquidator. @@ -994,11 +1077,7 @@ abstract contract VToken is if (address(vTokenCollateral) == address(this)) { seizeInternal(address(this), liquidator, borrower, seizeTokens); } else { - require( - vTokenCollateral.seize(liquidator, borrower, seizeTokens) == - NO_ERROR, - "token seizure failed" - ); + vTokenCollateral.seize(liquidator, borrower, seizeTokens); } /* We emit a LiquidateBorrow event */ @@ -1088,7 +1167,6 @@ abstract contract VToken is * @param vTokenCollateral The market in which to seize collateral from the borrower * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow * regardless of the account liquidity - * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function forceLiquidateBorrow( address liquidator, @@ -1096,7 +1174,7 @@ abstract contract VToken is uint256 repayAmount, VTokenInterface vTokenCollateral, bool skipLiquidityCheck - ) external override returns (uint256) { + ) external override { if (msg.sender != address(comptroller)) { revert ForceLiquidateBorrowUnauthorized(); } @@ -1107,7 +1185,6 @@ abstract contract VToken is vTokenCollateral, skipLiquidityCheck ); - return NO_ERROR; } /** @@ -1117,16 +1194,13 @@ abstract contract VToken is * @param liquidator The account receiving seized collateral * @param borrower The account having collateral seized * @param seizeTokens The number of vTokens to seize - * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ function seize( address liquidator, address borrower, uint256 seizeTokens - ) external override nonReentrant returns (uint256) { + ) external override nonReentrant { seizeInternal(msg.sender, liquidator, borrower, seizeTokens); - - return NO_ERROR; } /** @@ -1202,61 +1276,6 @@ abstract contract VToken is /*** Admin Functions ***/ - /** - * @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 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function _setPendingAdmin(address payable newPendingAdmin) - external - override - returns (uint256) - { - // Check caller = admin - if (msg.sender != admin) { - revert SetPendingAdminOwnerCheck(); - } - - // Save current value, if any, for inclusion in log - address oldPendingAdmin = pendingAdmin; - - // Store pendingAdmin with value newPendingAdmin - pendingAdmin = newPendingAdmin; - - // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin) - emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin); - - return NO_ERROR; - } - - /** - * @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 0=success, otherwise a failure (see ErrorReporter.sol for details) - */ - function _acceptAdmin() external override returns (uint256) { - // Check caller is pendingAdmin and pendingAdmin ≠ address(0) - if (msg.sender != pendingAdmin || msg.sender == address(0)) { - revert AcceptAdminPendingAdminCheck(); - } - - // Save current values for inclusion in log - address oldAdmin = admin; - address oldPendingAdmin = pendingAdmin; - - // Store admin with value pendingAdmin - admin = pendingAdmin; - - // Clear the pending value - pendingAdmin = payable(address(0)); - - emit NewAdmin(oldAdmin, admin); - emit NewPendingAdmin(oldPendingAdmin, pendingAdmin); - - return NO_ERROR; - } - /** * @notice Sets a new comptroller for the market * @dev Admin function to set a new comptroller @@ -1339,12 +1358,13 @@ abstract contract VToken is } /** - * @notice Accrues interest and reduces reserves by transferring from msg.sender - * @param addAmount Amount of addition to reserves + * @notice The sender adds to reserves. + * @param addAmount The amount fo underlying token to add as reserves * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) */ - function _addReservesInternal(uint256 addAmount) - internal + function _addReserves(uint256 addAmount) + external + override nonReentrant returns (uint256) { @@ -1550,31 +1570,6 @@ abstract contract VToken is return uint256(NO_ERROR); } - /*** Safe Token ***/ - - /** - * @notice Gets balance of this contract in terms of the underlying - * @dev This excludes the value of the current message, if any - * @return The quantity of underlying owned by this contract - */ - function getCashPrior() internal view virtual returns (uint256); - - /** - * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee. - * This may revert due to insufficient balance or insufficient allowance. - */ - function doTransferIn(address from, uint256 amount) - internal - virtual - returns (uint256); - - /** - * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting. - * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract. - * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions. - */ - function doTransferOut(address payable to, uint256 amount) internal virtual; - /*** Reentrancy Guard ***/ /** @@ -1621,4 +1616,62 @@ abstract contract VToken is badDebt = badDebt - _badDebt; } + + /** + * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock) + * @param token The address of the ERC-20 token to sweep + */ + function sweepToken(IERC20 token) external override { + require( + msg.sender == admin, + "VToken::sweepToken: only admin can sweep tokens" + ); + require( + address(token) != underlying, + "VToken::sweepToken: can not sweep underlying token" + ); + uint256 balance = token.balanceOf(address(this)); + token.safeTransfer(admin, balance); + } + + /*** Safe Token ***/ + + /** + * @notice Gets balance of this contract in terms of the underlying + * @dev This excludes the value of the current message, if any + * @return The quantity of underlying tokens owned by this contract + */ + function getCashPrior() internal virtual view returns (uint256) { + IERC20 token = IERC20(underlying); + return token.balanceOf(address(this)); + } + + /** + * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees. + * This function returns the actual amount received, + * which may be less than `amount` if there is a fee attached to the transfer. + */ + function doTransferIn(address from, uint256 amount) + internal + virtual + returns (uint256) + { + IERC20 token = IERC20(underlying); + uint256 balanceBefore = token.balanceOf(address(this)); + token.safeTransferFrom(from, address(this), amount); + uint256 balanceAfter = token.balanceOf(address(this)); + // Return the amount that was *actually* transferred + return balanceAfter - balanceBefore; + } + + /** + * @dev Just a regular ERC-20 transfer, reverts on failure + */ + function doTransferOut(address payable to, uint256 amount) + internal + virtual + { + IERC20 token = IERC20(underlying); + token.safeTransfer(to, amount); + } } diff --git a/contracts/VTokenInterfaces.sol b/contracts/VTokenInterfaces.sol index 399ca5f8c..6183d5559 100644 --- a/contracts/VTokenInterfaces.sol +++ b/contracts/VTokenInterfaces.sol @@ -14,6 +14,11 @@ contract VTokenStorage { */ bool internal _notEntered; + /** + * @notice Underlying asset for this VToken + */ + address public underlying; + /** * @notice EIP-20 token name for this token */ @@ -45,16 +50,6 @@ contract VTokenStorage { // Maximum fraction of interest that can be set aside for reserves uint256 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 */ @@ -213,16 +208,6 @@ abstract contract VTokenInterface is VTokenStorage { /*** 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 is updated - */ - event NewAdmin(address oldAdmin, address newAdmin); - /** * @notice Event emitted when comptroller is changed */ @@ -289,6 +274,58 @@ abstract contract VTokenInterface is VTokenStorage { /*** User Interface ***/ + struct RiskManagementInit { + address shortfall; + address payable riskFund; + address payable protocolShareReserve; + } + + /*** User Interface ***/ + + function mint(uint256 mintAmount) external virtual; + + function redeem(uint256 redeemTokens) external virtual; + + function redeemUnderlying(uint256 redeemAmount) + external + virtual; + + function borrow(uint256 borrowAmount) external virtual; + + function repayBorrow(uint256 repayAmount) + external + virtual; + + function repayBorrowBehalf(address borrower, uint256 repayAmount) + external + virtual; + + function liquidateBorrow( + address borrower, + uint256 repayAmount, + VTokenInterface vTokenCollateral + ) external virtual; + + function healBorrow( + address payer, + address borrower, + uint256 repayAmount + ) external virtual; + + function forceLiquidateBorrow( + address liquidator, + address borrower, + uint256 repayAmount, + VTokenInterface vTokenCollateral, + bool skipCloseFactorCheck + ) external virtual; + + function seize( + address liquidator, + address borrower, + uint256 seizeTokens + ) external virtual; + function transfer(address dst, uint256 amount) external virtual @@ -354,35 +391,10 @@ abstract contract VTokenInterface is VTokenStorage { function accrueInterest() external virtual returns (uint256); - function healBorrow( - address payer, - address borrower, - uint256 repayAmount - ) external virtual; - - function forceLiquidateBorrow( - address liquidator, - address borrower, - uint256 repayAmount, - VTokenInterface vTokenCollateral, - bool skipCloseFactorCheck - ) external virtual returns (uint256); - - function seize( - address liquidator, - address borrower, - uint256 seizeTokens - ) external virtual returns (uint256); + function sweepToken(IERC20 token) external virtual; /*** Admin Functions ***/ - function _setPendingAdmin(address payable newPendingAdmin) - external - virtual - returns (uint256); - - function _acceptAdmin() external virtual returns (uint256); - function _setComptroller(ComptrollerInterface newComptroller) external virtual @@ -402,97 +414,6 @@ abstract contract VTokenInterface is VTokenStorage { external virtual returns (uint256); -} - -contract VBep20Storage { - /** - * @notice Underlying asset for this VToken - */ - address public underlying; -} - -abstract contract VBep20Interface is VBep20Storage { - struct RiskManagementInit { - address shortfall; - address payable riskFund; - address payable protocolShareReserve; - } - - /*** User Interface ***/ - - function mint(uint256 mintAmount) external virtual returns (uint256); - - function redeem(uint256 redeemTokens) external virtual returns (uint256); - - function redeemUnderlying(uint256 redeemAmount) - external - virtual - returns (uint256); - - function borrow(uint256 borrowAmount) external virtual returns (uint256); - - function repayBorrow(uint256 repayAmount) - external - virtual - returns (uint256); - - function repayBorrowBehalf(address borrower, uint256 repayAmount) - external - virtual - returns (uint256); - - function liquidateBorrow( - address borrower, - uint256 repayAmount, - VTokenInterface vTokenCollateral - ) external virtual returns (uint256); - - function sweepToken(IERC20 token) external virtual; - - /*** Admin Functions ***/ function _addReserves(uint256 addAmount) external virtual returns (uint256); } - -contract CDelegationStorage { - /** - * @notice Implementation address for this contract - */ - address public implementation; -} - -abstract contract CDelegatorInterface is CDelegationStorage { - /** - * @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 virtual; -} - -abstract contract CDelegateInterface is CDelegationStorage { - /** - * @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 virtual; - - /** - * @notice Called by the delegator on a delegate to forfeit its responsibility - */ - function _resignImplementation() external virtual; -} From 9a627e69353e27be0ef54f159ad24ad47b7b0176 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Fri, 4 Nov 2022 19:51:01 +0300 Subject: [PATCH 2/4] refactor: replace VBep20Immutable with VToken in IL contracts --- ...roxyFactory.sol => VTokenProxyFactory.sol} | 18 ++-- contracts/Pool/PoolRegistry.sol | 18 ++-- contracts/RiskFund/RiskFund.sol | 2 +- contracts/Shortfall/Shortfall.sol | 9 +- tests/hardhat/Fork/RiskFund.ts | 26 +++--- tests/hardhat/PoolRegistry.ts | 24 +++--- tests/hardhat/Rewards.ts | 24 +++--- tests/hardhat/Shortfall.ts | 83 ++++++++++--------- 8 files changed, 101 insertions(+), 103 deletions(-) rename contracts/Factories/{VBep20ImmutableProxyFactory.sol => VTokenProxyFactory.sol} (74%) diff --git a/contracts/Factories/VBep20ImmutableProxyFactory.sol b/contracts/Factories/VTokenProxyFactory.sol similarity index 74% rename from contracts/Factories/VBep20ImmutableProxyFactory.sol rename to contracts/Factories/VTokenProxyFactory.sol index 9e8137aa6..c4f126eae 100644 --- a/contracts/Factories/VBep20ImmutableProxyFactory.sol +++ b/contracts/Factories/VTokenProxyFactory.sol @@ -3,12 +3,12 @@ pragma solidity 0.8.13; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import "../VBep20Immutable.sol"; +import "../VToken.sol"; import "../Governance/AccessControlManager.sol"; import "../VTokenInterfaces.sol"; -contract VBep20ImmutableProxyFactory { - struct VBep20Args { +contract VTokenProxyFactory { + struct VTokenArgs { address underlying_; ComptrollerInterface comptroller_; InterestRateModel interestRateModel_; @@ -18,20 +18,20 @@ contract VBep20ImmutableProxyFactory { uint8 decimals_; address payable admin_; AccessControlManager accessControlManager_; - VBep20Interface.RiskManagementInit riskManagement; + VTokenInterface.RiskManagementInit riskManagement; address vTokenProxyAdmin_; - VBep20Immutable tokenImplementation_; + VToken tokenImplementation_; } - function deployVBep20Proxy(VBep20Args memory input) + function deployVTokenProxy(VTokenArgs memory input) external - returns (VBep20Immutable) + returns (VToken) { TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( address(input.tokenImplementation_), input.vTokenProxyAdmin_, abi.encodeWithSelector( - input.tokenImplementation_.initializeVToken.selector, + input.tokenImplementation_.initialize.selector, input.underlying_, input.comptroller_, input.interestRateModel_, @@ -44,6 +44,6 @@ contract VBep20ImmutableProxyFactory { input.riskManagement ) ); - return VBep20Immutable(address(proxy)); + return VToken(address(proxy)); } } diff --git a/contracts/Pool/PoolRegistry.sol b/contracts/Pool/PoolRegistry.sol index b8dbff72b..5b21f18bd 100644 --- a/contracts/Pool/PoolRegistry.sol +++ b/contracts/Pool/PoolRegistry.sol @@ -6,12 +6,12 @@ import "@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol"; import "../Comptroller.sol"; import "../PriceOracle.sol"; -import "../Factories/VBep20ImmutableProxyFactory.sol"; +import "../Factories/VTokenProxyFactory.sol"; import "../Factories/JumpRateModelFactory.sol"; import "../Factories/WhitePaperInterestRateModelFactory.sol"; import "../WhitePaperInterestRateModel.sol"; import "../JumpRateModelV2.sol"; -import "../VBep20Immutable.sol"; +import "../VToken.sol"; import "../InterestRateModel.sol"; import "../Governance/AccessControlManager.sol"; import "../Shortfall/Shortfall.sol"; @@ -23,7 +23,7 @@ import "../VTokenInterfaces.sol"; * @notice PoolRegistry is a registry for Venus interest rate pools. */ contract PoolRegistry is OwnableUpgradeable { - VBep20ImmutableProxyFactory private vTokenFactory; + VTokenProxyFactory private vTokenFactory; JumpRateModelFactory private jumpRateFactory; WhitePaperInterestRateModelFactory private whitePaperFactory; Shortfall private shortfall; @@ -39,7 +39,7 @@ contract PoolRegistry is OwnableUpgradeable { * @param protocolShareReserve_ protocol's shares reserve address. */ function initialize( - VBep20ImmutableProxyFactory _vTokenFactory, + VTokenProxyFactory _vTokenFactory, JumpRateModelFactory _jumpRateFactory, WhitePaperInterestRateModelFactory _whitePaperFactory, Shortfall _shortfall, @@ -144,7 +144,7 @@ contract PoolRegistry is OwnableUpgradeable { uint256 liquidationThreshold; AccessControlManager accessControlManager; address vTokenProxyAdmin; - VBep20Immutable tokenImplementation_; + VToken tokenImplementation_; } /** @@ -368,8 +368,8 @@ contract PoolRegistry is OwnableUpgradeable { Comptroller comptroller = Comptroller(input.comptroller); - VBep20ImmutableProxyFactory.VBep20Args - memory initializeArgs = VBep20ImmutableProxyFactory.VBep20Args( + VTokenProxyFactory.VTokenArgs + memory initializeArgs = VTokenProxyFactory.VTokenArgs( input.asset, comptroller, rate, @@ -379,7 +379,7 @@ contract PoolRegistry is OwnableUpgradeable { input.decimals, payable(msg.sender), input.accessControlManager, - VBep20Interface.RiskManagementInit( + VTokenInterface.RiskManagementInit( address(shortfall), riskFund, protocolShareReserve @@ -388,7 +388,7 @@ contract PoolRegistry is OwnableUpgradeable { input.tokenImplementation_ ); - VBep20Immutable vToken = vTokenFactory.deployVBep20Proxy( + VToken vToken = vTokenFactory.deployVTokenProxy( initializeArgs ); diff --git a/contracts/RiskFund/RiskFund.sol b/contracts/RiskFund/RiskFund.sol index f126d812c..35213adc8 100644 --- a/contracts/RiskFund/RiskFund.sol +++ b/contracts/RiskFund/RiskFund.sol @@ -140,7 +140,7 @@ contract RiskFund is OwnableUpgradeable, ExponentialNoError { { uint256 totalAmount; - address underlyingAsset = VBep20Interface(address(vToken)).underlying(); + address underlyingAsset = VTokenInterface(address(vToken)).underlying(); uint256 balanceOfUnderlyingAsset = IERC20(underlyingAsset).balanceOf( address(this) ); diff --git a/contracts/Shortfall/Shortfall.sol b/contracts/Shortfall/Shortfall.sol index fb2dcd50c..f10fcefc6 100644 --- a/contracts/Shortfall/Shortfall.sol +++ b/contracts/Shortfall/Shortfall.sol @@ -6,7 +6,6 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "../VToken.sol"; -import "../VBep20.sol"; import "../PriceOracle.sol"; import "../ComptrollerInterface.sol"; import "../RiskFund/IRiskFund.sol"; @@ -262,8 +261,8 @@ contract Shortfall is OwnableUpgradeable, ReentrancyGuardUpgradeable { ); for (uint256 i = 0; i < auction.markets.length; i++) { - VBep20 vBep20 = VBep20(address(auction.markets[i])); - IERC20 erc20 = IERC20(address(vBep20.underlying())); + VToken vToken = VToken(address(auction.markets[i])); + IERC20 erc20 = IERC20(address(vToken.underlying())); if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) { if (auction.highestBidder != address(0)) { @@ -322,8 +321,8 @@ contract Shortfall is OwnableUpgradeable, ReentrancyGuardUpgradeable { auction.status = AuctionStatus.ENDED; for (uint256 i = 0; i < auction.markets.length; i++) { - VBep20 vBep20 = VBep20(address(auction.markets[i])); - IERC20 erc20 = IERC20(address(vBep20.underlying())); + VToken vToken = VToken(address(auction.markets[i])); + IERC20 erc20 = IERC20(address(vToken.underlying())); if (auction.auctionType == AuctionType.LARGE_POOL_DEBT) { uint256 bidAmount = ((auction.marketDebt[auction.markets[i]] * diff --git a/tests/hardhat/Fork/RiskFund.ts b/tests/hardhat/Fork/RiskFund.ts index eb53709aa..b113bfb75 100644 --- a/tests/hardhat/Fork/RiskFund.ts +++ b/tests/hardhat/Fork/RiskFund.ts @@ -9,9 +9,9 @@ import { ProtocolShareReserve, MockToken, Comptroller, - VBep20Immutable, + VToken, MockPriceOracle, - VBep20ImmutableProxyFactory, + VTokenProxyFactory, JumpRateModelFactory, WhitePaperInterestRateModelFactory, AccessControlManager, @@ -27,13 +27,11 @@ let comptroller2: Comptroller; let mainnetUSDC: MockToken; let mainnetBUSD: MockToken; let mainnetUSDT: MockToken; -let cUSDC: VBep20Immutable; -let cUSDT: VBep20Immutable; +let cUSDC: VToken; +let cUSDT: VToken; let priceOracle: MockPriceOracle; let comptroller1Proxy: Comptroller; -let unitroller1: Unitroller; -let unitroller2: Unitroller; -let vTokenFactory: VBep20ImmutableProxyFactory; +let vTokenFactory: VTokenProxyFactory; let jumpRateFactory: JumpRateModelFactory; let whitePaperRateFactory: WhitePaperInterestRateModelFactory; let fakeAccessControlManager: FakeContract; @@ -46,10 +44,10 @@ let usdtUser: any; const riskFundFixture = async (): Promise => { const [admin, user, proxyAdmin] = await ethers.getSigners(); - const VBep20ImmutableProxyFactory = await ethers.getContractFactory( - "VBep20ImmutableProxyFactory" + const VTokenProxyFactory = await ethers.getContractFactory( + "VTokenProxyFactory" ); - vTokenFactory = await VBep20ImmutableProxyFactory.deploy(); + vTokenFactory = await VTokenProxyFactory.deploy(); await vTokenFactory.deployed(); const JumpRateModelFactory = await ethers.getContractFactory( @@ -207,8 +205,8 @@ const riskFundFixture = async (): Promise => { const comptroller2Proxy = await ethers.getContractAt("Comptroller", pools[1].comptroller); await comptroller2Proxy.acceptAdmin(); - const VBep20Immutable = await ethers.getContractFactory("VBep20Immutable"); - const tokenImplementation = await VBep20Immutable.deploy(); + const VToken = await ethers.getContractFactory("VToken"); + const tokenImplementation = await VToken.deploy(); await tokenImplementation.deployed(); // Deploy CTokens @@ -257,8 +255,8 @@ const riskFundFixture = async (): Promise => { mainnetUSDC.address ); - cUSDT = await ethers.getContractAt("VBep20Immutable", cUSDTAddress); - cUSDC = await ethers.getContractAt("VBep20Immutable", cUSDCAddress); + cUSDT = await ethers.getContractAt("VToken", cUSDTAddress); + cUSDC = await ethers.getContractAt("VToken", cUSDCAddress); // Enter Markets await comptroller1Proxy.enterMarkets([cUSDC.address, cUSDT.address]); diff --git a/tests/hardhat/PoolRegistry.ts b/tests/hardhat/PoolRegistry.ts index feb78411a..0806cb593 100644 --- a/tests/hardhat/PoolRegistry.ts +++ b/tests/hardhat/PoolRegistry.ts @@ -4,9 +4,9 @@ import { MockToken, PoolRegistry, Comptroller, - VBep20Immutable, + VToken, MockPriceOracle, - VBep20ImmutableProxyFactory, + VTokenProxyFactory, JumpRateModelFactory, WhitePaperInterestRateModelFactory, AccessControlManager, @@ -21,12 +21,12 @@ let comptroller1: Comptroller; let comptroller2: Comptroller; let mockDAI: MockToken; let mockWBTC: MockToken; -let vDAI: VBep20Immutable; -let vWBTC: VBep20Immutable; +let vDAI: VToken; +let vWBTC: VToken; let priceOracle: MockPriceOracle; let comptroller1Proxy: Comptroller; let comptroller2Proxy: Comptroller; -let cTokenFactory: VBep20ImmutableProxyFactory; +let cTokenFactory: VTokenProxyFactory; let jumpRateFactory: JumpRateModelFactory; let whitePaperRateFactory: WhitePaperInterestRateModelFactory; let fakeAccessControlManager: FakeContract; @@ -39,10 +39,10 @@ describe("PoolRegistry: Tests", function () { */ before(async function () { const [, user, proxyAdmin] = await ethers.getSigners(); - const VBep20ImmutableProxyFactory = await ethers.getContractFactory( - "VBep20ImmutableProxyFactory" + const VTokenProxyFactory = await ethers.getContractFactory( + "VTokenProxyFactory" ); - cTokenFactory = await VBep20ImmutableProxyFactory.deploy(); + cTokenFactory = await VTokenProxyFactory.deploy(); await cTokenFactory.deployed(); const JumpRateModelFactory = await ethers.getContractFactory( "JumpRateModelFactory" @@ -164,8 +164,8 @@ describe("PoolRegistry: Tests", function () { ); await comptroller2Proxy.acceptAdmin(); - const VBep20Immutable = await ethers.getContractFactory("VBep20Immutable"); - const tokenImplementation = await VBep20Immutable.deploy(); + const VToken = await ethers.getContractFactory("VToken"); + const tokenImplementation = await VToken.deploy(); await tokenImplementation.deployed(); // Deploy VTokens @@ -214,8 +214,8 @@ describe("PoolRegistry: Tests", function () { mockDAI.address ); - vWBTC = await ethers.getContractAt("VBep20Immutable", vWBTCAddress); - vDAI = await ethers.getContractAt("VBep20Immutable", vDAIAddress); + vWBTC = await ethers.getContractAt("VToken", vWBTCAddress); + vDAI = await ethers.getContractAt("VToken", vDAIAddress); // Enter Markets await comptroller1Proxy.enterMarkets([vDAI.address, vWBTC.address]); diff --git a/tests/hardhat/Rewards.ts b/tests/hardhat/Rewards.ts index e09b18d29..272d0cf8a 100644 --- a/tests/hardhat/Rewards.ts +++ b/tests/hardhat/Rewards.ts @@ -6,8 +6,8 @@ import { MockToken, PoolRegistry, Comptroller, - VBep20Immutable, - VBep20ImmutableProxyFactory, + VToken, + VTokenProxyFactory, JumpRateModelFactory, WhitePaperInterestRateModelFactory, RewardsDistributor, @@ -26,10 +26,10 @@ let poolRegistry: MockContract; let comptroller: Comptroller; let mockDAI: MockToken; let mockWBTC: MockToken; -let vDAI: VBep20Immutable; -let vWBTC: VBep20Immutable; +let vDAI: VToken; +let vWBTC: VToken; let comptrollerProxy: Comptroller; -let vTokenFactory: VBep20ImmutableProxyFactory; +let vTokenFactory: VTokenProxyFactory; let jumpRateFactory: JumpRateModelFactory; let whitePaperRateFactory: WhitePaperInterestRateModelFactory; let rewardsDistributor: RewardsDistributor; @@ -45,10 +45,10 @@ describe("Rewards: Tests", async function () { */ before(async function () { const [, proxyAdmin] = await ethers.getSigners(); - const VBep20ImmutableProxyFactory = await ethers.getContractFactory( - "VBep20ImmutableProxyFactory" + const VTokenProxyFactory = await ethers.getContractFactory( + "VTokenProxyFactory" ); - vTokenFactory = await VBep20ImmutableProxyFactory.deploy(); + vTokenFactory = await VTokenProxyFactory.deploy(); await vTokenFactory.deployed(); const JumpRateModelFactory = await ethers.getContractFactory( @@ -168,8 +168,8 @@ describe("Rewards: Tests", async function () { await comptrollerProxy.acceptAdmin(); await comptrollerProxy._setPriceOracle(fakePriceOracle.address); - const VBep20Immutable = await ethers.getContractFactory("VBep20Immutable"); - const tokenImplementation = await VBep20Immutable.deploy(); + const VToken = await ethers.getContractFactory("VToken"); + const tokenImplementation = await VToken.deploy(); await tokenImplementation.deployed(); //Deploy VTokens @@ -218,8 +218,8 @@ describe("Rewards: Tests", async function () { mockDAI.address ); - vWBTC = await ethers.getContractAt("VBep20Immutable", vWBTCAddress); - vDAI = await ethers.getContractAt("VBep20Immutable", vDAIAddress); + vWBTC = await ethers.getContractAt("VToken", vWBTCAddress); + vDAI = await ethers.getContractAt("VToken", vDAIAddress); const [, , user] = await ethers.getSigners(); diff --git a/tests/hardhat/Shortfall.ts b/tests/hardhat/Shortfall.ts index 44a1c06bb..c5051dcb0 100644 --- a/tests/hardhat/Shortfall.ts +++ b/tests/hardhat/Shortfall.ts @@ -1,8 +1,8 @@ import { ethers } from "hardhat"; import { AccessControlManager, - VBep20, - VBep20__factory, + VToken, + VToken__factory, Comptroller, Comptroller__factory, IRiskFund, @@ -24,8 +24,8 @@ describe("Shortfall: Tests", async function () { let mockBUSD: MockToken; let mockDAI: MockToken; let mockWBTC: MockToken; - let cDAI: MockContract; - let cWBTC: MockContract; + let vDAI: MockContract; + let vWBTC: MockContract; let comptroller: MockContract; let fakeAccessControlManager: FakeContract; let fakePriceOracle: FakeContract; @@ -80,20 +80,21 @@ describe("Shortfall: Tests", async function () { comptroller = await Comptroller.deploy(poolRegistry.address, fakeAccessControlManager.address) poolId = comptroller.address - cDAI = await (await smock.mock("VBep20")).deploy() - cWBTC = await (await smock.mock("VBep20")).deploy() + const VToken = await smock.mock("VToken"); + vDAI = await VToken.deploy(); + vWBTC = await VToken.deploy(); - cWBTC.setVariable("decimals", 8); - cDAI.decimals.returns(18); + vWBTC.setVariable("decimals", 8); + vDAI.decimals.returns(18); - cDAI.underlying.returns(mockDAI.address) - cWBTC.setVariable("underlying", mockWBTC.address) + vDAI.underlying.returns(mockDAI.address) + vWBTC.setVariable("underlying", mockWBTC.address) - cDAI.setVariable("shortfall", shortfall.address) - cWBTC.setVariable("shortfall", shortfall.address) + vDAI.setVariable("shortfall", shortfall.address) + vWBTC.setVariable("shortfall", shortfall.address) comptroller.getAllMarkets.returns((args: any) => { - return [cDAI.address, cWBTC.address]; + return [vDAI.address, vWBTC.address]; }); fakePriceOracle = await smock.fake("PriceOracle"); @@ -102,8 +103,8 @@ describe("Shortfall: Tests", async function () { const daiPrice = "1"; fakePriceOracle.getUnderlyingPrice.returns((args: any) => { - if (cDAI && cWBTC) { - if (args[0] === cDAI.address) { + if (vDAI && vWBTC) { + if (args[0] === vDAI.address) { return convertToUnit(daiPrice, 18); } else { return convertToUnit(btcPrice, 28); @@ -120,27 +121,27 @@ describe("Shortfall: Tests", async function () { }); it("Should have debt and reserve", async function () { - cDAI.badDebt.returns(parseUnits("1000", 18)) - cWBTC.badDebt.returns(parseUnits("1", 8)) + vDAI.badDebt.returns(parseUnits("1000", 18)) + vWBTC.badDebt.returns(parseUnits("1", 8)) expect(await fakeRiskFund.getPoolReserve(comptroller.address)).equal(parseUnits(riskFundBalance, 18).toString()) - expect(await cDAI.badDebt()).equal(parseUnits("1000", 18)) - expect(await cWBTC.badDebt()).equal(parseUnits("1", 8)) + expect(await vDAI.badDebt()).equal(parseUnits("1000", 18)) + expect(await vWBTC.badDebt()).equal(parseUnits("1", 8)) }); it("Should not be able to start auction", async function () { - cDAI.badDebt.returns(parseUnits("20", 18)) - cWBTC.badDebt.returns(parseUnits("0.01", 8)) + vDAI.badDebt.returns(parseUnits("20", 18)) + vWBTC.badDebt.returns(parseUnits("0.01", 8)) await expect(shortfall.startAuction(poolId)).to.be.reverted; }); it("Scenerio 1 - Start auction", async function () { - cDAI.badDebt.returns(parseUnits("10000", 18)) - cDAI.setVariable("badDebt", parseUnits("10000", 18)) - cWBTC.badDebt.returns(parseUnits("2", 8)) - cWBTC.setVariable("badDebt", parseUnits("2", 8)) + vDAI.badDebt.returns(parseUnits("10000", 18)) + vDAI.setVariable("badDebt", parseUnits("10000", 18)) + vWBTC.badDebt.returns(parseUnits("2", 8)) + vWBTC.setVariable("badDebt", parseUnits("2", 8)) await shortfall.startAuction(poolId); @@ -169,13 +170,13 @@ describe("Shortfall: Tests", async function () { expect(((await mockWBTC.balanceOf(owner.address))).div(parseUnits("1", 8)).toNumber()).lt(previousWBTCBalance.div(parseUnits("1", 8)).toNumber()) let percentageToDeduct = (new BigNumber(auction.startBidBps.toString())).dividedBy(100); - let total = (new BigNumber((await cDAI.badDebt()).toString()).dividedBy(parseUnits("1", "18").toString())) + let total = (new BigNumber((await vDAI.badDebt()).toString()).dividedBy(parseUnits("1", "18").toString())) let amountToDeduct = ((new BigNumber(total)).times(percentageToDeduct)).dividedBy(100).toString() let amountDeducted = (new BigNumber(previousDaiBalance.div(parseUnits("1", 18)).toString())).minus(((await mockDAI.balanceOf(owner.address))).div(parseUnits("1", 18)).toString()).toString() expect(amountDeducted).equal(amountToDeduct) percentageToDeduct = (new BigNumber(auction.startBidBps.toString())).dividedBy(100); - total = (new BigNumber((await cWBTC.badDebt()).toString()).dividedBy(parseUnits("1", "8").toString())) + total = (new BigNumber((await vWBTC.badDebt()).toString()).dividedBy(parseUnits("1", "8").toString())) amountToDeduct = ((new BigNumber(total)).times(percentageToDeduct)).dividedBy(100).toString() amountDeducted = ((new BigNumber(previousWBTCBalance.toString())).minus((await mockWBTC.balanceOf(owner.address)).toString())).div(parseUnits("1", 8).toString()).toString() expect(amountDeducted).equal(amountToDeduct) @@ -193,18 +194,18 @@ describe("Shortfall: Tests", async function () { const auction = await shortfall.auctions(poolId); expect(auction.status).equal(2) - expect(cWBTC.badDebtRecovered).to.have.been.calledOnce; - expect(cWBTC.badDebtRecovered).to.have.been.calledWith(parseUnits("2", 8)); + expect(vWBTC.badDebtRecovered).to.have.been.calledOnce; + expect(vWBTC.badDebtRecovered).to.have.been.calledWith(parseUnits("2", 8)); - expect(cDAI.badDebtRecovered).to.have.been.calledOnce; - expect(cDAI.badDebtRecovered).to.have.been.calledWith(parseUnits("10000", 18)); + expect(vDAI.badDebtRecovered).to.have.been.calledOnce; + expect(vDAI.badDebtRecovered).to.have.been.calledWith(parseUnits("10000", 18)); }); it("Scenerio 2 - Start auction", async function () { - cDAI.badDebt.returns(parseUnits("10000", 18)) - cDAI.setVariable("badDebt", parseUnits("10000", 18)) - cWBTC.badDebt.returns(parseUnits("1", 8)) - cWBTC.setVariable("badDebt", parseUnits("1", 8)) + vDAI.badDebt.returns(parseUnits("10000", 18)) + vDAI.setVariable("badDebt", parseUnits("10000", 18)) + vWBTC.badDebt.returns(parseUnits("1", 8)) + vWBTC.setVariable("badDebt", parseUnits("1", 8)) riskFundBalance = "50000" fakeRiskFund.getPoolReserve.returns(parseUnits(riskFundBalance, 18)) @@ -236,13 +237,13 @@ describe("Shortfall: Tests", async function () { expect(((await mockWBTC.balanceOf(owner.address))).div(parseUnits("1", 8)).toNumber()).lt(previousWBTCBalance.div(parseUnits("1", 8)).toNumber()) let percentageToDeduct = (new BigNumber(auction.startBidBps.toString())).dividedBy(100); - let total = (new BigNumber((await cDAI.badDebt()).toString()).dividedBy(parseUnits("1", "18").toString())) + let total = (new BigNumber((await vDAI.badDebt()).toString()).dividedBy(parseUnits("1", "18").toString())) let amountToDeduct = ((new BigNumber(total)).times(percentageToDeduct)).dividedBy(100).toString() let amountDeducted = (new BigNumber(previousDaiBalance.div(parseUnits("1", 18)).toString())).minus(((await mockDAI.balanceOf(owner.address))).div(parseUnits("1", 18)).toString()).toString() expect(amountDeducted).equal(amountToDeduct) percentageToDeduct = (new BigNumber(auction.startBidBps.toString())).dividedBy(100); - total = (new BigNumber((await cWBTC.badDebt()).toString()).dividedBy(parseUnits("1", "8").toString())) + total = (new BigNumber((await vWBTC.badDebt()).toString()).dividedBy(parseUnits("1", "8").toString())) amountToDeduct = ((new BigNumber(total)).times(percentageToDeduct)).dividedBy(100).toString() amountDeducted = ((new BigNumber(previousWBTCBalance.toString())).minus((await mockWBTC.balanceOf(owner.address)).toString())).div(parseUnits("1", 8).toString()).toString() expect(amountDeducted).equal(amountToDeduct) @@ -261,10 +262,10 @@ describe("Shortfall: Tests", async function () { auction = await shortfall.auctions(poolId); expect(auction.status).equal(2) - expect(cWBTC.badDebtRecovered).to.have.been.calledTwice; - expect(cWBTC.badDebtRecovered).to.have.been.calledWith(parseUnits("1", 8)); + expect(vWBTC.badDebtRecovered).to.have.been.calledTwice; + expect(vWBTC.badDebtRecovered).to.have.been.calledWith(parseUnits("1", 8)); - expect(cDAI.badDebtRecovered).to.have.been.calledTwice; - expect(cDAI.badDebtRecovered).to.have.been.calledWith(parseUnits("10000", 18)); + expect(vDAI.badDebtRecovered).to.have.been.calledTwice; + expect(vDAI.badDebtRecovered).to.have.been.calledWith(parseUnits("10000", 18)); }); }); From a9ac8b9574fba148e78832e3223b14cacc901c76 Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Fri, 4 Nov 2022 19:52:39 +0300 Subject: [PATCH 3/4] refactor: account for VToken changes in PoolLens --- contracts/Lens/PoolLens.sol | 9 +++------ tests/hardhat/lens/PoolLens.ts | 34 +++++++++++++++++----------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/contracts/Lens/PoolLens.sol b/contracts/Lens/PoolLens.sol index df792b2c1..913afc4d5 100644 --- a/contracts/Lens/PoolLens.sol +++ b/contracts/Lens/PoolLens.sol @@ -4,7 +4,6 @@ pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import "../VBep20.sol"; import "../VToken.sol"; import "../PriceOracle.sol"; import "../ComptrollerInterface.sol"; @@ -209,9 +208,8 @@ contract PoolLens is ExponentialNoError { address underlyingAssetAddress; uint256 underlyingDecimals; - VBep20 vBep20 = VBep20(address(vToken)); - underlyingAssetAddress = vBep20.underlying(); - underlyingDecimals = IERC20Metadata(vBep20.underlying()).decimals(); + underlyingAssetAddress = vToken.underlying(); + underlyingDecimals = IERC20Metadata(vToken.underlying()).decimals(); return VTokenMetadata({ @@ -276,8 +274,7 @@ contract PoolLens is ExponentialNoError { uint256 tokenBalance; uint256 tokenAllowance; - VBep20 vBep20 = VBep20(address(vToken)); - IERC20 underlying = IERC20(vBep20.underlying()); + IERC20 underlying = IERC20(vToken.underlying()); tokenBalance = underlying.balanceOf(account); tokenAllowance = underlying.allowance(account, address(vToken)); diff --git a/tests/hardhat/lens/PoolLens.ts b/tests/hardhat/lens/PoolLens.ts index 8b959f05a..82fa67624 100644 --- a/tests/hardhat/lens/PoolLens.ts +++ b/tests/hardhat/lens/PoolLens.ts @@ -5,12 +5,12 @@ import { PoolRegistry, Comptroller, MockPriceOracle, - VBep20ImmutableProxyFactory, + VTokenProxyFactory, JumpRateModelFactory, WhitePaperInterestRateModelFactory, PoolLens, AccessControlManager, - VBep20Immutable, + VToken, RiskFund, ProtocolShareReserve, } from "../../../typechain"; @@ -24,12 +24,12 @@ let comptroller1: Comptroller; let comptroller2: Comptroller; let mockDAI: MockToken; let mockWBTC: MockToken; -let vDAI: VBep20Immutable; -let vWBTC: VBep20Immutable; +let vDAI: VToken; +let vWBTC: VToken; let priceOracle: MockPriceOracle; let comptroller1Proxy: Comptroller; let comptroller2Proxy: Comptroller; -let vTokenFactory: VBep20ImmutableProxyFactory; +let vTokenFactory: VTokenProxyFactory; let jumpRateFactory: JumpRateModelFactory; let whitePaperRateFactory: WhitePaperInterestRateModelFactory; let poolLens: PoolLens; @@ -52,10 +52,10 @@ describe("PoolLens - PoolView Tests", async function () { const [owner, proxyAdmin] = await ethers.getSigners(); ownerAddress = await owner.getAddress(); - const VBep20ImmutableProxyFactory = await ethers.getContractFactory( - "VBep20ImmutableProxyFactory" + const VTokenProxyFactory = await ethers.getContractFactory( + "VTokenProxyFactory" ); - vTokenFactory = await VBep20ImmutableProxyFactory.deploy(); + vTokenFactory = await VTokenProxyFactory.deploy(); await vTokenFactory.deployed(); const JumpRateModelFactory = await ethers.getContractFactory( @@ -170,8 +170,8 @@ describe("PoolLens - PoolView Tests", async function () { await priceOracle.setPrice(mockDAI.address, convertToUnit(daiPrice, 18)); await priceOracle.setPrice(mockWBTC.address, convertToUnit(btcPrice, 28)); - const VBep20Immutable = await ethers.getContractFactory("VBep20Immutable"); - const tokenImplementation = await VBep20Immutable.deploy(); + const VToken = await ethers.getContractFactory("VToken"); + const tokenImplementation = await VToken.deploy(); await tokenImplementation.deployed(); // Get all pools list. @@ -251,8 +251,8 @@ describe("PoolLens - PoolView Tests", async function () { mockDAI.address ); - vWBTC = await ethers.getContractAt("VBep20Immutable", vWBTCAddress); - vDAI = await ethers.getContractAt("VBep20Immutable", vDAIAddress); + vWBTC = await ethers.getContractAt("VToken", vWBTCAddress); + vDAI = await ethers.getContractAt("VToken", vDAIAddress); // Enter Markets await comptroller1Proxy.enterMarkets([vDAI.address, vWBTC.address]); @@ -392,10 +392,10 @@ describe("PoolLens - VTokens Query Tests", async function () { ); fakeAccessControlManager.isAllowedToCall.returns(true); - const VBep20ImmutableProxyFactory = await ethers.getContractFactory( - "VBep20ImmutableProxyFactory" + const VTokenProxyFactory = await ethers.getContractFactory( + "VTokenProxyFactory" ); - vTokenFactory = await VBep20ImmutableProxyFactory.deploy(); + vTokenFactory = await VTokenProxyFactory.deploy(); await vTokenFactory.deployed(); const JumpRateModelFactory = await ethers.getContractFactory( @@ -505,8 +505,8 @@ describe("PoolLens - VTokens Query Tests", async function () { await priceOracle.setPrice(mockDAI.address, convertToUnit(daiPrice, 18)); await priceOracle.setPrice(mockWBTC.address, convertToUnit(btcPrice, 28)); - const VBep20Immutable = await ethers.getContractFactory("VBep20Immutable"); - const tokenImplementation = await VBep20Immutable.deploy(); + const VToken = await ethers.getContractFactory("VToken"); + const tokenImplementation = await VToken.deploy(); await tokenImplementation.deployed(); // Get all pools list. From 1fe73340683453f5bdcfabdd3f1eb61ab161e6ae Mon Sep 17 00:00:00 2001 From: Kirill Kuvshinov Date: Fri, 4 Nov 2022 19:56:40 +0300 Subject: [PATCH 4/4] test: update tests to account for VToken breaking change --- contracts/test/Mocks/MockPriceOracle.sol | 4 +- contracts/test/PriceOracleProxy.sol | 3 +- contracts/test/SimplePriceOracle.sol | 4 +- ...{UpgradedVBEP20.sol => UpgradedVToken.sol} | 12 +++--- .../{VBep20Harness.sol => VTokenHarness.sol} | 22 +++++----- .../Comptroller/accountLiquidityTest.ts | 8 ++-- tests/hardhat/Comptroller/assetsListTest.ts | 34 ++++++++-------- tests/hardhat/Comptroller/healAccountTest.ts | 20 +++++----- .../liquidateCalculateAmountSeizeTest.ts | 20 +++++----- tests/hardhat/Comptroller/pauseTest.ts | 22 +++++----- tests/hardhat/Tokens/accrueInterestTest.ts | 8 ++-- tests/hardhat/Tokens/adminTest.ts | 40 +++++++++---------- tests/hardhat/Tokens/borrowAndRepayTest.ts | 14 +++---- tests/hardhat/Tokens/liquidateTest.ts | 12 +++--- tests/hardhat/Tokens/mintAndRedeemTest.ts | 18 ++++----- tests/hardhat/Tokens/setComptrollerTest.ts | 4 +- tests/hardhat/Tokens/transferTest.ts | 14 ++----- .../{UpgradedVBEP20.ts => UpgradedVToken.ts} | 28 ++++++------- tests/hardhat/util/TokenTestHelpers.ts | 27 ++++++------- tests/integration/index.ts | 23 +++++------ 20 files changed, 162 insertions(+), 175 deletions(-) rename contracts/test/{UpgradedVBEP20.sol => UpgradedVToken.sol} (90%) rename contracts/test/{VBep20Harness.sol => VTokenHarness.sol} (94%) rename tests/hardhat/{UpgradedVBEP20.ts => UpgradedVToken.ts} (88%) diff --git a/contracts/test/Mocks/MockPriceOracle.sol b/contracts/test/Mocks/MockPriceOracle.sol index fa2eb102c..be1e417d7 100644 --- a/contracts/test/Mocks/MockPriceOracle.sol +++ b/contracts/test/Mocks/MockPriceOracle.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import "../../PriceOracle.sol"; -import "../../VBep20.sol"; +import "../../VToken.sol"; contract MockPriceOracle { mapping(address => uint256) public assetPrices; @@ -15,7 +15,7 @@ contract MockPriceOracle { } //https://compound.finance/docs/prices - function getUnderlyingPrice(VBep20 vToken) public view returns (uint256) { + function getUnderlyingPrice(VToken vToken) public view returns (uint256) { return assetPrices[vToken.underlying()]; } diff --git a/contracts/test/PriceOracleProxy.sol b/contracts/test/PriceOracleProxy.sol index 19d6aa97d..0fcc49d94 100644 --- a/contracts/test/PriceOracleProxy.sol +++ b/contracts/test/PriceOracleProxy.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.10; -import "../../contracts/VBep20.sol"; import "../../contracts/VToken.sol"; import "../../contracts/PriceOracle.sol"; @@ -103,7 +102,7 @@ contract PriceOracleProxy is PriceOracle { } // otherwise just read from v1 oracle - address underlying = VBep20(vTokenAddress).underlying(); + address underlying = VToken(vTokenAddress).underlying(); return v1PriceOracle.assetPrices(underlying); } diff --git a/contracts/test/SimplePriceOracle.sol b/contracts/test/SimplePriceOracle.sol index bb654edfb..6a38e54d1 100644 --- a/contracts/test/SimplePriceOracle.sol +++ b/contracts/test/SimplePriceOracle.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import "../PriceOracle.sol"; -import "../VBep20.sol"; +import "../VToken.sol"; contract SimplePriceOracle is PriceOracle { mapping(address => uint256) prices; @@ -22,7 +22,7 @@ contract SimplePriceOracle is PriceOracle { if (compareStrings(vToken.symbol(), "vBNB")) { asset = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; } else { - asset = address(VBep20(address(vToken)).underlying()); + asset = address(VToken(address(vToken)).underlying()); } return asset; } diff --git a/contracts/test/UpgradedVBEP20.sol b/contracts/test/UpgradedVToken.sol similarity index 90% rename from contracts/test/UpgradedVBEP20.sol rename to contracts/test/UpgradedVToken.sol index 1e20dd801..fbd2d7268 100644 --- a/contracts/test/UpgradedVBEP20.sol +++ b/contracts/test/UpgradedVToken.sol @@ -3,15 +3,15 @@ pragma solidity ^0.8.10; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import "../VBep20.sol"; +import "../VToken.sol"; import "../Governance/AccessControlManager.sol"; /** - * @title Venus's VBep20Immutable Contract + * @title Venus's VToken Contract * @notice VTokens which wrap an EIP-20 underlying and are immutable * @author Venus */ -contract UpgradedVBEP20 is VBep20, Initializable { +contract UpgradedVToken is VToken { /** * @notice Construct a new money market * @param underlying_ The address of the underlying asset @@ -25,7 +25,7 @@ contract UpgradedVBEP20 is VBep20, Initializable { * @param riskManagement Addresses of risk fund contracts */ - function initializeVToken( + function initializeV2( address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, @@ -36,12 +36,12 @@ contract UpgradedVBEP20 is VBep20, Initializable { address payable admin_, AccessControlManager accessControlManager_, RiskManagementInit memory riskManagement - ) public initializer { + ) public reinitializer(2) { // Creator of the contract is admin during initialization admin = payable(msg.sender); // Initialize the market - initialize( + initializeInternal( underlying_, comptroller_, interestRateModel_, diff --git a/contracts/test/VBep20Harness.sol b/contracts/test/VTokenHarness.sol similarity index 94% rename from contracts/test/VBep20Harness.sol rename to contracts/test/VTokenHarness.sol index 1e79d547a..c164f990c 100644 --- a/contracts/test/VBep20Harness.sol +++ b/contracts/test/VTokenHarness.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.10; -import "../VBep20Immutable.sol"; +import "../VToken.sol"; import "../Governance/AccessControlManager.sol"; import "./ComptrollerScenario.sol"; -contract VBEP20Harness is VBep20Immutable { +contract VTokenHarness is VToken { uint256 public blockNumber = 100000; uint256 public harnessExchangeRate; bool public harnessExchangeRateStored; @@ -24,7 +24,7 @@ contract VBEP20Harness is VBep20Immutable { AccessControlManager accessControlManager_, RiskManagementInit memory riskManagement ) { - initializeVToken( + initialize( underlying_, comptroller_, interestRateModel_, @@ -222,7 +222,7 @@ contract VBEP20Harness is VBep20Immutable { } } -contract VBep20Scenario is VBep20Immutable { +contract VTokenScenario is VToken { constructor( address underlying_, ComptrollerInterface comptroller_, @@ -233,9 +233,9 @@ contract VBep20Scenario is VBep20Immutable { uint8 decimals_, address payable admin_, AccessControlManager accessControlManager_, - VBep20Interface.RiskManagementInit memory riskManagement + VTokenInterface.RiskManagementInit memory riskManagement ) { - initializeVToken( + initialize( underlying_, comptroller_, interestRateModel_, @@ -265,7 +265,7 @@ contract VBep20Scenario is VBep20Immutable { } } -contract CEvil is VBep20Scenario { +contract VEvil is VTokenScenario { constructor( address underlying_, ComptrollerInterface comptroller_, @@ -276,9 +276,9 @@ contract CEvil is VBep20Scenario { uint8 decimals_, address payable admin_, AccessControlManager accessControlManager_, - VBep20Interface.RiskManagementInit memory riskManagement + VTokenInterface.RiskManagementInit memory riskManagement ) - VBep20Scenario( + VTokenScenario( underlying_, comptroller_, interestRateModel_, @@ -297,7 +297,7 @@ contract CEvil is VBep20Scenario { address liquidator, address borrower, uint256 seizeTokens - ) public returns (uint256) { - return treasure.seize(liquidator, borrower, seizeTokens); + ) public { + treasure.seize(liquidator, borrower, seizeTokens); } } diff --git a/tests/hardhat/Comptroller/accountLiquidityTest.ts b/tests/hardhat/Comptroller/accountLiquidityTest.ts index 2bd44a74c..c8655460b 100644 --- a/tests/hardhat/Comptroller/accountLiquidityTest.ts +++ b/tests/hardhat/Comptroller/accountLiquidityTest.ts @@ -8,7 +8,7 @@ const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, Comptroller__factory, PoolRegistry, AccessControlManager, VBep20Immutable, PriceOracle + Comptroller, Comptroller__factory, PoolRegistry, AccessControlManager, VToken, PriceOracle } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { Error } from "../util/Errors"; @@ -45,9 +45,9 @@ async function makeVToken( underlyingPrice?: string | number poolRegistry: FakeContract, } -): Promise> { +): Promise> { accessControl.isAllowedToCall.returns(true); - const vToken = await smock.fake("VBep20Immutable"); + const vToken = await smock.fake("VToken"); configureVToken({ vToken, comptroller, exchangeRate }); if (supportMarket) { const poolRegistrySigner = await ethers.getSigner(poolRegistry.address); @@ -69,7 +69,7 @@ async function makeVToken( } function configureVToken({ vToken, comptroller, exchangeRate }: { - vToken: FakeContract, + vToken: FakeContract, comptroller: MockContract, exchangeRate?: BigNumberish }) { diff --git a/tests/hardhat/Comptroller/assetsListTest.ts b/tests/hardhat/Comptroller/assetsListTest.ts index 79d1bd87d..8feb85b30 100644 --- a/tests/hardhat/Comptroller/assetsListTest.ts +++ b/tests/hardhat/Comptroller/assetsListTest.ts @@ -7,7 +7,7 @@ const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, PriceOracle, Comptroller__factory, VBep20Immutable, AccessControlManager, PoolRegistry + Comptroller, PriceOracle, Comptroller__factory, VToken, AccessControlManager, PoolRegistry } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { Error } from "../util/Errors"; @@ -19,21 +19,21 @@ describe("assetListTest", () => { let accounts: Signer[]; let comptroller: MockContract; let poolRegistry: FakeContract; - let OMG: FakeContract; - let ZRX: FakeContract; - let BAT: FakeContract; - let SKT: FakeContract; - let allTokens: FakeContract[]; + let OMG: FakeContract; + let ZRX: FakeContract; + let BAT: FakeContract; + let SKT: FakeContract; + let allTokens: FakeContract[]; type AssetListFixture = { accessControl: FakeContract; comptroller: MockContract, oracle: FakeContract, - OMG: FakeContract, - ZRX: FakeContract, - BAT: FakeContract, - SKT: FakeContract, - allTokens: FakeContract[], + OMG: FakeContract, + ZRX: FakeContract, + BAT: FakeContract, + SKT: FakeContract, + allTokens: FakeContract[], names: string[] }; @@ -49,7 +49,7 @@ describe("assetListTest", () => { const names = ["OMG", "ZRX", "BAT", "sketch"]; const [OMG, ZRX, BAT, SKT] = await Promise.all( names.map(async (name) => { - const vToken = await smock.fake("VBep20Immutable"); + const vToken = await smock.fake("VToken"); if (name !== "sketch") { const poolRegistryBalance = await poolRegistry.provider.getBalance(poolRegistry.address) if (poolRegistryBalance.isZero()) { @@ -87,7 +87,7 @@ describe("assetListTest", () => { ({ comptroller, OMG, ZRX, BAT, SKT, allTokens } = contracts); }); - async function checkMarkets(expectedTokens: FakeContract[]) { + async function checkMarkets(expectedTokens: FakeContract[]) { for (let token of allTokens) { const isExpected = expectedTokens.some(e => e == token); expect(await comptroller.checkMembership(await customer.getAddress(), token.address)).to.equal(isExpected); @@ -95,8 +95,8 @@ describe("assetListTest", () => { } async function enterAndCheckMarkets( - enterTokens: FakeContract[], - expectedTokens: FakeContract[], + enterTokens: FakeContract[], + expectedTokens: FakeContract[], expectedErrors: Error[] | null = null ) { const reply = await comptroller.connect(customer).callStatic.enterMarkets(enterTokens.map(t => t.address)); @@ -118,8 +118,8 @@ describe("assetListTest", () => { }; async function exitAndCheckMarkets( - exitToken: FakeContract, - expectedTokens: FakeContract[], + exitToken: FakeContract, + expectedTokens: FakeContract[], expectedError: Error = Error.NO_ERROR ) { const reply = await comptroller.connect(customer).callStatic.exitMarket(exitToken.address); diff --git a/tests/hardhat/Comptroller/healAccountTest.ts b/tests/hardhat/Comptroller/healAccountTest.ts index 59bf10550..4ff6e3de2 100644 --- a/tests/hardhat/Comptroller/healAccountTest.ts +++ b/tests/hardhat/Comptroller/healAccountTest.ts @@ -7,7 +7,7 @@ const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, PriceOracle, Comptroller__factory, VBep20Immutable, AccessControlManager, PoolRegistry + Comptroller, PriceOracle, Comptroller__factory, VToken, AccessControlManager, PoolRegistry } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; @@ -22,19 +22,19 @@ describe("healAccount", () => { let userAddress: string; let comptroller: MockContract; - let OMG: FakeContract; - let ZRX: FakeContract; - let BAT: FakeContract; + let OMG: FakeContract; + let ZRX: FakeContract; + let BAT: FakeContract; type HealAccountFixture = { accessControl: FakeContract; comptroller: MockContract, oracle: FakeContract, - OMG: FakeContract, - ZRX: FakeContract, - BAT: FakeContract, - SKT: FakeContract, - allTokens: FakeContract[], + OMG: FakeContract, + ZRX: FakeContract, + BAT: FakeContract, + SKT: FakeContract, + allTokens: FakeContract[], names: string[] }; @@ -52,7 +52,7 @@ describe("healAccount", () => { const names = ["OMG", "ZRX", "BAT"]; const [OMG, ZRX, BAT, SKT] = await Promise.all( names.map(async (name) => { - const vToken = await smock.fake("VBep20Immutable"); + const vToken = await smock.fake("VToken"); const poolRegistryBalance = await poolRegistry.provider.getBalance(poolRegistry.address) if (poolRegistryBalance.isZero()) { setBalance(await root.getAddress(), 100n ** 18n) diff --git a/tests/hardhat/Comptroller/liquidateCalculateAmountSeizeTest.ts b/tests/hardhat/Comptroller/liquidateCalculateAmountSeizeTest.ts index 16fc42c01..39c6f3522 100644 --- a/tests/hardhat/Comptroller/liquidateCalculateAmountSeizeTest.ts +++ b/tests/hardhat/Comptroller/liquidateCalculateAmountSeizeTest.ts @@ -8,7 +8,7 @@ const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, Comptroller__factory, PriceOracle, VBep20Immutable, PoolRegistry, AccessControlManager + Comptroller, Comptroller__factory, PriceOracle, VToken, PoolRegistry, AccessControlManager } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { Error } from "../util/Errors"; @@ -20,8 +20,8 @@ const repayAmount = convertToUnit(1, 18); async function calculateSeizeTokens( comptroller: MockContract, - vTokenBorrowed: FakeContract, - vTokenCollateral: FakeContract, + vTokenBorrowed: FakeContract, + vTokenCollateral: FakeContract, repayAmount: BigNumberish ) { return comptroller.liquidateCalculateSeizeTokens(vTokenBorrowed.address, vTokenCollateral.address, repayAmount); @@ -36,18 +36,18 @@ describe('Comptroller', () => { let accounts: Signer[]; let comptroller: MockContract; let oracle: FakeContract; - let vTokenBorrowed: FakeContract; - let vTokenCollateral: FakeContract; + let vTokenBorrowed: FakeContract; + let vTokenCollateral: FakeContract; type LiquidateFixture = { accessControl: FakeContract; comptroller: MockContract; oracle: FakeContract; - vTokenBorrowed: FakeContract; - vTokenCollateral: FakeContract; + vTokenBorrowed: FakeContract; + vTokenCollateral: FakeContract; }; - async function setOraclePrice(vToken: FakeContract, price: BigNumberish) { + async function setOraclePrice(vToken: FakeContract, price: BigNumberish) { oracle.getUnderlyingPrice.whenCalledWith(vToken.address).returns(price); } @@ -62,8 +62,8 @@ describe('Comptroller', () => { await comptroller._setPriceOracle(oracle.address); await comptroller._setLiquidationIncentive(convertToUnit("1.1", 18)); - const vTokenBorrowed = await smock.fake("VBep20Immutable"); - const vTokenCollateral = await smock.fake("VBep20Immutable"); + const vTokenBorrowed = await smock.fake("VToken"); + const vTokenCollateral = await smock.fake("VToken"); return { accessControl, comptroller, oracle, vTokenBorrowed, vTokenCollateral }; } diff --git a/tests/hardhat/Comptroller/pauseTest.ts b/tests/hardhat/Comptroller/pauseTest.ts index f81982130..1c95306ea 100644 --- a/tests/hardhat/Comptroller/pauseTest.ts +++ b/tests/hardhat/Comptroller/pauseTest.ts @@ -7,7 +7,7 @@ const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, PriceOracle, Comptroller__factory, VBep20Immutable, AccessControlManager, PoolRegistry + Comptroller, PriceOracle, Comptroller__factory, VToken, AccessControlManager, PoolRegistry } from "../../../typechain"; @@ -16,11 +16,11 @@ type PauseFixture = { comptroller: MockContract; poolRegistry: FakeContract; oracle: FakeContract; - OMG: FakeContract; - ZRX: FakeContract; - BAT: FakeContract; - SKT: FakeContract; - allTokens: FakeContract[]; + OMG: FakeContract; + ZRX: FakeContract; + BAT: FakeContract; + SKT: FakeContract; + allTokens: FakeContract[]; names: string[]; }; @@ -37,7 +37,7 @@ async function pauseFixture(): Promise { const names = ["OMG", "ZRX", "BAT", "sketch"]; const [OMG, ZRX, BAT, SKT] = await Promise.all( names.map(async (name) => { - const vToken = await smock.fake("VBep20Immutable"); + const vToken = await smock.fake("VToken"); if (name !== "sketch") { const poolRegistryBalance = await poolRegistry.provider.getBalance(poolRegistry.address) if (poolRegistryBalance.isZero()) { @@ -76,10 +76,10 @@ describe("Comptroller", () => { let accounts: Signer[]; let accessControl: FakeContract; let comptroller: MockContract; - let OMG: FakeContract; - let ZRX: FakeContract; - let BAT: FakeContract; - let SKT: FakeContract; + let OMG: FakeContract; + let ZRX: FakeContract; + let BAT: FakeContract; + let SKT: FakeContract; beforeEach(async () => { [root, customer, ...accounts] = await ethers.getSigners(); diff --git a/tests/hardhat/Tokens/accrueInterestTest.ts b/tests/hardhat/Tokens/accrueInterestTest.ts index 2ff3a88c8..24db05cca 100644 --- a/tests/hardhat/Tokens/accrueInterestTest.ts +++ b/tests/hardhat/Tokens/accrueInterestTest.ts @@ -8,7 +8,7 @@ import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); -import { VBEP20Harness, ERC20Harness, Comptroller, InterestRateModel, AccessControlManager } from "../../../typechain"; +import { VTokenHarness, InterestRateModel } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { vTokenTestFixture } from "../util/TokenTestHelpers"; @@ -18,7 +18,7 @@ const borrowIndex = convertToUnit("1", 18); const borrowRate = convertToUnit("0.000001", 18); async function pretendBlock( - vToken: MockContract, + vToken: MockContract, accrualBlock: number | string = blockNumber, deltaBlocks: number | string = 1 ) { @@ -28,7 +28,7 @@ async function pretendBlock( } async function preAccrue({ vToken, interestRateModel }: { - vToken: MockContract; + vToken: MockContract; interestRateModel: FakeContract; }) { interestRateModel.getBorrowRate.reset(); @@ -40,7 +40,7 @@ async function preAccrue({ vToken, interestRateModel }: { describe('VToken', () => { let root: Signer; let accounts: Signer[]; - let vToken: MockContract; + let vToken: MockContract; let interestRateModel: FakeContract; beforeEach(async () => { diff --git a/tests/hardhat/Tokens/adminTest.ts b/tests/hardhat/Tokens/adminTest.ts index d50ec006d..2ca0b2220 100644 --- a/tests/hardhat/Tokens/adminTest.ts +++ b/tests/hardhat/Tokens/adminTest.ts @@ -6,12 +6,12 @@ import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); -import { VBEP20Harness } from "../../../typechain"; +import { VTokenHarness } from "../../../typechain"; import { vTokenTestFixture } from "../util/TokenTestHelpers"; -describe('admin / _setPendingAdmin / _acceptAdmin', () => { - let vToken: MockContract; +describe('admin / setPendingAdmin / acceptAdmin', () => { + let vToken: MockContract; let root: Signer; let rootAddress: string; let guy: Signer; @@ -37,10 +37,10 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { }); }); - describe('_setPendingAdmin()', () => { + describe('setPendingAdmin()', () => { it('should only be callable by admin', async () => { - await expect(vToken.connect(guy)._setPendingAdmin(guyAddress)) - .to.be.revertedWithCustomError(vToken, 'SetPendingAdminOwnerCheck'); + await expect(vToken.connect(guy).setPendingAdmin(guyAddress)) + .to.be.revertedWithCustomError(vToken, 'OnlyAdminAllowed'); // Check admin stays the same expect(await vToken.admin()).to.equal(rootAddress); @@ -49,7 +49,7 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { it('should properly set pending admin', async () => { //expect( - await vToken._setPendingAdmin(guyAddress) + await vToken.setPendingAdmin(guyAddress) //).toSucceed(); // Check admin stays the same @@ -59,10 +59,10 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { it('should properly set pending admin twice', async () => { //expect( - await vToken._setPendingAdmin(guyAddress) + await vToken.setPendingAdmin(guyAddress) //).toSucceed(); //expect( - await vToken._setPendingAdmin(await accounts[1].getAddress()) + await vToken.setPendingAdmin(await accounts[1].getAddress()) //).toSucceed(); // Check admin stays the same @@ -71,16 +71,16 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { }); it('should emit event', async () => { - expect(await vToken._setPendingAdmin(guyAddress)) + expect(await vToken.setPendingAdmin(guyAddress)) .to.emit(vToken, "NewPendingAdmin") .withArgs(constants.AddressZero, guyAddress); }); }); - describe('_acceptAdmin()', () => { + describe('acceptAdmin()', () => { it('should fail when pending admin is zero', async () => { - await expect(vToken._acceptAdmin()) - .to.be.revertedWithCustomError(vToken, "AcceptAdminPendingAdminCheck"); + await expect(vToken.acceptAdmin()) + .to.be.revertedWithCustomError(vToken, "OnlyAdminAllowed"); // Check admin stays the same expect(await vToken.admin()).to.equal(rootAddress); @@ -89,10 +89,10 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { it('should fail when called by another account (e.g. root)', async () => { //expect( - await vToken._setPendingAdmin(guyAddress) + await vToken.setPendingAdmin(guyAddress) //).toSucceed(); - await expect(vToken._acceptAdmin()) - .to.be.revertedWithCustomError(vToken, "AcceptAdminPendingAdminCheck"); + await expect(vToken.acceptAdmin()) + .to.be.revertedWithCustomError(vToken, "OnlyAdminAllowed"); // Check admin stays the same expect(await vToken.admin()).to.equal(rootAddress); @@ -101,10 +101,10 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { it('should succeed and set admin and clear pending admin', async () => { //expect( - await vToken._setPendingAdmin(guyAddress) + await vToken.setPendingAdmin(guyAddress) //).toSucceed(); //expect( - await vToken.connect(guy)._acceptAdmin() + await vToken.connect(guy).acceptAdmin() //).toSucceed(); expect(await vToken.admin()).to.equal(guyAddress); @@ -113,9 +113,9 @@ describe('admin / _setPendingAdmin / _acceptAdmin', () => { it('should emit log on success', async () => { //expect( - await vToken._setPendingAdmin(guyAddress) + await vToken.setPendingAdmin(guyAddress) //).toSucceed(); - const result = await vToken.connect(guy)._acceptAdmin(); + const result = await vToken.connect(guy).acceptAdmin(); expect(result) .to.emit(vToken, "NewAdmin") .withArgs(rootAddress, guyAddress); diff --git a/tests/hardhat/Tokens/borrowAndRepayTest.ts b/tests/hardhat/Tokens/borrowAndRepayTest.ts index 5aaf3fafa..4f9bb647a 100644 --- a/tests/hardhat/Tokens/borrowAndRepayTest.ts +++ b/tests/hardhat/Tokens/borrowAndRepayTest.ts @@ -8,7 +8,7 @@ import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); -import { VBEP20Harness, ERC20Harness, Comptroller, InterestRateModel } from "../../../typechain"; +import { VTokenHarness, ERC20Harness, Comptroller, InterestRateModel } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { Error } from "../util/Errors"; import { @@ -41,7 +41,7 @@ async function preBorrow( } async function borrowFresh( - vToken: MockContract, + vToken: MockContract, borrower: Signer, borrowAmount: BigNumberish ) { @@ -49,7 +49,7 @@ async function borrowFresh( } async function borrow( - vToken: MockContract, + vToken: MockContract, borrower: Signer, borrowAmount: BigNumberish ) { @@ -81,7 +81,7 @@ async function preRepay( } async function repayBorrowFresh( - vToken: MockContract, + vToken: MockContract, payer: Signer, borrower: Signer, repayAmount: BigNumberish @@ -92,7 +92,7 @@ async function repayBorrowFresh( } async function repayBorrow( - vToken: MockContract, + vToken: MockContract, borrower: Signer, repayAmount: BigNumberish ) { @@ -102,7 +102,7 @@ async function repayBorrow( } async function repayBorrowBehalf( - vToken: MockContract, + vToken: MockContract, payer: Signer, borrower: Signer, repayAmount: BigNumberish @@ -115,7 +115,7 @@ async function repayBorrowBehalf( describe('VToken', function () { let contracts: VTokenTestFixture; let comptroller: FakeContract; - let vToken: MockContract; + let vToken: MockContract; let underlying: MockContract; let interestRateModel: FakeContract; let root: Signer; diff --git a/tests/hardhat/Tokens/liquidateTest.ts b/tests/hardhat/Tokens/liquidateTest.ts index c3f62b8db..7d68146b5 100644 --- a/tests/hardhat/Tokens/liquidateTest.ts +++ b/tests/hardhat/Tokens/liquidateTest.ts @@ -9,7 +9,7 @@ const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, VBEP20Harness, AccessControlManager, Shortfall + Comptroller, VTokenHarness, AccessControlManager, Shortfall } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { Error } from "../util/Errors"; @@ -83,11 +83,11 @@ function configure({ comptroller, accessControlManager, collateral, borrowed }: } async function liquidateFresh( - vToken: MockContract, + vToken: MockContract, liquidator: Signer, borrower: Signer, repayAmount: BigNumberish, - vTokenCollateral: MockContract, + vTokenCollateral: MockContract, skipLiquidityCheck: boolean = false ) { @@ -101,11 +101,11 @@ async function liquidateFresh( } async function liquidate( - vToken: MockContract, + vToken: MockContract, liquidator: Signer, borrower: Signer, repayAmount: BigNumberish, - vTokenCollateral: MockContract + vTokenCollateral: MockContract ) { // make sure to have a block delta so we accrue interest @@ -121,7 +121,7 @@ async function liquidate( } async function seize( - vToken: MockContract, + vToken: MockContract, liquidator: Signer, borrower: Signer, seizeAmount: BigNumberish diff --git a/tests/hardhat/Tokens/mintAndRedeemTest.ts b/tests/hardhat/Tokens/mintAndRedeemTest.ts index cd0937568..a9b5c6150 100644 --- a/tests/hardhat/Tokens/mintAndRedeemTest.ts +++ b/tests/hardhat/Tokens/mintAndRedeemTest.ts @@ -8,7 +8,7 @@ import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); -import { VBEP20Harness, ERC20Harness, Comptroller, InterestRateModel, AccessControlManager } from "../../../typechain"; +import { VTokenHarness, ERC20Harness, Comptroller, InterestRateModel } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; import { Error } from "../util/Errors"; import { @@ -46,7 +46,7 @@ async function preMint( } async function mintFresh( - vToken: MockContract, + vToken: MockContract, minter: Signer, mintAmount: BigNumberish ) { @@ -54,7 +54,7 @@ async function mintFresh( } async function preSupply( - vToken: MockContract, + vToken: MockContract, account: Signer, tokens: BigNumberish, opts: { supply?: boolean } = { supply: true } @@ -92,7 +92,7 @@ async function preRedeem( } async function redeemFreshTokens( - vToken: MockContract, + vToken: MockContract, redeemer: Signer, redeemTokens: BigNumberish, redeemAmount: BigNumberish @@ -102,7 +102,7 @@ async function redeemFreshTokens( } async function redeemFreshAmount( - vToken: MockContract, + vToken: MockContract, redeemer: Signer, redeemTokens: BigNumberish, redeemAmount: BigNumberish @@ -113,7 +113,7 @@ async function redeemFreshAmount( async function quickMint( underlying: MockContract, - vToken: MockContract, + vToken: MockContract, minter: Signer, mintAmount: BigNumberish, opts: { approve?: boolean, exchangeRate?: BigNumberish, faucet?: boolean } = { approve: true, faucet: true } @@ -135,7 +135,7 @@ async function quickMint( } async function quickRedeem( - vToken: MockContract, + vToken: MockContract, redeemer: Signer, redeemTokens: BigNumberish, opts: { supply?: boolean, exchangeRate?: BigNumberish } = { supply: true } @@ -156,7 +156,7 @@ async function quickRedeem( } async function quickRedeemUnderlying( - vToken: MockContract, + vToken: MockContract, redeemer: Signer, redeemAmount: BigNumberish, opts: { exchangeRate?: BigNumberish } = {} @@ -182,7 +182,7 @@ describe('VToken', function () { let contracts: VTokenTestFixture; let comptroller: FakeContract; - let vToken: MockContract; + let vToken: MockContract; let underlying: MockContract; let interestRateModel: FakeContract; diff --git a/tests/hardhat/Tokens/setComptrollerTest.ts b/tests/hardhat/Tokens/setComptrollerTest.ts index dd87c2d8a..cfac94a8f 100644 --- a/tests/hardhat/Tokens/setComptrollerTest.ts +++ b/tests/hardhat/Tokens/setComptrollerTest.ts @@ -6,7 +6,7 @@ import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); -import { AccessControlManager, VBEP20Harness, Comptroller } from "../../../typechain"; +import { AccessControlManager, VTokenHarness, Comptroller } from "../../../typechain"; import { vTokenTestFixture } from "../util/TokenTestHelpers"; @@ -17,7 +17,7 @@ async function setComptrollerTestFixture() { } describe('VToken', function () { - let vToken: MockContract; + let vToken: MockContract; let comptroller: FakeContract; let newComptroller: FakeContract; let accessControlManager: FakeContract; diff --git a/tests/hardhat/Tokens/transferTest.ts b/tests/hardhat/Tokens/transferTest.ts index ef000c97d..695f935c0 100644 --- a/tests/hardhat/Tokens/transferTest.ts +++ b/tests/hardhat/Tokens/transferTest.ts @@ -1,19 +1,13 @@ import { ethers } from "hardhat"; import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { Signer, BigNumberish, constants } from "ethers"; +import { Signer } from "ethers"; import { loadFixture } from "@nomicfoundation/hardhat-network-helpers"; -import { BigNumber } from "bignumber.js"; import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); -import { VBEP20Harness, ERC20Harness, Comptroller, InterestRateModel, AccessControlManager } from "../../../typechain"; -import { convertToUnit } from "../../../helpers/utils"; -import { Error } from "../util/Errors"; -import { - getBalances, adjustBalances, preApprove, - vTokenTestFixture, VTokenTestFixture -} from "../util/TokenTestHelpers"; +import { VTokenHarness, Comptroller } from "../../../typechain"; +import { vTokenTestFixture } from "../util/TokenTestHelpers"; import { PANIC_CODES } from "@nomicfoundation/hardhat-chai-matchers/panic"; describe('VToken', function () { @@ -22,7 +16,7 @@ describe('VToken', function () { let rootAddress: string; let guyAddress: string; let accounts: Signer[]; - let vToken: MockContract; + let vToken: MockContract; let comptroller: FakeContract; beforeEach(async () => { diff --git a/tests/hardhat/UpgradedVBEP20.ts b/tests/hardhat/UpgradedVToken.ts similarity index 88% rename from tests/hardhat/UpgradedVBEP20.ts rename to tests/hardhat/UpgradedVToken.ts index 2e377921f..c15d3f640 100644 --- a/tests/hardhat/UpgradedVBEP20.ts +++ b/tests/hardhat/UpgradedVToken.ts @@ -4,9 +4,9 @@ import { MockToken, PoolRegistry, Comptroller, - VBep20Immutable, + VToken, MockPriceOracle, - VBep20ImmutableProxyFactory, + VTokenProxyFactory, JumpRateModelFactory, WhitePaperInterestRateModelFactory, AccessControlManager, @@ -21,9 +21,9 @@ let poolRegistry: PoolRegistry; let comptroller1: Comptroller; let comptroller1Proxy: Comptroller; let mockWBTC: MockToken; -let vWBTC: VBep20Immutable; +let vWBTC: VToken; let priceOracle: MockPriceOracle; -let cTokenFactory: VBep20ImmutableProxyFactory; +let vTokenFactory: VTokenProxyFactory; let jumpRateFactory: JumpRateModelFactory; let whitePaperRateFactory: WhitePaperInterestRateModelFactory; let fakeAccessControlManager: FakeContract; @@ -31,18 +31,18 @@ let protocolShareReserve: ProtocolShareReserve; let riskFund: RiskFund; let transparentProxy: TransparentUpgradeableProxy; -describe("UpgradedVBEP20: Tests", function () { +describe("UpgradedVToken: Tests", function () { /** * Deploying required contracts along with the poolRegistry. */ let proxyAdmin; before(async function () { [, proxyAdmin] = await ethers.getSigners(); - const VBep20ImmutableProxyFactory = await ethers.getContractFactory( - "VBep20ImmutableProxyFactory" + const VTokenProxyFactory = await ethers.getContractFactory( + "VTokenProxyFactory" ); - cTokenFactory = await VBep20ImmutableProxyFactory.deploy(); - await cTokenFactory.deployed(); + vTokenFactory = await VTokenProxyFactory.deploy(); + await vTokenFactory.deployed(); const JumpRateModelFactory = await ethers.getContractFactory( "JumpRateModelFactory" @@ -79,7 +79,7 @@ describe("UpgradedVBEP20: Tests", function () { await protocolShareReserve.deployed(); await poolRegistry.initialize( - cTokenFactory.address, + vTokenFactory.address, jumpRateFactory.address, whitePaperRateFactory.address, shortfall.address, @@ -137,8 +137,8 @@ describe("UpgradedVBEP20: Tests", function () { await comptroller1Proxy.acceptAdmin(); - const VBep20Immutable = await ethers.getContractFactory("VBep20Immutable"); - const tokenImplementation = await VBep20Immutable.deploy(); + const VToken = await ethers.getContractFactory("VToken"); + const tokenImplementation = await VToken.deploy(); await tokenImplementation.deployed(); // Deploy VTokens @@ -165,11 +165,11 @@ describe("UpgradedVBEP20: Tests", function () { mockWBTC.address ); - vWBTC = await ethers.getContractAt("VBep20Immutable", vWBTCAddress); + vWBTC = await ethers.getContractAt("VToken", vWBTCAddress); }); it("Upgrade the vToken contract", async function () { - const vToken = await ethers.getContractFactory("UpgradedVBEP20"); + const vToken = await ethers.getContractFactory("UpgradedVToken"); const vTokenDeploy = await vToken.deploy(); await vTokenDeploy.deployed(); diff --git a/tests/hardhat/util/TokenTestHelpers.ts b/tests/hardhat/util/TokenTestHelpers.ts index 216b82a19..5355ed810 100644 --- a/tests/hardhat/util/TokenTestHelpers.ts +++ b/tests/hardhat/util/TokenTestHelpers.ts @@ -1,24 +1,21 @@ import { ethers } from "hardhat"; import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { Signer, BigNumberish, constants } from "ethers"; -import { loadFixture } from "@nomicfoundation/hardhat-network-helpers"; +import { Signer, BigNumberish } from "ethers"; import { BigNumber } from "bignumber.js"; import chai from "chai"; const { expect } = chai; chai.use(smock.matchers); import { - Comptroller, VBEP20Harness, ERC20Harness, VBEP20Harness__factory, InterestRateModel, - Shortfall, - ERC20Harness__factory, AccessControlManager, + Comptroller, VTokenHarness, ERC20Harness, VTokenHarness__factory, InterestRateModel, + Shortfall, ERC20Harness__factory, AccessControlManager, RiskFund, ProtocolShareReserve } from "../../../typechain"; import { convertToUnit } from "../../../helpers/utils"; -import { Error } from "../util/Errors"; export type VTokenContracts = { - vToken: MockContract; + vToken: MockContract; underlying: MockContract; interestRateModel: FakeContract; }; @@ -34,7 +31,7 @@ export async function makeVToken({ name, comptroller, accessControlManager, admi interestRateModel.isInterestRateModel.returns(true); const underlyingFactory = await smock.mock("ERC20Harness"); const underlying = await underlyingFactory.deploy(0, name, 18, name); - const vTokenFactory = await smock.mock("VBEP20Harness"); + const vTokenFactory = await smock.mock("VTokenHarness"); const riskFund = await smock.fake("RiskFund"); const protocolShareReserve = await smock.fake("ProtocolShareReserve"); const initialExchangeRateMantissa = convertToUnit("1", 18); @@ -61,7 +58,7 @@ export async function makeVToken({ name, comptroller, accessControlManager, admi export type VTokenTestFixture = { accessControlManager: FakeContract; comptroller: FakeContract; - vToken: MockContract; + vToken: MockContract; underlying: MockContract; interestRateModel: FakeContract; }; @@ -97,12 +94,12 @@ type HolderSnapshot = { } type BalanceDeltaEntry = - [MockContract, string, keyof HolderSnapshot, string | number] - | [MockContract, keyof HolderSnapshot, string | number]; + [MockContract, string, keyof HolderSnapshot, string | number] + | [MockContract, keyof HolderSnapshot, string | number]; export async function getBalances( - vTokens: MockContract[], + vTokens: MockContract[], accounts: string[] ): Promise { const balances: BalancesSnapshot = {}; @@ -130,7 +127,7 @@ export async function getBalances( export function adjustBalances(balances: BalancesSnapshot, deltas: BalanceDeltaEntry[]) { for (let delta of deltas) { - let vToken: MockContract; + let vToken: MockContract; let account: string; let key: keyof HolderSnapshot; let diff: string | number; @@ -148,7 +145,7 @@ export function adjustBalances(balances: BalancesSnapshot, deltas: BalanceDeltaE export async function preApprove( erc20: MockContract, - vToken: MockContract, + vToken: MockContract, from: Signer, amount: BigNumberish, opts: { faucet?: boolean } = {} @@ -161,7 +158,7 @@ export async function preApprove( } export async function pretendBorrow( - vToken: MockContract, + vToken: MockContract, borrower: Signer, accountIndex: number, marketIndex: number, diff --git a/tests/integration/index.ts b/tests/integration/index.ts index c411e6b7d..86e82feac 100644 --- a/tests/integration/index.ts +++ b/tests/integration/index.ts @@ -2,17 +2,14 @@ import { PoolRegistry, AccessControlManager, RiskFund, - VBep20ImmutableProxyFactory, + VTokenProxyFactory, JumpRateModelFactory, WhitePaperInterestRateModelFactory, ProtocolShareReserve, - PriceOracle, MockPriceOracle, Comptroller, VToken, MockToken, - VBep20, - VBep20Immutable, } from "../../typechain"; import chai from "chai"; import { smock } from "@defi-wonderland/smock"; @@ -35,8 +32,8 @@ const setupTest = deployments.createFixture( "AccessControlManager" ); const RiskFund = await ethers.getContract("RiskFund"); - const VBep20ImmutableFactory = await ethers.getContract( - "VBep20ImmutableProxyFactory" + const VTokenFactory = await ethers.getContract( + "VTokenProxyFactory" ); const JumpRateModelFactory = await ethers.getContract( "JumpRateModelFactory" @@ -65,8 +62,8 @@ const setupTest = deployments.createFixture( const vWBTCAddress = await PoolRegistry.getVTokenForAsset(Comptroller.address, wBTC.address); const vDAIAddress = await PoolRegistry.getVTokenForAsset(Comptroller.address, DAI.address); - const vWBTC = await ethers.getContractAt("VBep20Immutable", vWBTCAddress); - const vDAI = await ethers.getContractAt("VBep20Immutable", vDAIAddress); + const vWBTC = await ethers.getContractAt("VToken", vWBTCAddress); + const vDAI = await ethers.getContractAt("VToken", vDAIAddress); //Enter Markets @@ -92,7 +89,7 @@ const setupTest = deployments.createFixture( PoolRegistry, AccessControlManager, RiskFund, - VBep20ImmutableFactory, + VTokenFactory, JumpRateModelFactory, WhitePaperRateFactory, ProtocolShareReserve, @@ -115,14 +112,14 @@ describe("Positive Cases", () => { let PoolRegistry: PoolRegistry; let AccessControlManager: AccessControlManager; let RiskFund: RiskFund; - let VBep20ImmutableFactory: VBep20ImmutableProxyFactory; + let VTokenFactory: VTokenProxyFactory; let JumpRateModelFactory: JumpRateModelFactory; let WhitePaperRateFactory: WhitePaperInterestRateModelFactory; let ProtocolShareReserve: ProtocolShareReserve; let PriceOracle: MockPriceOracle; let Comptroller: Comptroller; - let vWBTC: VBep20Immutable; - let vDAI: VBep20Immutable; + let vWBTC: VToken; + let vDAI: VToken; let wBTC: MockToken; let DAI: MockToken; let deployer: string; @@ -135,7 +132,7 @@ describe("Positive Cases", () => { PoolRegistry, AccessControlManager, RiskFund, - VBep20ImmutableFactory, + VTokenFactory, JumpRateModelFactory, WhitePaperRateFactory, ProtocolShareReserve,