From 3816ae4aa06df7da03844662d25159963108dfec Mon Sep 17 00:00:00 2001 From: Petrovska Date: Mon, 15 Jul 2024 20:28:39 +0900 Subject: [PATCH 1/3] chores: reorg events into its own interface file --- src/RoboSaverVirtualModule.sol | 69 +----------------- src/RoboSaverVirtualModuleFactory.sol | 8 +-- .../robosaver/IRoboSaverVirtualModule.sol | 70 +++++++++++++++++++ .../IRoboSaverVirtualModuleFactory.sol | 9 +++ test/unit/SettersTest.t.sol | 8 +-- 5 files changed, 89 insertions(+), 75 deletions(-) create mode 100644 src/interfaces/robosaver/IRoboSaverVirtualModule.sol create mode 100644 src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol diff --git a/src/RoboSaverVirtualModule.sol b/src/RoboSaverVirtualModule.sol index c4d5921..54e7020 100644 --- a/src/RoboSaverVirtualModule.sol +++ b/src/RoboSaverVirtualModule.sol @@ -16,6 +16,8 @@ import "@balancer-v2/interfaces/contracts/solidity-utils/misc/IERC4626.sol"; import {KeeperCompatibleInterface} from "@chainlink/automation/interfaces/KeeperCompatibleInterface.sol"; +import {IRoboSaverVirtualModule} from "./interfaces/robosaver/IRoboSaverVirtualModule.sol"; + import {VirtualModule} from "./types/DataTypes.sol"; import {Errors} from "./libraries/Errors.sol"; @@ -25,6 +27,7 @@ import {RoboSaverConstants} from "./abstracts/RoboSaverConstants.sol"; /// @author onchainification.xyz /// @notice Deposit and withdraw $EURe from your Gnosis Pay card to a liquidity pool contract RoboSaverVirtualModule is + IRoboSaverVirtualModule, // 1 inherited component KeeperCompatibleInterface, // 1 inherited component RoboSaverConstants // 1 inherited component { @@ -60,72 +63,6 @@ contract RoboSaverVirtualModule is /// @dev All asset related arrays should always follow this (alphabetical) order IAsset[] public poolAssets; - /*////////////////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////////////////*/ - - /// @notice Emitted when a transaction to close the pool has been queued up - /// @param safe The address of the card - /// @param amount The minimum amount of $EURe to receive from the pool closure - /// @param timestamp The timestamp of the transaction - event PoolCloseQueued(address indexed safe, uint256 amount, uint256 timestamp); - - /// @notice Emitted when a transaction to withdrawal from the pool has been queued up - /// @param safe The address of the card - /// @param amount The amount of $EURe to withdraw from the pool - /// @param timestamp The timestamp of the transaction - event PoolWithdrawalQueued(address indexed safe, uint256 amount, uint256 timestamp); - - /// @notice Emitted when a transaction to deposit into the pool has been queued up - /// @param safe The address of the card - /// @param amount The amount of $EURe to deposit into the pool - /// @param timestamp The timestamp of the transaction - event PoolDepositQueued(address indexed safe, uint256 amount, uint256 timestamp); - - /// @notice Emitted when a transaction to stake the residual bpt on the card has been queued up - /// @param safe The address of the card - /// @param amount The amount of bpt that is being staked - /// @param timestamp The timestamp of the transaction - event StakeQueued(address indexed safe, uint256 amount, uint256 timestamp); - - /// @notice Emitted when a transaction to shutdown RoboSaver has been queued up - /// @param safe The address of the card - /// @param amount The minimum amount of $EURe to receive from the pool closure - /// @param timestamp The timestamp of the transaction - event PoolShutdownQueued(address indexed safe, uint256 amount, uint256 timestamp); - - /// @notice Emitted when an adjustment pool transaction is being queued up - /// @dev Event is leverage by off-chain service to execute the queued transaction - /// @param target The address of the target contract - /// @param payload The payload of the transaction to be executed on the target contract - /// @param queueNonce The nonce of the queued transaction - event AdjustPoolTxDataQueued(address indexed target, bytes payload, uint256 queueNonce); - - /// @notice Emitted when an adjustment pool transaction is executed in the delay module - /// @param target The address of the target contract - /// @param payload The payload of the transaction executed on the target contract - /// @param nonce The nonce of the executed transaction tracking the delay module counting - /// @param timestamp The timestamp of the transaction - event AdjustPoolTxExecuted(address indexed target, bytes payload, uint256 nonce, uint256 timestamp); - - /// @notice Emitted when the admin sets a new keeper address - /// @param admin The address of the admin - /// @param oldKeeper The address of the old keeper - /// @param newKeeper The address of the new keeper - event SetKeeper(address indexed admin, address oldKeeper, address newKeeper); - - /// @notice Emitted when the admin sets a new buffer value - /// @param admin The address of the contract admin - /// @param oldBuffer The value of the old buffer - /// @param newBuffer The value of the new buffer - event SetBuffer(address indexed admin, uint256 oldBuffer, uint256 newBuffer); - - /// @notice Emitted when the admin sets a new slippage value - /// @param admin The address of the admin - /// @param oldSlippage The value of the old slippage - /// @param newSlippage The value of the new slippage - event SetSlippage(address indexed admin, uint256 oldSlippage, uint256 newSlippage); - /*////////////////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////////////////*/ diff --git a/src/RoboSaverVirtualModuleFactory.sol b/src/RoboSaverVirtualModuleFactory.sol index a998465..996ff5b 100644 --- a/src/RoboSaverVirtualModuleFactory.sol +++ b/src/RoboSaverVirtualModuleFactory.sol @@ -6,6 +6,8 @@ import {IKeeperRegistrar} from "./interfaces/chainlink/IKeeperRegistrar.sol"; import {IDelayModifier} from "@gnosispay-kit/interfaces/IDelayModifier.sol"; import {IRolesModifier} from "@gnosispay-kit/interfaces/IRolesModifier.sol"; +import {IRoboSaverVirtualModuleFactory} from "./interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol"; + import {Factory} from "./types/DataTypes.sol"; import {Errors} from "./libraries/Errors.sol"; @@ -17,6 +19,7 @@ import {RoboSaverVirtualModule} from "./RoboSaverVirtualModule.sol"; /// @author onchainification.xyz /// @notice Factory contract creates an unique {RoboSaverVirtualModule} per Gnosis Pay card, and registers it in the Chainlink Keeper Registry contract RoboSaverVirtualModuleFactory is + IRoboSaverVirtualModuleFactory, // 1 inherited component FactoryConstants // 1 inherited component { /*////////////////////////////////////////////////////////////////////////// @@ -26,11 +29,6 @@ contract RoboSaverVirtualModuleFactory is // card -> (module address, upkeep id) mapping(address => Factory.VirtualModuleDetails) public virtualModules; - /*////////////////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////////////////*/ - event RoboSaverVirtualModuleCreated(address virtualModule, address card, uint256 upkeepId, uint256 timestamp); - /*////////////////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////////*/ diff --git a/src/interfaces/robosaver/IRoboSaverVirtualModule.sol b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol new file mode 100644 index 0000000..7960cdc --- /dev/null +++ b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +interface IRoboSaverVirtualModule { + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Emitted when a transaction to close the pool has been queued up + /// @param safe The address of the card + /// @param amount The minimum amount of $EURe to receive from the pool closure + /// @param timestamp The timestamp of the transaction + event PoolCloseQueued(address indexed safe, uint256 amount, uint256 timestamp); + + /// @notice Emitted when a transaction to withdrawal from the pool has been queued up + /// @param safe The address of the card + /// @param amount The amount of $EURe to withdraw from the pool + /// @param timestamp The timestamp of the transaction + event PoolWithdrawalQueued(address indexed safe, uint256 amount, uint256 timestamp); + + /// @notice Emitted when a transaction to deposit into the pool has been queued up + /// @param safe The address of the card + /// @param amount The amount of $EURe to deposit into the pool + /// @param timestamp The timestamp of the transaction + event PoolDepositQueued(address indexed safe, uint256 amount, uint256 timestamp); + + /// @notice Emitted when a transaction to stake the residual bpt on the card has been queued up + /// @param safe The address of the card + /// @param amount The amount of bpt that is being staked + /// @param timestamp The timestamp of the transaction + event StakeQueued(address indexed safe, uint256 amount, uint256 timestamp); + + /// @notice Emitted when a transaction to shutdown RoboSaver has been queued up + /// @param safe The address of the card + /// @param amount The minimum amount of $EURe to receive from the pool closure + /// @param timestamp The timestamp of the transaction + event PoolShutdownQueued(address indexed safe, uint256 amount, uint256 timestamp); + + /// @notice Emitted when an adjustment pool transaction is being queued up + /// @dev Event is leverage by off-chain service to execute the queued transaction + /// @param target The address of the target contract + /// @param payload The payload of the transaction to be executed on the target contract + /// @param queueNonce The nonce of the queued transaction + event AdjustPoolTxDataQueued(address indexed target, bytes payload, uint256 queueNonce); + + /// @notice Emitted when an adjustment pool transaction is executed in the delay module + /// @param target The address of the target contract + /// @param payload The payload of the transaction executed on the target contract + /// @param nonce The nonce of the executed transaction tracking the delay module counting + /// @param timestamp The timestamp of the transaction + event AdjustPoolTxExecuted(address indexed target, bytes payload, uint256 nonce, uint256 timestamp); + + /// @notice Emitted when the admin sets a new keeper address + /// @param admin The address of the admin + /// @param oldKeeper The address of the old keeper + /// @param newKeeper The address of the new keeper + event SetKeeper(address indexed admin, address oldKeeper, address newKeeper); + + /// @notice Emitted when the admin sets a new buffer value + /// @param admin The address of the contract admin + /// @param oldBuffer The value of the old buffer + /// @param newBuffer The value of the new buffer + event SetBuffer(address indexed admin, uint256 oldBuffer, uint256 newBuffer); + + /// @notice Emitted when the admin sets a new slippage value + /// @param admin The address of the admin + /// @param oldSlippage The value of the old slippage + /// @param newSlippage The value of the new slippage + event SetSlippage(address indexed admin, uint256 oldSlippage, uint256 newSlippage); +} diff --git a/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol b/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol new file mode 100644 index 0000000..dc3fbb5 --- /dev/null +++ b/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +interface IRoboSaverVirtualModuleFactory { + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + event RoboSaverVirtualModuleCreated(address virtualModule, address card, uint256 upkeepId, uint256 timestamp); +} diff --git a/test/unit/SettersTest.t.sol b/test/unit/SettersTest.t.sol index f75766d..235fdc0 100644 --- a/test/unit/SettersTest.t.sol +++ b/test/unit/SettersTest.t.sol @@ -5,7 +5,7 @@ import {BaseFixture} from "../BaseFixture.sol"; import {Errors} from ".../../src/libraries/Errors.sol"; -import {RoboSaverVirtualModule} from "../../src/RoboSaverVirtualModule.sol"; +import {IRoboSaverVirtualModule} from "../../src/interfaces/robosaver/IRoboSaverVirtualModule.sol"; contract SettersTest is BaseFixture { function test_RevertWhen_BufferZeroValue() public { @@ -47,7 +47,7 @@ contract SettersTest is BaseFixture { uint256 newBuffer = 1000; vm.expectEmit(true, true, true, true); - emit RoboSaverVirtualModule.SetBuffer(roboModule.CARD(), oldBuffer, newBuffer); + emit IRoboSaverVirtualModule.SetBuffer(roboModule.CARD(), oldBuffer, newBuffer); vm.prank(roboModule.CARD()); roboModule.setBuffer(newBuffer); @@ -60,7 +60,7 @@ contract SettersTest is BaseFixture { address newKeeper = address(0x123); vm.expectEmit(true, true, true, true); - emit RoboSaverVirtualModule.SetKeeper(roboModule.CARD(), oldKeeper, newKeeper); + emit IRoboSaverVirtualModule.SetKeeper(roboModule.CARD(), oldKeeper, newKeeper); vm.prank(roboModule.CARD()); roboModule.setKeeper(newKeeper); @@ -73,7 +73,7 @@ contract SettersTest is BaseFixture { uint16 newSlippage = 777; vm.expectEmit(true, true, true, true); - emit RoboSaverVirtualModule.SetSlippage(roboModule.CARD(), oldSlippage, newSlippage); + emit IRoboSaverVirtualModule.SetSlippage(roboModule.CARD(), oldSlippage, newSlippage); vm.prank(roboModule.CARD()); roboModule.setSlippage(newSlippage); From 5c68fbc09ba49a3f7c7f1353dd8c430f24fa5369 Mon Sep 17 00:00:00 2001 From: Petrovska Date: Tue, 16 Jul 2024 01:01:33 +0900 Subject: [PATCH 2/3] feat: include methods and constants into robosaver interfaces --- .../robosaver/IRoboSaverVirtualModule.sol | 34 +++++++++++++++++++ .../IRoboSaverVirtualModuleFactory.sol | 5 +++ 2 files changed, 39 insertions(+) diff --git a/src/interfaces/robosaver/IRoboSaverVirtualModule.sol b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol index 7960cdc..031e91e 100644 --- a/src/interfaces/robosaver/IRoboSaverVirtualModule.sol +++ b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol @@ -67,4 +67,38 @@ interface IRoboSaverVirtualModule { /// @param oldSlippage The value of the old slippage /// @param newSlippage The value of the new slippage event SetSlippage(address indexed admin, uint256 oldSlippage, uint256 newSlippage); + + function CARD() external view returns (address); + + function FACTORY() external view returns (address); + + function buffer() external view returns (uint256); + + function checkUpkeep(bytes memory) external view returns (bool adjustPoolNeeded, bytes memory execPayload); + + function delayModule() external view returns (address); + + function keeper() external view returns (address); + + function name() external pure returns (string memory); + + function performUpkeep(bytes memory _performData) external; + + function poolAssets(uint256) external view returns (address); + + function queuedTx() external view returns (uint256 nonce, address target, bytes memory payload); + + function rolesModule() external view returns (address); + + function setBuffer(uint256 _buffer) external; + + function setKeeper(address _keeper) external; + + function setSlippage(uint16 _slippage) external; + + function shutdown() external; + + function slippage() external view returns (uint16); + + function version() external pure returns (string memory); } diff --git a/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol b/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol index dc3fbb5..f6e8d79 100644 --- a/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol +++ b/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol @@ -6,4 +6,9 @@ interface IRoboSaverVirtualModuleFactory { EVENTS //////////////////////////////////////////////////////////////////////////*/ event RoboSaverVirtualModuleCreated(address virtualModule, address card, uint256 upkeepId, uint256 timestamp); + + function createVirtualModule(address _delayModule, address _rolesModule, uint256 _buffer, uint16 _slippage) + external; + + function virtualModules(address) external view returns (address virtualModuleAddress, uint256 upkeepId); } From e1d3978ec9356debc4d4766ec58adb9637eeee93 Mon Sep 17 00:00:00 2001 From: Petrovska Date: Tue, 16 Jul 2024 19:15:33 +0900 Subject: [PATCH 3/3] fix: resolve conflict with the interfaces --- .../robosaver/IRoboSaverVirtualModule.sol | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/interfaces/robosaver/IRoboSaverVirtualModule.sol b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol index 031e91e..9b353fb 100644 --- a/src/interfaces/robosaver/IRoboSaverVirtualModule.sol +++ b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol @@ -72,24 +72,10 @@ interface IRoboSaverVirtualModule { function FACTORY() external view returns (address); - function buffer() external view returns (uint256); - - function checkUpkeep(bytes memory) external view returns (bool adjustPoolNeeded, bytes memory execPayload); - - function delayModule() external view returns (address); - - function keeper() external view returns (address); - function name() external pure returns (string memory); - function performUpkeep(bytes memory _performData) external; - - function poolAssets(uint256) external view returns (address); - function queuedTx() external view returns (uint256 nonce, address target, bytes memory payload); - function rolesModule() external view returns (address); - function setBuffer(uint256 _buffer) external; function setKeeper(address _keeper) external;