// SPDX-License-Identifier: Apache-2.0 // https://docs.soliditylang.org/en/v0.8.10/style-guide.html pragma solidity ^0.8.10; import "lib/forge-std/src/console.sol"; import {IManager} from "src/interfaces/IManager.sol"; import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {ImpactVault} from "src/grants/ImpactVault.sol"; import {IRegistry} from "src/interfaces/IRegistry.sol"; import {PausableUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol"; import {OwnableUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol"; import {ReentrancyGuardUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol"; import {SpiralsRegistry} from "src/grants/SpiralsRegistry.sol"; /// @title ImpactVaultManager /// /// @author @douglasqian contract ImpactVaultManager is OwnableUpgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable { /* * EVENTS */ event ImpactVaultCreated(bytes32 indexed id, address indexed owner); /* * STATE VARIABLES */ SpiralsRegistry public c_spiralsRegistry; // vault ID -> vault mapping(bytes32 => ImpactVault) internal vaults; /* * INITIALIZERS */ constructor() {} function initialize(address _registryAddress) external initializer { __Ownable_init(); __Pausable_init(); __ReentrancyGuard_init(); c_spiralsRegistry = SpiralsRegistry(_registryAddress); } /* * CREATE */ function createOwnerVault(address _owner, address _beneficiary) external whenNotPaused returns (ImpactVault vault) { bytes32 id = getOwnerVaultId(_owner, _beneficiary); vault = _createVault(id, _owner); return vault; } function createBeneficiaryVault(address _beneficiary) external whenNotPaused returns (ImpactVault vault) { bytes32 id = getBeneficiaryVaultId(_beneficiary); vault = _createVault(id, _beneficiary); return vault; } function _createVault(bytes32 _id, address _owner) internal returns (ImpactVault vault) { vault = new ImpactVault(_id, _owner, address(c_spiralsRegistry)); vaults[_id] = vault; emit ImpactVaultCreated(_id, _owner); return vault; } function getOwnerVaultId(address _owner, address _beneficiary) public pure returns (bytes32) { return keccak256(abi.encodePacked(_owner, _beneficiary)); } function getBeneficiaryVaultId(address _beneficiary) public pure returns (bytes32) { return keccak256(abi.encodePacked(_beneficiary)); } function getOwnerVault(address _owner, address _beneficiary) public view returns (ImpactVault) { return _getVault(getOwnerVaultId(_owner, _beneficiary)); } function getBeneficiaryVault(address _beneficiary) public view returns (ImpactVault) { return _getVault(getBeneficiaryVaultId(_beneficiary)); } function _getVault(bytes32 _id) public view returns (ImpactVault) { return vaults[_id]; } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }