diff --git a/src/RoboSaverVirtualModule.sol b/src/RoboSaverVirtualModule.sol index 0e2c98e..7bfec2c 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..9b353fb --- /dev/null +++ b/src/interfaces/robosaver/IRoboSaverVirtualModule.sol @@ -0,0 +1,90 @@ +// 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); + + function CARD() external view returns (address); + + function FACTORY() external view returns (address); + + function name() external pure returns (string memory); + + function queuedTx() external view returns (uint256 nonce, address target, bytes memory payload); + + 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 new file mode 100644 index 0000000..f6e8d79 --- /dev/null +++ b/src/interfaces/robosaver/IRoboSaverVirtualModuleFactory.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +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); +} 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);