Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle max functions compliance #79

Merged
merged 2 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/EVault/Dispatch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,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.
Expand Down
14 changes: 11 additions & 3 deletions src/EVault/modules/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils {
}

/// @inheritdoc IERC4626
/// @dev Because `nonReentrantView` can revert, the function might be considered not fully compliant with ERC4626
function maxDeposit(address account) public view virtual nonReentrantView returns (uint256) {
VaultCache memory vaultCache = loadVault();

Expand All @@ -52,12 +53,17 @@ abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils {
}

/// @inheritdoc IERC4626
/// @dev If the hook on `mint` allows only certain amounts, maxMint function might not be fully compliant with ERC4626
/// @dev Because `nonReentrantView` can revert, the function might be considered not fully compliant with ERC4626
function maxMint(address account) public view virtual nonReentrantView returns (uint256) {
VaultCache memory vaultCache = loadVault();

return validateAndCallHookView(vaultCache.hookedOps, OP_MINT)
? maxDepositInternal(vaultCache, account).toAssets().toSharesDown(vaultCache).toUint()
: 0;
if (!validateAndCallHookView(vaultCache.hookedOps, OP_MINT)) return 0;

// make sure to not revert on conversion
uint256 shares = maxDepositInternal(vaultCache, account).toAssets().toUint256SharesDown(vaultCache);

return shares < MAX_SANE_AMOUNT ? shares : MAX_SANE_AMOUNT;
}

/// @inheritdoc IERC4626
Expand All @@ -67,6 +73,7 @@ abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils {
}

/// @inheritdoc IERC4626
/// @dev Because `nonReentrantView` can revert, the function might be considered not fully compliant with ERC4626
function maxWithdraw(address owner) public view virtual nonReentrantView returns (uint256) {
VaultCache memory vaultCache = loadVault();

Expand All @@ -82,6 +89,7 @@ abstract contract VaultModule is IVault, Base, AssetTransfers, BalanceUtils {
}

/// @inheritdoc IERC4626
/// @dev Because `nonReentrantView` can revert, the function might be considered not fully compliant with ERC4626
function maxRedeem(address owner) public view virtual nonReentrantView returns (uint256) {
return validateAndCallHookView(vaultStorage.hookedOps, OP_REDEEM) ? maxRedeemInternal(owner).toUint() : 0;
}
Expand Down
6 changes: 5 additions & 1 deletion src/EVault/shared/types/Assets.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ library AssetsLib {
}

function toSharesDown(Assets amount, VaultCache memory vaultCache) internal pure returns (Shares) {
return TypesLib.toShares(toUint256SharesDown(amount, vaultCache));
}

function toUint256SharesDown(Assets amount, VaultCache memory vaultCache) internal pure returns (uint256) {
(uint256 totalAssets, uint256 totalShares) = ConversionHelpers.conversionTotals(vaultCache);
unchecked {
return TypesLib.toShares(amount.toUint() * totalShares / totalAssets);
return amount.toUint() * totalShares / totalAssets;
}
}

Expand Down
Loading