diff --git a/contracts/contracts/strategies/BridgedWOETHStrategy.sol b/contracts/contracts/strategies/BridgedWOETHStrategy.sol index a5ea8b9aa7..0b14783eb2 100644 --- a/contracts/contracts/strategies/BridgedWOETHStrategy.sol +++ b/contracts/contracts/strategies/BridgedWOETHStrategy.sol @@ -267,6 +267,7 @@ contract BridgedWOETHStrategy is InitializableAbstractStrategy { _asset != address(bridgedWOETH) && _asset != address(weth), "Cannot transfer supported asset" ); + // Use SafeERC20 only for rescuing unknown assets; core tokens are standard. IERC20(_asset).safeTransfer(governor(), _amount); } diff --git a/contracts/contracts/vault/VaultCore.sol b/contracts/contracts/vault/VaultCore.sol index 0be201183d..7498da79e5 100644 --- a/contracts/contracts/vault/VaultCore.sol +++ b/contracts/contracts/vault/VaultCore.sol @@ -85,7 +85,7 @@ abstract contract VaultCore is VaultInitializer { } // Mint oTokens - oUSD.mint(msg.sender, scaledAmount); + OToken.mint(msg.sender, scaledAmount); IERC20(asset).safeTransferFrom(msg.sender, address(this), _amount); @@ -129,14 +129,13 @@ abstract contract VaultCore is VaultInitializer { emit Mint(msg.sender, _amount); // Mint matching amount of OTokens - oUSD.mint(msg.sender, _amount); + OToken.mint(msg.sender, _amount); } /** * @notice Burn OTokens for an allowed Strategy * @param _amount Amount of OToken to burn * - * Todo: Maybe this is a comment that we can remove now? * @dev Notice: can't use `nonReentrant` modifier since the `redeem` function could * require withdrawal on an AMO strategy and that one can call `burnForStrategy` * while the execution of the `redeem` has not yet completed -> causing a `nonReentrant` collision. @@ -163,7 +162,7 @@ abstract contract VaultCore is VaultInitializer { emit Redeem(msg.sender, _amount); // Burn OTokens - oUSD.burn(msg.sender, _amount); + OToken.burn(msg.sender, _amount); } //////////////////////////////////////////////////// @@ -215,7 +214,7 @@ abstract contract VaultCore is VaultInitializer { }); // Burn the user's OToken - oUSD.burn(msg.sender, _amount); + OToken.burn(msg.sender, _amount); // Prevent withdrawal if the vault is solvent by more than the allowed percentage _postRedeem(_amount); @@ -362,7 +361,7 @@ abstract contract VaultCore is VaultInitializer { // Allow a max difference of maxSupplyDiff% between // asset value and OUSD total supply - uint256 diff = oUSD.totalSupply().divPrecisely(totalUnits); + uint256 diff = OToken.totalSupply().divPrecisely(totalUnits); require( (diff > 1e18 ? diff - 1e18 : 1e18 - diff) <= maxSupplyDiff, "Backing supply liquidity error" @@ -396,7 +395,7 @@ abstract contract VaultCore is VaultInitializer { if (assetAvailableInVault == 0) return; // Calculate the target buffer for the vault using the total supply - uint256 totalSupply = oUSD.totalSupply(); + uint256 totalSupply = OToken.totalSupply(); // Scaled to asset decimals uint256 targetBuffer = totalSupply.mulTruncate(vaultBuffer).scaleBy( assetDecimals, @@ -432,7 +431,7 @@ abstract contract VaultCore is VaultInitializer { * @return totalUnits Total balance of Vault in units */ function _rebase() internal whenNotRebasePaused returns (uint256) { - uint256 supply = oUSD.totalSupply(); + uint256 supply = OToken.totalSupply(); uint256 vaultValue = _totalValue(); // If no supply yet, do not rebase if (supply == 0) { @@ -457,15 +456,15 @@ abstract contract VaultCore is VaultInitializer { fee = (yield * trusteeFeeBps) / 1e4; if (fee > 0) { require(fee < yield, "Fee must not be greater than yield"); - oUSD.mint(_trusteeAddress, fee); + OToken.mint(_trusteeAddress, fee); } } emit YieldDistribution(_trusteeAddress, yield, fee); // Only ratchet OToken supply upwards // Final check uses latest totalSupply - if (newSupply > oUSD.totalSupply()) { - oUSD.changeSupply(newSupply); + if (newSupply > OToken.totalSupply()) { + OToken.changeSupply(newSupply); } return vaultValue; } @@ -476,17 +475,22 @@ abstract contract VaultCore is VaultInitializer { * @return yield amount of expected yield */ function previewYield() external view returns (uint256 yield) { - (yield, ) = _nextYield(oUSD.totalSupply(), _totalValue()); + (yield, ) = _nextYield(OToken.totalSupply(), _totalValue()); return yield; } + /** + * @dev Calculates the amount that would rebase at next rebase. + * See this Readme for detailed explanation: + * contracts/contracts/vault/README - Yield Limits.md + */ function _nextYield(uint256 supply, uint256 vaultValue) internal view virtual returns (uint256 yield, uint256 targetRate) { - uint256 nonRebasing = oUSD.nonRebasingSupply(); + uint256 nonRebasing = OToken.nonRebasingSupply(); uint256 rebasing = supply - nonRebasing; uint256 elapsed = block.timestamp - lastRebase; targetRate = rebasePerSecondTarget; diff --git a/contracts/contracts/vault/VaultInitializer.sol b/contracts/contracts/vault/VaultInitializer.sol index e1463a3eb9..54f159ba97 100644 --- a/contracts/contracts/vault/VaultInitializer.sol +++ b/contracts/contracts/vault/VaultInitializer.sol @@ -15,7 +15,7 @@ abstract contract VaultInitializer is VaultStorage { function initialize(address _oToken) external onlyGovernor initializer { require(_oToken != address(0), "oToken address is zero"); - oUSD = OUSD(_oToken); + OToken = OUSD(_oToken); rebasePaused = false; capitalPaused = true; diff --git a/contracts/contracts/vault/VaultStorage.sol b/contracts/contracts/vault/VaultStorage.sol index 00fc068449..e019b6fb6b 100644 --- a/contracts/contracts/vault/VaultStorage.sol +++ b/contracts/contracts/vault/VaultStorage.sol @@ -12,7 +12,7 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { IStrategy } from "../interfaces/IStrategy.sol"; -import { IWETH9 } from "../interfaces/IWETH9.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { Governable } from "../governance/Governable.sol"; import { OUSD } from "../token/OUSD.sol"; import { Initializable } from "../utils/Initializable.sol"; @@ -95,7 +95,7 @@ abstract contract VaultStorage is Initializable, Governable { uint256 public rebaseThreshold; /// @dev Address of the OToken token. eg OUSD or OETH. - OUSD public oUSD; + OUSD public OToken; /// @dev Address of the contract responsible for post rebase syncs with AMMs address private _deprecated_rebaseHooksAddr = address(0); @@ -217,7 +217,7 @@ abstract contract VaultStorage is Initializable, Governable { // slither-disable-end uninitialized-state constructor(address _asset) { - uint8 _decimals = IWETH9(_asset).decimals(); + uint8 _decimals = IERC20Metadata(_asset).decimals(); require(_decimals <= 18, "invalid asset decimals"); asset = _asset; assetDecimals = _decimals;