-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from QuantWealth/1-qwmanager-setup
init QWManager setup
- Loading branch information
Showing
17 changed files
with
523 additions
and
227 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: APACHE | ||
pragma solidity 0.8.23; | ||
|
||
// import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; | ||
|
||
/// | ||
/// NOT PART OF FIRST MVP | ||
/// | ||
|
||
// abstract contract QWGuardian is AccessControl { | ||
// /// Errors | ||
// error QWGuardian__onlyGuardian_notGuardian(); | ||
|
||
// /// Storage | ||
// // Storage records for validated guardian agent addresses. | ||
// mapping(address => bool) _guardians; | ||
// // This role will be able to update validated guardian addresses. | ||
// bytes32 public constant GUARDIAN_OPERATOR_ROLE = | ||
// keccak256("GUARDIAN_OPERATOR_ROLE"); | ||
|
||
// constructor(address operator) { | ||
// // Create operator role. Will be able to allow and disable assets. | ||
// _grantRole(GUARDIAN_OPERATOR_ROLE, operator); | ||
// } | ||
|
||
// /// Modifiers | ||
// /** | ||
// * @notice Only accept a valid guardian address as msg.sender. | ||
// */ | ||
// modifier onlyGuardian() { | ||
// if (!_guardians[msg.sender]) | ||
// revert QWGuardian__onlyGuardian_notGuardian(); | ||
// _; | ||
// } | ||
|
||
// /** | ||
// * @notice One-time function to set the GUARDIAN_OPERATOR_ROLE. | ||
// */ | ||
// function initializeGuardianOperator(address operator) external { | ||
// require( | ||
// hasRole(DEFAULT_ADMIN_ROLE, msg.sender), | ||
// "QWGuardian: Must have admin role to initialize" | ||
// ); | ||
// _grantRole(GUARDIAN_OPERATOR_ROLE, operator); | ||
// } | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// SPDX-License-Identifier: APACHE | ||
pragma solidity 0.8.23; | ||
|
||
import {QWRegistry} from './QWRegistry.sol'; | ||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; | ||
|
||
import {IQWChild} from 'interfaces/IQWChild.sol'; | ||
import {IQWManager} from 'interfaces/IQWManager.sol'; | ||
import {IQWRegistry} from 'interfaces/IQWRegistry.sol'; | ||
|
||
/** | ||
* @title Quant Wealth Manager Contract | ||
* @notice This contract manages the execution, closing, and withdrawal of various strategies for Quant Wealth. | ||
*/ | ||
contract QWManager is IQWManager { | ||
// Variables | ||
address public immutable REGISTRY; | ||
|
||
// Custom errors | ||
error InvalidInputLength(); // Error for mismatched input lengths | ||
error ContractNotWhitelisted(); // Error for contract not whitelisted | ||
error CallFailed(); // Error for call failed | ||
|
||
// Constructor | ||
constructor() { | ||
QWRegistry _registry = new QWRegistry(address(this)); | ||
REGISTRY = address(_registry); | ||
} | ||
|
||
// External Functions | ||
/** | ||
* @notice Execute a series of investments. | ||
* Transfers specified amounts of tokens and calls target contracts with provided calldata. | ||
* @param _targetQwChild List of contract addresses to interact with. | ||
* @param _callData Encoded function calls to be executed on the target contracts. | ||
* @param _tokenAddress Token address to transfer. | ||
* @param _amount Amount of tokens to transfer to each target contract. | ||
*/ | ||
function execute( | ||
address[] memory _targetQwChild, | ||
bytes[] memory _callData, | ||
address _tokenAddress, | ||
uint256 _amount | ||
) external override { | ||
if (_targetQwChild.length != _callData.length) { | ||
revert InvalidInputLength(); | ||
} | ||
|
||
for (uint256 i = 0; i < _targetQwChild.length; i++) { | ||
if (!IQWRegistry(REGISTRY).whitelist(_targetQwChild[i])) { | ||
revert ContractNotWhitelisted(); | ||
} | ||
|
||
IERC20 token = IERC20(_tokenAddress); | ||
token.approve(_targetQwChild[i], _amount); | ||
token.transferFrom(address(this), address(_targetQwChild[i]), _amount); | ||
|
||
(bool success) = IQWChild(_targetQwChild[i]).create(_callData[i], _tokenAddress, _amount); | ||
if (!success) { | ||
revert CallFailed(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @notice Close a series of investments. | ||
* Calls target contracts with provided calldata to close positions. | ||
* @param _targetQwChild List of contract addresses to interact with. | ||
* @param _callData Encoded function calls to be executed on the target contracts. | ||
*/ | ||
function close(address[] memory _targetQwChild, bytes[] memory _callData) external override { | ||
if (_targetQwChild.length != _callData.length) { | ||
revert InvalidInputLength(); | ||
} | ||
|
||
for (uint256 i = 0; i < _targetQwChild.length; i++) { | ||
(bool success) = IQWChild(_targetQwChild[i]).close(_callData[i]); | ||
if (!success) { | ||
revert CallFailed(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @notice Withdraw funds to a specified user. | ||
* Transfers a specified amount of funds to the user. | ||
* @param user The address of the user to receive the funds. | ||
* @param amount The amount of funds to transfer to the user. | ||
*/ | ||
function withdraw(address user, uint256 amount) external override { | ||
payable(user).transfer(amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.23; | ||
|
||
import {IQWChild} from 'interfaces/IQWChild.sol'; | ||
import {IQWRegistry} from 'interfaces/IQWRegistry.sol'; | ||
|
||
/** | ||
* @title Quant Wealth Registry Contract | ||
* @notice This contract manages the registration of child contracts and | ||
* ensures that only valid child contracts can be registered. | ||
*/ | ||
contract QWRegistry is IQWRegistry { | ||
// Variables | ||
address public immutable QW_MANAGER; | ||
mapping(address => bool) public whitelist; | ||
|
||
// Events | ||
event ChildRegistered(address indexed child); | ||
|
||
// Custom errors | ||
error ParentMismatch(); // Error for mismatched parent contract | ||
error InvalidAddress(); // Error for invalid address | ||
|
||
// Constructor | ||
/** | ||
* @dev Initializes the QWRegistry contract with the address of the Quant Wealth Manager contract. | ||
* @param _qwManager The address of the Quant Wealth Manager contract. | ||
*/ | ||
constructor(address _qwManager) { | ||
QW_MANAGER = _qwManager; | ||
} | ||
|
||
// External Functions | ||
|
||
/** | ||
* @notice Registers a child contract in the whitelist. | ||
* @dev This function ensures that the child contract's parent matches the QWManager. | ||
* @param _child The address of the child contract to register. | ||
*/ | ||
function registerChild(address _child) external { | ||
_validateInput(_child); | ||
IQWChild childContract = IQWChild(_child); | ||
if (childContract.QW_MANAGER() != QW_MANAGER) { | ||
revert ParentMismatch(); | ||
} | ||
whitelist[_child] = true; | ||
emit ChildRegistered(_child); // Emit an event when a child contract is registered | ||
} | ||
|
||
// Internal Functions | ||
|
||
// Error Handling: Ensure that input parameters are valid | ||
function _validateInput(address _child) private pure { | ||
if (_child == address(0)) { | ||
revert InvalidAddress(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: APACHE | ||
pragma solidity 0.8.23; | ||
|
||
// import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; | ||
|
||
/// NOT PART OF MVP | ||
|
||
// abstract contract QWWing is AccessControl { | ||
// /// Errors | ||
// error QWWing__onlyWing_notWing(); | ||
|
||
// /// Storage | ||
// // Crispy, slow-cooked, storage records for validated wing agent addresses. | ||
// mapping(address => bool) _wings; // alt: flight | ||
// // This role will be able to update validated wing addresses. | ||
// bytes32 public constant WING_OPERATOR_ROLE = | ||
// keccak256("WING_OPERATOR_ROLE"); | ||
|
||
// /// Constructor | ||
// constructor(address operator) { | ||
// // Create operator role. Will be able to allow and disable assets. | ||
// _grantRole(WING_OPERATOR_ROLE, operator); | ||
// } | ||
|
||
// /// Modifiers | ||
// /** | ||
// * @notice Only accept a valid wing address as msg.sender. | ||
// */ | ||
// modifier onlyWing() { | ||
// if (!_wings[msg.sender]) revert QWWing__onlyWing_notWing(); | ||
// _; | ||
// } | ||
|
||
// /** | ||
// * @notice One-time function to set the WING_OPERATOR_ROLE. | ||
// */ | ||
// function initializeWingOperator(address operator) external { | ||
// require( | ||
// hasRole(DEFAULT_ADMIN_ROLE, msg.sender), | ||
// "QWWing: Must have admin role to initialize" | ||
// ); | ||
// _grantRole(WING_OPERATOR_ROLE, operator); | ||
// } | ||
// } |
Oops, something went wrong.