Commit d4ebcd2b authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat: introduce op-dripper (#13788)

parent e8969704
...@@ -23,9 +23,6 @@ ...@@ -23,9 +23,6 @@
[submodule "packages/contracts-bedrock/lib/lib-keccak"] [submodule "packages/contracts-bedrock/lib/lib-keccak"]
path = packages/contracts-bedrock/lib/lib-keccak path = packages/contracts-bedrock/lib/lib-keccak
url = https://github.com/ethereum-optimism/lib-keccak url = https://github.com/ethereum-optimism/lib-keccak
[submodule "packages/contracts-bedrock/lib/automate"]
path = packages/contracts-bedrock/lib/automate
url = https://github.com/gelatodigital/automate
[submodule "packages/contracts-bedrock/lib/openzeppelin-contracts-v5"] [submodule "packages/contracts-bedrock/lib/openzeppelin-contracts-v5"]
path = packages/contracts-bedrock/lib/openzeppelin-contracts-v5 path = packages/contracts-bedrock/lib/openzeppelin-contracts-v5
url = https://github.com/OpenZeppelin/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts
......
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"errors"
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
)
// DrippieDripAction is an auto generated low-level Go binding around an user-defined struct.
type DrippieDripAction struct {
Target common.Address
Data []byte
Value *big.Int
}
// DrippieDripConfig is an auto generated low-level Go binding around an user-defined struct.
type DrippieDripConfig struct {
Reentrant bool
Interval *big.Int
Dripcheck common.Address
Checkparams []byte
Actions []DrippieDripAction
}
// DrippieMetaData contains all meta data concerning the Drippie contract.
var DrippieMetaData = &bind.MetaData{
ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"CALL\",\"inputs\":[{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"success_\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"data_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"DELEGATECALL\",\"inputs\":[{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"success_\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"data_\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"create\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_config\",\"type\":\"tuple\",\"internalType\":\"structDrippie.DripConfig\",\"components\":[{\"name\":\"reentrant\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"interval\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"dripcheck\",\"type\":\"address\",\"internalType\":\"contractIDripCheck\"},{\"name\":\"checkparams\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actions\",\"type\":\"tuple[]\",\"internalType\":\"structDrippie.DripAction[]\",\"components\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"created\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"drip\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"drips\",\"inputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumDrippie.DripStatus\"},{\"name\":\"config\",\"type\":\"tuple\",\"internalType\":\"structDrippie.DripConfig\",\"components\":[{\"name\":\"reentrant\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"interval\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"dripcheck\",\"type\":\"address\",\"internalType\":\"contractIDripCheck\"},{\"name\":\"checkparams\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actions\",\"type\":\"tuple[]\",\"internalType\":\"structDrippie.DripAction[]\",\"components\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]},{\"name\":\"last\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"count\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"executable\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDripCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDripInterval\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDripStatus\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"enumDrippie.DripStatus\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setOwner\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"status\",\"inputs\":[{\"name\":\"_name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"_status\",\"type\":\"uint8\",\"internalType\":\"enumDrippie.DripStatus\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawERC20\",\"inputs\":[{\"name\":\"_asset\",\"type\":\"address\",\"internalType\":\"contractERC20\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawERC20\",\"inputs\":[{\"name\":\"_asset\",\"type\":\"address\",\"internalType\":\"contractERC20\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawERC721\",\"inputs\":[{\"name\":\"_asset\",\"type\":\"address\",\"internalType\":\"contractERC721\"},{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_id\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawETH\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"_amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawETH\",\"inputs\":[{\"name\":\"_to\",\"type\":\"address\",\"internalType\":\"addresspayable\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"DripCreated\",\"inputs\":[{\"name\":\"nameref\",\"type\":\"string\",\"indexed\":true,\"internalType\":\"string\"},{\"name\":\"name\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"},{\"name\":\"config\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structDrippie.DripConfig\",\"components\":[{\"name\":\"reentrant\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"interval\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"dripcheck\",\"type\":\"address\",\"internalType\":\"contractIDripCheck\"},{\"name\":\"checkparams\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"actions\",\"type\":\"tuple[]\",\"internalType\":\"structDrippie.DripAction[]\",\"components\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DripExecuted\",\"inputs\":[{\"name\":\"nameref\",\"type\":\"string\",\"indexed\":true,\"internalType\":\"string\"},{\"name\":\"name\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"},{\"name\":\"executor\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DripStatusUpdated\",\"inputs\":[{\"name\":\"nameref\",\"type\":\"string\",\"indexed\":true,\"internalType\":\"string\"},{\"name\":\"name\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"},{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"enumDrippie.DripStatus\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnerUpdated\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceivedETH\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrewERC20\",\"inputs\":[{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"asset\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrewERC721\",\"inputs\":[{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"asset\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"id\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrewETH\",\"inputs\":[{\"name\":\"withdrawer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]",
}
// DrippieABI is the input ABI used to generate the binding from.
// Deprecated: Use DrippieMetaData.ABI instead.
var DrippieABI = DrippieMetaData.ABI
// Drippie is an auto generated Go binding around an Ethereum contract.
type Drippie struct {
DrippieCaller // Read-only binding to the contract
DrippieTransactor // Write-only binding to the contract
DrippieFilterer // Log filterer for contract events
}
// DrippieCaller is an auto generated read-only Go binding around an Ethereum contract.
type DrippieCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// DrippieTransactor is an auto generated write-only Go binding around an Ethereum contract.
type DrippieTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// DrippieFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type DrippieFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// DrippieSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type DrippieSession struct {
Contract *Drippie // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// DrippieCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type DrippieCallerSession struct {
Contract *DrippieCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// DrippieTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type DrippieTransactorSession struct {
Contract *DrippieTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// DrippieRaw is an auto generated low-level Go binding around an Ethereum contract.
type DrippieRaw struct {
Contract *Drippie // Generic contract binding to access the raw methods on
}
// DrippieCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type DrippieCallerRaw struct {
Contract *DrippieCaller // Generic read-only contract binding to access the raw methods on
}
// DrippieTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type DrippieTransactorRaw struct {
Contract *DrippieTransactor // Generic write-only contract binding to access the raw methods on
}
// NewDrippie creates a new instance of Drippie, bound to a specific deployed contract.
func NewDrippie(address common.Address, backend bind.ContractBackend) (*Drippie, error) {
contract, err := bindDrippie(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &Drippie{DrippieCaller: DrippieCaller{contract: contract}, DrippieTransactor: DrippieTransactor{contract: contract}, DrippieFilterer: DrippieFilterer{contract: contract}}, nil
}
// NewDrippieCaller creates a new read-only instance of Drippie, bound to a specific deployed contract.
func NewDrippieCaller(address common.Address, caller bind.ContractCaller) (*DrippieCaller, error) {
contract, err := bindDrippie(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &DrippieCaller{contract: contract}, nil
}
// NewDrippieTransactor creates a new write-only instance of Drippie, bound to a specific deployed contract.
func NewDrippieTransactor(address common.Address, transactor bind.ContractTransactor) (*DrippieTransactor, error) {
contract, err := bindDrippie(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &DrippieTransactor{contract: contract}, nil
}
// NewDrippieFilterer creates a new log filterer instance of Drippie, bound to a specific deployed contract.
func NewDrippieFilterer(address common.Address, filterer bind.ContractFilterer) (*DrippieFilterer, error) {
contract, err := bindDrippie(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &DrippieFilterer{contract: contract}, nil
}
// bindDrippie binds a generic wrapper to an already deployed contract.
func bindDrippie(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(DrippieABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Drippie *DrippieRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _Drippie.Contract.DrippieCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Drippie *DrippieRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Drippie.Contract.DrippieTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_Drippie *DrippieRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _Drippie.Contract.DrippieTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Drippie *DrippieCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _Drippie.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Drippie *DrippieTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Drippie.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_Drippie *DrippieTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _Drippie.Contract.contract.Transact(opts, method, params...)
}
// Created is a free data retrieval call binding the contract method 0x82cb6b72.
//
// Solidity: function created(uint256 ) view returns(string)
func (_Drippie *DrippieCaller) Created(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "created", arg0)
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Created is a free data retrieval call binding the contract method 0x82cb6b72.
//
// Solidity: function created(uint256 ) view returns(string)
func (_Drippie *DrippieSession) Created(arg0 *big.Int) (string, error) {
return _Drippie.Contract.Created(&_Drippie.CallOpts, arg0)
}
// Created is a free data retrieval call binding the contract method 0x82cb6b72.
//
// Solidity: function created(uint256 ) view returns(string)
func (_Drippie *DrippieCallerSession) Created(arg0 *big.Int) (string, error) {
return _Drippie.Contract.Created(&_Drippie.CallOpts, arg0)
}
// Drips is a free data retrieval call binding the contract method 0x4d7fba6e.
//
// Solidity: function drips(string ) view returns(uint8 status, (bool,uint256,address,bytes,(address,bytes,uint256)[]) config, uint256 last, uint256 count)
func (_Drippie *DrippieCaller) Drips(opts *bind.CallOpts, arg0 string) (struct {
Status uint8
Config DrippieDripConfig
Last *big.Int
Count *big.Int
}, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "drips", arg0)
outstruct := new(struct {
Status uint8
Config DrippieDripConfig
Last *big.Int
Count *big.Int
})
if err != nil {
return *outstruct, err
}
outstruct.Status = *abi.ConvertType(out[0], new(uint8)).(*uint8)
outstruct.Config = *abi.ConvertType(out[1], new(DrippieDripConfig)).(*DrippieDripConfig)
outstruct.Last = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int)
outstruct.Count = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int)
return *outstruct, err
}
// Drips is a free data retrieval call binding the contract method 0x4d7fba6e.
//
// Solidity: function drips(string ) view returns(uint8 status, (bool,uint256,address,bytes,(address,bytes,uint256)[]) config, uint256 last, uint256 count)
func (_Drippie *DrippieSession) Drips(arg0 string) (struct {
Status uint8
Config DrippieDripConfig
Last *big.Int
Count *big.Int
}, error) {
return _Drippie.Contract.Drips(&_Drippie.CallOpts, arg0)
}
// Drips is a free data retrieval call binding the contract method 0x4d7fba6e.
//
// Solidity: function drips(string ) view returns(uint8 status, (bool,uint256,address,bytes,(address,bytes,uint256)[]) config, uint256 last, uint256 count)
func (_Drippie *DrippieCallerSession) Drips(arg0 string) (struct {
Status uint8
Config DrippieDripConfig
Last *big.Int
Count *big.Int
}, error) {
return _Drippie.Contract.Drips(&_Drippie.CallOpts, arg0)
}
// Executable is a free data retrieval call binding the contract method 0xfc3e3eba.
//
// Solidity: function executable(string _name) view returns(bool)
func (_Drippie *DrippieCaller) Executable(opts *bind.CallOpts, _name string) (bool, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "executable", _name)
if err != nil {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
}
// Executable is a free data retrieval call binding the contract method 0xfc3e3eba.
//
// Solidity: function executable(string _name) view returns(bool)
func (_Drippie *DrippieSession) Executable(_name string) (bool, error) {
return _Drippie.Contract.Executable(&_Drippie.CallOpts, _name)
}
// Executable is a free data retrieval call binding the contract method 0xfc3e3eba.
//
// Solidity: function executable(string _name) view returns(bool)
func (_Drippie *DrippieCallerSession) Executable(_name string) (bool, error) {
return _Drippie.Contract.Executable(&_Drippie.CallOpts, _name)
}
// GetDripCount is a free data retrieval call binding the contract method 0xf1d42b47.
//
// Solidity: function getDripCount() view returns(uint256)
func (_Drippie *DrippieCaller) GetDripCount(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "getDripCount")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// GetDripCount is a free data retrieval call binding the contract method 0xf1d42b47.
//
// Solidity: function getDripCount() view returns(uint256)
func (_Drippie *DrippieSession) GetDripCount() (*big.Int, error) {
return _Drippie.Contract.GetDripCount(&_Drippie.CallOpts)
}
// GetDripCount is a free data retrieval call binding the contract method 0xf1d42b47.
//
// Solidity: function getDripCount() view returns(uint256)
func (_Drippie *DrippieCallerSession) GetDripCount() (*big.Int, error) {
return _Drippie.Contract.GetDripCount(&_Drippie.CallOpts)
}
// GetDripInterval is a free data retrieval call binding the contract method 0x90547c14.
//
// Solidity: function getDripInterval(string _name) view returns(uint256)
func (_Drippie *DrippieCaller) GetDripInterval(opts *bind.CallOpts, _name string) (*big.Int, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "getDripInterval", _name)
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// GetDripInterval is a free data retrieval call binding the contract method 0x90547c14.
//
// Solidity: function getDripInterval(string _name) view returns(uint256)
func (_Drippie *DrippieSession) GetDripInterval(_name string) (*big.Int, error) {
return _Drippie.Contract.GetDripInterval(&_Drippie.CallOpts, _name)
}
// GetDripInterval is a free data retrieval call binding the contract method 0x90547c14.
//
// Solidity: function getDripInterval(string _name) view returns(uint256)
func (_Drippie *DrippieCallerSession) GetDripInterval(_name string) (*big.Int, error) {
return _Drippie.Contract.GetDripInterval(&_Drippie.CallOpts, _name)
}
// GetDripStatus is a free data retrieval call binding the contract method 0x0d8f4697.
//
// Solidity: function getDripStatus(string _name) view returns(uint8)
func (_Drippie *DrippieCaller) GetDripStatus(opts *bind.CallOpts, _name string) (uint8, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "getDripStatus", _name)
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// GetDripStatus is a free data retrieval call binding the contract method 0x0d8f4697.
//
// Solidity: function getDripStatus(string _name) view returns(uint8)
func (_Drippie *DrippieSession) GetDripStatus(_name string) (uint8, error) {
return _Drippie.Contract.GetDripStatus(&_Drippie.CallOpts, _name)
}
// GetDripStatus is a free data retrieval call binding the contract method 0x0d8f4697.
//
// Solidity: function getDripStatus(string _name) view returns(uint8)
func (_Drippie *DrippieCallerSession) GetDripStatus(_name string) (uint8, error) {
return _Drippie.Contract.GetDripStatus(&_Drippie.CallOpts, _name)
}
// Owner is a free data retrieval call binding the contract method 0x8da5cb5b.
//
// Solidity: function owner() view returns(address)
func (_Drippie *DrippieCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _Drippie.contract.Call(opts, &out, "owner")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Owner is a free data retrieval call binding the contract method 0x8da5cb5b.
//
// Solidity: function owner() view returns(address)
func (_Drippie *DrippieSession) Owner() (common.Address, error) {
return _Drippie.Contract.Owner(&_Drippie.CallOpts)
}
// Owner is a free data retrieval call binding the contract method 0x8da5cb5b.
//
// Solidity: function owner() view returns(address)
func (_Drippie *DrippieCallerSession) Owner() (common.Address, error) {
return _Drippie.Contract.Owner(&_Drippie.CallOpts)
}
// CALL is a paid mutator transaction binding the contract method 0x6e2d44ae.
//
// Solidity: function CALL(address _target, bytes _data, uint256 _value) payable returns(bool success_, bytes data_)
func (_Drippie *DrippieTransactor) CALL(opts *bind.TransactOpts, _target common.Address, _data []byte, _value *big.Int) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "CALL", _target, _data, _value)
}
// CALL is a paid mutator transaction binding the contract method 0x6e2d44ae.
//
// Solidity: function CALL(address _target, bytes _data, uint256 _value) payable returns(bool success_, bytes data_)
func (_Drippie *DrippieSession) CALL(_target common.Address, _data []byte, _value *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.CALL(&_Drippie.TransactOpts, _target, _data, _value)
}
// CALL is a paid mutator transaction binding the contract method 0x6e2d44ae.
//
// Solidity: function CALL(address _target, bytes _data, uint256 _value) payable returns(bool success_, bytes data_)
func (_Drippie *DrippieTransactorSession) CALL(_target common.Address, _data []byte, _value *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.CALL(&_Drippie.TransactOpts, _target, _data, _value)
}
// DELEGATECALL is a paid mutator transaction binding the contract method 0xedee6239.
//
// Solidity: function DELEGATECALL(address _target, bytes _data) payable returns(bool success_, bytes data_)
func (_Drippie *DrippieTransactor) DELEGATECALL(opts *bind.TransactOpts, _target common.Address, _data []byte) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "DELEGATECALL", _target, _data)
}
// DELEGATECALL is a paid mutator transaction binding the contract method 0xedee6239.
//
// Solidity: function DELEGATECALL(address _target, bytes _data) payable returns(bool success_, bytes data_)
func (_Drippie *DrippieSession) DELEGATECALL(_target common.Address, _data []byte) (*types.Transaction, error) {
return _Drippie.Contract.DELEGATECALL(&_Drippie.TransactOpts, _target, _data)
}
// DELEGATECALL is a paid mutator transaction binding the contract method 0xedee6239.
//
// Solidity: function DELEGATECALL(address _target, bytes _data) payable returns(bool success_, bytes data_)
func (_Drippie *DrippieTransactorSession) DELEGATECALL(_target common.Address, _data []byte) (*types.Transaction, error) {
return _Drippie.Contract.DELEGATECALL(&_Drippie.TransactOpts, _target, _data)
}
// Create is a paid mutator transaction binding the contract method 0xe551cdaa.
//
// Solidity: function create(string _name, (bool,uint256,address,bytes,(address,bytes,uint256)[]) _config) returns()
func (_Drippie *DrippieTransactor) Create(opts *bind.TransactOpts, _name string, _config DrippieDripConfig) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "create", _name, _config)
}
// Create is a paid mutator transaction binding the contract method 0xe551cdaa.
//
// Solidity: function create(string _name, (bool,uint256,address,bytes,(address,bytes,uint256)[]) _config) returns()
func (_Drippie *DrippieSession) Create(_name string, _config DrippieDripConfig) (*types.Transaction, error) {
return _Drippie.Contract.Create(&_Drippie.TransactOpts, _name, _config)
}
// Create is a paid mutator transaction binding the contract method 0xe551cdaa.
//
// Solidity: function create(string _name, (bool,uint256,address,bytes,(address,bytes,uint256)[]) _config) returns()
func (_Drippie *DrippieTransactorSession) Create(_name string, _config DrippieDripConfig) (*types.Transaction, error) {
return _Drippie.Contract.Create(&_Drippie.TransactOpts, _name, _config)
}
// Drip is a paid mutator transaction binding the contract method 0x67148cd2.
//
// Solidity: function drip(string _name) returns()
func (_Drippie *DrippieTransactor) Drip(opts *bind.TransactOpts, _name string) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "drip", _name)
}
// Drip is a paid mutator transaction binding the contract method 0x67148cd2.
//
// Solidity: function drip(string _name) returns()
func (_Drippie *DrippieSession) Drip(_name string) (*types.Transaction, error) {
return _Drippie.Contract.Drip(&_Drippie.TransactOpts, _name)
}
// Drip is a paid mutator transaction binding the contract method 0x67148cd2.
//
// Solidity: function drip(string _name) returns()
func (_Drippie *DrippieTransactorSession) Drip(_name string) (*types.Transaction, error) {
return _Drippie.Contract.Drip(&_Drippie.TransactOpts, _name)
}
// SetOwner is a paid mutator transaction binding the contract method 0x13af4035.
//
// Solidity: function setOwner(address newOwner) returns()
func (_Drippie *DrippieTransactor) SetOwner(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "setOwner", newOwner)
}
// SetOwner is a paid mutator transaction binding the contract method 0x13af4035.
//
// Solidity: function setOwner(address newOwner) returns()
func (_Drippie *DrippieSession) SetOwner(newOwner common.Address) (*types.Transaction, error) {
return _Drippie.Contract.SetOwner(&_Drippie.TransactOpts, newOwner)
}
// SetOwner is a paid mutator transaction binding the contract method 0x13af4035.
//
// Solidity: function setOwner(address newOwner) returns()
func (_Drippie *DrippieTransactorSession) SetOwner(newOwner common.Address) (*types.Transaction, error) {
return _Drippie.Contract.SetOwner(&_Drippie.TransactOpts, newOwner)
}
// Status is a paid mutator transaction binding the contract method 0x9bc94d01.
//
// Solidity: function status(string _name, uint8 _status) returns()
func (_Drippie *DrippieTransactor) Status(opts *bind.TransactOpts, _name string, _status uint8) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "status", _name, _status)
}
// Status is a paid mutator transaction binding the contract method 0x9bc94d01.
//
// Solidity: function status(string _name, uint8 _status) returns()
func (_Drippie *DrippieSession) Status(_name string, _status uint8) (*types.Transaction, error) {
return _Drippie.Contract.Status(&_Drippie.TransactOpts, _name, _status)
}
// Status is a paid mutator transaction binding the contract method 0x9bc94d01.
//
// Solidity: function status(string _name, uint8 _status) returns()
func (_Drippie *DrippieTransactorSession) Status(_name string, _status uint8) (*types.Transaction, error) {
return _Drippie.Contract.Status(&_Drippie.TransactOpts, _name, _status)
}
// WithdrawERC20 is a paid mutator transaction binding the contract method 0x44004cc1.
//
// Solidity: function withdrawERC20(address _asset, address _to, uint256 _amount) returns()
func (_Drippie *DrippieTransactor) WithdrawERC20(opts *bind.TransactOpts, _asset common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "withdrawERC20", _asset, _to, _amount)
}
// WithdrawERC20 is a paid mutator transaction binding the contract method 0x44004cc1.
//
// Solidity: function withdrawERC20(address _asset, address _to, uint256 _amount) returns()
func (_Drippie *DrippieSession) WithdrawERC20(_asset common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawERC20(&_Drippie.TransactOpts, _asset, _to, _amount)
}
// WithdrawERC20 is a paid mutator transaction binding the contract method 0x44004cc1.
//
// Solidity: function withdrawERC20(address _asset, address _to, uint256 _amount) returns()
func (_Drippie *DrippieTransactorSession) WithdrawERC20(_asset common.Address, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawERC20(&_Drippie.TransactOpts, _asset, _to, _amount)
}
// WithdrawERC200 is a paid mutator transaction binding the contract method 0x9456fbcc.
//
// Solidity: function withdrawERC20(address _asset, address _to) returns()
func (_Drippie *DrippieTransactor) WithdrawERC200(opts *bind.TransactOpts, _asset common.Address, _to common.Address) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "withdrawERC200", _asset, _to)
}
// WithdrawERC200 is a paid mutator transaction binding the contract method 0x9456fbcc.
//
// Solidity: function withdrawERC20(address _asset, address _to) returns()
func (_Drippie *DrippieSession) WithdrawERC200(_asset common.Address, _to common.Address) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawERC200(&_Drippie.TransactOpts, _asset, _to)
}
// WithdrawERC200 is a paid mutator transaction binding the contract method 0x9456fbcc.
//
// Solidity: function withdrawERC20(address _asset, address _to) returns()
func (_Drippie *DrippieTransactorSession) WithdrawERC200(_asset common.Address, _to common.Address) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawERC200(&_Drippie.TransactOpts, _asset, _to)
}
// WithdrawERC721 is a paid mutator transaction binding the contract method 0x4025feb2.
//
// Solidity: function withdrawERC721(address _asset, address _to, uint256 _id) returns()
func (_Drippie *DrippieTransactor) WithdrawERC721(opts *bind.TransactOpts, _asset common.Address, _to common.Address, _id *big.Int) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "withdrawERC721", _asset, _to, _id)
}
// WithdrawERC721 is a paid mutator transaction binding the contract method 0x4025feb2.
//
// Solidity: function withdrawERC721(address _asset, address _to, uint256 _id) returns()
func (_Drippie *DrippieSession) WithdrawERC721(_asset common.Address, _to common.Address, _id *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawERC721(&_Drippie.TransactOpts, _asset, _to, _id)
}
// WithdrawERC721 is a paid mutator transaction binding the contract method 0x4025feb2.
//
// Solidity: function withdrawERC721(address _asset, address _to, uint256 _id) returns()
func (_Drippie *DrippieTransactorSession) WithdrawERC721(_asset common.Address, _to common.Address, _id *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawERC721(&_Drippie.TransactOpts, _asset, _to, _id)
}
// WithdrawETH is a paid mutator transaction binding the contract method 0x4782f779.
//
// Solidity: function withdrawETH(address _to, uint256 _amount) returns()
func (_Drippie *DrippieTransactor) WithdrawETH(opts *bind.TransactOpts, _to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "withdrawETH", _to, _amount)
}
// WithdrawETH is a paid mutator transaction binding the contract method 0x4782f779.
//
// Solidity: function withdrawETH(address _to, uint256 _amount) returns()
func (_Drippie *DrippieSession) WithdrawETH(_to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawETH(&_Drippie.TransactOpts, _to, _amount)
}
// WithdrawETH is a paid mutator transaction binding the contract method 0x4782f779.
//
// Solidity: function withdrawETH(address _to, uint256 _amount) returns()
func (_Drippie *DrippieTransactorSession) WithdrawETH(_to common.Address, _amount *big.Int) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawETH(&_Drippie.TransactOpts, _to, _amount)
}
// WithdrawETH0 is a paid mutator transaction binding the contract method 0x690d8320.
//
// Solidity: function withdrawETH(address _to) returns()
func (_Drippie *DrippieTransactor) WithdrawETH0(opts *bind.TransactOpts, _to common.Address) (*types.Transaction, error) {
return _Drippie.contract.Transact(opts, "withdrawETH0", _to)
}
// WithdrawETH0 is a paid mutator transaction binding the contract method 0x690d8320.
//
// Solidity: function withdrawETH(address _to) returns()
func (_Drippie *DrippieSession) WithdrawETH0(_to common.Address) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawETH0(&_Drippie.TransactOpts, _to)
}
// WithdrawETH0 is a paid mutator transaction binding the contract method 0x690d8320.
//
// Solidity: function withdrawETH(address _to) returns()
func (_Drippie *DrippieTransactorSession) WithdrawETH0(_to common.Address) (*types.Transaction, error) {
return _Drippie.Contract.WithdrawETH0(&_Drippie.TransactOpts, _to)
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: receive() payable returns()
func (_Drippie *DrippieTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Drippie.contract.RawTransact(opts, nil) // calldata is disallowed for receive function
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: receive() payable returns()
func (_Drippie *DrippieSession) Receive() (*types.Transaction, error) {
return _Drippie.Contract.Receive(&_Drippie.TransactOpts)
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: receive() payable returns()
func (_Drippie *DrippieTransactorSession) Receive() (*types.Transaction, error) {
return _Drippie.Contract.Receive(&_Drippie.TransactOpts)
}
// DrippieDripCreatedIterator is returned from FilterDripCreated and is used to iterate over the raw logs and unpacked data for DripCreated events raised by the Drippie contract.
type DrippieDripCreatedIterator struct {
Event *DrippieDripCreated // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieDripCreatedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieDripCreated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieDripCreated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieDripCreatedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieDripCreatedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieDripCreated represents a DripCreated event raised by the Drippie contract.
type DrippieDripCreated struct {
Nameref common.Hash
Name string
Config DrippieDripConfig
Raw types.Log // Blockchain specific contextual infos
}
// FilterDripCreated is a free log retrieval operation binding the contract event 0xe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6.
//
// Solidity: event DripCreated(string indexed nameref, string name, (bool,uint256,address,bytes,(address,bytes,uint256)[]) config)
func (_Drippie *DrippieFilterer) FilterDripCreated(opts *bind.FilterOpts, nameref []string) (*DrippieDripCreatedIterator, error) {
var namerefRule []interface{}
for _, namerefItem := range nameref {
namerefRule = append(namerefRule, namerefItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "DripCreated", namerefRule)
if err != nil {
return nil, err
}
return &DrippieDripCreatedIterator{contract: _Drippie.contract, event: "DripCreated", logs: logs, sub: sub}, nil
}
// WatchDripCreated is a free log subscription operation binding the contract event 0xe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6.
//
// Solidity: event DripCreated(string indexed nameref, string name, (bool,uint256,address,bytes,(address,bytes,uint256)[]) config)
func (_Drippie *DrippieFilterer) WatchDripCreated(opts *bind.WatchOpts, sink chan<- *DrippieDripCreated, nameref []string) (event.Subscription, error) {
var namerefRule []interface{}
for _, namerefItem := range nameref {
namerefRule = append(namerefRule, namerefItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "DripCreated", namerefRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieDripCreated)
if err := _Drippie.contract.UnpackLog(event, "DripCreated", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseDripCreated is a log parse operation binding the contract event 0xe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6.
//
// Solidity: event DripCreated(string indexed nameref, string name, (bool,uint256,address,bytes,(address,bytes,uint256)[]) config)
func (_Drippie *DrippieFilterer) ParseDripCreated(log types.Log) (*DrippieDripCreated, error) {
event := new(DrippieDripCreated)
if err := _Drippie.contract.UnpackLog(event, "DripCreated", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieDripExecutedIterator is returned from FilterDripExecuted and is used to iterate over the raw logs and unpacked data for DripExecuted events raised by the Drippie contract.
type DrippieDripExecutedIterator struct {
Event *DrippieDripExecuted // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieDripExecutedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieDripExecuted)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieDripExecuted)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieDripExecutedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieDripExecutedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieDripExecuted represents a DripExecuted event raised by the Drippie contract.
type DrippieDripExecuted struct {
Nameref common.Hash
Name string
Executor common.Address
Timestamp *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterDripExecuted is a free log retrieval operation binding the contract event 0xea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c6.
//
// Solidity: event DripExecuted(string indexed nameref, string name, address executor, uint256 timestamp)
func (_Drippie *DrippieFilterer) FilterDripExecuted(opts *bind.FilterOpts, nameref []string) (*DrippieDripExecutedIterator, error) {
var namerefRule []interface{}
for _, namerefItem := range nameref {
namerefRule = append(namerefRule, namerefItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "DripExecuted", namerefRule)
if err != nil {
return nil, err
}
return &DrippieDripExecutedIterator{contract: _Drippie.contract, event: "DripExecuted", logs: logs, sub: sub}, nil
}
// WatchDripExecuted is a free log subscription operation binding the contract event 0xea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c6.
//
// Solidity: event DripExecuted(string indexed nameref, string name, address executor, uint256 timestamp)
func (_Drippie *DrippieFilterer) WatchDripExecuted(opts *bind.WatchOpts, sink chan<- *DrippieDripExecuted, nameref []string) (event.Subscription, error) {
var namerefRule []interface{}
for _, namerefItem := range nameref {
namerefRule = append(namerefRule, namerefItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "DripExecuted", namerefRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieDripExecuted)
if err := _Drippie.contract.UnpackLog(event, "DripExecuted", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseDripExecuted is a log parse operation binding the contract event 0xea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c6.
//
// Solidity: event DripExecuted(string indexed nameref, string name, address executor, uint256 timestamp)
func (_Drippie *DrippieFilterer) ParseDripExecuted(log types.Log) (*DrippieDripExecuted, error) {
event := new(DrippieDripExecuted)
if err := _Drippie.contract.UnpackLog(event, "DripExecuted", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieDripStatusUpdatedIterator is returned from FilterDripStatusUpdated and is used to iterate over the raw logs and unpacked data for DripStatusUpdated events raised by the Drippie contract.
type DrippieDripStatusUpdatedIterator struct {
Event *DrippieDripStatusUpdated // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieDripStatusUpdatedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieDripStatusUpdated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieDripStatusUpdated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieDripStatusUpdatedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieDripStatusUpdatedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieDripStatusUpdated represents a DripStatusUpdated event raised by the Drippie contract.
type DrippieDripStatusUpdated struct {
Nameref common.Hash
Name string
Status uint8
Raw types.Log // Blockchain specific contextual infos
}
// FilterDripStatusUpdated is a free log retrieval operation binding the contract event 0x407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1.
//
// Solidity: event DripStatusUpdated(string indexed nameref, string name, uint8 status)
func (_Drippie *DrippieFilterer) FilterDripStatusUpdated(opts *bind.FilterOpts, nameref []string) (*DrippieDripStatusUpdatedIterator, error) {
var namerefRule []interface{}
for _, namerefItem := range nameref {
namerefRule = append(namerefRule, namerefItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "DripStatusUpdated", namerefRule)
if err != nil {
return nil, err
}
return &DrippieDripStatusUpdatedIterator{contract: _Drippie.contract, event: "DripStatusUpdated", logs: logs, sub: sub}, nil
}
// WatchDripStatusUpdated is a free log subscription operation binding the contract event 0x407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1.
//
// Solidity: event DripStatusUpdated(string indexed nameref, string name, uint8 status)
func (_Drippie *DrippieFilterer) WatchDripStatusUpdated(opts *bind.WatchOpts, sink chan<- *DrippieDripStatusUpdated, nameref []string) (event.Subscription, error) {
var namerefRule []interface{}
for _, namerefItem := range nameref {
namerefRule = append(namerefRule, namerefItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "DripStatusUpdated", namerefRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieDripStatusUpdated)
if err := _Drippie.contract.UnpackLog(event, "DripStatusUpdated", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseDripStatusUpdated is a log parse operation binding the contract event 0x407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1.
//
// Solidity: event DripStatusUpdated(string indexed nameref, string name, uint8 status)
func (_Drippie *DrippieFilterer) ParseDripStatusUpdated(log types.Log) (*DrippieDripStatusUpdated, error) {
event := new(DrippieDripStatusUpdated)
if err := _Drippie.contract.UnpackLog(event, "DripStatusUpdated", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieOwnerUpdatedIterator is returned from FilterOwnerUpdated and is used to iterate over the raw logs and unpacked data for OwnerUpdated events raised by the Drippie contract.
type DrippieOwnerUpdatedIterator struct {
Event *DrippieOwnerUpdated // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieOwnerUpdatedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieOwnerUpdated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieOwnerUpdated)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieOwnerUpdatedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieOwnerUpdatedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieOwnerUpdated represents a OwnerUpdated event raised by the Drippie contract.
type DrippieOwnerUpdated struct {
User common.Address
NewOwner common.Address
Raw types.Log // Blockchain specific contextual infos
}
// FilterOwnerUpdated is a free log retrieval operation binding the contract event 0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76.
//
// Solidity: event OwnerUpdated(address indexed user, address indexed newOwner)
func (_Drippie *DrippieFilterer) FilterOwnerUpdated(opts *bind.FilterOpts, user []common.Address, newOwner []common.Address) (*DrippieOwnerUpdatedIterator, error) {
var userRule []interface{}
for _, userItem := range user {
userRule = append(userRule, userItem)
}
var newOwnerRule []interface{}
for _, newOwnerItem := range newOwner {
newOwnerRule = append(newOwnerRule, newOwnerItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "OwnerUpdated", userRule, newOwnerRule)
if err != nil {
return nil, err
}
return &DrippieOwnerUpdatedIterator{contract: _Drippie.contract, event: "OwnerUpdated", logs: logs, sub: sub}, nil
}
// WatchOwnerUpdated is a free log subscription operation binding the contract event 0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76.
//
// Solidity: event OwnerUpdated(address indexed user, address indexed newOwner)
func (_Drippie *DrippieFilterer) WatchOwnerUpdated(opts *bind.WatchOpts, sink chan<- *DrippieOwnerUpdated, user []common.Address, newOwner []common.Address) (event.Subscription, error) {
var userRule []interface{}
for _, userItem := range user {
userRule = append(userRule, userItem)
}
var newOwnerRule []interface{}
for _, newOwnerItem := range newOwner {
newOwnerRule = append(newOwnerRule, newOwnerItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "OwnerUpdated", userRule, newOwnerRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieOwnerUpdated)
if err := _Drippie.contract.UnpackLog(event, "OwnerUpdated", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseOwnerUpdated is a log parse operation binding the contract event 0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76.
//
// Solidity: event OwnerUpdated(address indexed user, address indexed newOwner)
func (_Drippie *DrippieFilterer) ParseOwnerUpdated(log types.Log) (*DrippieOwnerUpdated, error) {
event := new(DrippieOwnerUpdated)
if err := _Drippie.contract.UnpackLog(event, "OwnerUpdated", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieReceivedETHIterator is returned from FilterReceivedETH and is used to iterate over the raw logs and unpacked data for ReceivedETH events raised by the Drippie contract.
type DrippieReceivedETHIterator struct {
Event *DrippieReceivedETH // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieReceivedETHIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieReceivedETH)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieReceivedETH)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieReceivedETHIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieReceivedETHIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieReceivedETH represents a ReceivedETH event raised by the Drippie contract.
type DrippieReceivedETH struct {
From common.Address
Amount *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterReceivedETH is a free log retrieval operation binding the contract event 0x4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c279624.
//
// Solidity: event ReceivedETH(address indexed from, uint256 amount)
func (_Drippie *DrippieFilterer) FilterReceivedETH(opts *bind.FilterOpts, from []common.Address) (*DrippieReceivedETHIterator, error) {
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "ReceivedETH", fromRule)
if err != nil {
return nil, err
}
return &DrippieReceivedETHIterator{contract: _Drippie.contract, event: "ReceivedETH", logs: logs, sub: sub}, nil
}
// WatchReceivedETH is a free log subscription operation binding the contract event 0x4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c279624.
//
// Solidity: event ReceivedETH(address indexed from, uint256 amount)
func (_Drippie *DrippieFilterer) WatchReceivedETH(opts *bind.WatchOpts, sink chan<- *DrippieReceivedETH, from []common.Address) (event.Subscription, error) {
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "ReceivedETH", fromRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieReceivedETH)
if err := _Drippie.contract.UnpackLog(event, "ReceivedETH", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseReceivedETH is a log parse operation binding the contract event 0x4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c279624.
//
// Solidity: event ReceivedETH(address indexed from, uint256 amount)
func (_Drippie *DrippieFilterer) ParseReceivedETH(log types.Log) (*DrippieReceivedETH, error) {
event := new(DrippieReceivedETH)
if err := _Drippie.contract.UnpackLog(event, "ReceivedETH", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieWithdrewERC20Iterator is returned from FilterWithdrewERC20 and is used to iterate over the raw logs and unpacked data for WithdrewERC20 events raised by the Drippie contract.
type DrippieWithdrewERC20Iterator struct {
Event *DrippieWithdrewERC20 // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieWithdrewERC20Iterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieWithdrewERC20)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieWithdrewERC20)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieWithdrewERC20Iterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieWithdrewERC20Iterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieWithdrewERC20 represents a WithdrewERC20 event raised by the Drippie contract.
type DrippieWithdrewERC20 struct {
Withdrawer common.Address
Recipient common.Address
Asset common.Address
Amount *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterWithdrewERC20 is a free log retrieval operation binding the contract event 0x6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa.
//
// Solidity: event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount)
func (_Drippie *DrippieFilterer) FilterWithdrewERC20(opts *bind.FilterOpts, withdrawer []common.Address, recipient []common.Address, asset []common.Address) (*DrippieWithdrewERC20Iterator, error) {
var withdrawerRule []interface{}
for _, withdrawerItem := range withdrawer {
withdrawerRule = append(withdrawerRule, withdrawerItem)
}
var recipientRule []interface{}
for _, recipientItem := range recipient {
recipientRule = append(recipientRule, recipientItem)
}
var assetRule []interface{}
for _, assetItem := range asset {
assetRule = append(assetRule, assetItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "WithdrewERC20", withdrawerRule, recipientRule, assetRule)
if err != nil {
return nil, err
}
return &DrippieWithdrewERC20Iterator{contract: _Drippie.contract, event: "WithdrewERC20", logs: logs, sub: sub}, nil
}
// WatchWithdrewERC20 is a free log subscription operation binding the contract event 0x6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa.
//
// Solidity: event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount)
func (_Drippie *DrippieFilterer) WatchWithdrewERC20(opts *bind.WatchOpts, sink chan<- *DrippieWithdrewERC20, withdrawer []common.Address, recipient []common.Address, asset []common.Address) (event.Subscription, error) {
var withdrawerRule []interface{}
for _, withdrawerItem := range withdrawer {
withdrawerRule = append(withdrawerRule, withdrawerItem)
}
var recipientRule []interface{}
for _, recipientItem := range recipient {
recipientRule = append(recipientRule, recipientItem)
}
var assetRule []interface{}
for _, assetItem := range asset {
assetRule = append(assetRule, assetItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "WithdrewERC20", withdrawerRule, recipientRule, assetRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieWithdrewERC20)
if err := _Drippie.contract.UnpackLog(event, "WithdrewERC20", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseWithdrewERC20 is a log parse operation binding the contract event 0x6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa.
//
// Solidity: event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount)
func (_Drippie *DrippieFilterer) ParseWithdrewERC20(log types.Log) (*DrippieWithdrewERC20, error) {
event := new(DrippieWithdrewERC20)
if err := _Drippie.contract.UnpackLog(event, "WithdrewERC20", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieWithdrewERC721Iterator is returned from FilterWithdrewERC721 and is used to iterate over the raw logs and unpacked data for WithdrewERC721 events raised by the Drippie contract.
type DrippieWithdrewERC721Iterator struct {
Event *DrippieWithdrewERC721 // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieWithdrewERC721Iterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieWithdrewERC721)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieWithdrewERC721)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieWithdrewERC721Iterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieWithdrewERC721Iterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieWithdrewERC721 represents a WithdrewERC721 event raised by the Drippie contract.
type DrippieWithdrewERC721 struct {
Withdrawer common.Address
Recipient common.Address
Asset common.Address
Id *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterWithdrewERC721 is a free log retrieval operation binding the contract event 0x30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8.
//
// Solidity: event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id)
func (_Drippie *DrippieFilterer) FilterWithdrewERC721(opts *bind.FilterOpts, withdrawer []common.Address, recipient []common.Address, asset []common.Address) (*DrippieWithdrewERC721Iterator, error) {
var withdrawerRule []interface{}
for _, withdrawerItem := range withdrawer {
withdrawerRule = append(withdrawerRule, withdrawerItem)
}
var recipientRule []interface{}
for _, recipientItem := range recipient {
recipientRule = append(recipientRule, recipientItem)
}
var assetRule []interface{}
for _, assetItem := range asset {
assetRule = append(assetRule, assetItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "WithdrewERC721", withdrawerRule, recipientRule, assetRule)
if err != nil {
return nil, err
}
return &DrippieWithdrewERC721Iterator{contract: _Drippie.contract, event: "WithdrewERC721", logs: logs, sub: sub}, nil
}
// WatchWithdrewERC721 is a free log subscription operation binding the contract event 0x30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8.
//
// Solidity: event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id)
func (_Drippie *DrippieFilterer) WatchWithdrewERC721(opts *bind.WatchOpts, sink chan<- *DrippieWithdrewERC721, withdrawer []common.Address, recipient []common.Address, asset []common.Address) (event.Subscription, error) {
var withdrawerRule []interface{}
for _, withdrawerItem := range withdrawer {
withdrawerRule = append(withdrawerRule, withdrawerItem)
}
var recipientRule []interface{}
for _, recipientItem := range recipient {
recipientRule = append(recipientRule, recipientItem)
}
var assetRule []interface{}
for _, assetItem := range asset {
assetRule = append(assetRule, assetItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "WithdrewERC721", withdrawerRule, recipientRule, assetRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieWithdrewERC721)
if err := _Drippie.contract.UnpackLog(event, "WithdrewERC721", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseWithdrewERC721 is a log parse operation binding the contract event 0x30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8.
//
// Solidity: event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id)
func (_Drippie *DrippieFilterer) ParseWithdrewERC721(log types.Log) (*DrippieWithdrewERC721, error) {
event := new(DrippieWithdrewERC721)
if err := _Drippie.contract.UnpackLog(event, "WithdrewERC721", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// DrippieWithdrewETHIterator is returned from FilterWithdrewETH and is used to iterate over the raw logs and unpacked data for WithdrewETH events raised by the Drippie contract.
type DrippieWithdrewETHIterator struct {
Event *DrippieWithdrewETH // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *DrippieWithdrewETHIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(DrippieWithdrewETH)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(DrippieWithdrewETH)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *DrippieWithdrewETHIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *DrippieWithdrewETHIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// DrippieWithdrewETH represents a WithdrewETH event raised by the Drippie contract.
type DrippieWithdrewETH struct {
Withdrawer common.Address
Recipient common.Address
Amount *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterWithdrewETH is a free log retrieval operation binding the contract event 0x1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc.
//
// Solidity: event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount)
func (_Drippie *DrippieFilterer) FilterWithdrewETH(opts *bind.FilterOpts, withdrawer []common.Address, recipient []common.Address) (*DrippieWithdrewETHIterator, error) {
var withdrawerRule []interface{}
for _, withdrawerItem := range withdrawer {
withdrawerRule = append(withdrawerRule, withdrawerItem)
}
var recipientRule []interface{}
for _, recipientItem := range recipient {
recipientRule = append(recipientRule, recipientItem)
}
logs, sub, err := _Drippie.contract.FilterLogs(opts, "WithdrewETH", withdrawerRule, recipientRule)
if err != nil {
return nil, err
}
return &DrippieWithdrewETHIterator{contract: _Drippie.contract, event: "WithdrewETH", logs: logs, sub: sub}, nil
}
// WatchWithdrewETH is a free log subscription operation binding the contract event 0x1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc.
//
// Solidity: event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount)
func (_Drippie *DrippieFilterer) WatchWithdrewETH(opts *bind.WatchOpts, sink chan<- *DrippieWithdrewETH, withdrawer []common.Address, recipient []common.Address) (event.Subscription, error) {
var withdrawerRule []interface{}
for _, withdrawerItem := range withdrawer {
withdrawerRule = append(withdrawerRule, withdrawerItem)
}
var recipientRule []interface{}
for _, recipientItem := range recipient {
recipientRule = append(recipientRule, recipientItem)
}
logs, sub, err := _Drippie.contract.WatchLogs(opts, "WithdrewETH", withdrawerRule, recipientRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(DrippieWithdrewETH)
if err := _Drippie.contract.UnpackLog(event, "WithdrewETH", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseWithdrewETH is a log parse operation binding the contract event 0x1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc.
//
// Solidity: event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount)
func (_Drippie *DrippieFilterer) ParseWithdrewETH(log types.Log) (*DrippieWithdrewETH, error) {
event := new(DrippieWithdrewETH)
if err := _Drippie.contract.UnpackLog(event, "WithdrewETH", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
package main
import (
"context"
"os"
"github.com/ethereum-optimism/optimism/op-service/ctxinterrupt"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-dripper/dripper"
"github.com/ethereum-optimism/optimism/op-dripper/flags"
"github.com/ethereum-optimism/optimism/op-dripper/metrics"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/metrics/doc"
"github.com/ethereum/go-ethereum/log"
)
var (
Version = "v0.0.0"
GitCommit = ""
GitDate = ""
)
func main() {
oplog.SetupDefaults()
app := cli.NewApp()
app.Flags = cliapp.ProtectFlags(flags.Flags)
app.Version = opservice.FormatVersion(Version, GitCommit, GitDate, "")
app.Name = "op-dripper"
app.Usage = "Drippie Executor"
app.Description = "Service for executing Drippie drips"
app.Action = cliapp.LifecycleCmd(dripper.Main(Version))
app.Commands = []*cli.Command{
{
Name: "doc",
Subcommands: doc.NewSubcommands(metrics.NewMetrics("default")),
},
}
ctx := ctxinterrupt.WithSignalWaiterMain(context.Background())
err := app.RunContext(ctx, os.Args)
if err != nil {
log.Crit("Application failed", "message", err)
}
}
package dripper
import (
"errors"
"time"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-dripper/flags"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum-optimism/optimism/op-service/oppprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
type CLIConfig struct {
L1EthRpc string
DrippieAddress string
PollInterval time.Duration
TxMgrConfig txmgr.CLIConfig
RPCConfig oprpc.CLIConfig
LogConfig oplog.CLIConfig
MetricsConfig opmetrics.CLIConfig
PprofConfig oppprof.CLIConfig
}
func (c *CLIConfig) Check() error {
if err := c.RPCConfig.Check(); err != nil {
return err
}
if err := c.MetricsConfig.Check(); err != nil {
return err
}
if err := c.PprofConfig.Check(); err != nil {
return err
}
if c.DrippieAddress == "" {
return errors.New("drippie address is required")
}
return nil
}
func NewConfig(ctx *cli.Context) *CLIConfig {
return &CLIConfig{
// Required Flags
L1EthRpc: ctx.String(flags.L1EthRpcFlag.Name),
DrippieAddress: ctx.String(flags.DrippieAddressFlag.Name),
PollInterval: ctx.Duration(flags.PollIntervalFlag.Name),
TxMgrConfig: txmgr.ReadCLIConfig(ctx),
// Optional Flags
RPCConfig: oprpc.ReadCLIConfig(ctx),
LogConfig: oplog.ReadCLIConfig(ctx),
MetricsConfig: opmetrics.ReadCLIConfig(ctx),
PprofConfig: oppprof.ReadCLIConfig(ctx),
}
}
package dripper
import (
"context"
"fmt"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-dripper/flags"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
)
func Main(version string) cliapp.LifecycleAction {
return func(cliCtx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, error) {
if err := flags.CheckRequired(cliCtx); err != nil {
return nil, err
}
cfg := NewConfig(cliCtx)
if err := cfg.Check(); err != nil {
return nil, fmt.Errorf("invalid CLI flags: %w", err)
}
l := oplog.NewLogger(oplog.AppOut(cliCtx), cfg.LogConfig)
oplog.SetGlobalLogHandler(l.Handler())
opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, l)
l.Info("initializing executor")
return DripExecutorServiceFromCLIConfig(cliCtx.Context, version, cfg, l)
}
}
package dripper
import (
"context"
"errors"
"fmt"
"math/big"
"sync"
"time"
"github.com/ethereum-optimism/optimism/op-dripper/bindings"
"github.com/ethereum-optimism/optimism/op-dripper/metrics"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
type Client interface {
CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
}
type DrippieContract interface {
GetDripCount(*bind.CallOpts) (*big.Int, error)
Created(*bind.CallOpts, *big.Int) (string, error)
Executable(*bind.CallOpts, string) (bool, error)
}
type DriverSetup struct {
Log log.Logger
Metr metrics.Metricer
Cfg DripExecutorConfig
Txmgr txmgr.TxManager
Client Client
}
type DripExecutor struct {
DriverSetup
wg sync.WaitGroup
done chan struct{}
ctx context.Context
cancel context.CancelFunc
mutex sync.Mutex
running bool
drippieContract DrippieContract
drippieABI *abi.ABI
}
func NewDripExecutor(setup DriverSetup) (_ *DripExecutor, err error) {
ctx, cancel := context.WithCancel(context.Background())
// Ensure context does't leak.
defer func() {
if err != nil || recover() != nil {
cancel()
}
}()
if setup.Cfg.DrippieAddr == nil {
return nil, errors.New("drippie address is required")
}
return newDripExecutor(ctx, cancel, setup)
}
func newDripExecutor(ctx context.Context, cancel context.CancelFunc, setup DriverSetup) (*DripExecutor, error) {
drippieContract, err := bindings.NewDrippieCaller(*setup.Cfg.DrippieAddr, setup.Client)
if err != nil {
cancel()
return nil, fmt.Errorf("failed to create drippie at address %s: %w", setup.Cfg.DrippieAddr, err)
}
log.Info("connected to drippie", "address", setup.Cfg.DrippieAddr)
parsed, err := bindings.DrippieMetaData.GetAbi()
if err != nil {
cancel()
return nil, err
}
return &DripExecutor{
DriverSetup: setup,
done: make(chan struct{}),
ctx: ctx,
cancel: cancel,
drippieContract: drippieContract,
drippieABI: parsed,
}, nil
}
func (d *DripExecutor) Start() error {
d.Log.Info("starting executor")
d.mutex.Lock()
defer d.mutex.Unlock()
if d.running {
return errors.New("drip executor is already running")
}
d.running = true
d.wg.Add(1)
go d.loop()
d.Log.Info("started executor")
return nil
}
func (d *DripExecutor) Stop() error {
d.Log.Info("stopping executor")
d.mutex.Lock()
defer d.mutex.Unlock()
if !d.running {
return errors.New("drip executor is not running")
}
d.running = false
d.cancel()
close(d.done)
d.wg.Wait()
d.Log.Info("stopped executor")
return nil
}
func (d *DripExecutor) loop() {
defer d.wg.Done()
defer d.Log.Info("loop returning")
ctx := d.ctx
ticker := time.NewTicker(d.Cfg.PollInterval)
defer ticker.Stop()
//nolint:gosimple // This is an event loop that needs to handle multiple channels
for {
select {
case <-ticker.C:
// Prioritize quit signal
select {
case <-d.done:
return
default:
}
drips, err := d.fetchExecutableDrips(ctx)
if err != nil {
d.Log.Warn("failed to fetch executable drips", "error", err)
continue
}
for _, drip := range drips {
d.executeDrip(ctx, drip)
}
}
}
}
func (d *DripExecutor) fetchExecutableDrips(ctx context.Context) ([]string, error) {
// Get total number of drips
d.Log.Info("getting drip count")
count, err := d.drippieContract.GetDripCount(&bind.CallOpts{Context: ctx})
if err != nil {
return nil, fmt.Errorf("failed to get drip count: %w", err)
}
d.Log.Info("drip count", "count", count)
var executableDrips []string
// Iterate through all drips
for i := int64(0); i < count.Int64(); i++ {
// Get drip name at index
name, err := d.drippieContract.Created(&bind.CallOpts{Context: ctx}, big.NewInt(i))
if err != nil {
d.Log.Error("failed to get drip name", "index", i, "error", err)
continue
}
// Check if drip is executable
// Note: This call may revert if the drip is not executable
executable, err := d.drippieContract.Executable(&bind.CallOpts{Context: ctx}, name)
if err != nil {
// Log the error but continue with next drip
d.Log.Info("drip is not executable", "name", name, "error", err)
continue
}
if executable {
d.Log.Info("drip is executable", "name", name)
executableDrips = append(executableDrips, name)
} else {
d.Log.Info("drip is not executable", "name", name)
}
}
return executableDrips, nil
}
func (d *DripExecutor) executeDrip(ctx context.Context, name string) {
cCtx, cCancel := context.WithTimeout(ctx, 10*time.Minute)
defer cCancel()
if err := d.sendTransaction(cCtx, name); err != nil {
d.Log.Error("failed to send drip execution transaction", "name", name, "error", err)
return
}
d.Metr.RecordDripExecuted(name)
}
func (d *DripExecutor) sendTransaction(ctx context.Context, name string) error {
d.Log.Info("executing drip", "name", name)
data, err := d.executeDripTxData(name)
if err != nil {
return err
}
receipt, err := d.Txmgr.Send(ctx, txmgr.TxCandidate{
TxData: data,
To: d.Cfg.DrippieAddr,
GasLimit: 0,
})
if err != nil {
return err
}
if receipt.Status == types.ReceiptStatusFailed {
d.Log.Error("drip execution failed", "name", name, "tx_hash", receipt.TxHash)
} else {
d.Log.Info("drip executed", "name", name, "tx_hash", receipt.TxHash)
}
return nil
}
func (d *DripExecutor) executeDripTxData(name string) ([]byte, error) {
return executeDripTxData(d.drippieABI, name)
}
func executeDripTxData(abi *abi.ABI, name string) ([]byte, error) {
return abi.Pack(
"drip",
name)
}
package dripper
import (
"context"
"errors"
"fmt"
"io"
"sync/atomic"
"time"
"github.com/ethereum-optimism/optimism/op-dripper/metrics"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/httputil"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum-optimism/optimism/op-service/oppprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
var ErrAlreadyStopped = errors.New("already stopped")
type DripExecutorDriver interface {
Start() error
Stop() error
}
type DripExecutorConfig struct {
PollInterval time.Duration
NetworkTimeout time.Duration
DrippieAddr *common.Address
}
type DripExecutorService struct {
Log log.Logger
Metrics metrics.Metricer
DripExecutorConfig
TxManager txmgr.TxManager
Client *ethclient.Client
driver *DripExecutor
Version string
pprofService *oppprof.Service
metricsSrv *httputil.HTTPServer
rpcServer *oprpc.Server
balanceMetricer io.Closer
stopped atomic.Bool
}
func DripExecutorServiceFromCLIConfig(ctx context.Context, version string, cfg *CLIConfig, log log.Logger) (*DripExecutorService, error) {
var ds DripExecutorService
if err := ds.initFromCLIConfig(ctx, version, cfg, log); err != nil {
return nil, errors.Join(err, ds.Stop(ctx))
}
return &ds, nil
}
func (ds *DripExecutorService) initFromCLIConfig(ctx context.Context, version string, cfg *CLIConfig, log log.Logger) error {
ds.Version = version
ds.Log = log
ds.initMetrics(cfg)
ds.PollInterval = cfg.PollInterval
ds.NetworkTimeout = cfg.TxMgrConfig.NetworkTimeout
ds.initDrippieAddress(cfg)
if err := ds.initRPCClients(ctx, cfg); err != nil {
return err
}
if err := ds.initTxManager(cfg); err != nil {
return fmt.Errorf("failed to init tx manager: %w", err)
}
if err := ds.initMetricsServer(cfg); err != nil {
return fmt.Errorf("failed to start metrics server: %w", err)
}
if err := ds.initPProf(cfg); err != nil {
return fmt.Errorf("failed to init pprof server: %w", err)
}
if err := ds.initDriver(); err != nil {
return fmt.Errorf("failed to init driver: %w", err)
}
if err := ds.initRPCServer(cfg); err != nil {
return fmt.Errorf("failed to start rpc server: %w", err)
}
ds.initBalanceMonitor(cfg)
ds.Metrics.RecordInfo(ds.Version)
ds.Metrics.RecordUp()
return nil
}
func (ds *DripExecutorService) initRPCClients(ctx context.Context, cfg *CLIConfig) error {
client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, ds.Log, cfg.L1EthRpc)
if err != nil {
return fmt.Errorf("failed to dial rpc: %w", err)
}
ds.Client = client
return nil
}
func (ds *DripExecutorService) initMetrics(cfg *CLIConfig) {
if cfg.MetricsConfig.Enabled {
procName := "default"
ds.Metrics = metrics.NewMetrics(procName)
} else {
ds.Metrics = metrics.NoopMetrics
}
}
func (ds *DripExecutorService) initBalanceMonitor(cfg *CLIConfig) {
if cfg.MetricsConfig.Enabled {
ds.balanceMetricer = ds.Metrics.StartBalanceMetrics(ds.Log, ds.Client, ds.TxManager.From())
}
}
func (ds *DripExecutorService) initTxManager(cfg *CLIConfig) error {
txManager, err := txmgr.NewSimpleTxManager("dripper", ds.Log, ds.Metrics, cfg.TxMgrConfig)
if err != nil {
return err
}
ds.TxManager = txManager
return nil
}
func (ds *DripExecutorService) initPProf(cfg *CLIConfig) error {
ds.pprofService = oppprof.New(
cfg.PprofConfig.ListenEnabled,
cfg.PprofConfig.ListenAddr,
cfg.PprofConfig.ListenPort,
cfg.PprofConfig.ProfileType,
cfg.PprofConfig.ProfileDir,
cfg.PprofConfig.ProfileFilename,
)
if err := ds.pprofService.Start(); err != nil {
return fmt.Errorf("failed to start pprof service: %w", err)
}
return nil
}
func (ds *DripExecutorService) initMetricsServer(cfg *CLIConfig) error {
if !cfg.MetricsConfig.Enabled {
ds.Log.Info("metrics disabled")
return nil
}
m, ok := ds.Metrics.(opmetrics.RegistryMetricer)
if !ok {
return fmt.Errorf("metrics were enabled, but metricer %T does not expose registry for metrics-server", ds.Metrics)
}
ds.Log.Debug("starting metrics server", "addr", cfg.MetricsConfig.ListenAddr, "port", cfg.MetricsConfig.ListenPort)
metricsSrv, err := opmetrics.StartServer(m.Registry(), cfg.MetricsConfig.ListenAddr, cfg.MetricsConfig.ListenPort)
if err != nil {
return fmt.Errorf("failed to start metrics server: %w", err)
}
ds.Log.Info("started metrics server", "addr", metricsSrv.Addr())
ds.metricsSrv = metricsSrv
return nil
}
func (ds *DripExecutorService) initDrippieAddress(cfg *CLIConfig) {
drippieAddress, err := opservice.ParseAddress(cfg.DrippieAddress)
if err != nil {
return
}
ds.DrippieAddr = &drippieAddress
}
func (ds *DripExecutorService) initDriver() error {
driver, err := NewDripExecutor(DriverSetup{
Log: ds.Log,
Metr: ds.Metrics,
Cfg: ds.DripExecutorConfig,
Txmgr: ds.TxManager,
Client: ds.Client,
})
if err != nil {
return err
}
ds.driver = driver
return nil
}
func (ds *DripExecutorService) initRPCServer(cfg *CLIConfig) error {
server := oprpc.NewServer(
cfg.RPCConfig.ListenAddr,
cfg.RPCConfig.ListenPort,
ds.Version,
oprpc.WithLogger(ds.Log),
)
if cfg.RPCConfig.EnableAdmin {
server.AddAPI(ds.TxManager.API())
ds.Log.Info("admin rpc enabled")
}
ds.Log.Info("starting json-rpc server")
if err := server.Start(); err != nil {
return fmt.Errorf("unable to start rpc server: %w", err)
}
ds.rpcServer = server
return nil
}
func (ds *DripExecutorService) Start(ctx context.Context) error {
return ds.driver.Start()
}
func (ds *DripExecutorService) Stopped() bool {
return ds.stopped.Load()
}
func (ds *DripExecutorService) Kill() error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
return ds.Stop(ctx)
}
func (ds *DripExecutorService) Stop(ctx context.Context) error {
if ds.Stopped() {
return ErrAlreadyStopped
}
ds.Log.Info("stopping executor")
var result error
if ds.driver != nil {
if err := ds.driver.Stop(); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop executor: %w", err))
}
}
if ds.rpcServer != nil {
if err := ds.rpcServer.Stop(); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop rpc server: %w", err))
}
}
if ds.pprofService != nil {
if err := ds.pprofService.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop pprof server: %w", err))
}
}
if ds.balanceMetricer != nil {
if err := ds.balanceMetricer.Close(); err != nil {
result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err))
}
}
if ds.TxManager != nil {
ds.TxManager.Close()
}
if ds.metricsSrv != nil {
if err := ds.metricsSrv.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err))
}
}
if ds.Client != nil {
ds.Client.Close()
}
if result == nil {
ds.stopped.Store(true)
ds.Log.Info("stopped executor")
}
return result
}
var _ cliapp.Lifecycle = (*DripExecutorService)(nil)
func (ds *DripExecutorService) Driver() DripExecutorDriver {
return ds.driver
}
package flags
import (
"fmt"
"time"
"github.com/urfave/cli/v2"
opservice "github.com/ethereum-optimism/optimism/op-service"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum-optimism/optimism/op-service/oppprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
const EnvVarPrefix = "OP_DRIPPER"
func prefixEnvVars(name string) []string {
return opservice.PrefixEnvVar(EnvVarPrefix, name)
}
var (
// Required Flags
L1EthRpcFlag = &cli.StringFlag{
Name: "l1-eth-rpc",
Usage: "The RPC URL for the L1 Ethereum chain to drip",
EnvVars: prefixEnvVars("L1_ETH_RPC"),
Required: true,
}
DrippieAddressFlag = &cli.StringFlag{
Name: "drippie-address",
Usage: "The address of the drippie contract",
EnvVars: prefixEnvVars("DRIPPIE_ADDRESS"),
Required: true,
}
// Optional Flags
PollIntervalFlag = &cli.DurationFlag{
Name: "poll-interval",
Usage: "How frequently to poll L2 for new blocks (legacy L2OO)",
Value: 12 * time.Second,
EnvVars: prefixEnvVars("POLL_INTERVAL"),
}
)
var requiredFlags = []cli.Flag{
L1EthRpcFlag,
DrippieAddressFlag,
}
var optionalFlags = []cli.Flag{
PollIntervalFlag,
}
func init() {
optionalFlags = append(optionalFlags, oprpc.CLIFlags(EnvVarPrefix)...)
optionalFlags = append(optionalFlags, oplog.CLIFlags(EnvVarPrefix)...)
optionalFlags = append(optionalFlags, opmetrics.CLIFlags(EnvVarPrefix)...)
optionalFlags = append(optionalFlags, oppprof.CLIFlags(EnvVarPrefix)...)
optionalFlags = append(optionalFlags, txmgr.CLIFlags(EnvVarPrefix)...)
Flags = append(requiredFlags, optionalFlags...)
}
var Flags []cli.Flag
func CheckRequired(ctx *cli.Context) error {
for _, f := range requiredFlags {
if !ctx.IsSet(f.Names()[0]) {
return fmt.Errorf("flag %s is required", f.Names()[0])
}
}
return nil
}
import '../justfiles/go.just'
# Build ldflags string
_LDFLAGSSTRING := "'" + trim(
"-X main.GitCommit=" + GITCOMMIT + " " + \
"-X main.GitDate=" + GITDATE + " " + \
"-X main.Version=" + VERSION + " " + \
"") + "'"
BINARY := "./bin/op-dripper"
# Build op-dripper binary
op-dripper: (go_build BINARY "./cmd" "-ldflags" _LDFLAGSSTRING)
# Clean build artifacts
clean:
rm -f {{BINARY}}
# Run tests
test: (go_test "./...")
package metrics
import (
"io"
"github.com/prometheus/client_golang/prometheus"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)
const Namespace = "op_dripper"
var _ opmetrics.RegistryMetricer = (*Metrics)(nil)
type Metricer interface {
RecordInfo(version string)
RecordUp()
opmetrics.RefMetricer
opmetrics.RPCMetricer
txmetrics.TxMetricer
StartBalanceMetrics(l log.Logger, client *ethclient.Client, account common.Address) io.Closer
RecordDripExecuted(name string)
}
type Metrics struct {
ns string
registry *prometheus.Registry
factory opmetrics.Factory
opmetrics.RefMetrics
opmetrics.RPCMetrics
txmetrics.TxMetrics
info prometheus.GaugeVec
drips prometheus.GaugeVec
up prometheus.Gauge
}
var _ Metricer = (*Metrics)(nil)
func NewMetrics(procName string) *Metrics {
if procName == "" {
procName = "default"
}
ns := Namespace + "_" + procName
registry := opmetrics.NewRegistry()
factory := opmetrics.With(registry)
return &Metrics{
ns: ns,
registry: registry,
factory: factory,
RefMetrics: opmetrics.MakeRefMetrics(ns, factory),
RPCMetrics: opmetrics.MakeRPCMetrics(ns, factory),
TxMetrics: txmetrics.MakeTxMetrics(ns, factory),
info: *factory.NewGaugeVec(prometheus.GaugeOpts{
Namespace: ns,
Name: "info",
Help: "Information about the dripper",
}, []string{
"version",
}),
drips: *factory.NewGaugeVec(prometheus.GaugeOpts{
Namespace: ns,
Name: "drips",
Help: "Drips executed",
}, []string{
"name",
}),
up: factory.NewGauge(prometheus.GaugeOpts{
Namespace: ns,
Name: "up",
Help: "1 if the op-dripper has finished starting up",
}),
}
}
func (m *Metrics) Registry() *prometheus.Registry {
return m.registry
}
func (m *Metrics) StartBalanceMetrics(l log.Logger, client *ethclient.Client, account common.Address) io.Closer {
return opmetrics.LaunchBalanceMetrics(l, m.registry, m.ns, client, account)
}
func (m *Metrics) RecordInfo(version string) {
m.info.WithLabelValues(version).Set(1)
}
func (m *Metrics) RecordUp() {
prometheus.MustRegister()
m.up.Set(1)
}
func (m *Metrics) RecordDripExecuted(name string) {
m.drips.WithLabelValues(name).Inc()
}
func (m *Metrics) Document() []opmetrics.DocumentedMetric {
return m.factory.Document()
}
package metrics
import (
"io"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)
type noopMetrics struct {
opmetrics.NoopRefMetrics
txmetrics.NoopTxMetrics
opmetrics.NoopRPCMetrics
}
var NoopMetrics Metricer = new(noopMetrics)
func (*noopMetrics) RecordInfo(version string) {}
func (*noopMetrics) RecordUp() {}
func (*noopMetrics) RecordDripExecuted(name string) {}
func (*noopMetrics) StartBalanceMetrics(log.Logger, *ethclient.Client, common.Address) io.Closer {
return nil
}
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
...@@ -10,11 +10,6 @@ ...@@ -10,11 +10,6 @@
"faucetAdminDripV1Interval": 86400, "faucetAdminDripV1Interval": 86400,
"faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Threshold": 100000000000000000,
"faucetAdminDripV1Value": 1000000000000000000, "faucetAdminDripV1Value": 1000000000000000000,
"faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f",
"faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF",
"faucetGelatoBalanceV1DripInterval": 86400,
"faucetGelatoBalanceV1Value": 1000000000000000000,
"faucetGelatoThreshold": 100000000000000000,
"faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC",
"faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleTtl": 86400,
"faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOnchainAuthModuleAmount": 1000000000000000000,
......
{ {
"create2DeploymentSalt": "0.0.7", "create2DeploymentSalt": "0.0.8",
"gelatoAutomateContract": "0x2A6C106ae13B558BB9E2Ec64Bd2f1f7BEFF3A5E0", "operationsDrippieOwner": "0xEdc8e780ff786F2DE335FC859349d43392D037a3",
"operationsDrippieOwner": "0xCd438409d5Cac9D2E076Ac7Bd0Bf2377E99BB6e4",
"faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5",
"opChainAdminWalletDripValue": 1000000000000000000, "opChainAdminWalletDripValue": 1000000000000000000,
......
{ {
"drippie": "0xd6F935Bd272BEE05bD64096D82970482EF16D64b", "drippie": "0xd6F935Bd272BEE05bD64096D82970482EF16D64b",
"gelato": "0x859E31b3848Ec384012EECc72C5c49821008296C",
"__comment": "Addresses of dripcheck contracts to be used in drips", "__comment": "Addresses of dripcheck contracts to be used in drips",
"dripchecks": [ "dripchecks": [
...@@ -8,10 +7,6 @@ ...@@ -8,10 +7,6 @@
"00__name": "CheckBalanceLow", "00__name": "CheckBalanceLow",
"01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af" "01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af"
}, },
{
"00__name": "CheckGelatoLow",
"01__address": "0x0fF11AfAC4146a0bABf7F9F042a22C8053a54674"
},
{ {
"00__name": "CheckSecrets", "00__name": "CheckSecrets",
"01__address": "0x32c1e36E733913388076D7c3055300072814bF2A" "01__address": "0x32c1e36E733913388076D7c3055300072814bF2A"
......
{ {
"drippie": "0xd6F935Bd272BEE05bD64096D82970482EF16D64b", "drippie": "0xd6F935Bd272BEE05bD64096D82970482EF16D64b",
"gelato": "0x859E31b3848Ec384012EECc72C5c49821008296C",
"__comment": "Addresses of dripcheck contracts to be used in drips", "__comment": "Addresses of dripcheck contracts to be used in drips",
"dripchecks": [ "dripchecks": [
...@@ -8,10 +7,6 @@ ...@@ -8,10 +7,6 @@
"00__name": "CheckBalanceLow", "00__name": "CheckBalanceLow",
"01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af" "01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af"
}, },
{
"00__name": "CheckGelatoLow",
"01__address": "0x0fF11AfAC4146a0bABf7F9F042a22C8053a54674"
},
{ {
"00__name": "CheckSecrets", "00__name": "CheckSecrets",
"01__address": "0x32c1e36E733913388076D7c3055300072814bF2A" "01__address": "0x32c1e36E733913388076D7c3055300072814bF2A"
...@@ -62,19 +57,6 @@ ...@@ -62,19 +57,6 @@
"04__value": 1000000000000000000, "04__value": 1000000000000000000,
"05__interval": 86400, "05__interval": 86400,
"06__data": "" "06__data": ""
},
{
"00__name": "gelato_v1",
"01__dripcheck": "CheckGelatoLow",
"02__checkparams": {
"00__treasury": "0x7506C12a824d73D9b08564d5Afc22c949434755e",
"01__threshold": 100000000000000000,
"02__recipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF"
},
"03__recipient": "0x7506C12a824d73D9b08564d5Afc22c949434755e",
"04__value": 1000000000000000000,
"05__interval": 86400,
"06__data": "0x0000000000000000000000000e9b4649eb0760a4f01646636e032d68cfde58ff"
} }
] ]
} }
{ {
"drippie": "0xa0fF2a54AdC3fB33c44a141E67d194CF249258cb", "drippie": "0xa0fF2a54AdC3fB33c44a141E67d194CF249258cb",
"gelato": "0x2A6C106ae13B558BB9E2Ec64Bd2f1f7BEFF3A5E0",
"__comment": "Addresses of dripcheck contracts to be used in drips", "__comment": "Addresses of dripcheck contracts to be used in drips",
"dripchecks": [ "dripchecks": [
...@@ -8,10 +7,6 @@ ...@@ -8,10 +7,6 @@
"00__name": "CheckBalanceLow", "00__name": "CheckBalanceLow",
"01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af" "01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af"
}, },
{
"00__name": "CheckGelatoLow",
"01__address": "0x0fF11AfAC4146a0bABf7F9F042a22C8053a54674"
},
{ {
"00__name": "CheckSecrets", "00__name": "CheckSecrets",
"01__address": "0x32c1e36E733913388076D7c3055300072814bF2A" "01__address": "0x32c1e36E733913388076D7c3055300072814bF2A"
...@@ -62,19 +57,6 @@ ...@@ -62,19 +57,6 @@
"04__value": 100000000000000000000, "04__value": 100000000000000000000,
"05__interval": 3600, "05__interval": 3600,
"06__data": "" "06__data": ""
},
{
"00__name": "gelato_v3",
"01__dripcheck": "CheckGelatoLow",
"02__checkparams": {
"00__treasury": "0x7506C12a824d73D9b08564d5Afc22c949434755e",
"01__threshold": 1000000000000000000,
"02__recipient": "0xCd438409d5Cac9D2E076Ac7Bd0Bf2377E99BB6e4"
},
"03__recipient": "0x7506C12a824d73D9b08564d5Afc22c949434755e",
"04__value": 1000000000000000000,
"05__interval": 86400,
"06__data": "0x0000000000000000000000000Cd438409d5Cac9D2E076Ac7Bd0Bf2377E99BB6e4"
} }
] ]
} }
{
"drippie": "0x7ECe0FdeA734B9E77dDd04362c312562924857F6",
"__comment": "Addresses of dripcheck contracts to be used in drips",
"dripchecks": [
{
"00__name": "CheckBalanceLow",
"01__address": "0xaF8C77CfeB57620c4D9dCC81df75a1F0Da7064Af"
},
{
"00__name": "CheckSecrets",
"01__address": "0x32c1e36E733913388076D7c3055300072814bF2A"
},
{
"00__name": "CheckTrue",
"01__address": "0xcBCb3896Ddec35d91901768733C5d3738e10509F"
}
],
"__comment": "Prefix is used to namespace drips so that drip management can be handled modularly",
"prefix": "operations",
"__comment": "Object attributes below are prefixed with numbers because of how foundry parses JSON into structs in alphabetical order",
"drips": [
{
"00__name": "test_v2",
"01__dripcheck": "CheckBalanceLow",
"02__checkparams": {
"01__target": "0x68108902De3A5031197a6eB3b74b3b033e8E8e4d",
"02__threshold": 10000000000000000000
},
"03__recipient": "0x68108902De3A5031197a6eB3b74b3b033e8E8e4d",
"04__value": 10000000000000000,
"05__interval": 1,
"06__data": ""
},
{
"00__name": "test_2_v1",
"01__dripcheck": "CheckBalanceLow",
"02__checkparams": {
"01__target": "0x68108902De3A5031197a6eB3b74b3b033e8E8e4d",
"02__threshold": 10000000000000000000
},
"03__recipient": "0x68108902De3A5031197a6eB3b74b3b033e8E8e4d",
"04__value": 1000000000000000,
"05__interval": 20,
"06__data": ""
}
]
}
...@@ -39,7 +39,6 @@ remappings = [ ...@@ -39,7 +39,6 @@ remappings = [
'ds-test/=lib/forge-std/lib/ds-test/src', 'ds-test/=lib/forge-std/lib/ds-test/src',
'safe-contracts/=lib/safe-contracts/contracts', 'safe-contracts/=lib/safe-contracts/contracts',
'kontrol-cheatcodes/=lib/kontrol-cheatcodes/src', 'kontrol-cheatcodes/=lib/kontrol-cheatcodes/src',
'gelato/=lib/automate/contracts',
'interfaces/=interfaces' 'interfaces/=interfaces'
] ]
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title IGelatoTreasury
/// @notice Interface for the GelatoTreasury contract.
interface IGelatoTreasury {
function totalDepositedAmount(address _user, address _token) external view returns (uint256);
function totalWithdrawnAmount(address _user, address _token) external view returns (uint256);
}
Subproject commit 0117585fea20ff0cd24fd17bf74a6debaa4d57d2
...@@ -13,7 +13,6 @@ import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; ...@@ -13,7 +13,6 @@ import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
import { Proxy } from "src/universal/Proxy.sol"; import { Proxy } from "src/universal/Proxy.sol";
import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol";
import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol";
import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol";
import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol";
import { CheckSecrets } from "src/periphery/drippie/dripchecks/CheckSecrets.sol"; import { CheckSecrets } from "src/periphery/drippie/dripchecks/CheckSecrets.sol";
...@@ -35,6 +34,7 @@ contract DeployPeriphery is Script { ...@@ -35,6 +34,7 @@ contract DeployPeriphery is Script {
/// @notice Sets up the deployment script. /// @notice Sets up the deployment script.
function setUp() public { function setUp() public {
vm.allowCheatcodes(address(artifacts));
vm.etch(address(artifacts), vm.getDeployedCode("Artifacts.s.sol:Artifacts")); vm.etch(address(artifacts), vm.getDeployedCode("Artifacts.s.sol:Artifacts"));
artifacts.setUp(); artifacts.setUp();
...@@ -50,7 +50,6 @@ contract DeployPeriphery is Script { ...@@ -50,7 +50,6 @@ contract DeployPeriphery is Script {
if (cfg.deployDripchecks()) { if (cfg.deployDripchecks()) {
deployCheckTrue(); deployCheckTrue();
deployCheckBalanceLow(); deployCheckBalanceLow();
deployCheckGelatoLow();
deployCheckSecrets(); deployCheckSecrets();
} }
...@@ -191,15 +190,6 @@ contract DeployPeriphery is Script { ...@@ -191,15 +190,6 @@ contract DeployPeriphery is Script {
}); });
} }
/// @notice Deploy CheckGelatoLow contract.
function deployCheckGelatoLow() public broadcast returns (address addr_) {
addr_ = _deployCreate2({
_name: "CheckGelatoLow",
_creationCode: type(CheckGelatoLow).creationCode,
_constructorParams: hex""
});
}
/// @notice Deploy CheckSecrets contract. /// @notice Deploy CheckSecrets contract.
function deployCheckSecrets() public broadcast returns (address addr_) { function deployCheckSecrets() public broadcast returns (address addr_) {
addr_ = _deployCreate2({ addr_ = _deployCreate2({
......
...@@ -15,9 +15,6 @@ contract PeripheryDeployConfig is Script { ...@@ -15,9 +15,6 @@ contract PeripheryDeployConfig is Script {
// General configuration. // General configuration.
string public create2DeploymentSalt; string public create2DeploymentSalt;
// Configuration for Gelato.
address public gelatoAutomateContract;
// Configuration for standard operations Drippie contract. // Configuration for standard operations Drippie contract.
address public operationsDrippieOwner; address public operationsDrippieOwner;
...@@ -50,9 +47,6 @@ contract PeripheryDeployConfig is Script { ...@@ -50,9 +47,6 @@ contract PeripheryDeployConfig is Script {
// General configuration. // General configuration.
create2DeploymentSalt = stdJson.readString(_json, "$.create2DeploymentSalt"); create2DeploymentSalt = stdJson.readString(_json, "$.create2DeploymentSalt");
// Configuration for Gelato.
gelatoAutomateContract = stdJson.readAddress(_json, "$.gelatoAutomateContract");
// Configuration for the standard operations Drippie contract. // Configuration for the standard operations Drippie contract.
operationsDrippieOwner = stdJson.readAddress(_json, "$.operationsDrippieOwner"); operationsDrippieOwner = stdJson.readAddress(_json, "$.operationsDrippieOwner");
......
...@@ -5,11 +5,8 @@ import { Script } from "forge-std/Script.sol"; ...@@ -5,11 +5,8 @@ import { Script } from "forge-std/Script.sol";
import { console2 as console } from "forge-std/console2.sol"; import { console2 as console } from "forge-std/console2.sol";
import { stdJson } from "forge-std/StdJson.sol"; import { stdJson } from "forge-std/StdJson.sol";
import { IAutomate as IGelato } from "gelato/interfaces/IAutomate.sol";
import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol";
import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol";
import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
import { CheckSecrets } from "src/periphery/drippie/dripchecks/CheckSecrets.sol"; import { CheckSecrets } from "src/periphery/drippie/dripchecks/CheckSecrets.sol";
/// @title DrippieConfig /// @title DrippieConfig
...@@ -47,9 +44,6 @@ contract DrippieConfig is Script { ...@@ -47,9 +44,6 @@ contract DrippieConfig is Script {
/// @notice Drippie contract. /// @notice Drippie contract.
Drippie public drippie; Drippie public drippie;
/// @notice Gelato automation contract.
IGelato public gelato;
/// @notice Prefix for the configuration file. /// @notice Prefix for the configuration file.
string public prefix; string public prefix;
...@@ -76,9 +70,6 @@ contract DrippieConfig is Script { ...@@ -76,9 +70,6 @@ contract DrippieConfig is Script {
// Load the Drippie contract address. // Load the Drippie contract address.
drippie = Drippie(payable(stdJson.readAddress(_json, "$.drippie"))); drippie = Drippie(payable(stdJson.readAddress(_json, "$.drippie")));
// Load the Gelato contract address.
gelato = IGelato(stdJson.readAddress(_json, "$.gelato"));
// Load the prefix. // Load the prefix.
prefix = stdJson.readString(_json, "$.prefix"); prefix = stdJson.readString(_json, "$.prefix");
...@@ -120,8 +111,6 @@ contract DrippieConfig is Script { ...@@ -120,8 +111,6 @@ contract DrippieConfig is Script {
console.log("DrippieConfig: attempting to decode check parameters for %s", fullname); console.log("DrippieConfig: attempting to decode check parameters for %s", fullname);
if (strcmp(dripcheck, "CheckBalanceLow")) { if (strcmp(dripcheck, "CheckBalanceLow")) {
abi.decode(checkparams, (CheckBalanceLow.Params)); abi.decode(checkparams, (CheckBalanceLow.Params));
} else if (strcmp(dripcheck, "CheckGelatoLow")) {
abi.decode(checkparams, (CheckGelatoLow.Params));
} else if (strcmp(dripcheck, "CheckSecrets")) { } else if (strcmp(dripcheck, "CheckSecrets")) {
abi.decode(checkparams, (CheckSecrets.Params)); abi.decode(checkparams, (CheckSecrets.Params));
} else if (strcmp(dripcheck, "CheckTrue")) { } else if (strcmp(dripcheck, "CheckTrue")) {
......
...@@ -6,11 +6,6 @@ import { Script } from "forge-std/Script.sol"; ...@@ -6,11 +6,6 @@ import { Script } from "forge-std/Script.sol";
import { LibString } from "@solady/utils/LibString.sol"; import { LibString } from "@solady/utils/LibString.sol";
import { IAutomate as IGelato } from "gelato/interfaces/IAutomate.sol";
import { LibDataTypes as GelatoDataTypes } from "gelato/libraries/LibDataTypes.sol";
import { LibTaskId as GelatoTaskId } from "gelato/libraries/LibTaskId.sol";
import { GelatoBytes } from "gelato/vendor/gelato/GelatoBytes.sol";
import { Config } from "scripts/libraries/Config.sol"; import { Config } from "scripts/libraries/Config.sol";
import { DrippieConfig } from "scripts/periphery/drippie/DrippieConfig.s.sol"; import { DrippieConfig } from "scripts/periphery/drippie/DrippieConfig.s.sol";
...@@ -20,15 +15,6 @@ import { IDripCheck } from "src/periphery/drippie/IDripCheck.sol"; ...@@ -20,15 +15,6 @@ import { IDripCheck } from "src/periphery/drippie/IDripCheck.sol";
/// @title ManageDrippie /// @title ManageDrippie
/// @notice Script for managing drips in the Drippie contract. /// @notice Script for managing drips in the Drippie contract.
contract ManageDrippie is Script { contract ManageDrippie is Script {
/// @notice Struct that contains the data for a Gelato task.
struct GelatoTaskData {
address taskCreator;
address execAddress;
bytes execData;
GelatoDataTypes.ModuleData moduleData;
address feeToken;
}
/// @notice Drippie configuration. /// @notice Drippie configuration.
DrippieConfig public cfg; DrippieConfig public cfg;
...@@ -68,12 +54,6 @@ contract ManageDrippie is Script { ...@@ -68,12 +54,6 @@ contract ManageDrippie is Script {
console.log("ManageDrippie: pausing drip for %s", name); console.log("ManageDrippie: pausing drip for %s", name);
cfg.drippie().status(name, Drippie.DripStatus.PAUSED); cfg.drippie().status(name, Drippie.DripStatus.PAUSED);
} }
// Cancel the Gelato task if it's active.
if (_isGelatoDripTaskActive(cfg.gelato(), cfg.drippie(), name)) {
console.log("ManageDrippie: pausing Gelato task for %s", name);
_pauseGelatoDripTask(cfg.gelato(), cfg.drippie(), name);
}
} }
} }
} }
...@@ -86,7 +66,6 @@ contract ManageDrippie is Script { ...@@ -86,7 +66,6 @@ contract ManageDrippie is Script {
Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); Drippie.DripAction[] memory actions = new Drippie.DripAction[](1);
actions[0] = Drippie.DripAction({ target: payable(drip.recipient), data: drip.data, value: drip.value }); actions[0] = Drippie.DripAction({ target: payable(drip.recipient), data: drip.data, value: drip.value });
_installDrip({ _installDrip({
_gelato: cfg.gelato(),
_drippie: cfg.drippie(), _drippie: cfg.drippie(),
_name: drip.name, _name: drip.name,
_config: Drippie.DripConfig({ _config: Drippie.DripConfig({
...@@ -100,126 +79,14 @@ contract ManageDrippie is Script { ...@@ -100,126 +79,14 @@ contract ManageDrippie is Script {
} }
} }
/// @notice Generates the data for a Gelato task that would trigger a drip.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip.
/// @return taskData_ Gelato task data.
function _makeGelatoDripTaskData(
Drippie _drippie,
string memory _name
)
internal
view
returns (GelatoTaskData memory taskData_)
{
// Get the drip interval.
uint256 dripInterval = _drippie.getDripInterval(_name);
// Set up module types.
GelatoDataTypes.Module[] memory modules = new GelatoDataTypes.Module[](2);
modules[0] = GelatoDataTypes.Module.PROXY;
modules[1] = GelatoDataTypes.Module.TRIGGER;
// Interval is in milliseconds, so we should be multiplying by 1000.
// We then want to attempt to trigger the drip 10x per interval, so we divide by 10.
// Total multiplier is then 1000 / 10 = 100.
uint128 interval = uint128(dripInterval) * 100;
// Create arguments for the PROXY and TRIGGER modules.
bytes[] memory args = new bytes[](2);
args[0] = abi.encode(_name);
args[1] = abi.encode(uint128(GelatoDataTypes.TriggerType.TIME), abi.encode(uint128(0), interval));
// Create the task data.
taskData_ = GelatoTaskData({
taskCreator: msg.sender,
execAddress: address(_drippie),
execData: abi.encodeCall(Drippie.drip, (_name)),
moduleData: GelatoDataTypes.ModuleData({ modules: modules, args: args }),
feeToken: address(0)
});
}
/// @notice Starts a gelato drip task.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip being triggered.
function _startGelatoDripTask(IGelato _gelato, Drippie _drippie, string memory _name) internal {
GelatoTaskData memory taskData = _makeGelatoDripTaskData({ _drippie: _drippie, _name: _name });
_gelato.createTask({
execAddress: taskData.execAddress,
execData: taskData.execData,
moduleData: taskData.moduleData,
feeToken: taskData.feeToken
});
}
/// @notice Determines if a gelato drip task is active or not.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip being triggered.
/// @return active_ True if the task is active, false otherwise.
function _isGelatoDripTaskActive(
IGelato _gelato,
Drippie _drippie,
string memory _name
)
internal
view
returns (bool active_)
{
GelatoTaskData memory taskData = _makeGelatoDripTaskData({ _drippie: _drippie, _name: _name });
bytes32 taskId = GelatoTaskId.getTaskId({
taskCreator: taskData.taskCreator,
execAddress: taskData.execAddress,
execSelector: GelatoBytes.memorySliceSelector(taskData.execData),
moduleData: taskData.moduleData,
feeToken: taskData.feeToken
});
// Iterate over the task IDs to see if the task is active.
bytes32[] memory taskIds = _gelato.getTaskIdsByUser(taskData.taskCreator);
for (uint256 i = 0; i < taskIds.length; i++) {
if (taskIds[i] == taskId) {
active_ = true;
}
}
}
/// @notice Pauses a gelato drip task.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract.
/// @param _name The name of the drip being triggered.
function _pauseGelatoDripTask(IGelato _gelato, Drippie _drippie, string memory _name) internal {
GelatoTaskData memory taskData = _makeGelatoDripTaskData({ _drippie: _drippie, _name: _name });
_gelato.cancelTask(
GelatoTaskId.getTaskId({
taskCreator: taskData.taskCreator,
execAddress: taskData.execAddress,
execSelector: GelatoBytes.memorySliceSelector(taskData.execData),
moduleData: taskData.moduleData,
feeToken: taskData.feeToken
})
);
}
/// @notice Installs a drip in the drippie contract. /// @notice Installs a drip in the drippie contract.
/// @param _gelato The gelato contract.
/// @param _drippie The drippie contract. /// @param _drippie The drippie contract.
/// @param _name The name of the drip. /// @param _name The name of the drip.
/// @param _config The configuration of the drip. /// @param _config The configuration of the drip.
function _installDrip( function _installDrip(Drippie _drippie, string memory _name, Drippie.DripConfig memory _config) internal {
IGelato _gelato,
Drippie _drippie,
string memory _name,
Drippie.DripConfig memory _config
)
internal
{
if (_drippie.getDripStatus(_name) == Drippie.DripStatus.NONE) { if (_drippie.getDripStatus(_name) == Drippie.DripStatus.NONE) {
console.log("installing %s", _name); console.log("installing %s", _name);
_drippie.create(_name, _config); _drippie.create(_name, _config);
_startGelatoDripTask(_gelato, _drippie, _name);
console.log("%s installed successfully", _name); console.log("%s installed successfully", _name);
} else { } else {
console.log("%s already installed", _name); console.log("%s already installed", _name);
......
[
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "execute_",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "treasury",
"type": "address"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"indexed": false,
"internalType": "struct CheckGelatoLow.Params",
"name": "params",
"type": "tuple"
}
],
"name": "_EventToExposeStructInABI__Params",
"type": "event"
}
]
\ No newline at end of file
[
{
"bytes": "32",
"label": "name",
"offset": 0,
"slot": "0",
"type": "string"
}
]
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Interfaces
import { IGelatoTreasury } from "interfaces/vendor/IGelatoTreasury.sol";
import { IDripCheck } from "src/periphery/drippie/IDripCheck.sol";
/// @title CheckGelatoLow
/// @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.
contract CheckGelatoLow is IDripCheck {
struct Params {
address treasury;
uint256 threshold;
address recipient;
}
/// @notice External event used to help client-side tooling encode parameters.
/// @param params Parameters to encode.
event _EventToExposeStructInABI__Params(Params params);
/// @inheritdoc IDripCheck
string public name = "CheckGelatoLow";
/// @inheritdoc IDripCheck
function check(bytes memory _params) external view returns (bool execute_) {
Params memory params = abi.decode(_params, (Params));
// Gelato represents ETH as 0xeeeee....eeeee.
address eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
// Get the total deposited amount.
uint256 deposited = IGelatoTreasury(params.treasury).totalDepositedAmount(params.recipient, eth);
// Get the total withdrawn amount.
uint256 withdrawn = IGelatoTreasury(params.treasury).totalWithdrawnAmount(params.recipient, eth);
// Figure out the current balance.
uint256 balance = deposited - withdrawn;
// Check if the balance is below the threshold.
execute_ = balance < params.threshold;
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { CheckGelatoLow, IGelatoTreasury } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol";
/// @title MockGelatoTreasury
/// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary setting of balances.
contract MockGelatoTreasury is IGelatoTreasury {
mapping(address => mapping(address => uint256)) private totalDeposited;
mapping(address => mapping(address => uint256)) private totalWithdrawn;
function totalDepositedAmount(address _user, address _token) external view override returns (uint256) {
return totalDeposited[_token][_user];
}
function totalWithdrawnAmount(address _user, address _token) external view override returns (uint256) {
return totalWithdrawn[_token][_user];
}
function setTotalDepositedAmount(address _user, address _token, uint256 _amount) external {
totalDeposited[_token][_user] = _amount;
}
}
/// @title CheckGelatoLowTest
/// @notice Tests the CheckGelatoLow contract via fuzzing both the success and failure cases.
contract CheckGelatoLowTest is Test {
/// @notice An instance of the CheckGelatoLow contract.
CheckGelatoLow c;
/// @notice An instance of the MockGelatoTreasury contract.
MockGelatoTreasury gelato;
/// @notice The account Gelato uses to represent ether
address internal constant eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @notice Deploy the `CheckGelatoLow` and `MockGelatoTreasury` contracts.
function setUp() external {
c = new CheckGelatoLow();
gelato = new MockGelatoTreasury();
}
/// @notice Test that the `name` function returns the correct value.
function test_name_succeeds() external view {
assertEq(c.name(), "CheckGelatoLow");
}
/// @notice Fuzz the `check` function and assert that it always returns true
/// when the user's balance in the treasury is less than the threshold.
function testFuzz_check_succeeds(uint256 _threshold, address _recipient) external view {
CheckGelatoLow.Params memory p =
CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
vm.assume(
gelato.totalDepositedAmount(_recipient, eth) - gelato.totalWithdrawnAmount(_recipient, eth) < _threshold
);
assertEq(c.check(abi.encode(p)), true);
}
/// @notice Fuzz the `check` function and assert that it always returns false
/// when the user's balance in the treasury is greater than or equal
/// to the threshold.
function testFuzz_check_highBalance_fails(uint256 _threshold, address _recipient) external {
CheckGelatoLow.Params memory p =
CheckGelatoLow.Params({ treasury: address(gelato), threshold: _threshold, recipient: _recipient });
gelato.setTotalDepositedAmount(_recipient, eth, _threshold);
assertEq(c.check(abi.encode(p)), false);
}
}
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