Commit 0ae1166b authored by Andreas Bigger's avatar Andreas Bigger

Port drippie contracts to triple slash natspec styling

parent 1a8f502f
...@@ -4,27 +4,22 @@ pragma solidity 0.8.15; ...@@ -4,27 +4,22 @@ pragma solidity 0.8.15;
import { AssetReceiver } from "../AssetReceiver.sol"; import { AssetReceiver } from "../AssetReceiver.sol";
import { IDripCheck } from "./IDripCheck.sol"; import { IDripCheck } from "./IDripCheck.sol";
/** /// @title Drippie
* @title Drippie /// @notice Drippie is a system for managing automated contract interactions. A specific interaction
* @notice Drippie is a system for managing automated contract interactions. A specific interaction /// is called a "drip" and can be executed according to some condition (called a dripcheck)
* is called a "drip" and can be executed according to some condition (called a dripcheck) /// and an execution interval. Drips cannot be executed faster than the execution interval.
* and an execution interval. Drips cannot be executed faster than the execution interval. /// Drips can trigger arbitrary contract calls where the calling contract is this contract
* Drips can trigger arbitrary contract calls where the calling contract is this contract /// address. Drips can also send ETH value, which makes them ideal for keeping addresses
* address. Drips can also send ETH value, which makes them ideal for keeping addresses /// sufficiently funded with ETH. Drippie is designed to be connected with smart contract
* sufficiently funded with ETH. Drippie is designed to be connected with smart contract /// automation services so that drips can be executed automatically. However, Drippie is
* automation services so that drips can be executed automatically. However, Drippie is /// specifically designed to be separated from these services so that trust assumptions are
* specifically designed to be separated from these services so that trust assumptions are /// better compartmentalized.
* better compartmentalized.
*/
contract Drippie is AssetReceiver { contract Drippie is AssetReceiver {
/** /// @notice Enum representing different status options for a given drip.
* @notice Enum representing different status options for a given drip. /// @custom:value NONE Drip does not exist.
* /// @custom:value PAUSED Drip is paused and cannot be executed until reactivated.
* @custom:value NONE Drip does not exist. /// @custom:value ACTIVE Drip is active and can be executed.
* @custom:value PAUSED Drip is paused and cannot be executed until reactivated. /// @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.
* @custom:value ACTIVE Drip is active and can be executed.
* @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.
*/
enum DripStatus { enum DripStatus {
NONE, NONE,
PAUSED, PAUSED,
...@@ -32,18 +27,14 @@ contract Drippie is AssetReceiver { ...@@ -32,18 +27,14 @@ contract Drippie is AssetReceiver {
ARCHIVED ARCHIVED
} }
/** /// @notice Represents a drip action.
* @notice Represents a drip action.
*/
struct DripAction { struct DripAction {
address payable target; address payable target;
bytes data; bytes data;
uint256 value; uint256 value;
} }
/** /// @notice Represents the configuration for a given drip.
* @notice Represents the configuration for a given drip.
*/
struct DripConfig { struct DripConfig {
bool reentrant; bool reentrant;
uint256 interval; uint256 interval;
...@@ -52,9 +43,7 @@ contract Drippie is AssetReceiver { ...@@ -52,9 +43,7 @@ contract Drippie is AssetReceiver {
DripAction[] actions; DripAction[] actions;
} }
/** /// @notice Represents the state of an active drip.
* @notice Represents the state of an active drip.
*/
struct DripState { struct DripState {
DripStatus status; DripStatus status;
DripConfig config; DripConfig config;
...@@ -62,13 +51,10 @@ contract Drippie is AssetReceiver { ...@@ -62,13 +51,10 @@ contract Drippie is AssetReceiver {
uint256 count; uint256 count;
} }
/** /// @notice Emitted when a new drip is created.
* @notice Emitted when a new drip is created. /// @param nameref Indexed name parameter (hashed).
* /// @param name Unindexed name parameter (unhashed).
* @param nameref Indexed name parameter (hashed). /// @param config Config for the created drip.
* @param name Unindexed name parameter (unhashed).
* @param config Config for the created drip.
*/
event DripCreated( event DripCreated(
// Emit name twice because indexed version is hashed. // Emit name twice because indexed version is hashed.
string indexed nameref, string indexed nameref,
...@@ -76,13 +62,10 @@ contract Drippie is AssetReceiver { ...@@ -76,13 +62,10 @@ contract Drippie is AssetReceiver {
DripConfig config DripConfig config
); );
/** /// @notice Emitted when a drip status is updated.
* @notice Emitted when a drip status is updated. /// @param nameref Indexed name parameter (hashed).
* /// @param name Unindexed name parameter (unhashed).
* @param nameref Indexed name parameter (hashed). /// @param status New drip status.
* @param name Unindexed name parameter (unhashed).
* @param status New drip status.
*/
event DripStatusUpdated( event DripStatusUpdated(
// Emit name twice because indexed version is hashed. // Emit name twice because indexed version is hashed.
string indexed nameref, string indexed nameref,
...@@ -90,14 +73,11 @@ contract Drippie is AssetReceiver { ...@@ -90,14 +73,11 @@ contract Drippie is AssetReceiver {
DripStatus status DripStatus status
); );
/** /// @notice Emitted when a drip is executed.
* @notice Emitted when a drip is executed. /// @param nameref Indexed name parameter (hashed).
* /// @param name Unindexed name parameter (unhashed).
* @param nameref Indexed name parameter (hashed). /// @param executor Address that executed the drip.
* @param name Unindexed name parameter (unhashed). /// @param timestamp Time when the drip was executed.
* @param executor Address that executed the drip.
* @param timestamp Time when the drip was executed.
*/
event DripExecuted( event DripExecuted(
// Emit name twice because indexed version is hashed. // Emit name twice because indexed version is hashed.
string indexed nameref, string indexed nameref,
...@@ -106,24 +86,17 @@ contract Drippie is AssetReceiver { ...@@ -106,24 +86,17 @@ contract Drippie is AssetReceiver {
uint256 timestamp uint256 timestamp
); );
/** /// @notice Maps from drip names to drip states.
* @notice Maps from drip names to drip states.
*/
mapping(string => DripState) public drips; mapping(string => DripState) public drips;
/** //// @param _owner Initial contract owner.
* @param _owner Initial contract owner.
*/
constructor(address _owner) AssetReceiver(_owner) {} constructor(address _owner) AssetReceiver(_owner) {}
/** /// @notice Creates a new drip with the given name and configuration. Once created, drips cannot
* @notice Creates a new drip with the given name and configuration. Once created, drips cannot /// be modified in any way (this is a security measure). If you want to update a drip,
* be modified in any way (this is a security measure). If you want to update a drip, /// simply pause (and potentially archive) the existing drip and create a new one.
* simply pause (and potentially archive) the existing drip and create a new one. /// @param _name Name of the drip.
* /// @param _config Configuration for the drip.
* @param _name Name of the drip.
* @param _config Configuration for the drip.
*/
function create(string calldata _name, DripConfig calldata _config) external onlyOwner { function create(string calldata _name, DripConfig calldata _config) external onlyOwner {
// Make sure this drip doesn't already exist. We *must* guarantee that no other function // Make sure this drip doesn't already exist. We *must* guarantee that no other function
// will ever set the status of a drip back to NONE after it's been created. This is why // will ever set the status of a drip back to NONE after it's been created. This is why
...@@ -165,15 +138,12 @@ contract Drippie is AssetReceiver { ...@@ -165,15 +138,12 @@ contract Drippie is AssetReceiver {
emit DripCreated(_name, _name, _config); emit DripCreated(_name, _name, _config);
} }
/** /// @notice Sets the status for a given drip. The behavior of this function depends on the
* @notice Sets the status for a given drip. The behavior of this function depends on the /// status that the user is trying to set. A drip can always move between ACTIVE and
* status that the user is trying to set. A drip can always move between ACTIVE and /// PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back
* PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back /// to ACTIVE or PAUSED.
* to ACTIVE or PAUSED. /// @param _name Name of the drip to update.
* /// @param _status New drip status.
* @param _name Name of the drip to update.
* @param _status New drip status.
*/
function status(string calldata _name, DripStatus _status) external onlyOwner { function status(string calldata _name, DripStatus _status) external onlyOwner {
// Make sure we can never set drip status back to NONE. A simple security measure to // Make sure we can never set drip status back to NONE. A simple security measure to
// prevent accidental overwrites if this code is ever updated down the line. // prevent accidental overwrites if this code is ever updated down the line.
...@@ -223,13 +193,9 @@ contract Drippie is AssetReceiver { ...@@ -223,13 +193,9 @@ contract Drippie is AssetReceiver {
emit DripStatusUpdated(_name, _name, _status); emit DripStatusUpdated(_name, _name, _status);
} }
/** /// @notice Checks if a given drip is executable.
* @notice Checks if a given drip is executable. /// @param _name Drip to check.
* /// @return True if the drip is executable, reverts otherwise.
* @param _name Drip to check.
*
* @return True if the drip is executable, reverts otherwise.
*/
function executable(string calldata _name) public view returns (bool) { function executable(string calldata _name) public view returns (bool) {
DripState storage state = drips[_name]; DripState storage state = drips[_name];
...@@ -259,18 +225,15 @@ contract Drippie is AssetReceiver { ...@@ -259,18 +225,15 @@ contract Drippie is AssetReceiver {
return true; return true;
} }
/** /// @notice Triggers a drip. This function is deliberately left as a public function because the
* @notice Triggers a drip. This function is deliberately left as a public function because the /// assumption being made here is that setting the drip to ACTIVE is an affirmative
* assumption being made here is that setting the drip to ACTIVE is an affirmative /// signal that the drip should be executable according to the drip parameters, drip
* signal that the drip should be executable according to the drip parameters, drip /// check, and drip interval. Note that drip parameters are read entirely from the state
* check, and drip interval. Note that drip parameters are read entirely from the state /// and are not supplied as user input, so there should not be any way for a
* and are not supplied as user input, so there should not be any way for a /// non-authorized user to influence the behavior of the drip. Note that the drip check
* non-authorized user to influence the behavior of the drip. Note that the drip check /// is executed only **once** at the beginning of the call to the drip function and will
* is executed only **once** at the beginning of the call to the drip function and will /// not be executed again between the drip actions within this call.
* not be executed again between the drip actions within this call. /// @param _name Name of the drip to trigger.
*
* @param _name Name of the drip to trigger.
*/
function drip(string calldata _name) external { function drip(string calldata _name) external {
DripState storage state = drips[_name]; DripState storage state = drips[_name];
......
...@@ -7,12 +7,8 @@ interface IDripCheck { ...@@ -7,12 +7,8 @@ interface IDripCheck {
// possible to easily encode parameters on the client side. Solidity does not support generics // possible to easily encode parameters on the client side. Solidity does not support generics
// so it's not possible to do this with explicit typing. // so it's not possible to do this with explicit typing.
/** /// @notice Checks whether a drip should be executable.
* @notice Checks whether a drip should be executable. /// @param _params Encoded parameters for the drip check.
* /// @return execute_ Whether the drip should be executed.
* @param _params Encoded parameters for the drip check. function check(bytes memory _params) external view returns (bool execute_);
*
* @return Whether the drip should be executed.
*/
function check(bytes memory _params) external view returns (bool);
} }
...@@ -3,30 +3,23 @@ pragma solidity 0.8.15; ...@@ -3,30 +3,23 @@ pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
/** /// @title CheckBalanceHigh
* @title CheckBalanceHigh /// @notice DripCheck for checking if an account's balance is above a given threshold.
* @notice DripCheck for checking if an account's balance is above a given threshold.
*/
contract CheckBalanceHigh is IDripCheck { contract CheckBalanceHigh is IDripCheck {
struct Params { struct Params {
address target; address target;
uint256 threshold; uint256 threshold;
} }
/** /// @notice External event used to help client-side tooling encode parameters.
* @notice External event used to help client-side tooling encode parameters. /// @param params Parameters to encode.
*
* @param params Parameters to encode.
*/
event _EventToExposeStructInABI__Params(Params params); event _EventToExposeStructInABI__Params(Params params);
/** /// @inheritdoc IDripCheck
* @inheritdoc IDripCheck function check(bytes memory _params) external view returns (bool execute_) {
*/
function check(bytes memory _params) external view returns (bool) {
Params memory params = abi.decode(_params, (Params)); Params memory params = abi.decode(_params, (Params));
// Check target balance is above threshold. // Check target balance is above threshold.
return params.target.balance > params.threshold; execute_ = params.target.balance > params.threshold;
} }
} }
...@@ -3,30 +3,23 @@ pragma solidity 0.8.15; ...@@ -3,30 +3,23 @@ pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
/** /// @title CheckBalanceLow
* @title CheckBalanceLow /// @notice DripCheck for checking if an account's balance is below a given threshold.
* @notice DripCheck for checking if an account's balance is below a given threshold.
*/
contract CheckBalanceLow is IDripCheck { contract CheckBalanceLow is IDripCheck {
struct Params { struct Params {
address target; address target;
uint256 threshold; uint256 threshold;
} }
/** /// @notice External event used to help client-side tooling encode parameters.
* @notice External event used to help client-side tooling encode parameters. /// @param params Parameters to encode.
*
* @param params Parameters to encode.
*/
event _EventToExposeStructInABI__Params(Params params); event _EventToExposeStructInABI__Params(Params params);
/** /// @inheritdoc IDripCheck
* @inheritdoc IDripCheck function check(bytes memory _params) external view returns (bool execute_) {
*/
function check(bytes memory _params) external view returns (bool) {
Params memory params = abi.decode(_params, (Params)); Params memory params = abi.decode(_params, (Params));
// Check target ETH balance is below threshold. // Check target ETH balance is below threshold.
return params.target.balance < params.threshold; execute_ = params.target.balance < params.threshold;
} }
} }
...@@ -7,10 +7,8 @@ interface IGelatoTreasury { ...@@ -7,10 +7,8 @@ interface IGelatoTreasury {
function userTokenBalance(address _user, address _token) external view returns (uint256); function userTokenBalance(address _user, address _token) external view returns (uint256);
} }
/** /// @title CheckGelatoLow
* @title CheckGelatoLow /// @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.
* @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.
*/
contract CheckGelatoLow is IDripCheck { contract CheckGelatoLow is IDripCheck {
struct Params { struct Params {
address treasury; address treasury;
...@@ -18,25 +16,21 @@ contract CheckGelatoLow is IDripCheck { ...@@ -18,25 +16,21 @@ contract CheckGelatoLow is IDripCheck {
address recipient; address recipient;
} }
/** /// @notice External event used to help client-side tooling encode parameters.
* @notice External event used to help client-side tooling encode parameters. /// @param params Parameters to encode.
*
* @param params Parameters to encode.
*/
event _EventToExposeStructInABI__Params(Params params); event _EventToExposeStructInABI__Params(Params params);
/** /// @inheritdoc IDripCheck
* @inheritdoc IDripCheck function check(bytes memory _params) external view returns (bool execute_) {
*/
function check(bytes memory _params) external view returns (bool) {
Params memory params = abi.decode(_params, (Params)); Params memory params = abi.decode(_params, (Params));
// Check GelatoTreasury ETH balance is below threshold. // Check GelatoTreasury ETH balance is below threshold.
return execute_ =
IGelatoTreasury(params.treasury).userTokenBalance( IGelatoTreasury(params.treasury).userTokenBalance(
params.recipient, params.recipient,
// Gelato represents ETH as 0xeeeee....eeeee // Gelato represents ETH as 0xeeeee....eeeee
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
) < params.threshold; ) <
params.threshold;
} }
} }
...@@ -3,15 +3,11 @@ pragma solidity 0.8.15; ...@@ -3,15 +3,11 @@ pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
/** /// @title CheckTrue
* @title CheckTrue /// @notice DripCheck that always returns true.
* @notice DripCheck that always returns true.
*/
contract CheckTrue is IDripCheck { contract CheckTrue is IDripCheck {
/** /// @inheritdoc IDripCheck
* @inheritdoc IDripCheck function check(bytes memory) external pure returns (bool execute_) {
*/ execute_ = true;
function check(bytes memory) external pure returns (bool) {
return true;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment