From f2c0c0b1a2f8ce3cdb9619e53eae3b0777603fad Mon Sep 17 00:00:00 2001 From: dglowinski Date: Fri, 29 Mar 2024 13:39:48 +0100 Subject: [PATCH 1/7] add natspec --- src/EVault/DToken.sol | 3 + src/EVault/Dispatch.sol | 7 +- src/EVault/EVault.sol | 37 ++++++-- src/EVault/IEVault.sol | 22 +++++ src/EVault/modules/BalanceForwarder.sol | 10 ++- src/EVault/modules/Borrowing.sol | 4 + src/EVault/modules/Governance.sol | 4 + src/EVault/modules/Initialize.sol | 4 + src/EVault/modules/Liquidation.sol | 4 + src/EVault/modules/RiskManager.sol | 4 + src/EVault/modules/Token.sol | 4 + src/EVault/modules/Vault.sol | 4 + src/EVault/shared/AssetTransfers.sol | 3 + src/EVault/shared/BalanceUtils.sol | 3 + src/EVault/shared/Base.sol | 3 + src/EVault/shared/BorrowUtils.sol | 3 + src/EVault/shared/Cache.sol | 8 +- src/EVault/shared/Constants.sol | 8 +- src/EVault/shared/EVCClient.sol | 3 + src/EVault/shared/Errors.sol | 3 + src/EVault/shared/Events.sol | 94 ++++++++++++++++++--- src/EVault/shared/LTVUtils.sol | 3 + src/EVault/shared/LiquidityUtils.sol | 3 + src/EVault/shared/Storage.sol | 7 ++ src/EVault/shared/lib/ConversionHelpers.sol | 3 + src/EVault/shared/lib/ProxyUtils.sol | 3 + src/EVault/shared/lib/RevertBytes.sol | 3 + src/EVault/shared/lib/SafeERC20Lib.sol | 3 + src/EVault/shared/types/AmountCap.sol | 16 ++-- src/EVault/shared/types/Assets.sol | 3 + src/EVault/shared/types/ConfigAmount.sol | 8 +- src/EVault/shared/types/Flags.sol | 3 + src/EVault/shared/types/LTVConfig.sol | 23 ++++- src/EVault/shared/types/Owed.sol | 6 +- src/EVault/shared/types/Shares.sol | 3 + src/EVault/shared/types/Snapshot.sol | 12 ++- src/EVault/shared/types/Types.sol | 5 +- src/EVault/shared/types/UserStorage.sol | 13 ++- src/EVault/shared/types/VaultCache.sol | 24 ++++++ src/EVault/shared/types/VaultStorage.sol | 31 ++++++- 40 files changed, 354 insertions(+), 53 deletions(-) diff --git a/src/EVault/DToken.sol b/src/EVault/DToken.sol index 7391a071..d6b706ff 100644 --- a/src/EVault/DToken.sol +++ b/src/EVault/DToken.sol @@ -6,6 +6,9 @@ import {Errors} from "./shared/Errors.sol"; import {Events} from "./shared/Events.sol"; import {IERC20, IEVault} from "./IEVault.sol"; +/// @title DToken +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Contract implements `Transfer` events and read only ERC20 interface for EVault's debt contract DToken is IERC20, Errors, Events { address public immutable eVault; diff --git a/src/EVault/Dispatch.sol b/src/EVault/Dispatch.sol index 1345f21f..d869fd66 100644 --- a/src/EVault/Dispatch.sol +++ b/src/EVault/Dispatch.sol @@ -15,6 +15,9 @@ import {RiskManagerModule} from "./modules/RiskManager.sol"; import "./shared/Constants.sol"; +/// @title Dispatch +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Contract which ties in the EVault modules and provides utilities for routing calls to modules and the EVC abstract contract Dispatch is Base, InitializeModule, @@ -78,6 +81,8 @@ abstract contract Dispatch is } } + // External function which is only callable by the EVault itself. It's purpose is to be static called by `delegateToModuleView` + // which allows delegate-calling modules also for external view functions. function viewDelegate() external { if (msg.sender != address(this)) revert E_Unauthorized(); @@ -122,7 +127,7 @@ abstract contract Dispatch is // Modifier ensures, that the body of the function is always executed from the EVC call. // It is accomplished by intercepting calls incoming directly to the vault and passing them - // to the EVC.call function. EVC calls the vault back with original calldata. As a result, the account + // to the EVC.call function. EVC calls the vault back with original calldata. As a result, the account // and vault status checks are always executed in the checks deferral frame, at the end of the call, // outside of the vault's re-entrancy protections. // The modifier is applied to all functions which schedule account or vault status checks. diff --git a/src/EVault/EVault.sol b/src/EVault/EVault.sol index c1756513..7bcd4b5f 100644 --- a/src/EVault/EVault.sol +++ b/src/EVault/EVault.sol @@ -4,17 +4,26 @@ pragma solidity ^0.8.0; import {Dispatch} from "./Dispatch.sol"; +/// @title EVault +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice This contract implements an EVC enabled lending vault +/// @notice White paper: https://github.com/euler-xyz/euler-docusaurus/blob/main/docs/euler-vault-kit-white-paper/index.md +/// @dev The responsibility of this contract is call routing. Select functions are embedded, while most are delegated to the modules. contract EVault is Dispatch { constructor(Integrations memory integrations, DeployedModules memory modules) Dispatch(integrations, modules) {} - // ------------ Initialization ------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // INITIALIZATION // + /////////////////////////////////////////////////////////////////////////////////////////////// function initialize(address proxyCreator) public virtual override use(MODULE_INITIALIZE) {} - // ----------------- Token ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // TOKEN // + /////////////////////////////////////////////////////////////////////////////////////////////// function name() public view virtual override useView(MODULE_TOKEN) returns (string memory) {} @@ -39,7 +48,9 @@ contract EVault is Dispatch { - // ----------------- Vault ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // VAULT // + /////////////////////////////////////////////////////////////////////////////////////////////// function asset() public view virtual override returns (address) { return super.asset(); } @@ -84,7 +95,9 @@ contract EVault is Dispatch { - // ----------------- Borrowing ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // BORROWING // + /////////////////////////////////////////////////////////////////////////////////////////////// function totalBorrows() public view virtual override useView(MODULE_BORROWING) returns (uint256) {} @@ -121,7 +134,9 @@ contract EVault is Dispatch { - // ----------------- Liquidation ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // LIQUIDATION // + /////////////////////////////////////////////////////////////////////////////////////////////// function checkLiquidation(address liquidator, address violator, address collateral) public view virtual override useView(MODULE_LIQUIDATION) returns (uint256 maxRepay, uint256 maxYield) {} @@ -129,7 +144,9 @@ contract EVault is Dispatch { - // ----------------- RiskManager ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // RISK MANAGEMENT // + /////////////////////////////////////////////////////////////////////////////////////////////// function accountLiquidity(address account, bool liquidation) public view virtual override useView(MODULE_RISKMANAGER) returns (uint256 collateralValue, uint256 liabilityValue) {} @@ -144,7 +161,9 @@ contract EVault is Dispatch { - // ----------------- Balance Forwarder ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // BALANCE TRACKING // + /////////////////////////////////////////////////////////////////////////////////////////////// function balanceTrackerAddress() public view virtual override useView(MODULE_BALANCE_FORWARDER) returns (address) {} @@ -157,7 +176,9 @@ contract EVault is Dispatch { - // ----------------- Governance ----------------- + /////////////////////////////////////////////////////////////////////////////////////////////// + // GOVERNANCE // + /////////////////////////////////////////////////////////////////////////////////////////////// function governorAdmin() public view virtual override useView(MODULE_GOVERNANCE) returns (address) {} diff --git a/src/EVault/IEVault.sol b/src/EVault/IEVault.sol index 537bd822..9ff16b33 100644 --- a/src/EVault/IEVault.sol +++ b/src/EVault/IEVault.sol @@ -6,12 +6,16 @@ import {IVault as IEVCVault} from "ethereum-vault-connector/interfaces/IVault.so // Full interface of EVault and all it's modules +/// @title IInitialize +/// @notice Interface of the initialization module of EVault interface IInitialize { /// @notice Initialization of the newly deployed proxy contract /// @param proxyCreator Account which created the proxy or should be the initial governor function initialize(address proxyCreator) external; } +/// @title IERC20 +/// @notice Interface of an ERC20 token interface IERC20 { /// @notice Vault share token (eToken) name, ie "Euler Vault: DAI" function name() external view returns (string memory); @@ -50,6 +54,8 @@ interface IERC20 { function approve(address spender, uint256 amount) external returns (bool); } +/// @title IToken +/// @notice Interface of the EVault's Token module interface IToken is IERC20 { /// @notice Transfer the full eToken balance of an address to another /// @param from This address must've approved the to address @@ -57,6 +63,8 @@ interface IToken is IERC20 { function transferFromMax(address from, address to) external returns (bool); } +/// @title IERC4626 +/// @notice Interface of an ERC4626 vault interface IERC4626 { /// @notice Vault underlying asset function asset() external view returns (address); @@ -134,6 +142,8 @@ interface IERC4626 { function redeem(uint256 amount, address receiver, address owner) external returns (uint256); } +/// @title IVault +/// @notice Interface of the EVault's Vault module interface IVault is IERC4626 { /// @notice Balance of the fees accumulator, in eTokens function accumulatedFees() external view returns (uint256); @@ -152,6 +162,8 @@ interface IVault is IERC4626 { function skim(uint256 amount, address receiver) external returns (uint256); } +/// @title IBorrowing +/// @notice Interface of the EVault's Borrowing module interface IBorrowing { /// @notice Sum of all outstanding debts, in underlying units (increases as interest is accrued) function totalBorrows() external view returns (uint256); @@ -223,6 +235,8 @@ interface IBorrowing { function touch() external; } +/// @title ILiquidation +/// @notice Interface of the EVault's Liquidation module interface ILiquidation { /// @notice Checks to see if a liquidation would be profitable, without actually doing anything /// @param liquidator Address that will initiate the liquidation @@ -243,6 +257,8 @@ interface ILiquidation { function liquidate(address violator, address collateral, uint256 repayAssets, uint256 minYieldBalance) external; } +/// @title IRiskManager +/// @notice Interface of the EVault's RiskManager module interface IRiskManager is IEVCVault { /// @notice Retrieve account's total liquidity /// @param account Account holding debt in this vault @@ -280,6 +296,8 @@ interface IRiskManager is IEVCVault { function checkVaultStatus() external returns (bytes4); } +/// @title IBalanceForwarder +/// @notice Interface of the EVault's BalanceForwarder module interface IBalanceForwarder { /// @notice Retrieve the address of rewards contract, tracking changes in account's balances function balanceTrackerAddress() external view returns (address); @@ -298,6 +316,8 @@ interface IBalanceForwarder { function disableBalanceForwarder() external; } +/// @title IGovernance +/// @notice Interface of the EVault's Governance module interface IGovernance { /// @notice Retrieves the address of the governor function governorAdmin() external view returns (address); @@ -408,6 +428,8 @@ interface IGovernance { function setInterestFee(uint16 newFee) external; } +/// @title IEVault +/// @notice Interface of the EVault, an EVC enabled lending vault interface IEVault is IInitialize, IToken, diff --git a/src/EVault/modules/BalanceForwarder.sol b/src/EVault/modules/BalanceForwarder.sol index 92460e00..b9ccd033 100644 --- a/src/EVault/modules/BalanceForwarder.sol +++ b/src/EVault/modules/BalanceForwarder.sol @@ -5,6 +5,9 @@ pragma solidity ^0.8.0; import {IBalanceForwarder} from "../IEVault.sol"; import {Base} from "../shared/Base.sol"; +/// @title BalanceForwarderModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling communication with balance tracker contract. abstract contract BalanceForwarderModule is IBalanceForwarder, Base { /// @inheritdoc IBalanceForwarder function balanceTrackerAddress() public view virtual reentrantOK returns (address) { @@ -13,7 +16,7 @@ abstract contract BalanceForwarderModule is IBalanceForwarder, Base { /// @inheritdoc IBalanceForwarder function balanceForwarderEnabled(address account) public view virtual reentrantOK returns (bool) { - return vaultStorage.users[account].getBalanceForwarderEnabled(); + return vaultStorage.users[account].isBalanceForwarderEnabled(); } /// @inheritdoc IBalanceForwarder @@ -21,7 +24,7 @@ abstract contract BalanceForwarderModule is IBalanceForwarder, Base { if (address(balanceTracker) == address(0)) revert E_BalanceForwarderUnsupported(); address account = EVCAuthenticate(); - bool wasBalanceForwarderEnabled = vaultStorage.users[account].getBalanceForwarderEnabled(); + bool wasBalanceForwarderEnabled = vaultStorage.users[account].isBalanceForwarderEnabled(); vaultStorage.users[account].setBalanceForwarder(true); balanceTracker.balanceTrackerHook(account, vaultStorage.users[account].getBalance().toUint(), false); @@ -34,7 +37,7 @@ abstract contract BalanceForwarderModule is IBalanceForwarder, Base { if (address(balanceTracker) == address(0)) revert E_BalanceForwarderUnsupported(); address account = EVCAuthenticate(); - bool wasBalanceForwarderEnabled = vaultStorage.users[account].getBalanceForwarderEnabled(); + bool wasBalanceForwarderEnabled = vaultStorage.users[account].isBalanceForwarderEnabled(); vaultStorage.users[account].setBalanceForwarder(false); balanceTracker.balanceTrackerHook(account, 0, false); @@ -43,6 +46,7 @@ abstract contract BalanceForwarderModule is IBalanceForwarder, Base { } } +/// @dev Deployable contract contract BalanceForwarder is BalanceForwarderModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Borrowing.sol b/src/EVault/modules/Borrowing.sol index 61848424..cbdf2db0 100644 --- a/src/EVault/modules/Borrowing.sol +++ b/src/EVault/modules/Borrowing.sol @@ -17,6 +17,9 @@ interface IFlashLoan { function onFlashLoan(bytes memory data) external; } +/// @title BorrowingModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling borrowing and repaying of vault assets abstract contract BorrowingModule is IBorrowing, Base, AssetTransfers, BalanceUtils, LiquidityUtils { using TypesLib for uint256; using SafeERC20Lib for IERC20; @@ -226,6 +229,7 @@ abstract contract BorrowingModule is IBorrowing, Base, AssetTransfers, BalanceUt } } +/// @dev Deployable contract contract Borrowing is BorrowingModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Governance.sol b/src/EVault/modules/Governance.sol index a00ee471..56254f2f 100644 --- a/src/EVault/modules/Governance.sol +++ b/src/EVault/modules/Governance.sol @@ -12,6 +12,9 @@ import {ProxyUtils} from "../shared/lib/ProxyUtils.sol"; import "../shared/types/Types.sol"; +/// @title GovernanceModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling governance, including configuration and fees abstract contract GovernanceModule is IGovernance, Base, BalanceUtils, BorrowUtils, LTVUtils { using TypesLib for uint16; @@ -285,6 +288,7 @@ abstract contract GovernanceModule is IGovernance, Base, BalanceUtils, BorrowUti } } +/// @dev Deployable contract contract Governance is GovernanceModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Initialize.sol b/src/EVault/modules/Initialize.sol index 4a5986b8..2000cdf4 100644 --- a/src/EVault/modules/Initialize.sol +++ b/src/EVault/modules/Initialize.sol @@ -12,6 +12,9 @@ import {VaultCache} from "../shared/types/VaultCache.sol"; import "../shared/Constants.sol"; import "../shared/types/Types.sol"; +/// @title InitializeModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module implementing the initialization of the new vault contract abstract contract InitializeModule is IInitialize, Base, BorrowUtils { using TypesLib for uint16; @@ -57,6 +60,7 @@ abstract contract InitializeModule is IInitialize, Base, BorrowUtils { } } +/// @dev Deployable contract contract Initialize is InitializeModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Liquidation.sol b/src/EVault/modules/Liquidation.sol index ced1f870..8e690a20 100644 --- a/src/EVault/modules/Liquidation.sol +++ b/src/EVault/modules/Liquidation.sol @@ -9,6 +9,9 @@ import {LiquidityUtils} from "../shared/LiquidityUtils.sol"; import "../shared/types/Types.sol"; +/// @title LiquidationModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling liquidations of unhealthy accounts abstract contract LiquidationModule is ILiquidation, Base, BalanceUtils, LiquidityUtils { using TypesLib for uint256; @@ -216,6 +219,7 @@ abstract contract LiquidationModule is ILiquidation, Base, BalanceUtils, Liquidi } } +/// @dev Deployable contract contract Liquidation is LiquidationModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/RiskManager.sol b/src/EVault/modules/RiskManager.sol index 6b0adcd2..85fcec78 100644 --- a/src/EVault/modules/RiskManager.sol +++ b/src/EVault/modules/RiskManager.sol @@ -8,6 +8,9 @@ import {LiquidityUtils} from "../shared/LiquidityUtils.sol"; import "../shared/types/Types.sol"; +/// @title RiskManagerModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling risk management, including vault and account health checks abstract contract RiskManagerModule is IRiskManager, Base, LiquidityUtils { using TypesLib for uint256; @@ -113,6 +116,7 @@ abstract contract RiskManagerModule is IRiskManager, Base, LiquidityUtils { } } +/// @dev Deployable contract contract RiskManager is RiskManagerModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Token.sol b/src/EVault/modules/Token.sol index 3cce545d..4d957e67 100644 --- a/src/EVault/modules/Token.sol +++ b/src/EVault/modules/Token.sol @@ -9,6 +9,9 @@ import {ProxyUtils} from "../shared/lib/ProxyUtils.sol"; import "../shared/types/Types.sol"; +/// @title TokenModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling ERC20 behaviour of vault shares abstract contract TokenModule is IToken, Base, BalanceUtils { using TypesLib for uint256; @@ -79,6 +82,7 @@ abstract contract TokenModule is IToken, Base, BalanceUtils { } } +/// @dev Deployable contract contract Token is TokenModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Vault.sol b/src/EVault/modules/Vault.sol index f010b48d..3798ea4e 100644 --- a/src/EVault/modules/Vault.sol +++ b/src/EVault/modules/Vault.sol @@ -11,6 +11,9 @@ import {ProxyUtils} from "../shared/lib/ProxyUtils.sol"; import "../shared/types/Types.sol"; +/// @title BalanceForwarderModule +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice An EVault module handling ERC4626 standard behaviour abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils { using TypesLib for uint256; using SafeERC20Lib for IERC20; @@ -267,6 +270,7 @@ abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils { } } +/// @dev Deployable contract contract Vault is VaultModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/shared/AssetTransfers.sol b/src/EVault/shared/AssetTransfers.sol index e87daa79..a8d443a1 100644 --- a/src/EVault/shared/AssetTransfers.sol +++ b/src/EVault/shared/AssetTransfers.sol @@ -7,6 +7,9 @@ import {Base} from "./Base.sol"; import "./types/Types.sol"; +/// @title AssetTransfers +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Transfer assets into and out of the vault abstract contract AssetTransfers is Base { using TypesLib for uint256; using SafeERC20Lib for IERC20; diff --git a/src/EVault/shared/BalanceUtils.sol b/src/EVault/shared/BalanceUtils.sol index 4f25ae0a..391329bd 100644 --- a/src/EVault/shared/BalanceUtils.sol +++ b/src/EVault/shared/BalanceUtils.sol @@ -7,6 +7,9 @@ import {IBalanceTracker} from "../../interfaces/IBalanceTracker.sol"; import "./types/Types.sol"; +/// @title BalanceUtils +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Utilities for tracking shares balances and allowances abstract contract BalanceUtils is Base { using TypesLib for uint256; diff --git a/src/EVault/shared/Base.sol b/src/EVault/shared/Base.sol index c20bf517..2856b34b 100644 --- a/src/EVault/shared/Base.sol +++ b/src/EVault/shared/Base.sol @@ -11,6 +11,9 @@ import {IBalanceTracker} from "../../interfaces/IBalanceTracker.sol"; import "./types/Types.sol"; +/// @title Base +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Base contract for EVault modules with top level modifiers and utilities abstract contract Base is EVCClient, Cache { IProtocolConfig immutable protocolConfig; IBalanceTracker immutable balanceTracker; diff --git a/src/EVault/shared/BorrowUtils.sol b/src/EVault/shared/BorrowUtils.sol index 299ec673..94eea646 100644 --- a/src/EVault/shared/BorrowUtils.sol +++ b/src/EVault/shared/BorrowUtils.sol @@ -8,6 +8,9 @@ import {IIRM} from "../../InterestRateModels/IIRM.sol"; import "./types/Types.sol"; +/// @title BorrowUtils +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Utilities for tracking debt and interest rates abstract contract BorrowUtils is Base { using TypesLib for uint256; diff --git a/src/EVault/shared/Cache.sol b/src/EVault/shared/Cache.sol index 35ae7333..e46ec829 100644 --- a/src/EVault/shared/Cache.sol +++ b/src/EVault/shared/Cache.sol @@ -10,6 +10,9 @@ import {ProxyUtils} from "./lib/ProxyUtils.sol"; import "./types/Types.sol"; +/// @title Cache +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Load vault storage into memory, update it with accrued interest contract Cache is Storage, Errors { using TypesLib for uint256; using SafeERC20Lib for IERC20; @@ -61,12 +64,12 @@ contract Cache is Storage, Errors { vaultCache.interestAccumulator = vaultStorage.interestAccumulator; // Update interest accumulator and fees balance - uint256 deltaT = block.timestamp - vaultCache.lastInterestAccumulatorUpdate; + uint256 deltaT = block.timestamp - vaultCache.lastInterestAccumulatorUpdate; if (deltaT > 0) { dirty = true; - // Compute new values. Use full precision for intermediate results. + // Compute new cache values. Use full precision for intermediate results. ConfigAmount interestFee = vaultStorage.interestFee; uint256 interestRate = vaultStorage.interestRate; @@ -76,6 +79,7 @@ contract Cache is Storage, Errors { unchecked { (uint256 multiplier, bool overflow) = RPow.rpow(interestRate + 1e27, deltaT, 1e27); + // if exponentiation or accumulator update overflows, keep the old accumulator if (!overflow) { uint256 intermediate = newInterestAccumulator * multiplier; if (newInterestAccumulator == intermediate / multiplier) { diff --git a/src/EVault/shared/Constants.sol b/src/EVault/shared/Constants.sol index 08bcb61e..53e01929 100644 --- a/src/EVault/shared/Constants.sol +++ b/src/EVault/shared/Constants.sol @@ -1,10 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; -// TODO merge with IRM updates -uint256 constant SECONDS_PER_YEAR = 365.2425 * 86400; // Gregorian calendar -uint256 constant MAX_ALLOWED_INTEREST_RATE = 291867236321699131285; // 1,000,000% APY: ln(1 + (1000000 / 100)) * 1e27 / (365.2425 * 86400) - // Implementation internals // asset amounts are shifted left by this number of bits for increased precision of debt tracking. @@ -15,6 +11,10 @@ uint256 constant MAX_SANE_AMOUNT = type(uint112).max; uint256 constant MAX_SANE_DEBT_AMOUNT = uint256(MAX_SANE_AMOUNT) << INTERNAL_DEBT_PRECISION; // proxy trailing calldata length in bytes. Three addresses, 20 bytes each: vault underlying asset, oracle and unit of account. uint256 constant PROXY_METADATA_LENGTH = 60; +// gregorian calendar +uint256 constant SECONDS_PER_YEAR = 365.2425 * 86400; +// max interest rate accepted from interest rate model contract. 1,000,000% APY: ln(1 + (1000000 / 100)) * 1e27 / (365.2425 * 86400) +uint256 constant MAX_ALLOWED_INTEREST_RATE = 291867236321699131285; // Account status checks special values diff --git a/src/EVault/shared/EVCClient.sol b/src/EVault/shared/EVCClient.sol index 6115b4d9..fc85f173 100644 --- a/src/EVault/shared/EVCClient.sol +++ b/src/EVault/shared/EVCClient.sol @@ -11,6 +11,9 @@ import "./Constants.sol"; import {IERC20} from "../IEVault.sol"; import {IEVC} from "ethereum-vault-connector/interfaces/IEthereumVaultConnector.sol"; +/// @title EVCClient +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Utilities for interacting with the EVC (Ethereum Vault Connector) abstract contract EVCClient is Storage, Events, Errors { IEVC immutable evc; diff --git a/src/EVault/shared/Errors.sol b/src/EVault/shared/Errors.sol index 9b621d65..a2264973 100644 --- a/src/EVault/shared/Errors.sol +++ b/src/EVault/shared/Errors.sol @@ -2,6 +2,9 @@ pragma solidity ^0.8.0; +/// @title Errors +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Defines EVault custom errors contract Errors { error E_Initialized(); error E_ProxyMetadata(); diff --git a/src/EVault/shared/Events.sol b/src/EVault/shared/Events.sol index bda9c35c..39441e06 100644 --- a/src/EVault/shared/Events.sol +++ b/src/EVault/shared/Events.sol @@ -2,32 +2,59 @@ pragma solidity ^0.8.0; -import {LTVConfig} from "./types/LTVConfig.sol"; - +/// @title Events +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice This contract implements Evault's events abstract contract Events { - event EVaultCreated(address indexed creator, address indexed asset, address dToken); + // ERC20 + /// @notice Transfer an ERC20 token balance + /// @param from Sender address + /// @param to Receiver address + /// @param value Tokens sent event Transfer(address indexed from, address indexed to, uint256 value); + + /// @notice Set an ERC20 approval + /// @param owner Address granting approval to spend tokens + /// @param spender Address receiving approval to spend tokens + /// @param value Amount of tokens approved to spend event Approval(address indexed owner, address indexed spender, uint256 value); + // ERC4626 + + /// @notice Deposit assets into an ERC4626 vault + /// @param sender Address initiaiting the deposit + /// @param owner Address holding the assets + /// @param assets Amount of assets deposited + /// @param shares Amount of shares minted as recipt for the deposit event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + + /// @notice Withdraw from an ERC4626 vault + /// @param sender Address initiating the withdrawal + /// @param receiver Address receiving the assets + /// @param owner Address holding the shares + /// @param assets Amount of assets sent to receiver + /// @param shares Amount of shares burned event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); - event Borrow(address indexed account, uint256 assets); - event Repay(address indexed account, uint256 assets); - - event DebtSocialized(address indexed account, uint256 assets); + // EVault - event ConvertFees( - address indexed sender, - address indexed protocolReceiver, - address indexed governorReceiver, - uint256 protocolShares, - uint256 governorShares - ); + /// @notice New EVault is initialized + /// @param creator The address calling the factory + /// @param asset The underlying asset of the vault + /// @param dToken Address of the sidecar debt tracking token + event EVaultCreated(address indexed creator, address indexed asset, address dToken); + /// @notice Log the current vault status + /// @param totalShares Sum of all shares + /// @param totalBorrows Sum of all borrows in assets + /// @param accumulatedFees Interest fees accrued in the accumulator + /// @param cash The amount of assets held by the vault directly + /// @param interestAccumulator Current interest accumulator in ray + /// @param interestRate Current interest rate, which will be applied during the next fee accrual + /// @param timestamp Current block's timestamp event VaultStatus( uint256 totalShares, uint256 totalBorrows, @@ -37,6 +64,23 @@ abstract contract Events { uint256 interestRate, uint256 timestamp ); + + /// @notice Increase account's debt + /// @param account Address adding liability + /// @param assets Amount of debt added in assets + event Borrow(address indexed account, uint256 assets); + + /// @notice Decrease account's debt + /// @param account Address repaying the debt + /// @param assets Amount of debt removed in assets + event Repay(address indexed account, uint256 assets); + + /// @notice Liquidate unhealthy account + /// @param liquidator Address executing the liquidation + /// @param violator Address holding an unhealthy borrow + /// @param collateral Address of the asset seized + /// @param repayAssets Amount of debt in assets transfered from violator to liquidator + /// @param yieldBalance Amount of collateral asset's balance transfer from violator to liquidator event Liquidate( address indexed liquidator, address indexed violator, @@ -45,5 +89,27 @@ abstract contract Events { uint256 yieldBalance ); + /// @notice Socialize debt after liquidating all of the unhealthy account's collateral + /// @param account Address holding an unhealthy borrow + /// @param assets Amount of debt socialized among all of the share holders + event DebtSocialized(address indexed account, uint256 assets); + + /// @notice Split the accumulated fees between the governor and the protocol + /// @param sender Address initializing the conversion + /// @param protocolReceiver Address receiving the protocol's share of fees + /// @param governorReceiver Address receiving the governor's share of fees + /// @param protocolShares Amount of shares tranfered to the protocol receiver + /// @param governorShares Amount of shares tranfered to the governor receiver + event ConvertFees( + address indexed sender, + address indexed protocolReceiver, + address indexed governorReceiver, + uint256 protocolShares, + uint256 governorShares + ); + + /// @notice Enable or disable balance tracking for the account + /// @param account Address which enabled or disabled balance tracking + /// @param status True if balance tracking was enabled, false otherwise event BalanceForwarderStatus(address indexed account, bool status); } diff --git a/src/EVault/shared/LTVUtils.sol b/src/EVault/shared/LTVUtils.sol index ad0c9172..2b096a52 100644 --- a/src/EVault/shared/LTVUtils.sol +++ b/src/EVault/shared/LTVUtils.sol @@ -5,6 +5,9 @@ pragma solidity ^0.8.0; import {Storage} from "./Storage.sol"; import "./types/Types.sol"; +/// @title LTVUtils +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Overridable getters for LTV configuration abstract contract LTVUtils is Storage { function getLTV(address collateral, LTVType ltvType) internal view virtual returns (ConfigAmount) { return vaultStorage.ltvLookup[collateral].getLTV(ltvType); diff --git a/src/EVault/shared/LiquidityUtils.sol b/src/EVault/shared/LiquidityUtils.sol index af322e92..a4ff1fd5 100644 --- a/src/EVault/shared/LiquidityUtils.sol +++ b/src/EVault/shared/LiquidityUtils.sol @@ -7,6 +7,9 @@ import {LTVUtils} from "./LTVUtils.sol"; import "./types/Types.sol"; +/// @title LiquidityUtils +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Utilities for calculating account liquidity and health status abstract contract LiquidityUtils is BorrowUtils, LTVUtils { using TypesLib for uint256; diff --git a/src/EVault/shared/Storage.sol b/src/EVault/shared/Storage.sol index 6406c5ff..9e9f0e05 100644 --- a/src/EVault/shared/Storage.sol +++ b/src/EVault/shared/Storage.sol @@ -4,10 +4,17 @@ pragma solidity ^0.8.0; import {VaultStorage, Snapshot} from "./types/Types.sol"; +/// @title Storage +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Contract defines the EVault's data storage abstract contract Storage { + /// @notice Flag indicating if the vault has been initialized bool initialized; + /// @notice Snapshot of vault's cash and borrows created at the beginning of an operation or a batch of operations + /// @dev The snapshot is separate from VaultStorage, because it could be implemented as transient storage Snapshot snapshot; + /// @notice A singleton VaultStorage VaultStorage vaultStorage; } diff --git a/src/EVault/shared/lib/ConversionHelpers.sol b/src/EVault/shared/lib/ConversionHelpers.sol index d78ada49..514957e4 100644 --- a/src/EVault/shared/lib/ConversionHelpers.sol +++ b/src/EVault/shared/lib/ConversionHelpers.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.0; import {VaultCache} from "../types/VaultCache.sol"; +/// @title ConversionHelpers Library +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice The library provides a helper function for conversions between shares and assets library ConversionHelpers { // virtual deposit used in conversions between shares and assets, serving as exchange rate manipulation mitigation uint256 constant VIRTUAL_DEPOSIT_AMOUNT = 1e6; diff --git a/src/EVault/shared/lib/ProxyUtils.sol b/src/EVault/shared/lib/ProxyUtils.sol index 65ee2efe..61ad56b6 100644 --- a/src/EVault/shared/lib/ProxyUtils.sol +++ b/src/EVault/shared/lib/ProxyUtils.sol @@ -5,6 +5,9 @@ pragma solidity ^0.8.0; import {IERC20} from "../../IEVault.sol"; import {IPriceOracle} from "../../../interfaces/IPriceOracle.sol"; +/// @title ProxyUtils Library +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice The library provides a helper function for working with proxy meta data library ProxyUtils { function metadata() internal pure returns (IERC20 asset, IPriceOracle oracle, address unitOfAccount) { assembly { diff --git a/src/EVault/shared/lib/RevertBytes.sol b/src/EVault/shared/lib/RevertBytes.sol index c841d8da..0fdfc24a 100644 --- a/src/EVault/shared/lib/RevertBytes.sol +++ b/src/EVault/shared/lib/RevertBytes.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.0; import "../Errors.sol"; +/// @title RevertBytes Library +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice The library provides a helper function for bubbling up errors library RevertBytes { function revertBytes(bytes memory errMsg) internal pure { if (errMsg.length > 0) { diff --git a/src/EVault/shared/lib/SafeERC20Lib.sol b/src/EVault/shared/lib/SafeERC20Lib.sol index c81ced9d..dfdd2f1f 100644 --- a/src/EVault/shared/lib/SafeERC20Lib.sol +++ b/src/EVault/shared/lib/SafeERC20Lib.sol @@ -6,6 +6,9 @@ import {IERC20} from "../../IEVault.sol"; import {RevertBytes} from "./RevertBytes.sol"; import {IPermit2} from "../../../interfaces/IPermit2.sol"; +/// @title SafeERC20Lib Library +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice The library provides helpers for ERC20 transfers, including Permit2 support library SafeERC20Lib { error E_TransferFromFailed(bytes errorTransferFrom, bytes errorPermit2); error E_Permit2AmountOverflow(); diff --git a/src/EVault/shared/types/AmountCap.sol b/src/EVault/shared/types/AmountCap.sol index 8a8e8f4f..fd4d3f02 100644 --- a/src/EVault/shared/types/AmountCap.sol +++ b/src/EVault/shared/types/AmountCap.sol @@ -4,13 +4,15 @@ pragma solidity ^0.8.0; import {AmountCap} from "./Types.sol"; -// AmountCaps are 16-bit decimal floating point values: -// * The least significant 6 bits are the exponent -// * The most significant 10 bits are the mantissa, scaled by 100 -// * The special value of 0 means limit is not set -// * This is so that uninitialized storage implies no limit -// * For an actual cap value of 0, use a zero mantissa and non-zero exponent - +/// @title AmountCapLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for `AmountCap` custom type +/// @dev AmountCaps are 16-bit decimal floating point values: +/// * The least significant 6 bits are the exponent +/// * The most significant 10 bits are the mantissa, scaled by 100 +/// * The special value of 0 means limit is not set +/// * This is so that uninitialized storage implies no limit +/// * For an actual cap value of 0, use a zero mantissa and non-zero exponent library AmountCapLib { function toUint(AmountCap self) internal pure returns (uint256) { uint256 amountCap = AmountCap.unwrap(self); diff --git a/src/EVault/shared/types/Assets.sol b/src/EVault/shared/types/Assets.sol index 636623ed..5f5b54fd 100644 --- a/src/EVault/shared/types/Assets.sol +++ b/src/EVault/shared/types/Assets.sol @@ -7,6 +7,9 @@ import {VaultCache} from "./VaultCache.sol"; import {ConversionHelpers} from "../lib/ConversionHelpers.sol"; import "../Constants.sol"; +/// @title AssetsLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Custom type `Assets` represents amounts of the vault's underlying asset library AssetsLib { function toUint(Assets self) internal pure returns (uint256) { return Assets.unwrap(self); diff --git a/src/EVault/shared/types/ConfigAmount.sol b/src/EVault/shared/types/ConfigAmount.sol index 27010bfa..cfccf481 100644 --- a/src/EVault/shared/types/ConfigAmount.sol +++ b/src/EVault/shared/types/ConfigAmount.sol @@ -6,9 +6,11 @@ import {ConfigAmount} from "./Types.sol"; import {Errors} from "../Errors.sol"; import "../Constants.sol"; -// ConfigAmounts are floating point values encoded in 16 bits with a 1e4 precision. -// The type is used to store protocol configuration values. - +/// @title ConfigAmountLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for `ConfigAmount` custom type +/// @dev ConfigAmounts are floating point values encoded in 16 bits with a 1e4 precision. +/// The type is used to store protocol configuration values. library ConfigAmountLib { // note assuming arithmetic checks are already performed function mulDiv(ConfigAmount self, uint256 multiplier, uint256 divisor) internal pure returns (uint256) { diff --git a/src/EVault/shared/types/Flags.sol b/src/EVault/shared/types/Flags.sol index 9959b7a4..9066c840 100644 --- a/src/EVault/shared/types/Flags.sol +++ b/src/EVault/shared/types/Flags.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.0; import {Flags} from "./Types.sol"; +/// @title FlagsLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for `Flags` custom type library FlagsLib { /// @dev Are *all* of the flags in bitMask set? function isSet(Flags self, uint32 bitMask) internal pure returns (bool) { diff --git a/src/EVault/shared/types/LTVConfig.sol b/src/EVault/shared/types/LTVConfig.sol index 8caa17c8..0481902e 100644 --- a/src/EVault/shared/types/LTVConfig.sol +++ b/src/EVault/shared/types/LTVConfig.sol @@ -2,25 +2,41 @@ pragma solidity ^0.8.0; -import {Errors} from "../Errors.sol"; import {ConfigAmount} from "./Types.sol"; -import {LTVType} from "./LTVType.sol"; -import "../Constants.sol"; +/// @title LTVType +/// @notice Enum of LTV types +enum LTVType { + BORROWING, + LIQUIDATION +} + +/// @title LTVConfig +/// @notice This packed struct is used to store LTV configuration of a collateral struct LTVConfig { // Packed slot: 6 + 2 + 4 + 2 + 1 = 15 + // The timestamp when the new liquidation LTV ramping is finished uint48 targetTimestamp; + // The value of fully converged LTV value ConfigAmount targetLTV; + // The time it takes the liquidation LTV to converge with borrowing LTV uint32 rampDuration; + // The previous liquidation LTV value, from which the ramping begun ConfigAmount originalLTV; + // A flag indicating the configuration was initialized for the collateral bool initialized; } +/// @title LTVConfigLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for getting and setting the LTV configurations library LTVConfigLib { + // Is the collateral considered safe to liquidate function isRecognizedCollateral(LTVConfig memory self) internal pure returns (bool) { return self.targetTimestamp != 0; } + // Get current LTV of a collateral. When liquidation LTV is lowered, it is ramped down to target value over a period of time. function getLTV(LTVConfig memory self, LTVType ltvType) internal view returns (ConfigAmount) { if ( ltvType == LTVType.BORROWING || block.timestamp >= self.targetTimestamp || self.targetLTV > self.originalLTV @@ -52,6 +68,7 @@ library LTVConfigLib { newLTV.initialized = true; } + // When LTV is cleared, the collateral can't be liquidated, as it's deemed unsafe function clear(LTVConfig storage self) internal { self.targetTimestamp = 0; self.targetLTV = ConfigAmount.wrap(0); diff --git a/src/EVault/shared/types/Owed.sol b/src/EVault/shared/types/Owed.sol index 92c260e5..860ea71e 100644 --- a/src/EVault/shared/types/Owed.sol +++ b/src/EVault/shared/types/Owed.sol @@ -5,7 +5,11 @@ pragma solidity ^0.8.0; import {Owed, Assets, TypesLib} from "./Types.sol"; import "../Constants.sol"; -/// @dev The owed type tracks borrowed assets in the assets units scaled up by shifting left INTERNAL_DEBT_PRECISION bits. Increased precision allows for accurate interest accounting. +/// @title OwedLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for `Owed` custom type +/// @dev The owed type tracks borrowed funds in asset units scaled up by shifting left INTERNAL_DEBT_PRECISION bits. +/// Increased precision allows for accurate interest accounting. library OwedLib { function toUint(Owed self) internal pure returns (uint256) { return Owed.unwrap(self); diff --git a/src/EVault/shared/types/Shares.sol b/src/EVault/shared/types/Shares.sol index c9ea71b6..a7683e5c 100644 --- a/src/EVault/shared/types/Shares.sol +++ b/src/EVault/shared/types/Shares.sol @@ -6,6 +6,9 @@ import {Shares, Assets, TypesLib} from "./Types.sol"; import {VaultCache} from "./VaultCache.sol"; import {ConversionHelpers} from "../lib/ConversionHelpers.sol"; +/// @title SharesLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for `Shares` custom type, which is used to store vault's shares balances library SharesLib { function toUint(Shares self) internal pure returns (uint256) { return Shares.unwrap(self); diff --git a/src/EVault/shared/types/Snapshot.sol b/src/EVault/shared/types/Snapshot.sol index 07b07b62..5bc9ff53 100644 --- a/src/EVault/shared/types/Snapshot.sol +++ b/src/EVault/shared/types/Snapshot.sol @@ -4,20 +4,28 @@ pragma solidity ^0.8.0; import {Assets} from "./Types.sol"; +/// @title Snapshot +/// @notice This struct is used to store a snapshot of the vault's cash and total borrows at the beginning of user operation struct Snapshot { // Packed slot: 14 + 14 + 4 = 32 + // vault's cash holdings Assets cash; + // vault's total borrows in regular asset units precision Assets borrows; - uint32 _stamp; + // stamp occupies the rest of the storage slot and makes sure the slot is non-zero for gas savings + uint32 stamp; } +/// @title SnapshotLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for working with the `Snapshot` struct library SnapshotLib { uint32 constant STAMP = 1 << 31; // non zero initial value of the snapshot slot to save gas on SSTORE function set(Snapshot storage self, Assets cash, Assets borrows) internal { self.cash = cash; self.borrows = borrows; - self._stamp = STAMP; + self.stamp = STAMP; } function reset(Snapshot storage self) internal { diff --git a/src/EVault/shared/types/Types.sol b/src/EVault/shared/types/Types.sol index b50e39f5..9e966cb0 100644 --- a/src/EVault/shared/types/Types.sol +++ b/src/EVault/shared/types/Types.sol @@ -15,7 +15,8 @@ import "./Owed.sol"; import "./ConfigAmount.sol"; import "./Flags.sol"; import "./AmountCap.sol"; -import "./LTVType.sol"; + +/// @notice In this file, custom types are defined and linked globally with their libraries and operators type Shares is uint112; @@ -54,6 +55,8 @@ using {gtConfigAmount as >, ltConfigAmount as <} for ConfigAmount global; using AmountCapLib for AmountCap global; using FlagsLib for Flags global; +/// @title TypesLib +/// @notice Library for casting basic types' amounts into custom types library TypesLib { function toShares(uint256 amount) internal pure returns (Shares) { if (amount > MAX_SANE_AMOUNT) revert Errors.E_AmountTooLargeToEncode(); diff --git a/src/EVault/shared/types/UserStorage.sol b/src/EVault/shared/types/UserStorage.sol index 455975c3..9a14a89a 100644 --- a/src/EVault/shared/types/UserStorage.sol +++ b/src/EVault/shared/types/UserStorage.sol @@ -4,21 +4,30 @@ pragma solidity ^0.8.0; import {Shares, Owed} from "./Types.sol"; +/// @dev Custom type for holding shares and debt balances of an account, packed with balance forwarder opt-in flag type PackedUserSlot is uint256; +/// @title UserStorage +/// @notice This struct is used to store user account data struct UserStorage { - PackedUserSlot data; // Shares and debt balance, balance forwarder opt-in flag + // Shares and debt balances, balance forwarder opt-in + PackedUserSlot data; + // Snapshot of the interest accumulator from the last change to account's liability uint256 interestAccumulator; + // A mapping with allowances for the valt shares token mapping(address spender => uint256 allowance) eTokenAllowance; } +/// @title SharesLib +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Library for working with the UserStorage struct library UserStorageLib { uint256 constant BALANCE_FORWARDER_MASK = 0x8000000000000000000000000000000000000000000000000000000000000000; uint256 constant OWED_MASK = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000; uint256 constant SHARES_MASK = 0x000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF; uint256 constant OWED_OFFSET = 112; - function getBalanceForwarderEnabled(UserStorage storage self) internal view returns (bool) { + function isBalanceForwarderEnabled(UserStorage storage self) internal view returns (bool) { return unpackBalanceForwarder(self.data); } diff --git a/src/EVault/shared/types/VaultCache.sol b/src/EVault/shared/types/VaultCache.sol index 4053f272..49e24eb8 100644 --- a/src/EVault/shared/types/VaultCache.sol +++ b/src/EVault/shared/types/VaultCache.sol @@ -7,22 +7,46 @@ import {IPriceOracle} from "../../../interfaces/IPriceOracle.sol"; import {Assets, Owed, Shares, Flags} from "./Types.sol"; +/// @title VaultCache +/// @notice This struct is used to hold all the most often used vault data in memory struct VaultCache { + // Proxy immutables + + // Vault's asset IERC20 asset; + // Vault's pricing oracle IPriceOracle oracle; + // Unit of account is the asset in which collateral and liability values are expressed address unitOfAccount; + // Vault data + + // A timestamp of the last interest accumulator update uint48 lastInterestAccumulatorUpdate; + // The amount of assets held directly by the vault Assets cash; + // Sum of all user debts Owed totalBorrows; + // Sum of all user shares Shares totalShares; + // Interest fees accrued since the last fee conversion Shares accumulatedFees; + // Current interest accumulator uint256 interestAccumulator; + // Vault config + + // Current supply cap in asset units uint256 supplyCap; + // Current borrow cap in asset units uint256 borrowCap; + // A bitfield of operations which trigger a hook call Flags hookedOps; + // A bitfield of vault configuration options Flags configFlags; + // Runtime + + // A flag indicating if the vault snapshot has already been initialized for the currently executing batch bool snapshotInitialized; } \ No newline at end of file diff --git a/src/EVault/shared/types/VaultStorage.sol b/src/EVault/shared/types/VaultStorage.sol index 64a5812e..9658b020 100644 --- a/src/EVault/shared/types/VaultStorage.sol +++ b/src/EVault/shared/types/VaultStorage.sol @@ -6,42 +6,69 @@ import {Assets, Shares, Owed, AmountCap, ConfigAmount, Flags} from "./Types.sol" import {LTVConfig} from "./LTVConfig.sol"; import {UserStorage} from "./UserStorage.sol"; +/// @title VaultStorage +/// @notice This struct is used to hold all of the vault storage +/// @dev Note that snapshots are not a part of this struct, as they might be reimplemented as transient storage struct VaultStorage { // Packed slot 6 + 14 + 2 + 2 + 4 + 1 + 1 = 30 + // A timestamp of the last interest accumulator update uint48 lastInterestAccumulatorUpdate; + // The amount of assets held directly by the vault Assets cash; + // Current supply cap in asset units AmountCap supplyCap; + // Current borrow cap in asset units AmountCap borrowCap; + // A bitfield of operations which trigger a hook call Flags hookedOps; + // A vault global re-entrancy protection flag bool reentrancyLocked; + // A flag indicating if the vault snapshot has already been initialized for the currently executing batch bool snapshotInitialized; // Packed slot 14 + 18 = 32 + // Sum of all user shares Shares totalShares; + // Current borrow cap in asset units Owed totalBorrows; // Packed slot 14 + 4 = 18 + // Interest fees accrued since the last fee conversion Shares accumulatedFees; + // A bitfield of vault configuration options Flags configFlags; + // Current interest accumulator uint256 interestAccumulator; // Packed slot 20 + 2 + 9 = 31 - address interestRateModel; // 0% interest, if zero address + // Address of the interest rate model contract. If not set, 0% interest is applied + address interestRateModel; + // Percentage of interest accrued charged as fees ConfigAmount interestFee; + // Current interest rate on borrows uint72 interestRate; + // Name of the shares token (eToken) string name; + // Symbol of the shares token (eToken) string symbol; + // Address of the vault creator address creator; + // Address of the vault admin address governorAdmin; + // Address which receives governor fees address feeReceiver; + // Address which will be called for enabled hooks address hookTarget; + // User accounts data mapping(address account => UserStorage) users; + // LTV configuration for collaterals mapping(address collateral => LTVConfig) ltvLookup; + // List of addresses which were at any point configured as collateral address[] ltvList; -} \ No newline at end of file +} From 37dad184b6b78cd9b586aaeaa14d3450d7a51dfe Mon Sep 17 00:00:00 2001 From: dglowinski Date: Fri, 29 Mar 2024 13:47:02 +0100 Subject: [PATCH 2/7] update natspec --- src/EVault/DToken.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EVault/DToken.sol b/src/EVault/DToken.sol index d6b706ff..d5e05adb 100644 --- a/src/EVault/DToken.sol +++ b/src/EVault/DToken.sol @@ -8,7 +8,7 @@ import {IERC20, IEVault} from "./IEVault.sol"; /// @title DToken /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice Contract implements `Transfer` events and read only ERC20 interface for EVault's debt +/// @notice Contract implements read only ERC20 interface, and `Transfer` events, for EVault's debt contract DToken is IERC20, Errors, Events { address public immutable eVault; From b63c468b8f963ae21bf3dae9f9bd03fa225eec27 Mon Sep 17 00:00:00 2001 From: dglowinski Date: Fri, 29 Mar 2024 13:48:33 +0100 Subject: [PATCH 3/7] natspec --- src/EVault/IEVault.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EVault/IEVault.sol b/src/EVault/IEVault.sol index 9ff16b33..6cc7f22d 100644 --- a/src/EVault/IEVault.sol +++ b/src/EVault/IEVault.sol @@ -15,7 +15,7 @@ interface IInitialize { } /// @title IERC20 -/// @notice Interface of an ERC20 token +/// @notice Interface of the EVault's Initialize module interface IERC20 { /// @notice Vault share token (eToken) name, ie "Euler Vault: DAI" function name() external view returns (string memory); From 517009d7821a59b310066feecb09b3a5af59e7ad Mon Sep 17 00:00:00 2001 From: dglowinski Date: Fri, 29 Mar 2024 13:50:49 +0100 Subject: [PATCH 4/7] natspec --- src/EVault/modules/BalanceForwarder.sol | 2 +- src/EVault/modules/Borrowing.sol | 2 +- src/EVault/modules/Governance.sol | 2 +- src/EVault/modules/Initialize.sol | 2 +- src/EVault/modules/Liquidation.sol | 2 +- src/EVault/modules/RiskManager.sol | 2 +- src/EVault/modules/Token.sol | 2 +- src/EVault/modules/Vault.sol | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/EVault/modules/BalanceForwarder.sol b/src/EVault/modules/BalanceForwarder.sol index b9ccd033..bdc1dcd2 100644 --- a/src/EVault/modules/BalanceForwarder.sol +++ b/src/EVault/modules/BalanceForwarder.sol @@ -46,7 +46,7 @@ abstract contract BalanceForwarderModule is IBalanceForwarder, Base { } } -/// @dev Deployable contract +/// @dev Deployable module contract contract BalanceForwarder is BalanceForwarderModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Borrowing.sol b/src/EVault/modules/Borrowing.sol index cbdf2db0..263ddfbf 100644 --- a/src/EVault/modules/Borrowing.sol +++ b/src/EVault/modules/Borrowing.sol @@ -229,7 +229,7 @@ abstract contract BorrowingModule is IBorrowing, Base, AssetTransfers, BalanceUt } } -/// @dev Deployable contract +/// @dev Deployable module contract contract Borrowing is BorrowingModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Governance.sol b/src/EVault/modules/Governance.sol index 56254f2f..c521dbb8 100644 --- a/src/EVault/modules/Governance.sol +++ b/src/EVault/modules/Governance.sol @@ -288,7 +288,7 @@ abstract contract GovernanceModule is IGovernance, Base, BalanceUtils, BorrowUti } } -/// @dev Deployable contract +/// @dev Deployable module contract contract Governance is GovernanceModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Initialize.sol b/src/EVault/modules/Initialize.sol index 2000cdf4..cddf15ef 100644 --- a/src/EVault/modules/Initialize.sol +++ b/src/EVault/modules/Initialize.sol @@ -60,7 +60,7 @@ abstract contract InitializeModule is IInitialize, Base, BorrowUtils { } } -/// @dev Deployable contract +/// @dev Deployable module contract contract Initialize is InitializeModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Liquidation.sol b/src/EVault/modules/Liquidation.sol index 8e690a20..d879edd0 100644 --- a/src/EVault/modules/Liquidation.sol +++ b/src/EVault/modules/Liquidation.sol @@ -219,7 +219,7 @@ abstract contract LiquidationModule is ILiquidation, Base, BalanceUtils, Liquidi } } -/// @dev Deployable contract +/// @dev Deployable module contract contract Liquidation is LiquidationModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/RiskManager.sol b/src/EVault/modules/RiskManager.sol index 85fcec78..919b2dfd 100644 --- a/src/EVault/modules/RiskManager.sol +++ b/src/EVault/modules/RiskManager.sol @@ -116,7 +116,7 @@ abstract contract RiskManagerModule is IRiskManager, Base, LiquidityUtils { } } -/// @dev Deployable contract +/// @dev Deployable module contract contract RiskManager is RiskManagerModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Token.sol b/src/EVault/modules/Token.sol index 4d957e67..bdbed7a1 100644 --- a/src/EVault/modules/Token.sol +++ b/src/EVault/modules/Token.sol @@ -82,7 +82,7 @@ abstract contract TokenModule is IToken, Base, BalanceUtils { } } -/// @dev Deployable contract +/// @dev Deployable module contract contract Token is TokenModule { constructor(Integrations memory integrations) Base(integrations) {} } diff --git a/src/EVault/modules/Vault.sol b/src/EVault/modules/Vault.sol index 3798ea4e..e7f2d832 100644 --- a/src/EVault/modules/Vault.sol +++ b/src/EVault/modules/Vault.sol @@ -270,7 +270,7 @@ abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils { } } -/// @dev Deployable contract +/// @dev Deployable module contract contract Vault is VaultModule { constructor(Integrations memory integrations) Base(integrations) {} } From e633e7acfa68bcc897698ed2a22941f9c96faf9e Mon Sep 17 00:00:00 2001 From: dglowinski Date: Fri, 29 Mar 2024 15:15:44 +0100 Subject: [PATCH 5/7] natspec --- src/EVault/modules/Vault.sol | 2 +- src/EVault/shared/BalanceUtils.sol | 2 +- src/EVault/shared/Cache.sol | 2 +- src/EVault/shared/Errors.sol | 2 +- src/EVault/shared/Events.sol | 12 ++++++------ src/EVault/shared/types/ConfigAmount.sol | 2 +- src/EVault/shared/types/Owed.sol | 2 +- src/EVault/shared/types/Snapshot.sol | 2 +- src/EVault/shared/types/UserStorage.sol | 4 ++-- src/EVault/shared/types/VaultCache.sol | 2 +- src/EVault/shared/types/VaultStorage.sol | 14 +++++++------- 11 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/EVault/modules/Vault.sol b/src/EVault/modules/Vault.sol index e7f2d832..b0818012 100644 --- a/src/EVault/modules/Vault.sol +++ b/src/EVault/modules/Vault.sol @@ -11,7 +11,7 @@ import {ProxyUtils} from "../shared/lib/ProxyUtils.sol"; import "../shared/types/Types.sol"; -/// @title BalanceForwarderModule +/// @title VaultModule /// @author Euler Labs (https://www.eulerlabs.com/) /// @notice An EVault module handling ERC4626 standard behaviour abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils { diff --git a/src/EVault/shared/BalanceUtils.sol b/src/EVault/shared/BalanceUtils.sol index 391329bd..97242383 100644 --- a/src/EVault/shared/BalanceUtils.sol +++ b/src/EVault/shared/BalanceUtils.sol @@ -9,7 +9,7 @@ import "./types/Types.sol"; /// @title BalanceUtils /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice Utilities for tracking shares balances and allowances +/// @notice Utilities for tracking share balances and allowances abstract contract BalanceUtils is Base { using TypesLib for uint256; diff --git a/src/EVault/shared/Cache.sol b/src/EVault/shared/Cache.sol index e46ec829..bd4b4419 100644 --- a/src/EVault/shared/Cache.sol +++ b/src/EVault/shared/Cache.sol @@ -12,7 +12,7 @@ import "./types/Types.sol"; /// @title Cache /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice Load vault storage into memory, update it with accrued interest +/// @notice Utilities for loading vault storage and updating it with interest accured contract Cache is Storage, Errors { using TypesLib for uint256; using SafeERC20Lib for IERC20; diff --git a/src/EVault/shared/Errors.sol b/src/EVault/shared/Errors.sol index a2264973..7d2894dc 100644 --- a/src/EVault/shared/Errors.sol +++ b/src/EVault/shared/Errors.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; /// @title Errors /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice Defines EVault custom errors +/// @notice Contract implementing EVault's custom errors contract Errors { error E_Initialized(); error E_ProxyMetadata(); diff --git a/src/EVault/shared/Events.sol b/src/EVault/shared/Events.sol index 39441e06..1b48f102 100644 --- a/src/EVault/shared/Events.sol +++ b/src/EVault/shared/Events.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; /// @title Events /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice This contract implements Evault's events +/// @notice Contract implementing EVault's events abstract contract Events { // ERC20 @@ -42,9 +42,9 @@ abstract contract Events { // EVault /// @notice New EVault is initialized - /// @param creator The address calling the factory + /// @param creator Address designated as the vault's creator /// @param asset The underlying asset of the vault - /// @param dToken Address of the sidecar debt tracking token + /// @param dToken Address of the sidecar debt token event EVaultCreated(address indexed creator, address indexed asset, address dToken); /// @notice Log the current vault status @@ -80,7 +80,7 @@ abstract contract Events { /// @param violator Address holding an unhealthy borrow /// @param collateral Address of the asset seized /// @param repayAssets Amount of debt in assets transfered from violator to liquidator - /// @param yieldBalance Amount of collateral asset's balance transfer from violator to liquidator + /// @param yieldBalance Amount of collateral asset's balance transfered from violator to liquidator event Liquidate( address indexed liquidator, address indexed violator, @@ -96,8 +96,8 @@ abstract contract Events { /// @notice Split the accumulated fees between the governor and the protocol /// @param sender Address initializing the conversion - /// @param protocolReceiver Address receiving the protocol's share of fees - /// @param governorReceiver Address receiving the governor's share of fees + /// @param protocolReceiver Address receiving the protocol's share of the fees + /// @param governorReceiver Address receiving the governor's share of the fees /// @param protocolShares Amount of shares tranfered to the protocol receiver /// @param governorShares Amount of shares tranfered to the governor receiver event ConvertFees( diff --git a/src/EVault/shared/types/ConfigAmount.sol b/src/EVault/shared/types/ConfigAmount.sol index cfccf481..5e702169 100644 --- a/src/EVault/shared/types/ConfigAmount.sol +++ b/src/EVault/shared/types/ConfigAmount.sol @@ -10,7 +10,7 @@ import "../Constants.sol"; /// @author Euler Labs (https://www.eulerlabs.com/) /// @notice Library for `ConfigAmount` custom type /// @dev ConfigAmounts are floating point values encoded in 16 bits with a 1e4 precision. -/// The type is used to store protocol configuration values. +/// @dev The type is used to store protocol configuration values. library ConfigAmountLib { // note assuming arithmetic checks are already performed function mulDiv(ConfigAmount self, uint256 multiplier, uint256 divisor) internal pure returns (uint256) { diff --git a/src/EVault/shared/types/Owed.sol b/src/EVault/shared/types/Owed.sol index 860ea71e..08c6d5a7 100644 --- a/src/EVault/shared/types/Owed.sol +++ b/src/EVault/shared/types/Owed.sol @@ -9,7 +9,7 @@ import "../Constants.sol"; /// @author Euler Labs (https://www.eulerlabs.com/) /// @notice Library for `Owed` custom type /// @dev The owed type tracks borrowed funds in asset units scaled up by shifting left INTERNAL_DEBT_PRECISION bits. -/// Increased precision allows for accurate interest accounting. +/// @dev Increased precision allows for accurate interest accounting. library OwedLib { function toUint(Owed self) internal pure returns (uint256) { return Owed.unwrap(self); diff --git a/src/EVault/shared/types/Snapshot.sol b/src/EVault/shared/types/Snapshot.sol index 5bc9ff53..86fd6208 100644 --- a/src/EVault/shared/types/Snapshot.sol +++ b/src/EVault/shared/types/Snapshot.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import {Assets} from "./Types.sol"; /// @title Snapshot -/// @notice This struct is used to store a snapshot of the vault's cash and total borrows at the beginning of user operation +/// @notice This struct is used to store a snapshot of the vault's cash and total borrows at the beginning of an operation (or a batch thereof) struct Snapshot { // Packed slot: 14 + 14 + 4 = 32 // vault's cash holdings diff --git a/src/EVault/shared/types/UserStorage.sol b/src/EVault/shared/types/UserStorage.sol index 9a14a89a..4c42e88d 100644 --- a/src/EVault/shared/types/UserStorage.sol +++ b/src/EVault/shared/types/UserStorage.sol @@ -14,11 +14,11 @@ struct UserStorage { PackedUserSlot data; // Snapshot of the interest accumulator from the last change to account's liability uint256 interestAccumulator; - // A mapping with allowances for the valt shares token + // A mapping with allowances for the vault shares token (eToken) mapping(address spender => uint256 allowance) eTokenAllowance; } -/// @title SharesLib +/// @title UserStorageLib /// @author Euler Labs (https://www.eulerlabs.com/) /// @notice Library for working with the UserStorage struct library UserStorageLib { diff --git a/src/EVault/shared/types/VaultCache.sol b/src/EVault/shared/types/VaultCache.sol index 49e24eb8..8597d159 100644 --- a/src/EVault/shared/types/VaultCache.sol +++ b/src/EVault/shared/types/VaultCache.sol @@ -49,4 +49,4 @@ struct VaultCache { // A flag indicating if the vault snapshot has already been initialized for the currently executing batch bool snapshotInitialized; -} \ No newline at end of file +} diff --git a/src/EVault/shared/types/VaultStorage.sol b/src/EVault/shared/types/VaultStorage.sol index 9658b020..becb9577 100644 --- a/src/EVault/shared/types/VaultStorage.sol +++ b/src/EVault/shared/types/VaultStorage.sol @@ -7,7 +7,7 @@ import {LTVConfig} from "./LTVConfig.sol"; import {UserStorage} from "./UserStorage.sol"; /// @title VaultStorage -/// @notice This struct is used to hold all of the vault storage +/// @notice This struct is used to hold all of the vault's permanent storage /// @dev Note that snapshots are not a part of this struct, as they might be reimplemented as transient storage struct VaultStorage { // Packed slot 6 + 14 + 2 + 2 + 4 + 1 + 1 = 30 @@ -29,7 +29,7 @@ struct VaultStorage { // Packed slot 14 + 18 = 32 // Sum of all user shares Shares totalShares; - // Current borrow cap in asset units + // Sum of all user debts Owed totalBorrows; // Packed slot 14 + 4 = 18 @@ -44,9 +44,9 @@ struct VaultStorage { // Packed slot 20 + 2 + 9 = 31 // Address of the interest rate model contract. If not set, 0% interest is applied address interestRateModel; - // Percentage of interest accrued charged as fees + // Percentage of accrued interest that is directed to fees ConfigAmount interestFee; - // Current interest rate on borrows + // Current interest rate applied to outstanding borrows uint72 interestRate; // Name of the shares token (eToken) @@ -54,17 +54,17 @@ struct VaultStorage { // Symbol of the shares token (eToken) string symbol; - // Address of the vault creator + // Address of the vault's creator address creator; - // Address of the vault admin + // Address of the vault's governor address governorAdmin; // Address which receives governor fees address feeReceiver; // Address which will be called for enabled hooks address hookTarget; - // User accounts data + // User accounts mapping(address account => UserStorage) users; // LTV configuration for collaterals From 451a5cf494f752f03a51d6d4f920b867db8ba525 Mon Sep 17 00:00:00 2001 From: dglowinski Date: Fri, 29 Mar 2024 15:41:51 +0100 Subject: [PATCH 6/7] natspec --- src/EVault/shared/types/Snapshot.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EVault/shared/types/Snapshot.sol b/src/EVault/shared/types/Snapshot.sol index 86fd6208..81107ba4 100644 --- a/src/EVault/shared/types/Snapshot.sol +++ b/src/EVault/shared/types/Snapshot.sol @@ -10,7 +10,7 @@ struct Snapshot { // Packed slot: 14 + 14 + 4 = 32 // vault's cash holdings Assets cash; - // vault's total borrows in regular asset units precision + // vault's total borrows in assets, in regular precision Assets borrows; // stamp occupies the rest of the storage slot and makes sure the slot is non-zero for gas savings uint32 stamp; From 0ee69cc4aefd0202f209087812315463b8f5d470 Mon Sep 17 00:00:00 2001 From: Doug Hoyte Date: Sun, 31 Mar 2024 00:14:33 -0400 Subject: [PATCH 7/7] typos --- src/EVault/Dispatch.sol | 5 +++-- src/EVault/EVault.sol | 1 - src/EVault/modules/BalanceForwarder.sol | 2 +- src/EVault/shared/Cache.sol | 2 +- src/EVault/shared/Events.sol | 4 ++-- src/EVault/shared/Storage.sol | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/EVault/Dispatch.sol b/src/EVault/Dispatch.sol index d869fd66..db778c9d 100644 --- a/src/EVault/Dispatch.sol +++ b/src/EVault/Dispatch.sol @@ -81,8 +81,9 @@ abstract contract Dispatch is } } - // External function which is only callable by the EVault itself. It's purpose is to be static called by `delegateToModuleView` - // which allows delegate-calling modules also for external view functions. + // External function which is only callable by the EVault itself. Its purpose is to be static called by `delegateToModuleView` + // which allows view functions to be implemented in modules, even though delegatecall cannot be directly used within + // view functions. function viewDelegate() external { if (msg.sender != address(this)) revert E_Unauthorized(); diff --git a/src/EVault/EVault.sol b/src/EVault/EVault.sol index 7bcd4b5f..809440a6 100644 --- a/src/EVault/EVault.sol +++ b/src/EVault/EVault.sol @@ -7,7 +7,6 @@ import {Dispatch} from "./Dispatch.sol"; /// @title EVault /// @author Euler Labs (https://www.eulerlabs.com/) /// @notice This contract implements an EVC enabled lending vault -/// @notice White paper: https://github.com/euler-xyz/euler-docusaurus/blob/main/docs/euler-vault-kit-white-paper/index.md /// @dev The responsibility of this contract is call routing. Select functions are embedded, while most are delegated to the modules. contract EVault is Dispatch { constructor(Integrations memory integrations, DeployedModules memory modules) Dispatch(integrations, modules) {} diff --git a/src/EVault/modules/BalanceForwarder.sol b/src/EVault/modules/BalanceForwarder.sol index bdc1dcd2..36850548 100644 --- a/src/EVault/modules/BalanceForwarder.sol +++ b/src/EVault/modules/BalanceForwarder.sol @@ -7,7 +7,7 @@ import {Base} from "../shared/Base.sol"; /// @title BalanceForwarderModule /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice An EVault module handling communication with balance tracker contract. +/// @notice An EVault module handling communication a with balance tracker contract. abstract contract BalanceForwarderModule is IBalanceForwarder, Base { /// @inheritdoc IBalanceForwarder function balanceTrackerAddress() public view virtual reentrantOK returns (address) { diff --git a/src/EVault/shared/Cache.sol b/src/EVault/shared/Cache.sol index bd4b4419..ab1db971 100644 --- a/src/EVault/shared/Cache.sol +++ b/src/EVault/shared/Cache.sol @@ -12,7 +12,7 @@ import "./types/Types.sol"; /// @title Cache /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice Utilities for loading vault storage and updating it with interest accured +/// @notice Utilities for loading vault storage and updating it with interest accrued contract Cache is Storage, Errors { using TypesLib for uint256; using SafeERC20Lib for IERC20; diff --git a/src/EVault/shared/Events.sol b/src/EVault/shared/Events.sol index 1b48f102..b47153a0 100644 --- a/src/EVault/shared/Events.sol +++ b/src/EVault/shared/Events.sol @@ -98,8 +98,8 @@ abstract contract Events { /// @param sender Address initializing the conversion /// @param protocolReceiver Address receiving the protocol's share of the fees /// @param governorReceiver Address receiving the governor's share of the fees - /// @param protocolShares Amount of shares tranfered to the protocol receiver - /// @param governorShares Amount of shares tranfered to the governor receiver + /// @param protocolShares Amount of shares transferred to the protocol receiver + /// @param governorShares Amount of shares transferred to the governor receiver event ConvertFees( address indexed sender, address indexed protocolReceiver, diff --git a/src/EVault/shared/Storage.sol b/src/EVault/shared/Storage.sol index 9e9f0e05..fcad5470 100644 --- a/src/EVault/shared/Storage.sol +++ b/src/EVault/shared/Storage.sol @@ -6,7 +6,7 @@ import {VaultStorage, Snapshot} from "./types/Types.sol"; /// @title Storage /// @author Euler Labs (https://www.eulerlabs.com/) -/// @notice Contract defines the EVault's data storage +/// @notice Contract that defines the EVault's data storage abstract contract Storage { /// @notice Flag indicating if the vault has been initialized bool initialized;