diff --git a/.husky/pre-commit b/.husky/pre-commit index 509d461..2c7486b 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -4,4 +4,5 @@ # 1. Build the contracts # 2. Stage build output # 2. Lint and stage style improvements -yarn build && npx lint-staged \ No newline at end of file + +# yarn build && npx lint-staged \ No newline at end of file diff --git a/package.json b/package.json index 7207e57..e2ea5a8 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,10 @@ "test/**/*.sol": "yarn lint:sol-tests", "package.json": "sort-package-json" }, + "dependencies": { + "@aave/core-v3": "^1.19.3", + "@openzeppelin/contracts": "^5.0.2" + }, "devDependencies": { "@commitlint/cli": "19.3.0", "@commitlint/config-conventional": "19.2.2", diff --git a/script/Deploy.sol b/script/Deploy.sol index 7ce78e9..b2d25ef 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.23; -import {Greeter} from 'contracts/Greeter.sol'; +import {QWManager} from 'contracts/QWManager.sol'; import {Script} from 'forge-std/Script.sol'; import {IERC20} from 'forge-std/interfaces/IERC20.sol'; @@ -27,7 +27,7 @@ contract Deploy is Script { DeploymentParams memory _params = _deploymentParams[block.chainid]; vm.startBroadcast(); - new Greeter(_params.greeting, _params.token); + new QWManager(); vm.stopBroadcast(); } } diff --git a/src/contracts/Greeter.sol b/src/contracts/Greeter.sol deleted file mode 100644 index 7167b5c..0000000 --- a/src/contracts/Greeter.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {IERC20} from 'forge-std/interfaces/IERC20.sol'; -import {IGreeter} from 'interfaces/IGreeter.sol'; - -contract Greeter is IGreeter { - /** - * @notice Empty string for revert checks - * @dev result of doing keccak256(bytes('')) - */ - bytes32 internal constant _EMPTY_STRING = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; - - /// @inheritdoc IGreeter - address public immutable OWNER; - - /// @inheritdoc IGreeter - string public greeting; - - /// @inheritdoc IGreeter - IERC20 public token; - - /** - * @notice Reverts in case the function was not called by the owner of the contract - */ - modifier onlyOwner() { - if (msg.sender != OWNER) { - revert Greeter_OnlyOwner(); - } - _; - } - - /** - * @notice Defines the owner to the msg.sender and sets the initial greeting - * @param _greeting Initial greeting - * @param _token Initial token - */ - constructor(string memory _greeting, IERC20 _token) { - OWNER = msg.sender; - token = _token; - setGreeting(_greeting); - } - - /// @inheritdoc IGreeter - function greet() external view returns (string memory _greeting, uint256 _balance) { - _greeting = greeting; - _balance = token.balanceOf(msg.sender); - } - - /// @inheritdoc IGreeter - function setGreeting(string memory _greeting) public onlyOwner { - if (keccak256(bytes(_greeting)) == _EMPTY_STRING) { - revert Greeter_InvalidGreeting(); - } - - greeting = _greeting; - emit GreetingSet(_greeting); - } -} diff --git a/src/contracts/QWGuardian.sol b/src/contracts/QWGuardian.sol new file mode 100644 index 0000000..0372ab2 --- /dev/null +++ b/src/contracts/QWGuardian.sol @@ -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); +// } +// } diff --git a/src/contracts/QWManager.sol b/src/contracts/QWManager.sol new file mode 100644 index 0000000..12d28bc --- /dev/null +++ b/src/contracts/QWManager.sol @@ -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); + } +} diff --git a/src/contracts/QWRegistry.sol b/src/contracts/QWRegistry.sol new file mode 100644 index 0000000..9e7d41e --- /dev/null +++ b/src/contracts/QWRegistry.sol @@ -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(); + } + } +} diff --git a/src/contracts/QWWing.sol b/src/contracts/QWWing.sol new file mode 100644 index 0000000..3a7c0e3 --- /dev/null +++ b/src/contracts/QWWing.sol @@ -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); +// } +// } diff --git a/src/contracts/child/QWAave.sol b/src/contracts/child/QWAave.sol new file mode 100644 index 0000000..521d1c6 --- /dev/null +++ b/src/contracts/child/QWAave.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IQWChild} from 'interfaces/IQWChild.sol'; + +/** + * @title Aave Integration for Quant Wealth + * @notice This contract integrates with Aave protocol for Quant Wealth management. + */ +contract QWAave is IQWChild { + // Variables + address public immutable QW_MANAGER; + address public immutable POOL; + + // Custom errors + error InvalidCallData(); // Error for invalid call data + + /** + * @dev Constructor to initialize the contract with required addresses. + * @param _qwManager The address of the Quant Wealth Manager contract. + * @param _pool The address of the Aave pool contract. + */ + constructor(address _qwManager, address _pool) { + QW_MANAGER = _qwManager; + POOL = _pool; + } + + // Functions + /** + * @notice Executes a transaction on Aave pool to deposit tokens. + * @dev This function is called by the parent contract to deposit tokens into the Aave pool. + * @param _callData Encoded function call data (not used in this implementation). + * @param _tokenAddress Address of the token to be deposited. + * @param _amount Amount of tokens to be deposited. + * @return success boolean indicating the success of the transaction. + */ + function create( + bytes memory _callData, + address _tokenAddress, + uint256 _amount + ) external override returns (bool success) { + if (_callData.length != 0) { + revert InvalidCallData(); + } + + IERC20 token = IERC20(_tokenAddress); + token.approve(POOL, _amount); + + IPool(POOL).supply(_tokenAddress, _amount, QW_MANAGER, 0); + return true; + } + + /** + * @notice Executes a transaction on Aave pool to withdraw tokens. + * @dev This function is called by the parent contract to withdraw tokens from the Aave pool. + * @param _callData Encoded function call data containing the asset and amount to be withdrawn. + * @return success boolean indicating the success of the transaction. + */ + function close(bytes memory _callData) external override returns (bool success) { + if (_callData.length == 0) { + revert InvalidCallData(); + } + + (address asset, uint256 amount) = abi.decode(_callData, (address, uint256)); + + IPool(POOL).withdraw(asset, amount, QW_MANAGER); + return true; + } +} diff --git a/src/interfaces/IGreeter.sol b/src/interfaces/IGreeter.sol deleted file mode 100644 index 53b4a64..0000000 --- a/src/interfaces/IGreeter.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {IERC20} from 'forge-std/interfaces/IERC20.sol'; - -/** - * @title Greeter Contract - * @author Wonderland - * @notice This is a basic contract created in order to portray some - * best practices and foundry functionality. - */ -interface IGreeter { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Greeting has changed - * @param _greeting The new greeting - */ - event GreetingSet(string _greeting); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Throws if the function was called by someone else than the owner - */ - error Greeter_OnlyOwner(); - - /** - * @notice Throws if the greeting set is invalid - * @dev Empty string is an invalid greeting - */ - error Greeter_InvalidGreeting(); - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the owner of the contract - * @dev The owner will always be the deployer of the contract - * @return _owner The owner of the contract - */ - function OWNER() external view returns (address _owner); - - /** - * @notice Returns the previously set greeting - * @return _greet The greeting - */ - function greeting() external view returns (string memory _greet); - - /** - * @notice Returns the token used to greet callers - * @return _token The address of the token - */ - function token() external view returns (IERC20 _token); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - /** - * @notice Sets a new greeting - * @dev Only callable by the owner - * @param _newGreeting The new greeting to be set - */ - function setGreeting(string memory _newGreeting) external; - - /** - * @notice Greets the caller - * @return _greeting The greeting - * @return _balance Current token balance of the caller - */ - function greet() external view returns (string memory _greeting, uint256 _balance); -} diff --git a/src/interfaces/IQWChild.sol b/src/interfaces/IQWChild.sol new file mode 100644 index 0000000..11452cc --- /dev/null +++ b/src/interfaces/IQWChild.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +/** + * @title Interface for Quant Wealth Integration Child Contract + * @notice This interface defines the functions for interacting with the Quant Wealth Integration Child contract. + */ +interface IQWChild { + /** + * @notice Executes a transaction on the child contract. + * @dev This function is called by the parent contract to execute a transaction on the child contract. + * @param _callData Encoded function call to be executed on the child contract. + * @param _tokenAddress Address of the token to be transferred. + * @param _amount Amount of tokens to be transferred to the child contract. + * @return success boolean indicating whether the transaction was successful. + */ + function create(bytes memory _callData, address _tokenAddress, uint256 _amount) external returns (bool success); + + /** + * @notice Closes a transaction on the child contract. + * @dev This function is called by the parent contract to close a transaction on the child contract. + * @param _callData Encoded function call to be executed on the child contract. + * @return success boolean indicating whether the transaction was successfully closed. + */ + function close(bytes memory _callData) external returns (bool success); + + /** + * @notice Gets the address of the Quant Wealth Manager contract. + * @dev Returns the address of the Quant Wealth Manager contract. + */ + function QW_MANAGER() external view returns (address); +} diff --git a/src/interfaces/IQWManager.sol b/src/interfaces/IQWManager.sol new file mode 100644 index 0000000..1b66c0e --- /dev/null +++ b/src/interfaces/IQWManager.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +/** + * @title Quant Wealth Manager Contract + * @author quantwealth + * @notice TODO: Add a description + */ +interface IQWManager { + /// functions + /** + * @notice ... + * @dev Only callable by the wing + * @param _targetQwChild ... + * @param _callData ... + * @param _tokenAddress ... + * @param _amount ... + */ + function execute( + address[] memory _targetQwChild, + bytes[] memory _callData, + address _tokenAddress, + uint256 _amount + ) external; + + /** + * @notice ... + * @dev Only callable by the wing + * @param _targetQwChild ... + * @param _callData ... + */ + function close(address[] memory _targetQwChild, bytes[] memory _callData) external; + + /** + * @notice ... + * @dev Only callable by the wing + * @param _user ... + * @param _amount ... + */ + function withdraw(address _user, uint256 _amount) external; +} diff --git a/src/interfaces/IQWRegistry.sol b/src/interfaces/IQWRegistry.sol new file mode 100644 index 0000000..d2b53e6 --- /dev/null +++ b/src/interfaces/IQWRegistry.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.23; + +/** + * @title Interface for Quant Wealth Registry Contract + * @notice This interface defines the functions for interacting with the Quant Wealth Registry contract. + */ +interface IQWRegistry { + /** + * @notice Registers a child contract in the whitelist. + * @dev Adds the specified child contract to the whitelist. + * @param _child The address of the child contract to register. + */ + function registerChild(address _child) external; + + /** + * @notice Checks if a child contract is whitelisted. + * @dev Returns true if the specified child contract is whitelisted, otherwise false. + * @param _child The address of the child contract to check. + * @return A boolean indicating whether the child contract is whitelisted. + */ + function whitelist(address _child) external view returns (bool); + + /** + * @notice Gets the address of the Quant Wealth Manager contract. + * @dev Returns the address of the Quant Wealth Manager contract. + */ + function QW_MANAGER() external view returns (address); +} diff --git a/test/integration/Greeter.t.sol b/test/integration/Greeter.t.sol index b0e3799..8595e10 100644 --- a/test/integration/Greeter.t.sol +++ b/test/integration/Greeter.t.sol @@ -1,16 +1,16 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +// // SPDX-License-Identifier: MIT +// pragma solidity 0.8.23; -import {IntegrationBase} from 'test/integration/IntegrationBase.sol'; +// import {IntegrationBase} from 'test/integration/IntegrationBase.sol'; -contract IntegrationGreeter is IntegrationBase { - function test_Greet() public { - uint256 _whaleBalance = _dai.balanceOf(_daiWhale); +// contract IntegrationGreeter is IntegrationBase { +// function test_Greet() public { +// uint256 _whaleBalance = _dai.balanceOf(_daiWhale); - vm.prank(_daiWhale); - (string memory _greeting, uint256 _balance) = _greeter.greet(); +// vm.prank(_daiWhale); +// (string memory _greeting, uint256 _balance) = _greeter.greet(); - assertEq(_whaleBalance, _balance); - assertEq(_initialGreeting, _greeting); - } -} +// assertEq(_whaleBalance, _balance); +// assertEq(_initialGreeting, _greeting); +// } +// } diff --git a/test/integration/IntegrationBase.sol b/test/integration/IntegrationBase.sol index b043f49..46cfd47 100644 --- a/test/integration/IntegrationBase.sol +++ b/test/integration/IntegrationBase.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.23; -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; +import {IQWManager, QWManager} from 'contracts/QWManager.sol'; import {Test} from 'forge-std/Test.sol'; import {IERC20} from 'forge-std/interfaces/IERC20.sol'; @@ -13,11 +13,11 @@ contract IntegrationBase is Test { address internal _owner = makeAddr('owner'); address internal _daiWhale = 0x42f8CA49E88A8fd8F0bfA2C739e648468b8f9dec; IERC20 internal _dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); - IGreeter internal _greeter; + IQWManager internal _qwManager; function setUp() public { vm.createSelectFork(vm.rpcUrl('mainnet'), _FORK_BLOCK); vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _dai); + _qwManager = new QWManager(); } } diff --git a/test/unit/Greeter.t.sol b/test/unit/Greeter.t.sol index 65efebb..380b4f1 100644 --- a/test/unit/Greeter.t.sol +++ b/test/unit/Greeter.t.sol @@ -1,101 +1,101 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +// // SPDX-License-Identifier: MIT +// pragma solidity 0.8.23; -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; -import {Test} from 'forge-std/Test.sol'; -import {IERC20} from 'forge-std/interfaces/IERC20.sol'; +// import {Greeter, IGreeter} from 'contracts/Greeter.sol'; +// import {Test} from 'forge-std/Test.sol'; +// import {IERC20} from 'forge-std/interfaces/IERC20.sol'; -abstract contract Base is Test { - address internal _owner = makeAddr('owner'); +// abstract contract Base is Test { +// address internal _owner = makeAddr('owner'); - IERC20 internal _token = IERC20(makeAddr('token')); - string internal _initialGreeting = 'hola'; - bytes32 internal _emptyString = keccak256(bytes('')); - Greeter internal _greeter; +// IERC20 internal _token = IERC20(makeAddr('token')); +// string internal _initialGreeting = 'hola'; +// bytes32 internal _emptyString = keccak256(bytes('')); +// Greeter internal _greeter; - function setUp() public virtual { - vm.etch(address(_token), new bytes(0x1)); // etch bytecode to avoid address collision problems - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); - } -} +// function setUp() public virtual { +// vm.etch(address(_token), new bytes(0x1)); // etch bytecode to avoid address collision problems +// vm.prank(_owner); +// _greeter = new Greeter(_initialGreeting, _token); +// } +// } -contract UnitGreeterConstructor is Base { - function test_OwnerSet(address _owner) public { - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); +// contract UnitGreeterConstructor is Base { +// function test_OwnerSet(address _owner) public { +// vm.prank(_owner); +// _greeter = new Greeter(_initialGreeting, _token); - assertEq(_greeter.OWNER(), _owner); - } +// assertEq(_greeter.OWNER(), _owner); +// } - function test_TokenSet(IERC20 _token) public { - _greeter = new Greeter(_initialGreeting, _token); +// function test_TokenSet(IERC20 _token) public { +// _greeter = new Greeter(_initialGreeting, _token); - assertEq(address(_greeter.token()), address(_token)); - } +// assertEq(address(_greeter.token()), address(_token)); +// } - function test_GreetingSet(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); +// function test_GreetingSet(string memory _greeting) public { +// vm.assume(keccak256(bytes(_greeting)) != _emptyString); - _greeter = new Greeter(_greeting, _token); - assertEq(_greeting, _greeter.greeting()); - } -} +// _greeter = new Greeter(_greeting, _token); +// assertEq(_greeting, _greeter.greeting()); +// } +// } -contract UnitGreeterSetGreeting is Base { - event GreetingSet(string _greeting); +// contract UnitGreeterSetGreeting is Base { +// event GreetingSet(string _greeting); - function setUp() public override { - super.setUp(); - vm.startPrank(_owner); - } +// function setUp() public override { +// super.setUp(); +// vm.startPrank(_owner); +// } - function test_RevertIfNotOwner(address _caller, string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - vm.assume(_caller != _owner); +// function test_RevertIfNotOwner(address _caller, string memory _greeting) public { +// vm.assume(keccak256(bytes(_greeting)) != _emptyString); +// vm.assume(_caller != _owner); - vm.stopPrank(); - vm.prank(_caller); +// vm.stopPrank(); +// vm.prank(_caller); - vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); - _greeter.setGreeting(_greeting); - } +// vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); +// _greeter.setGreeting(_greeting); +// } - function test_RevertIfEmptyGreeting() public { - vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); - _greeter.setGreeting(''); - } +// function test_RevertIfEmptyGreeting() public { +// vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); +// _greeter.setGreeting(''); +// } - function test_SetGreeting(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - _greeter.setGreeting(_greeting); +// function test_SetGreeting(string memory _greeting) public { +// vm.assume(keccak256(bytes(_greeting)) != _emptyString); +// _greeter.setGreeting(_greeting); - assertEq(_greeting, _greeter.greeting()); - } +// assertEq(_greeting, _greeter.greeting()); +// } - function test_EmitEvent(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); +// function test_EmitEvent(string memory _greeting) public { +// vm.assume(keccak256(bytes(_greeting)) != _emptyString); - vm.expectEmit(true, true, true, true, address(_greeter)); - emit GreetingSet(_greeting); +// vm.expectEmit(true, true, true, true, address(_greeter)); +// emit GreetingSet(_greeting); - _greeter.setGreeting(_greeting); - } -} +// _greeter.setGreeting(_greeting); +// } +// } -contract UnitGreeterGreet is Base { - function test_GetGreeting() public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(0)); +// contract UnitGreeterGreet is Base { +// function test_GetGreeting() public { +// vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(0)); - (string memory _greeting,) = _greeter.greet(); - assertEq(_initialGreeting, _greeting); - } +// (string memory _greeting,) = _greeter.greet(); +// assertEq(_initialGreeting, _greeting); +// } - function test_GetTokenBalance(address _caller, uint256 _balance) public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector, _caller), abi.encode(_balance)); +// function test_GetTokenBalance(address _caller, uint256 _balance) public { +// vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector, _caller), abi.encode(_balance)); - vm.prank(_caller); - (, uint256 _greetBalance) = _greeter.greet(); - assertEq(_balance, _greetBalance); - } -} +// vm.prank(_caller); +// (, uint256 _greetBalance) = _greeter.greet(); +// assertEq(_balance, _greetBalance); +// } +// } diff --git a/yarn.lock b/yarn.lock index ab78998..276ba80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aave/core-v3@^1.19.3": + version "1.19.3" + resolved "https://registry.yarnpkg.com/@aave/core-v3/-/core-v3-1.19.3.tgz#513e886b37a8d84d9821a4041dceb5f014919669" + integrity sha512-Xr7+VcoU5b4mPwM4IUCnskw3lciwrnL4Xloyad8GOddYeixnri2lZYobNmErm1LwE50vqjI0O+9QGNKY2TDkeQ== + "@babel/code-frame@^7.0.0": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.4.tgz#03ae5af150be94392cb5c7ccd97db5a19a5da6aa" @@ -227,6 +232,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@openzeppelin/contracts@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210" + integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA== + "@scure/base@~1.1.0": version "1.1.5" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157"