From 98b6e1090c7c37bc55ea859b9cf27e0da68e4430 Mon Sep 17 00:00:00 2001 From: blockgroot <170620375+blockgroot@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:39:43 +0530 Subject: [PATCH] add vault factory --- on-chain-contracts/VaultFactory.sol | 98 +++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 on-chain-contracts/VaultFactory.sol diff --git a/on-chain-contracts/VaultFactory.sol b/on-chain-contracts/VaultFactory.sol new file mode 100644 index 00000000..06d1ac7e --- /dev/null +++ b/on-chain-contracts/VaultFactory.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import '../library/UtilLib.sol'; +import '../VaultProxy.sol'; +import '../interfaces/IVaultFactory.sol'; +import '../interfaces/IStaderConfig.sol'; + +import '@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol'; +import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol'; + +contract VaultFactory is IVaultFactory, AccessControlUpgradeable { + IStaderConfig public staderConfig; + address public vaultProxyImplementation; + + bytes32 public constant override NODE_REGISTRY_CONTRACT = keccak256('NODE_REGISTRY_CONTRACT'); + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize(address _admin, address _staderConfig) external initializer { + UtilLib.checkNonZeroAddress(_admin); + UtilLib.checkNonZeroAddress(_staderConfig); + __AccessControl_init_unchained(); + + staderConfig = IStaderConfig(_staderConfig); + vaultProxyImplementation = address(new VaultProxy()); + + _grantRole(DEFAULT_ADMIN_ROLE, _admin); + } + + function deployWithdrawVault( + uint8 _poolId, + uint256 _operatorId, + uint256 _validatorCount, + uint256 _validatorId + ) external override onlyRole(NODE_REGISTRY_CONTRACT) returns (address) { + bytes32 salt = sha256(abi.encode(_poolId, _operatorId, _validatorCount)); + address withdrawVaultAddress = ClonesUpgradeable.cloneDeterministic(vaultProxyImplementation, salt); + VaultProxy(payable(withdrawVaultAddress)).initialise(true, _poolId, _validatorId, address(staderConfig)); + + emit WithdrawVaultCreated(withdrawVaultAddress); + return withdrawVaultAddress; + } + + function deployNodeELRewardVault(uint8 _poolId, uint256 _operatorId) + external + override + onlyRole(NODE_REGISTRY_CONTRACT) + returns (address) + { + bytes32 salt = sha256(abi.encode(_poolId, _operatorId)); + address nodeELRewardVaultAddress = ClonesUpgradeable.cloneDeterministic(vaultProxyImplementation, salt); + VaultProxy(payable(nodeELRewardVaultAddress)).initialise(false, _poolId, _operatorId, address(staderConfig)); + + emit NodeELRewardVaultCreated(nodeELRewardVaultAddress); + return nodeELRewardVaultAddress; + } + + function computeWithdrawVaultAddress( + uint8 _poolId, + uint256 _operatorId, + uint256 _validatorCount + ) external view override returns (address) { + bytes32 salt = sha256(abi.encode(_poolId, _operatorId, _validatorCount)); + return ClonesUpgradeable.predictDeterministicAddress(vaultProxyImplementation, salt); + } + + function computeNodeELRewardVaultAddress(uint8 _poolId, uint256 _operatorId) + external + view + override + returns (address) + { + bytes32 salt = sha256(abi.encode(_poolId, _operatorId)); + return ClonesUpgradeable.predictDeterministicAddress(vaultProxyImplementation, salt); + } + + function getValidatorWithdrawCredential(address _withdrawVault) external pure override returns (bytes memory) { + return abi.encodePacked(bytes1(0x01), bytes11(0x0), address(_withdrawVault)); + } + + //update the address of staderConfig + function updateStaderConfig(address _staderConfig) external override onlyRole(DEFAULT_ADMIN_ROLE) { + UtilLib.checkNonZeroAddress(_staderConfig); + staderConfig = IStaderConfig(_staderConfig); + emit UpdatedStaderConfig(_staderConfig); + } + + //update the implementation address of vaultProxy contract + function updateVaultProxyAddress(address _vaultProxyImpl) external override onlyRole(DEFAULT_ADMIN_ROLE) { + UtilLib.checkNonZeroAddress(_vaultProxyImpl); + vaultProxyImplementation = _vaultProxyImpl; + emit UpdatedVaultProxyImplementation(vaultProxyImplementation); + } +}