From b6289fe8be5150561d158f7745889509d4bf50c3 Mon Sep 17 00:00:00 2001 From: Henry <11198460+godzillaba@users.noreply.github.com> Date: Fri, 19 Sep 2025 11:03:23 -0700 Subject: [PATCH 1/4] add ownership to MVF --- .../ethereum/L1AtomicTokenBridgeCreator.sol | 1 + .../libraries/vault/MasterVaultFactory.sol | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol b/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol index fa7aba5fe..83bab1411 100644 --- a/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol +++ b/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol @@ -270,6 +270,7 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { address(l1Templates.masterVaultFactory), proxyAdmin ); + MasterVaultFactory(l1Deployment.masterVaultFactory).initialize(upgradeExecutor); } // l1 router deployment block diff --git a/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol b/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol index 7564a37f0..e7b344b3e 100644 --- a/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol +++ b/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol @@ -3,22 +3,24 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/Create2.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./IMasterVault.sol"; import "./MasterVault.sol"; -contract MasterVaultFactory { - event VaultDeployed(address indexed token, address indexed gateway, address vault); +contract MasterVaultFactory is OwnableUpgradeable { + event VaultDeployed(address indexed token, address indexed vault); - error VaultDeploymentFailed(); error ZeroAddress(); + function initialize(address _owner) public initializer { + _transferOwnership(_owner); + } + function deployVault(address token) public returns (address vault) { if (token == address(0)) { revert ZeroAddress(); } - address gateway = msg.sender; - bytes memory bytecode = abi.encodePacked( type(MasterVault).creationCode, abi.encode(token) @@ -26,7 +28,7 @@ contract MasterVaultFactory { vault = Create2.deploy(0, bytes32(0), bytecode); - emit VaultDeployed(token, gateway, vault); + emit VaultDeployed(token, vault); } function calculateVaultAddress( From 5ebd90c5bf1a6a7d0364f635b2726bed57edd998 Mon Sep 17 00:00:00 2001 From: Henry <11198460+godzillaba@users.noreply.github.com> Date: Mon, 22 Sep 2025 07:20:12 -0600 Subject: [PATCH 2/4] setSubVault --- contracts/tokenbridge/libraries/vault/MasterVault.sol | 1 + .../tokenbridge/libraries/vault/MasterVaultFactory.sol | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/contracts/tokenbridge/libraries/vault/MasterVault.sol b/contracts/tokenbridge/libraries/vault/MasterVault.sol index 41d3cb73a..21853ebce 100644 --- a/contracts/tokenbridge/libraries/vault/MasterVault.sol +++ b/contracts/tokenbridge/libraries/vault/MasterVault.sol @@ -9,6 +9,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IERC4626 } from "lib/forge-std/src/interfaces/IERC4626.sol"; // todo: make this more like a 4626 vault, erc20 shares + deposit + withdraw +// todo: consider beacon proxy contract MasterVault is IMasterVault, Ownable { using SafeERC20 for IERC20; diff --git a/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol b/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol index e7b344b3e..e22cd3e65 100644 --- a/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol +++ b/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol @@ -9,6 +9,7 @@ import "./MasterVault.sol"; contract MasterVaultFactory is OwnableUpgradeable { event VaultDeployed(address indexed token, address indexed vault); + event SubVaultSet(address indexed masterVault, address indexed subVault); error ZeroAddress(); @@ -49,4 +50,12 @@ contract MasterVaultFactory is OwnableUpgradeable { } return vault; } + + function setSubVault( + address masterVault, + address subVault + ) external onlyOwner { + IMasterVault(masterVault).setSubVault(subVault); + emit SubVaultSet(masterVault, subVault); + } } From 3de2e157a198014611e7299490b3165ec38a49bd Mon Sep 17 00:00:00 2001 From: Henry <11198460+godzillaba@users.noreply.github.com> Date: Mon, 22 Sep 2025 07:21:47 -0600 Subject: [PATCH 3/4] comment on ownership --- contracts/tokenbridge/libraries/vault/MasterVault.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/tokenbridge/libraries/vault/MasterVault.sol b/contracts/tokenbridge/libraries/vault/MasterVault.sol index 21853ebce..a6579dc85 100644 --- a/contracts/tokenbridge/libraries/vault/MasterVault.sol +++ b/contracts/tokenbridge/libraries/vault/MasterVault.sol @@ -33,7 +33,7 @@ contract MasterVault is IMasterVault, Ownable { } // todo: remove gateway and owner params - // factory can transfer ownership to upgrade executor + // factory retains ownership. anyone can call deposit and withdraw since it's close to a standard 4626 vault constructor(address _token, address _gateway, address _owner) Ownable() { if (_token == address(0) || _gateway == address(0) || _owner == address(0)) { revert ZeroAddress(); From 510c3de893031bc7ba9f4e592e5fbff455a58058 Mon Sep 17 00:00:00 2001 From: Henry <11198460+godzillaba@users.noreply.github.com> Date: Tue, 23 Sep 2025 19:34:41 -0600 Subject: [PATCH 4/4] add note about ownership transfer --- contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol b/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol index e22cd3e65..79e3c8fba 100644 --- a/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol +++ b/contracts/tokenbridge/libraries/vault/MasterVaultFactory.sol @@ -51,6 +51,7 @@ contract MasterVaultFactory is OwnableUpgradeable { return vault; } + // todo: consider a method to enable bridge owner to transfer specific master vault ownership to new address function setSubVault( address masterVault, address subVault