Commit 184f6b50 authored by Kelvin Fichter's avatar Kelvin Fichter

feat(ctb): deploy drippie to Goerli

Deploys the updated version of Drippie to Goerli. Drippie has been fully
configured and seeded with a significant amount of Goerli ETH.
parent 0b7a9f7f
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0x9C6373dE60c2D3297b18A8f964618ac46E011B58',
l2ProxyOwnerAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistName: 'Optimist',
optimistSymbol: 'OPTIMIST',
attestorAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
}
export default config
import { ethers } from 'ethers'
import { DrippieConfig, Time } from '../../src'
const config: DrippieConfig = {
BatcherBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0x7431310e026b69bfc676c0013e12a1a11411eec9',
threshold: ethers.utils.parseEther('50'),
},
actions: [
{
target: '0x7431310e026b69bfc676c0013e12a1a11411eec9',
value: ethers.utils.parseEther('100'),
},
],
},
ProposerBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0x02b1786a85ec3f71fbbba46507780db7cf9014f6',
threshold: ethers.utils.parseEther('50'),
},
actions: [
{
target: '0x02b1786a85ec3f71fbbba46507780db7cf9014f6',
value: ethers.utils.parseEther('100'),
},
],
},
GelatoBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckGelatoLow',
checkparams: {
treasury: '0xf381dfd7a139caab83c26140e5595c0b85ddadcd',
recipient: '0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
threshold: ethers.utils.parseEther('0.1'),
},
actions: [
{
target: '0xf381dfd7a139caab83c26140e5595c0b85ddadcd',
value: ethers.utils.parseEther('1'),
data: {
fn: 'depositFunds',
args: [
// receiver
'0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
// token
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// amount
ethers.utils.parseEther('1'),
],
},
},
],
},
}
export default config
{
"address": "0x7eC64a8a591bFf829ff6C8be76074D540ACb813F",
"abi": [
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct CheckBalanceHigh.Params",
"name": "params",
"type": "tuple"
}
],
"name": "_EventToExposeStructInABI__Params",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x1d1543b42c1a5404d3b1794a399239d1e3f40c10e865d0f2e4a362a349d30a6e",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58",
"contractAddress": null,
"transactionIndex": 76,
"gasUsed": "176628",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x0b10b7612a1de5326e045069eb60151e2fa615ce7d342b13acb14ba165edddb1",
"transactionHash": "0x1d1543b42c1a5404d3b1794a399239d1e3f40c10e865d0f2e4a362a349d30a6e",
"logs": [],
"blockNumber": 8182666,
"cumulativeGasUsed": "10050194",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988",
"metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceHigh.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckBalanceHigh\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's balance is above a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":\"CheckBalanceHigh\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceHigh\\n * @notice DripCheck for checking if an account's balance is above a given threshold.\\n */\\ncontract CheckBalanceHigh is IDripCheck {\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target balance is above threshold.\\n return params.target.balance > params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0xcb27d9e50a7c32406872b8fdc4ca62ee0d27372eb9077657f6d16f3cd3b58c85\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212203818d112b628fa60d8cffe88e7198c860e268b9375b8b118dacdbf531c397ef864736f6c63430008100033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea26469706673582212203818d112b628fa60d8cffe88e7198c860e268b9375b8b118dacdbf531c397ef864736f6c63430008100033",
"devdoc": {
"events": {
"_EventToExposeStructInABI__Params((address,uint256))": {
"params": {
"params": "Parameters to encode."
}
}
},
"kind": "dev",
"methods": {
"check(bytes)": {
"params": {
"_params": "Encoded parameters for the drip check."
},
"returns": {
"_0": "Whether the drip should be executed."
}
}
},
"title": "CheckBalanceHigh",
"version": 1
},
"userdoc": {
"events": {
"_EventToExposeStructInABI__Params((address,uint256))": {
"notice": "External event used to help client-side tooling encode parameters."
}
},
"kind": "user",
"methods": {
"check(bytes)": {
"notice": "Checks whether a drip should be executable."
}
},
"notice": "DripCheck for checking if an account's balance is above a given threshold.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"address": "0x381a4eFC2A2C914eA1889722bB4B44Fa6BD5b640",
"abi": [
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct CheckBalanceLow.Params",
"name": "params",
"type": "tuple"
}
],
"name": "_EventToExposeStructInABI__Params",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x27c46f8d4f3a93eb7388ebd9be8b8c4628a30de6b358f721e810e9c881a279e5",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58",
"contractAddress": null,
"transactionIndex": 67,
"gasUsed": "176640",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x4a6c891cb4fae11711c0494dae3ec8e90c64b1ff33e424de9db865098471e10d",
"transactionHash": "0x27c46f8d4f3a93eb7388ebd9be8b8c4628a30de6b358f721e810e9c881a279e5",
"logs": [],
"blockNumber": 8182667,
"cumulativeGasUsed": "14037277",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988",
"metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckBalanceLow\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's balance is below a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":\"CheckBalanceLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceLow\\n * @notice DripCheck for checking if an account's balance is below a given threshold.\\n */\\ncontract CheckBalanceLow is IDripCheck {\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target ETH balance is below threshold.\\n return params.target.balance < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x6a1187a80093770931296d3360b1ecc7d17f69157fe88f628989b257548b564b\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220cc86d01120737597addcccffd841244801dcb64ce402d73b8d8569a52348996464736f6c63430008100033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220cc86d01120737597addcccffd841244801dcb64ce402d73b8d8569a52348996464736f6c63430008100033",
"devdoc": {
"events": {
"_EventToExposeStructInABI__Params((address,uint256))": {
"params": {
"params": "Parameters to encode."
}
}
},
"kind": "dev",
"methods": {
"check(bytes)": {
"params": {
"_params": "Encoded parameters for the drip check."
},
"returns": {
"_0": "Whether the drip should be executed."
}
}
},
"title": "CheckBalanceLow",
"version": 1
},
"userdoc": {
"events": {
"_EventToExposeStructInABI__Params((address,uint256))": {
"notice": "External event used to help client-side tooling encode parameters."
}
},
"kind": "user",
"methods": {
"check(bytes)": {
"notice": "Checks whether a drip should be executable."
}
},
"notice": "DripCheck for checking if an account's balance is below a given threshold.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"address": "0x4f7CFc43f6D262a085F3b946cAC69E7a8E39BBAa",
"abi": [
{
"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"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x6426a895e674bb8849028c089ed41d1b9179d8392adc9ad6d225cd53c53fe49c",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58",
"contractAddress": null,
"transactionIndex": 61,
"gasUsed": "222032",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x4b8ed6e59a8559084820c6f9514b9ddec7de519cbf6940131b43f939c63c4307",
"transactionHash": "0x6426a895e674bb8849028c089ed41d1b9179d8392adc9ad6d225cd53c53fe49c",
"logs": [],
"blockNumber": 8182670,
"cumulativeGasUsed": "12472395",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988",
"metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"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\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256,address))\":{\"params\":{\"params\":\"Parameters to encode.\"}}},\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckGelatoLow\",\"version\":1},\"userdoc\":{\"events\":{\"_EventToExposeStructInABI__Params((address,uint256,address))\":{\"notice\":\"External event used to help client-side tooling encode parameters.\"}},\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck for checking if an account's Gelato ETH balance is below some threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":\"CheckGelatoLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\ninterface IGelatoTreasury {\\n function userTokenBalance(address _user, address _token) external view returns (uint256);\\n}\\n\\n/**\\n * @title CheckGelatoLow\\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\\n */\\ncontract CheckGelatoLow is IDripCheck {\\n struct Params {\\n address treasury;\\n uint256 threshold;\\n address recipient;\\n }\\n\\n /**\\n * @notice External event used to help client-side tooling encode parameters.\\n *\\n * @param params Parameters to encode.\\n */\\n event _EventToExposeStructInABI__Params(Params params);\\n\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check GelatoTreasury ETH balance is below threshold.\\n return\\n IGelatoTreasury(params.treasury).userTokenBalance(\\n params.recipient,\\n // Gelato represents ETH as 0xeeeee....eeeee\\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\\n ) < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x1a127a2c8955525cc2e5cd3c6703edc785c662a79222f524df4574cf47ddd864\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5061030c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220d5d7b760af134f89109f20dbf88fd89e78bb4b81bed97f9aa45772b3775b388964736f6c63430008100033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e366004610160565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610258565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c890604401602060405180830381865afa158015610105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012991906102bd565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561017257600080fd5b813567ffffffffffffffff8082111561018a57600080fd5b818401915084601f83011261019e57600080fd5b8135818111156101b0576101b0610131565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f6576101f6610131565b8160405282815287602084870101111561020f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461025357600080fd5b919050565b60006060828403121561026a57600080fd5b6040516060810181811067ffffffffffffffff8211171561028d5761028d610131565b6040526102998361022f565b8152602083015160208201526102b16040840161022f565b60408201529392505050565b6000602082840312156102cf57600080fd5b505191905056fea2646970667358221220d5d7b760af134f89109f20dbf88fd89e78bb4b81bed97f9aa45772b3775b388964736f6c63430008100033",
"devdoc": {
"events": {
"_EventToExposeStructInABI__Params((address,uint256,address))": {
"params": {
"params": "Parameters to encode."
}
}
},
"kind": "dev",
"methods": {
"check(bytes)": {
"params": {
"_params": "Encoded parameters for the drip check."
},
"returns": {
"_0": "Whether the drip should be executed."
}
}
},
"title": "CheckGelatoLow",
"version": 1
},
"userdoc": {
"events": {
"_EventToExposeStructInABI__Params((address,uint256,address))": {
"notice": "External event used to help client-side tooling encode parameters."
}
},
"kind": "user",
"methods": {
"check(bytes)": {
"notice": "Checks whether a drip should be executable."
}
},
"notice": "DripCheck for checking if an account's Gelato ETH balance is below some threshold.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"address": "0x5c741a38cb11424711231777D71689C458eE835D",
"abi": [
{
"inputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "pure",
"type": "function"
}
],
"transactionHash": "0xeacb73acd8f3d741e1a4a136e95cec43d21aef36b95611cdaa86c87066bfd087",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58",
"contractAddress": null,
"transactionIndex": 81,
"gasUsed": "139230",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x396e72234d59683880032c4c9e6fd61a46b839b61c644c7bd180e02d565c3b14",
"transactionHash": "0xeacb73acd8f3d741e1a4a136e95cec43d21aef36b95611cdaa86c87066bfd087",
"logs": [],
"blockNumber": 8182671,
"cumulativeGasUsed": "17047212",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "2373b7ba869baea4fec58e6e7f7b8988",
"metadata": "{\"compiler\":{\"version\":\"0.8.16+commit.07a7930e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"check(bytes)\":{\"params\":{\"_params\":\"Encoded parameters for the drip check.\"},\"returns\":{\"_0\":\"Whether the drip should be executed.\"}}},\"title\":\"CheckTrue\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"check(bytes)\":{\"notice\":\"Checks whether a drip should be executable.\"}},\"notice\":\"DripCheck that always returns true.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":\"CheckTrue\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n /**\\n * @notice Checks whether a drip should be executable.\\n *\\n * @param _params Encoded parameters for the drip check.\\n *\\n * @return Whether the drip should be executed.\\n */\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xb52c89360566b2963dfd82cb2cc23f0c3ce4503a69e8563878e8aa80b6c60b3f\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.16;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckTrue\\n * @notice DripCheck that always returns true.\\n */\\ncontract CheckTrue is IDripCheck {\\n /**\\n * @inheritdoc IDripCheck\\n */\\n function check(bytes memory) external pure returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0xf2f5474f12983c30ca4fe9d19e7f88e6d2262e4a6f779e86b4a2117498fdbea5\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5061018c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212200bb899cb0e5f9dce180ebe72a1dfade46ffc5ec3cab398d1f2af09e8b9ce76d164736f6c63430008100033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212200bb899cb0e5f9dce180ebe72a1dfade46ffc5ec3cab398d1f2af09e8b9ce76d164736f6c63430008100033",
"devdoc": {
"kind": "dev",
"methods": {
"check(bytes)": {
"params": {
"_params": "Encoded parameters for the drip check."
},
"returns": {
"_0": "Whether the drip should be executed."
}
}
},
"title": "CheckTrue",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"check(bytes)": {
"notice": "Checks whether a drip should be executable."
}
},
"notice": "DripCheck that always returns true.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"language": "Solidity",
"sources": {
"contracts/testing/helpers/TestERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n constructor() ERC20(\"TEST\", \"TST\", 18) {}\n\n function mint(address to, uint256 value) public {\n _mint(to, value);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * @notice Emitted when ETH is received by this address.\n *\n * @param from Address that sent ETH to this contract.\n * @param amount Amount of ETH received.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * @notice Emitted when ETH is withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param amount ETH amount withdrawn.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param amount ERC20 amount withdrawn.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param id Token ID being withdrawn.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * @notice Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * @notice Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * @notice Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n (bool success, ) = _to.call{ value: _amount }(\"\");\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * @notice Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * @notice Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * @notice Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _value ETH value to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(address _target, bytes memory _data)\n external\n payable\n onlyOwner\n returns (bool, bytes memory)\n {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck)\n * and an execution interval. Drips cannot be executed faster than the execution interval.\n * Drips can trigger arbitrary contract calls where the calling contract is this contract\n * address. Drips can also send ETH value, which makes them ideal for keeping addresses\n * sufficiently funded with ETH. Drippie is designed to be connected with smart contract\n * automation services so that drips can be executed automatically. However, Drippie is\n * specifically designed to be separated from these services so that trust assumptions are\n * better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * @notice Enum representing different status options for a given drip.\n *\n * @custom:value NONE Drip does not exist.\n * @custom:value PAUSED Drip is paused and cannot be executed until reactivated.\n * @custom:value ACTIVE Drip is active and can be executed.\n * @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.\n */\n enum DripStatus {\n NONE,\n PAUSED,\n ACTIVE,\n ARCHIVED\n }\n\n /**\n * @notice Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * @notice Represents the configuration for a given drip.\n */\n struct DripConfig {\n bool reentrant;\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * @notice Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n uint256 count;\n }\n\n /**\n * @notice Emitted when a new drip is created.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param config Config for the created drip.\n */\n event DripCreated(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n DripConfig config\n );\n\n /**\n * @notice Emitted when a drip status is updated.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param status New drip status.\n */\n event DripStatusUpdated(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n DripStatus status\n );\n\n /**\n * @notice Emitted when a drip is executed.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param executor Address that executed the drip.\n * @param timestamp Time when the drip was executed.\n */\n event DripExecuted(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n address executor,\n uint256 timestamp\n );\n\n /**\n * @notice Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * @notice Creates a new drip with the given name and configuration. Once created, drips cannot\n * be modified in any way (this is a security measure). If you want to update a drip,\n * simply pause (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string calldata _name, DripConfig calldata _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // Validate the drip interval, only allowing an interval of zero if the drip has explicitly\n // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable\n // within the same block (of course, restricted by gas limits).\n if (_config.reentrant) {\n require(\n _config.interval == 0,\n \"Drippie: if allowing reentrant drip, must set interval to zero\"\n );\n } else {\n require(\n _config.interval > 0,\n \"Drippie: interval must be greater than zero if drip is not reentrant\"\n );\n }\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.reentrant = _config.reentrant;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _name, _config);\n }\n\n /**\n * @notice Sets the status for a given drip. The behavior of this function depends on the\n * status that the user is trying to set. A drip can always move between ACTIVE and\n * PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back\n * to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string calldata _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Load the drip status once to avoid unnecessary SLOADs.\n DripStatus curr = drips[_name].status;\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n curr != DripStatus.NONE,\n \"Drippie: drip with that name does not exist and cannot be updated\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n curr != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived and cannot be updated\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n curr != _status,\n \"Drippie: cannot set drip status to the same status as its current status\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n curr == DripStatus.PAUSED,\n \"Drippie: drip must first be paused before being archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, _name, _status);\n }\n\n /**\n * @notice Checks if a given drip is executable.\n *\n * @param _name Drip to check.\n *\n * @return True if the drip is executable, reverts otherwise.\n */\n function executable(string calldata _name) public view returns (bool) {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Alright, we're good to execute.\n return true;\n }\n\n /**\n * @notice Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative\n * signal that the drip should be executable according to the drip parameters, drip\n * check, and drip interval. Note that drip parameters are read entirely from the state\n * and are not supplied as user input, so there should not be any way for a\n * non-authorized user to influence the behavior of the drip. Note that the drip check\n * is executed only **once** at the beginning of the call to the drip function and will\n * not be executed again between the drip actions within this call.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string calldata _name) external {\n DripState storage state = drips[_name];\n\n // Make sure the drip can be executed. Since executable reverts if the drip is not ready to\n // be executed, we don't need to do an assertion that the returned value is true.\n executable(_name);\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Update the number of times this drip has been executed. Although this increases the cost\n // of using Drippie, it slightly simplifies the client-side by not having to worry about\n // counting drips via events. Useful for monitoring the rate of drip execution.\n state.count++;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, _name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n /**\n * @notice Checks whether a drip should be executable.\n *\n * @param _params Encoded parameters for the drip check.\n *\n * @return Whether the drip should be executed.\n */\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n struct Params {\n address target;\n uint256 threshold;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n struct Params {\n address target;\n uint256 threshold;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
},
"contracts/testing/helpers/TestERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"TEST\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n function tokenURI(uint256) public pure virtual override returns (string memory) {}\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
import { task } from 'hardhat/config'
import { LedgerSigner } from '@ethersproject/hardware-wallets'
import { PopulatedTransaction } from 'ethers'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { isSameConfig, getDrippieConfig } from '../src'
......
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