Skip to content
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
26 changes: 3 additions & 23 deletions contracts/tokenbridge/libraries/vault/MasterVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,6 @@
/// @param _subVault The subvault to set. Must be an ERC4626 vault with the same asset as this MasterVault.
/// @param minSubVaultExchRateWad Minimum acceptable ratio (times 1e18) of new subvault shares to outstanding MasterVault shares after deposit.
function setSubVault(IERC4626 _subVault, uint256 minSubVaultExchRateWad) external onlyRole(VAULT_MANAGER_ROLE) {
_setSubVault(_subVault, minSubVaultExchRateWad);
}

/// @notice Revokes the current subvault, moving all assets back to MasterVault
/// @param minAssetExchRateWad Minimum acceptable ratio (times 1e18) of assets received from subvault to outstanding MasterVault shares
function revokeSubVault(uint256 minAssetExchRateWad) external onlyRole(VAULT_MANAGER_ROLE) {
_revokeSubVault(minAssetExchRateWad);
}

function _setSubVault(IERC4626 _subVault, uint256 minSubVaultExchRateWad) internal {
IERC20 underlyingAsset = IERC20(asset());
if (address(subVault) != address(0)) revert SubVaultAlreadySet();
if (address(_subVault.asset()) != address(underlyingAsset)) revert SubVaultAssetMismatch();
Expand All @@ -124,33 +114,23 @@
emit SubvaultChanged(address(0), address(_subVault));
}

function _revokeSubVault(uint256 minAssetExchRateWad) internal {
/// @notice Revokes the current subvault, moving all assets back to MasterVault
/// @param minAssetExchRateWad Minimum acceptable ratio (times 1e18) of assets received from subvault to outstanding MasterVault shares
function revokeSubVault(uint256 minAssetExchRateWad) external onlyRole(VAULT_MANAGER_ROLE) {
IERC4626 oldSubVault = subVault;
if (address(oldSubVault) == address(0)) revert NoExistingSubVault();

subVault = IERC4626(address(0));

oldSubVault.redeem(oldSubVault.balanceOf(address(this)), address(this), address(this));
IERC20(asset()).safeApprove(address(oldSubVault), 0);

uint256 assetExchRateWad = IERC20(asset()).balanceOf(address(this)).mulDiv(1e18, totalSupply(), MathUpgradeable.Rounding.Down);
if (assetExchRateWad < minAssetExchRateWad) revert SubVaultExchangeRateTooLow();

emit SubvaultChanged(address(oldSubVault), address(0));
}

Check warning

Code scanning / Slither

Unused return Medium


/// @notice Switches to a new subvault or revokes current subvault if newSubVault is zero address
/// @param newSubVault The new subvault to switch to, or zero address to revoke current subvault
/// @param minAssetExchRateWad Minimum acceptable ratio (times 1e18) of assets received from old subvault to outstanding MasterVault shares
/// @param minNewSubVaultExchRateWad Minimum acceptable ratio (times 1e18) of new subvault shares to outstanding MasterVault shares after deposit
function switchSubVault(IERC4626 newSubVault, uint256 minAssetExchRateWad, uint256 minNewSubVaultExchRateWad) external onlyRole(VAULT_MANAGER_ROLE) {
_revokeSubVault(minAssetExchRateWad);

if (address(newSubVault) != address(0)) {
_setSubVault(newSubVault, minNewSubVaultExchRateWad);
}
}

function masterSharesToSubShares(uint256 masterShares, MathUpgradeable.Rounding rounding) public view returns (uint256) {
// masterShares * totalSubVaultShares / totalMasterShares
return masterShares.mulDiv(subVault.balanceOf(address(this)), totalSupply(), rounding);
Expand Down
42 changes: 0 additions & 42 deletions test-foundry/libraries/vault/MasterVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -126,48 +126,6 @@ contract MasterVaultTest is Test {
assertEq(subVault.balanceOf(address(vault)), depositAmount, "SubVault should have received assets");
}

function test_switchSubvault() public {
MockSubVault oldSubVault = new MockSubVault(
IERC20(address(token)),
"Old Sub Vault",
"osvTST"
);

MockSubVault newSubVault = new MockSubVault(
IERC20(address(token)),
"New Sub Vault",
"nsvTST"
);

vm.startPrank(user);
token.mint();
uint256 depositAmount = token.balanceOf(user);
token.approve(address(vault), depositAmount);
vault.deposit(depositAmount, user, 0);
vm.stopPrank();

vault.setSubVault(oldSubVault, 1e18);

assertEq(address(vault.subVault()), address(oldSubVault), "Old subvault should be set");
assertEq(oldSubVault.balanceOf(address(vault)), depositAmount, "Old subvault should have assets");
assertEq(newSubVault.balanceOf(address(vault)), 0, "New subvault should have no assets initially");

uint256 minAssetExchRateWad = 1e18;
uint256 minNewSubVaultExchRateWad = 1e18;

vm.expectEmit(true, true, false, false);
emit SubvaultChanged(address(oldSubVault), address(0));
vm.expectEmit(true, true, false, false);
emit SubvaultChanged(address(0), address(newSubVault));

vault.switchSubVault(newSubVault, minAssetExchRateWad, minNewSubVaultExchRateWad);

assertEq(address(vault.subVault()), address(newSubVault), "New subvault should be set");
assertEq(vault.totalAssets(), depositAmount, "Total assets should remain the same");
assertEq(oldSubVault.balanceOf(address(vault)), 0, "Old subvault should have no assets");
assertEq(newSubVault.balanceOf(address(vault)), depositAmount, "New subvault should have received assets");
}

function test_revokeSubvault() public {
MockSubVault subVault = new MockSubVault(
IERC20(address(token)),
Expand Down
Loading