From 3e795ce4df6325175ff339041a6b4a0d89029397 Mon Sep 17 00:00:00 2001 From: Ashitaka Date: Tue, 30 Jul 2024 23:06:54 -0300 Subject: [PATCH] feat: owner --- foundry.toml | 2 +- script/Deploy.sol | 33 ----- src/contracts/EBORequestCreator.sol | 116 +++++++++++++++++ src/contracts/Greeter.sol | 59 --------- src/interfaces/IEBORequestCreator.sol | 153 ++++++++++++++++++++++ src/interfaces/IGreeter.sol | 74 ----------- test/integration/Greeter.t.sol | 16 --- test/integration/IntegrationBase.sol | 5 +- test/invariants/fuzz/Greeter.t.sol | 37 ------ test/invariants/symbolic/Greeter.t.sol | 58 --------- test/unit/EBORequestCreator.t.sol | 172 +++++++++++++++++++++++++ test/unit/Greeter.t.sol | 99 -------------- test/unit/Greeter.tree | 25 ---- yarn.lock | 13 -- 14 files changed, 443 insertions(+), 419 deletions(-) delete mode 100644 script/Deploy.sol create mode 100644 src/contracts/EBORequestCreator.sol delete mode 100644 src/contracts/Greeter.sol create mode 100644 src/interfaces/IEBORequestCreator.sol delete mode 100644 src/interfaces/IGreeter.sol delete mode 100644 test/integration/Greeter.t.sol delete mode 100644 test/invariants/fuzz/Greeter.t.sol delete mode 100644 test/invariants/symbolic/Greeter.t.sol create mode 100644 test/unit/EBORequestCreator.t.sol delete mode 100644 test/unit/Greeter.t.sol delete mode 100644 test/unit/Greeter.tree diff --git a/foundry.toml b/foundry.toml index b9d9beb..95bed70 100644 --- a/foundry.toml +++ b/foundry.toml @@ -9,7 +9,7 @@ multiline_func_header = 'params_first' sort_imports = true [profile.default] -solc_version = '0.8.23' +solc_version = '0.8.26' libs = ['node_modules', 'lib'] optimizer_runs = 10_000 diff --git a/script/Deploy.sol b/script/Deploy.sol deleted file mode 100644 index 7ce78e9..0000000 --- a/script/Deploy.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {Greeter} from 'contracts/Greeter.sol'; -import {Script} from 'forge-std/Script.sol'; -import {IERC20} from 'forge-std/interfaces/IERC20.sol'; - -contract Deploy is Script { - struct DeploymentParams { - string greeting; - IERC20 token; - } - - /// @notice Deployment parameters for each chain - mapping(uint256 _chainId => DeploymentParams _params) internal _deploymentParams; - - function setUp() public { - // Mainnet - _deploymentParams[1] = DeploymentParams('Hello, Mainnet!', IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)); - - // Sepolia - _deploymentParams[11_155_111] = - DeploymentParams('Hello, Sepolia!', IERC20(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6)); - } - - function run() public { - DeploymentParams memory _params = _deploymentParams[block.chainid]; - - vm.startBroadcast(); - new Greeter(_params.greeting, _params.token); - vm.stopBroadcast(); - } -} diff --git a/src/contracts/EBORequestCreator.sol b/src/contracts/EBORequestCreator.sol new file mode 100644 index 0000000..3a4c822 --- /dev/null +++ b/src/contracts/EBORequestCreator.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.26; + +import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import {IEBORequestCreator} from 'interfaces/IEBORequestCreator.sol'; + +contract EBORequestCreator is IEBORequestCreator { + using EnumerableSet for EnumerableSet.Bytes32Set; + + // /// @inheritdoc IEBORequestCreator + // IOracle public oracle; + + /// @inheritdoc IEBORequestCreator + address public owner; + + /// @inheritdoc IEBORequestCreator + address public pendingOwner; + + /// @inheritdoc IEBORequestCreator + uint256 public reward; + + /** + * @notice The list of chain ids + */ + EnumerableSet.Bytes32Set internal _chainIds; + + constructor(address _owner) { + // oracle = _oracle; + + owner = _owner; + reward = 0; + } + + /// @inheritdoc IEBORequestCreator + function setPendingOwner(address _pendingOwner) external onlyOwner { + pendingOwner = _pendingOwner; + + emit PendingOwnerSetted(_pendingOwner); + } + + /// @inheritdoc IEBORequestCreator + function acceptPendingOwner() external onlyPendingOwner { + address _oldOwner = owner; + owner = pendingOwner; + pendingOwner = address(0); + + emit OwnerSetted(_oldOwner, owner); + } + + /// @inheritdoc IEBORequestCreator + function createRequest( + address _requester, + address _target, + bytes calldata _data, + uint256 _value, + uint256 _nonce + ) external returns (bytes32 _requestId) { + // emit RequestCreated(_requestId, _requester, _target, _data, _value, _nonce); + } + + /// @inheritdoc IEBORequestCreator + function addChain(string calldata _chainId) external onlyOwner { + if (!_chainIds.add(_chaindIdToBytes32(_chainId))) { + revert EBORequestCreator_ChainAlreadyAdded(); + } + emit ChainAdded(_chainId); + } + + /// @inheritdoc IEBORequestCreator + function removeChain(string calldata _chainId) external onlyOwner { + if (!_chainIds.remove(_chaindIdToBytes32(_chainId))) { + revert EBORequestCreator_ChainNotAdded(); + } + emit ChainRemoved(_chainId); + } + + /// @inheritdoc IEBORequestCreator + function setReward(uint256 _reward) external onlyOwner { + uint256 _oldReward = reward; + reward = _reward; + emit RewardSet(_oldReward, _reward); + } + + /// @inheritdoc IEBORequestCreator + function getChainIds() external view returns (string[] memory _chainIdsValues) { + bytes32[] memory _chainIdsBytes = _chainIds.values(); + + for (uint256 _i; _i < _chainIdsBytes.length; _i++) { + _chainIdsValues[_i] = _chaindIdToString(_chainIdsBytes[_i]); + } + } + + function _chaindIdToBytes32(string memory _chainId) internal pure returns (bytes32 _convertedChainId) { + assembly { + _convertedChainId := mload(add(_chainId, 32)) + } + } + + function _chaindIdToString(bytes32 _chainId) internal pure returns (string memory _convertedChainId) { + _convertedChainId = string(abi.encodePacked(_chainId)); + } + + modifier onlyOwner() { + if (msg.sender != owner) { + revert EBORequestCreator_OnlyOwner(); + } + _; + } + + modifier onlyPendingOwner() { + if (msg.sender != pendingOwner) { + revert EBORequestCreator_OnlyPendingOwner(); + } + _; + } +} 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/interfaces/IEBORequestCreator.sol b/src/interfaces/IEBORequestCreator.sol new file mode 100644 index 0000000..44e670d --- /dev/null +++ b/src/interfaces/IEBORequestCreator.sol @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.26; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +interface IEBORequestCreator { + /*/////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Emitted when the pending owner is set + * @param _pendingOwner The address of the pending owner + */ + event PendingOwnerSetted(address _pendingOwner); + + /** + * @notice Emitted when the owner is set + * @param _oldOwner The old owner address + * @param _newOwner The new owner address + */ + event OwnerSetted(address _oldOwner, address _newOwner); + + /** + * @notice Emitted when a request is created + * @param _epoch The epoch of the request + * @param _chainId The chain id of the request + */ + event RequestCreated(uint256 _epoch, uint256 _chainId); + + /** + * @notice Emitted when a chain is added + * @param _chainId The chain id added + */ + event ChainAdded(string _chainId); + + /** + * @notice Emitted when a chain is removed + * @param _chainId The chain id removed + */ + event ChainRemoved(string _chainId); + + /** + * @notice Emitted when the reward is set + * @param _oldReward The old reward value + * @param _newReward The new reward value + */ + event RewardSet(uint256 _oldReward, uint256 _newReward); + + /*/////////////////////////////////////////////////////////////// + ERRORS + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Thrown when the caller is not the owner + */ + error EBORequestCreator_OnlyOwner(); + + /** + * @notice Thrown when the caller is not the pending owner + */ + error EBORequestCreator_OnlyPendingOwner(); + + /** + * @notice hrown when the chain is already added + */ + error EBORequestCreator_ChainAlreadyAdded(); + + /** + * @notice Thrown when the chain is not added + */ + error EBORequestCreator_ChainNotAdded(); + + /*/////////////////////////////////////////////////////////////// + VARIABLES + //////////////////////////////////////////////////////////////*/ + + // /** + // * @notice The oracle contract + // */ + // function oracle() external view returns (IOracle _oracle); + + /** + * @notice The owner of the contract + */ + function owner() external view returns (address _owner); + + /** + * @notice The pending owner of the contract + */ + function pendingOwner() external view returns (address _pendingOwner); + + /** + * @notice The reward paid for each chain updated + */ + function reward() external view returns (uint256 _reward); + + /*/////////////////////////////////////////////////////////////// + LOGIC + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Set the pending owner + * @param _pendingOwner The address of the pending owner + */ + function setPendingOwner(address _pendingOwner) external; + + /** + * @notice Accept the pending owner + */ + function acceptPendingOwner() external; + + /** + * @notice Create a request + * @param _requester The address of the requester + * @param _target The address of the target + * @param _data The data of the request + * @param _value The value of the request + * @param _nonce The nonce of the request + * @return _requestId The id of the request + */ + function createRequest( + address _requester, + address _target, + bytes calldata _data, + uint256 _value, + uint256 _nonce + ) external returns (bytes32 _requestId); + + /** + * @notice Add a chain to the allowed chains which can be updated + * @param _chainId The chain id to add + */ + function addChain(string calldata _chainId) external; + + /** + * @notice Remove a chain from the allowed chains which can be updated + * @param _chainId The chain id to remove + */ + function removeChain(string calldata _chainId) external; + + /** + * @notice Set the reward paid for each chain updated + * @param _reward The reward to set + */ + function setReward(uint256 _reward) external; + + /** + * @notice Get the chain ids + * @return _chainIdsValues The chain ids + */ + function getChainIds() external view returns (string[] memory _chainIdsValues); +} 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/test/integration/Greeter.t.sol b/test/integration/Greeter.t.sol deleted file mode 100644 index b0e3799..0000000 --- a/test/integration/Greeter.t.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.23; - -import {IntegrationBase} from 'test/integration/IntegrationBase.sol'; - -contract IntegrationGreeter is IntegrationBase { - function test_Greet() public { - uint256 _whaleBalance = _dai.balanceOf(_daiWhale); - - vm.prank(_daiWhale); - (string memory _greeting, uint256 _balance) = _greeter.greet(); - - assertEq(_whaleBalance, _balance); - assertEq(_initialGreeting, _greeting); - } -} diff --git a/test/integration/IntegrationBase.sol b/test/integration/IntegrationBase.sol index b043f49..0569527 100644 --- a/test/integration/IntegrationBase.sol +++ b/test/integration/IntegrationBase.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.23; +pragma solidity 0.8.26; -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; import {Test} from 'forge-std/Test.sol'; import {IERC20} from 'forge-std/interfaces/IERC20.sol'; @@ -13,11 +12,9 @@ contract IntegrationBase is Test { address internal _owner = makeAddr('owner'); address internal _daiWhale = 0x42f8CA49E88A8fd8F0bfA2C739e648468b8f9dec; IERC20 internal _dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); - IGreeter internal _greeter; function setUp() public { vm.createSelectFork(vm.rpcUrl('mainnet'), _FORK_BLOCK); vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _dai); } } diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol deleted file mode 100644 index 96e2b1e..0000000 --- a/test/invariants/fuzz/Greeter.t.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.23; - -import {Greeter, IERC20} from 'contracts/Greeter.sol'; - -interface IHevm { - function prank(address) external; -} - -contract InvariantGreeter { - IHevm internal _hevm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - Greeter internal _targetContract; - - constructor() { - _targetContract = new Greeter('a', IERC20(address(1))); - } - - function checkGreeterNeverEmpty(string memory _newGreeting) public { - // Execution - (bool _success,) = address(_targetContract).call(abi.encodeCall(Greeter.setGreeting, _newGreeting)); - - // Check output condition - assert((_success && keccak256(bytes(_targetContract.greeting())) != keccak256(bytes(''))) || !_success); - } - - function checkOnlyOwnerSetsGreeting(address _caller) public { - // Input conditions - _hevm.prank(_caller); - - // Execution - (bool _success,) = address(this).call(abi.encodeCall(Greeter.setGreeting, 'hello')); - - // Check output condition - assert((_success && msg.sender == _targetContract.OWNER()) || (!_success && msg.sender != _targetContract.OWNER())); - } -} diff --git a/test/invariants/symbolic/Greeter.t.sol b/test/invariants/symbolic/Greeter.t.sol deleted file mode 100644 index 16a7edd..0000000 --- a/test/invariants/symbolic/Greeter.t.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.23; - -import {Greeter, IERC20} from 'contracts/Greeter.sol'; - -import {Test} from 'forge-std/Test.sol'; -import {SymTest} from 'halmos-cheatcodes/src/SymTest.sol'; // See https://github.com/a16z/halmos-cheatcodes?tab=readme-ov-file - -contract SymbolicGreeter is SymTest, Test { - Greeter public targetContract; - - function setUp() public { - string memory _initialGreeting = svm.createString(64, 'initial greeting'); - address _token = svm.createAddress('token'); - - targetContract = new Greeter(_initialGreeting, IERC20(_token)); - } - - function check_validState_greeterNeverEmpty(address _caller) public { - // Input conditions: any caller - vm.prank(_caller); - - // Execution: Halmos cannot use a dynamic-sized array, iterate over multiple string lengths - bool _success; - for (uint256 i = 1; i < 3; i++) { - string memory greeting = svm.createString(i, 'greeting'); - (_success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (greeting))); - - // Output condition check - vm.assume(_success); // discard failing calls - assert(keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))); - } - - // Add the empty string (bypass the non-empty check of svm.createString) - (_success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (''))); - - // Output condition check - vm.assume(_success); // discard failing calls - assert(keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))); - } - - function check_setGreeting_onlyOwnerSetsGreeting(address _caller) public { - // Input conditions - string memory _newGreeting = svm.createString(64, 'new greeting'); - - // Execution - vm.prank(_caller); - (bool _success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (_newGreeting))); - - // Output condition check - if (_success) { - assert(_caller == targetContract.OWNER()); - assert(keccak256(bytes(targetContract.greeting())) == keccak256(bytes(_newGreeting))); - } else { - assert(_caller != targetContract.OWNER() || keccak256(bytes(_newGreeting)) == keccak256(bytes(''))); - } - } -} diff --git a/test/unit/EBORequestCreator.t.sol b/test/unit/EBORequestCreator.t.sol new file mode 100644 index 0000000..2e47326 --- /dev/null +++ b/test/unit/EBORequestCreator.t.sol @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.26; + +import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +import {EBORequestCreator, IEBORequestCreator} from 'contracts/EBORequestCreator.sol'; + +import {Test} from 'forge-std/Test.sol'; + +contract EBORequestCreatorForTest is EBORequestCreator { + using EnumerableSet for EnumerableSet.Bytes32Set; + + constructor() EBORequestCreator(owner) {} + + function setChainIdForTest(string calldata _chainId) external { + _chainIds.add(_chaindIdToBytes32(_chainId)); + } +} + +// abstract contract EBORequestCreatorUnitTest is Test { +// /// Events +// event RequestCreated(uint256 _epoch, uint256 _chainId); +// event ChainAdded(uint256 _chainId); +// event ChainRemoved(uint256 _chainId); +// event RewardSet(uint256 _oldReward, uint256 _newReward); + +// /// Contracts +// EBORequestCreatorForTest public eboRequestCreator; +// // IOracle public oracle; + +// /// EOAs +// address public owner; + +// function setUp() external { +// owner = makeAddr('Owner'); +// // oracle = IOracle(makeAddr('Oracle')); + +// vm.prank(owner); +// eboRequestCreator = new EBORequestCreatorForTest(); +// } +// } + +// contract UnitEBORequestCreatorConstructor is EBORequestCreatorUnitTest { +// function testConstructor() external view { +// assertEq(eboRequestCreator.reward(), 0); +// assertEq(eboRequestCreator.owner(), owner); +// assertEq(eboRequestCreator.pendingOwner(), address(0)); +// // assertEq(eboRequestCreator.oracle(), oracle); +// } +// } + +// // contract UnitEBORequestCreatorCreateRequest is EBORequestCreatorUnitTest { +// // function test_CreateRequest() external { +// // bytes32 requestId = eboRequestCreator.createRequest(address(this), address(this), '0x', 0, 0); +// // assertEq(uint256(requestId), uint256(keccak256(abi.encodePacked(address(this), address(this), '0x', 0, 0))); +// // } +// // } + +// contract UnitEBORequestCreatorAddChain is EBORequestCreatorUnitTest { +// modifier happyPath() { +// vm.startPrank(owner); +// _; +// } + +// function testRevertIfNotOwner(uint256 _chainId) external { +// vm.expectRevert(); +// eboRequestCreator.addChain(_chainId); +// } + +// function testRevertIfChainAdded(uint256 _chainId) external happyPath { +// eboRequestCreator.setChainIdForTest(_chainId); + +// vm.expectRevert(abi.encodeWithSelector(IEBORequestCreator.EBORequestCreator_ChainAlreadyAdded.selector, _chainId)); +// eboRequestCreator.addChain(_chainId); +// } + +// function testAddChain(uint256 _chainId) external happyPath { +// eboRequestCreator.addChain(_chainId); + +// assertEq(eboRequestCreator.getChainIds().length, 1); +// assertEq(eboRequestCreator.getChainIds()[0], _chainId); +// } + +// function testEmitChainAdded(uint256 _chainId) external happyPath { +// vm.expectEmit(); +// emit ChainAdded(_chainId); + +// eboRequestCreator.addChain(_chainId); +// } +// } + +// contract UnitEBORequestCreatorRemoveChain is EBORequestCreatorUnitTest { +// modifier happyPath(uint256 _chainId) { +// eboRequestCreator.setChainIdForTest(_chainId); +// vm.startPrank(owner); +// _; +// } + +// function testRevertIfNotOwner(uint256 _chainId) external { +// vm.expectRevert(); +// eboRequestCreator.removeChain(_chainId); +// } + +// function testRevertIfChainNotAdded(uint256 _chainId) external { +// vm.expectRevert(abi.encodeWithSelector(IEBORequestCreator.EBORequestCreator_ChainNotAdded.selector, _chainId)); + +// vm.prank(owner); +// eboRequestCreator.removeChain(_chainId); +// } + +// function testRemoveChain(uint256 _chainId) external happyPath(_chainId) { +// eboRequestCreator.removeChain(_chainId); + +// assertEq(eboRequestCreator.getChainIds().length, 0); +// } + +// function testEmitChainRemoved(uint256 _chainId) external happyPath(_chainId) { +// vm.expectEmit(); +// emit ChainRemoved(_chainId); + +// eboRequestCreator.removeChain(_chainId); +// } +// } + +// contract UnitEBORequestCreatorSetReward is EBORequestCreatorUnitTest { +// modifier happyPath(uint256 _reward) { +// vm.startPrank(owner); +// _; +// } + +// function testRevertIfNotOwner(uint256 _reward) external { +// vm.expectRevert(); +// eboRequestCreator.setReward(_reward); +// } + +// function testSetReward(uint256 _reward) external happyPath(_reward) { +// eboRequestCreator.setReward(_reward); + +// assertEq(eboRequestCreator.reward(), _reward); +// } + +// function testEmitRewardSet(uint256 _reward) external happyPath(_reward) { +// vm.expectEmit(); +// emit RewardSet(0, _reward); + +// eboRequestCreator.setReward(_reward); +// } +// } + +// contract UnitEBORequestCreatorGetChainIds is EBORequestCreatorUnitTest { +// using EnumerableSet for EnumerableSet.UintSet; + +// EnumerableSet.UintSet internal _cleanChainIds; + +// modifier happyPath(uint256[] memory _chainIds) { +// vm.assume(_chainIds.length > 0 && _chainIds.length <= 256); +// for (uint256 _i; _i < _chainIds.length; ++_i) { +// eboRequestCreator.setChainIdForTest(_chainIds[_i]); +// _cleanChainIds.add(_chainIds[_i]); +// } +// _; +// } + +// function testGetChainIds(uint256[] memory _chainIds) external happyPath(_chainIds) { +// uint256[] memory _getChainIds = eboRequestCreator.getChainIds(); +// assertEq(_getChainIds.length, _cleanChainIds.length()); + +// for (uint256 _i; _i < _getChainIds.length; ++_i) { +// assert(_cleanChainIds.contains(_getChainIds[_i])); +// } +// } +// } diff --git a/test/unit/Greeter.t.sol b/test/unit/Greeter.t.sol deleted file mode 100644 index 82f59c9..0000000 --- a/test/unit/Greeter.t.sol +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -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'; - -contract UnitGreeter is Test { - address internal _owner = makeAddr('owner'); - IERC20 internal _token = IERC20(makeAddr('token')); - uint256 internal _initialBalance = 100; - string internal _initialGreeting = 'hola'; - - Greeter internal _greeter; - - event GreetingSet(string _greeting); - - function setUp() external { - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); - - vm.etch(address(_token), new bytes(0x1)); - } - - function test_EmptyTestExample() external { - // it does nothing - vm.skip(true); - } - - function test_ConstructorWhenPassingValidGreetingString() external { - vm.prank(_owner); - - // it deploys - _greeter = new Greeter(_initialGreeting, _token); - - // it sets the greeting string - assertEq(_greeter.greeting(), _initialGreeting); - - // it sets the owner as sender - assertEq(_greeter.OWNER(), _owner); - - // it sets the token used - assertEq(address(_greeter.token()), address(_token)); - } - - function test_ConstructorWhenPassingAnEmptyGreetingString() external { - vm.prank(_owner); - - // it reverts - vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); - _greeter = new Greeter('', _token); - } - - function test_GreetWhenCalled() external { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(_initialBalance)); - vm.expectCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector)); - (string memory _greet, uint256 _balance) = _greeter.greet(); - - // it returns the greeting string - assertEq(_greet, _initialGreeting); - - // it returns the token balance of the contract - assertEq(_balance, _initialBalance); - } - - modifier whenCalledByTheOwner() { - vm.startPrank(_owner); - _; - vm.stopPrank(); - } - - function test_SetGreetingWhenPassingAValidGreetingString() external whenCalledByTheOwner { - string memory _newGreeting = 'hello'; - - // it emit GreetingSet - vm.expectEmit(true, true, true, true, address(_greeter)); - emit GreetingSet(_newGreeting); - - _greeter.setGreeting(_newGreeting); - - // it sets the greeting string - assertEq(_greeter.greeting(), _newGreeting); - } - - function test_SetGreetingWhenPassingAnEmptyGreetingString() external whenCalledByTheOwner { - // it reverts - vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); - _greeter.setGreeting(''); - } - - function test_SetGreetingWhenCalledByANon_owner(address _caller) external { - vm.assume(_caller != _owner); - vm.prank(_caller); - - // it reverts - vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); - _greeter.setGreeting('new greeting'); - } -} diff --git a/test/unit/Greeter.tree b/test/unit/Greeter.tree deleted file mode 100644 index bbc74ea..0000000 --- a/test/unit/Greeter.tree +++ /dev/null @@ -1,25 +0,0 @@ -Greeter::constructor -├── when passing valid greeting string -│ ├── it deploys -│ ├── it sets the greeting string -│ ├── it sets the owner as sender -│ └── it sets the token used -└── when passing an empty greeting string - └── it reverts - - -Greeter::greet -└── when called - ├── it returns the greeting string - └── it returns the token balance of the contract - - -Greeter::setGreeting -├── when called by the owner -│ ├── when passing a valid greeting string -│ │ ├── it sets the greeting string -│ │ └── it emit GreetingSet -│ └── when passing an empty greeting string -│ └── it reverts -└── when called by a non-owner - └── it reverts \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8f853f3..a0b6304 100644 --- a/yarn.lock +++ b/yarn.lock @@ -702,11 +702,6 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -"ds-test@git+https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0": - version "1.0.0" - uid e282159d5170298eb2455a6c05280ab5a73a4ef0 - resolved "git+https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0" - "ds-test@https://github.com/dapphub/ds-test": version "1.0.0" uid e282159d5170298eb2455a6c05280ab5a73a4ef0 @@ -868,10 +863,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -"forge-std@git+https://github.com/foundry-rs/forge-std.git#e8a047e3f40f13fa37af6fe14e6e06283d9a060e": - version "1.5.6" - resolved "git+https://github.com/foundry-rs/forge-std.git#e8a047e3f40f13fa37af6fe14e6e06283d9a060e" - "forge-std@github:foundry-rs/forge-std#1.8.2": version "1.8.2" resolved "https://codeload.github.com/foundry-rs/forge-std/tar.gz/978ac6fadb62f5f0b723c996f64be52eddba6801" @@ -1780,10 +1771,6 @@ solhint-community@4.0.0: optionalDependencies: prettier "^2.8.3" -"solmate@git+https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c": - version "6.1.0" - resolved "git+https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c" - "solmate@https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c": version "6.1.0" resolved "https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c"