Sepolia Testnet

Contract

0x859E31b3848Ec384012EECc72C5c49821008296C

Overview

ETH Balance

10,757 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Transfer64436332024-08-05 20:05:0063 days ago1722888300IN
0x859E31b3...21008296C
20,000 ETH0.0002350610.45145453
Transfer64436262024-08-05 20:03:2463 days ago1722888204IN
0x859E31b3...21008296C
10 ETH0.0002365410.51736883
Status60597332024-06-07 18:19:12122 days ago1717784352IN
0x859E31b3...21008296C
0 ETH0.000008130.24687144
Create60597332024-06-07 18:19:12122 days ago1717784352IN
0x859E31b3...21008296C
0 ETH0.000059680.24687144
Status60550202024-06-07 2:04:00123 days ago1717725840IN
0x859E31b3...21008296C
0 ETH0.000000020.00073209
Create60550202024-06-07 2:04:00123 days ago1717725840IN
0x859E31b3...21008296C
0 ETH0.000000170.00073209
Status60550202024-06-07 2:04:00123 days ago1717725840IN
0x859E31b3...21008296C
0 ETH0.000000020.00073209
Create60550202024-06-07 2:04:00123 days ago1717725840IN
0x859E31b3...21008296C
0 ETH0.000000170.00073209
Status60550202024-06-07 2:04:00123 days ago1717725840IN
0x859E31b3...21008296C
0 ETH0.000000020.00073209
Create60550202024-06-07 2:04:00123 days ago1717725840IN
0x859E31b3...21008296C
0 ETH0.000000170.00073209
Transfer54749742024-03-13 4:07:24209 days ago1710302844IN
0x859E31b3...21008296C
300 ETH0.000037061.64809124
Status54610692024-03-11 4:29:24211 days ago1710131364IN
0x859E31b3...21008296C
0 ETH0.000106533.15107669
Create54610682024-03-11 4:29:12211 days ago1710131352IN
0x859E31b3...21008296C
0 ETH0.0010573.14878748
Status54610672024-03-11 4:29:00211 days ago1710131340IN
0x859E31b3...21008296C
0 ETH0.000106073.14413119
Create54610662024-03-11 4:28:48211 days ago1710131328IN
0x859E31b3...21008296C
0 ETH0.001056923.14910068
Status54379372024-03-07 22:09:12214 days ago1709849352IN
0x859E31b3...21008296C
0 ETH0.000103463.06022871
Create54379362024-03-07 22:09:00214 days ago1709849340IN
0x859E31b3...21008296C
0 ETH0.000681793.06539533
Status54379352024-03-07 22:08:48214 days ago1709849328IN
0x859E31b3...21008296C
0 ETH0.00010323.05911811
Create54379342024-03-07 22:08:36214 days ago1709849316IN
0x859E31b3...21008296C
0 ETH0.000679163.05436913
Status51613282024-01-27 2:50:48255 days ago1706323848IN
0x859E31b3...21008296C
0 ETH0.000107573.18202946
Create51613282024-01-27 2:50:48255 days ago1706323848IN
0x859E31b3...21008296C
0 ETH0.001068163.18202946
Status51613282024-01-27 2:50:48255 days ago1706323848IN
0x859E31b3...21008296C
0 ETH0.000107343.18202946
Create51613282024-01-27 2:50:48255 days ago1706323848IN
0x859E31b3...21008296C
0 ETH0.001067973.18202946
Transfer50968532024-01-16 14:52:48265 days ago1705416768IN
0x859E31b3...21008296C
42,000 ETH0.0021673996.3674
Transfer50934102024-01-16 0:47:36266 days ago1705366056IN
0x859E31b3...21008296C
600 ETH0.0015176867.47963923
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
68378982024-10-08 11:26:1256 mins ago1728386772
0x859E31b3...21008296C
20 ETH
68356482024-10-08 2:26:129 hrs ago1728354372
0x859E31b3...21008296C
20 ETH
68352722024-10-08 0:56:1211 hrs ago1728348972
0x859E31b3...21008296C
20 ETH
68349092024-10-07 23:26:1212 hrs ago1728343572
0x859E31b3...21008296C
20 ETH
68345382024-10-07 21:56:1214 hrs ago1728338172
0x859E31b3...21008296C
20 ETH
68341812024-10-07 20:26:1215 hrs ago1728332772
0x859E31b3...21008296C
20 ETH
68338052024-10-07 18:56:2417 hrs ago1728327384
0x859E31b3...21008296C
20 ETH
68334452024-10-07 17:26:1218 hrs ago1728321972
0x859E31b3...21008296C
20 ETH
68189042024-10-05 9:56:123 days ago1728122172
0x859E31b3...21008296C
20 ETH
68179772024-10-05 6:26:123 days ago1728109572
0x859E31b3...21008296C
20 ETH
68175692024-10-05 4:56:123 days ago1728104172
0x859E31b3...21008296C
20 ETH
68171722024-10-05 3:26:123 days ago1728098772
0x859E31b3...21008296C
20 ETH
68167792024-10-05 1:56:123 days ago1728093372
0x859E31b3...21008296C
20 ETH
68163752024-10-05 0:26:123 days ago1728087972
0x859E31b3...21008296C
20 ETH
68159782024-10-04 22:56:123 days ago1728082572
0x859E31b3...21008296C
20 ETH
68100112024-10-04 0:26:124 days ago1728001572
0x859E31b3...21008296C
20 ETH
68096222024-10-03 22:57:004 days ago1727996220
0x859E31b3...21008296C
20 ETH
68088362024-10-03 19:56:124 days ago1727985372
0x859E31b3...21008296C
20 ETH
68056522024-10-03 7:56:125 days ago1727942172
0x859E31b3...21008296C
20 ETH
68048382024-10-03 4:56:125 days ago1727931372
0x859E31b3...21008296C
20 ETH
68044432024-10-03 3:26:125 days ago1727925972
0x859E31b3...21008296C
20 ETH
68040472024-10-03 1:56:125 days ago1727920572
0x859E31b3...21008296C
20 ETH
68036442024-10-03 0:26:125 days ago1727915172
0x859E31b3...21008296C
20 ETH
68032452024-10-02 22:56:125 days ago1727909772
0x859E31b3...21008296C
20 ETH
67987492024-10-02 5:56:126 days ago1727848572
0x859E31b3...21008296C
20 ETH
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x7050443C...88B4a7cE3
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Drippie

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 999999 runs

Other Settings:
london EvmVersion
File 1 of 7 : Drippie.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { AssetReceiver } from "../AssetReceiver.sol";
import { IDripCheck } from "./IDripCheck.sol";

/// @title Drippie
/// @notice Drippie is a system for managing automated contract interactions. A specific interaction
///         is called a "drip" and can be executed according to some condition (called a dripcheck)
///         and an execution interval. Drips cannot be executed faster than the execution interval.
///         Drips can trigger arbitrary contract calls where the calling contract is this contract
///         address. Drips can also send ETH value, which makes them ideal for keeping addresses
///         sufficiently funded with ETH. Drippie is designed to be connected with smart contract
///         automation services so that drips can be executed automatically. However, Drippie is
///         specifically designed to be separated from these services so that trust assumptions are
///         better compartmentalized.
contract Drippie is AssetReceiver {
    /// @notice Enum representing different status options for a given drip.
    /// @custom:value NONE     Drip does not exist.
    /// @custom:value PAUSED   Drip is paused and cannot be executed until reactivated.
    /// @custom:value ACTIVE   Drip is active and can be executed.
    /// @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.
    enum DripStatus {
        NONE,
        PAUSED,
        ACTIVE,
        ARCHIVED
    }

    /// @notice Represents a drip action.
    struct DripAction {
        address payable target;
        bytes data;
        uint256 value;
    }

    /// @notice Represents the configuration for a given drip.
    struct DripConfig {
        bool reentrant;
        uint256 interval;
        IDripCheck dripcheck;
        bytes checkparams;
        DripAction[] actions;
    }

    /// @notice Represents the state of an active drip.
    struct DripState {
        DripStatus status;
        DripConfig config;
        uint256 last;
        uint256 count;
    }

    /// @notice Emitted when a new drip is created.
    /// @param nameref Indexed name parameter (hashed).
    /// @param name    Unindexed name parameter (unhashed).
    /// @param config  Config for the created drip.
    // Emit name twice because indexed version is hashed.
    event DripCreated(string indexed nameref, string name, DripConfig config);

    /// @notice Emitted when a drip status is updated.
    /// @param nameref Indexed name parameter (hashed).
    /// @param name    Unindexed name parameter (unhashed).
    /// @param status  New drip status.
    // Emit name twice because indexed version is hashed.
    event DripStatusUpdated(string indexed nameref, string name, DripStatus status);

    /// @notice Emitted when a drip is executed.
    /// @param nameref   Indexed name parameter (hashed).
    /// @param name      Unindexed name parameter (unhashed).
    /// @param executor  Address that executed the drip.
    /// @param timestamp Time when the drip was executed.
    // Emit name twice because indexed version is hashed.
    event DripExecuted(string indexed nameref, string name, address executor, uint256 timestamp);

    /// @notice Maps from drip names to drip states.
    mapping(string => DripState) public drips;

    //// @param _owner Initial contract owner.
    constructor(address _owner) AssetReceiver(_owner) { }

    /// @notice Creates a new drip with the given name and configuration. Once created, drips cannot
    ///         be modified in any way (this is a security measure). If you want to update a drip,
    ///         simply pause (and potentially archive) the existing drip and create a new one.
    /// @param _name   Name of the drip.
    /// @param _config Configuration for the drip.
    function create(string calldata _name, DripConfig calldata _config) external onlyOwner {
        // Make sure this drip doesn't already exist. We *must* guarantee that no other function
        // will ever set the status of a drip back to NONE after it's been created. This is why
        // archival is a separate status.
        require(drips[_name].status == DripStatus.NONE, "Drippie: drip with that name already exists");

        // Validate the drip interval, only allowing an interval of zero if the drip has explicitly
        // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable
        // within the same block (of course, restricted by gas limits).
        if (_config.reentrant) {
            require(_config.interval == 0, "Drippie: if allowing reentrant drip, must set interval to zero");
        } else {
            require(_config.interval > 0, "Drippie: interval must be greater than zero if drip is not reentrant");
        }

        // We initialize this way because Solidity won't let us copy arrays into storage yet.
        DripState storage state = drips[_name];
        state.status = DripStatus.PAUSED;
        state.config.reentrant = _config.reentrant;
        state.config.interval = _config.interval;
        state.config.dripcheck = _config.dripcheck;
        state.config.checkparams = _config.checkparams;

        // Solidity doesn't let us copy arrays into storage, so we push each array one by one.
        for (uint256 i = 0; i < _config.actions.length; i++) {
            state.config.actions.push(_config.actions[i]);
        }

        // Tell the world!
        emit DripCreated(_name, _name, _config);
    }

    /// @notice Sets the status for a given drip. The behavior of this function depends on the
    ///         status that the user is trying to set. A drip can always move between ACTIVE and
    ///         PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back
    ///         to ACTIVE or PAUSED.
    /// @param _name   Name of the drip to update.
    /// @param _status New drip status.
    function status(string calldata _name, DripStatus _status) external onlyOwner {
        // Make sure we can never set drip status back to NONE. A simple security measure to
        // prevent accidental overwrites if this code is ever updated down the line.
        require(_status != DripStatus.NONE, "Drippie: drip status can never be set back to NONE after creation");

        // Load the drip status once to avoid unnecessary SLOADs.
        DripStatus curr = drips[_name].status;

        // Make sure the drip in question actually exists. Not strictly necessary but there doesn't
        // seem to be any clear reason why you would want to do this, and it may save some gas in
        // the case of a front-end bug.
        require(curr != DripStatus.NONE, "Drippie: drip with that name does not exist and cannot be updated");

        // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire
        // point of archiving a drip.
        require(curr != DripStatus.ARCHIVED, "Drippie: drip with that name has been archived and cannot be updated");

        // Although not strictly necessary, we make sure that the status here is actually changing.
        // This may save the client some gas if there's a front-end bug and the user accidentally
        // tries to "change" the status to the same value as before.
        require(curr != _status, "Drippie: cannot set drip status to the same status as its current status");

        // If the user is trying to archive this drip, make sure the drip has been paused. We do
        // not allow users to archive active drips so that the effects of this action are more
        // abundantly clear.
        if (_status == DripStatus.ARCHIVED) {
            require(curr == DripStatus.PAUSED, "Drippie: drip must first be paused before being archived");
        }

        // If we made it here then we can safely update the status.
        drips[_name].status = _status;
        emit DripStatusUpdated(_name, _name, _status);
    }

    /// @notice Checks if a given drip is executable.
    /// @param _name Drip to check.
    /// @return True if the drip is executable, reverts otherwise.
    function executable(string calldata _name) public view returns (bool) {
        DripState storage state = drips[_name];

        // Only allow active drips to be executed, an obvious security measure.
        require(state.status == DripStatus.ACTIVE, "Drippie: selected drip does not exist or is not currently active");

        // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This
        // is a safety measure that prevents a malicious recipient from, e.g., spending all of
        // their funds and repeatedly requesting new drips. Limits the potential impact of a
        // compromised recipient to just a single drip interval, after which the drip can be paused
        // by the owner address.
        require(
            state.last + state.config.interval <= block.timestamp,
            "Drippie: drip interval has not elapsed since last drip"
        );

        // Make sure we're allowed to execute this drip.
        require(
            state.config.dripcheck.check(state.config.checkparams),
            "Drippie: dripcheck failed so drip is not yet ready to be triggered"
        );

        // Alright, we're good to execute.
        return true;
    }

    /// @notice Triggers a drip. This function is deliberately left as a public function because the
    ///         assumption being made here is that setting the drip to ACTIVE is an affirmative
    ///         signal that the drip should be executable according to the drip parameters, drip
    ///         check, and drip interval. Note that drip parameters are read entirely from the state
    ///         and are not supplied as user input, so there should not be any way for a
    ///         non-authorized user to influence the behavior of the drip. Note that the drip check
    ///         is executed only **once** at the beginning of the call to the drip function and will
    ///         not be executed again between the drip actions within this call.
    /// @param _name Name of the drip to trigger.
    function drip(string calldata _name) external {
        DripState storage state = drips[_name];

        // Make sure the drip can be executed. Since executable reverts if the drip is not ready to
        // be executed, we don't need to do an assertion that the returned value is true.
        executable(_name);

        // Update the last execution time for this drip before the call. Note that it's entirely
        // possible for a drip to be executed multiple times per block or even multiple times
        // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users
        // should set a drip interval of 1 if they'd like the drip to be executed only once per
        // block (since this will then prevent re-entrancy).
        state.last = block.timestamp;

        // Update the number of times this drip has been executed. Although this increases the cost
        // of using Drippie, it slightly simplifies the client-side by not having to worry about
        // counting drips via events. Useful for monitoring the rate of drip execution.
        state.count++;

        // Execute each action in the drip. We allow drips to have multiple actions because there
        // are scenarios in which a contract must do multiple things atomically. For example, the
        // contract may need to withdraw ETH from one account and then deposit that ETH into
        // another account within the same transaction.
        uint256 len = state.config.actions.length;
        for (uint256 i = 0; i < len; i++) {
            // Must be marked as "storage" because copying structs into memory is not yet supported
            // by Solidity. Won't significantly reduce gas costs but at least makes it easier to
            // read what the rest of this section is doing.
            DripAction storage action = state.config.actions[i];

            // Actually execute the action. We could use ExcessivelySafeCall here but not strictly
            // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this
            // will ever happen in practice). Could save a marginal amount of gas to ignore the
            // returndata.
            // slither-disable-next-line calls-loop
            (bool success,) = action.target.call{ value: action.value }(action.data);

            // Generally should not happen, but could if there's a misconfiguration (e.g., passing
            // the wrong data to the target contract), the recipient is not payable, or
            // insufficient gas was supplied to this transaction. We revert so the drip can be
            // fixed and triggered again later. Means we cannot emit an event to alert of the
            // failure, but can reasonably be detected by off-chain services even without an event.
            // Note that this forces the drip executor to supply sufficient gas to the call
            // (assuming there is some sufficient gas limit that exists, otherwise the drip will
            // not execute).
            require(success, "Drippie: drip was unsuccessful, please check your configuration for mistakes");
        }

        emit DripExecuted(_name, _name, msg.sender, block.timestamp);
    }

    /// @notice Returns the status of a given drip.
    /// @param _name Drip to check.
    /// @return DripStatus of the given drip.
    function getDripStatus(string calldata _name) public view returns (DripStatus) {
        return drips[_name].status;
    }
}

File 2 of 7 : AssetReceiver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol";
import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol";
import { Transactor } from "./Transactor.sol";

/// @title AssetReceiver
/// @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either
///         ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.
contract AssetReceiver is Transactor {
    /// @notice Emitted when ETH is received by this address.
    /// @param from   Address that sent ETH to this contract.
    /// @param amount Amount of ETH received.
    event ReceivedETH(address indexed from, uint256 amount);

    /// @notice Emitted when ETH is withdrawn from this address.
    /// @param withdrawer Address that triggered the withdrawal.
    /// @param recipient  Address that received the withdrawal.
    /// @param amount     ETH amount withdrawn.
    event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);

    /// @notice Emitted when ERC20 tokens are withdrawn from this address.
    /// @param withdrawer Address that triggered the withdrawal.
    /// @param recipient  Address that received the withdrawal.
    /// @param asset      Address of the token being withdrawn.
    /// @param amount     ERC20 amount withdrawn.
    event WithdrewERC20(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 amount);

    /// @notice Emitted when ERC20 tokens are withdrawn from this address.
    /// @param withdrawer Address that triggered the withdrawal.
    /// @param recipient  Address that received the withdrawal.
    /// @param asset      Address of the token being withdrawn.
    /// @param id         Token ID being withdrawn.
    event WithdrewERC721(address indexed withdrawer, address indexed recipient, address indexed asset, uint256 id);

    /// @param _owner Initial contract owner.
    constructor(address _owner) Transactor(_owner) { }

    /// @notice Make sure we can receive ETH.
    receive() external payable {
        emit ReceivedETH(msg.sender, msg.value);
    }

    /// @notice Withdraws full ETH balance to the recipient.
    /// @param _to Address to receive the ETH balance.
    function withdrawETH(address payable _to) external onlyOwner {
        withdrawETH(_to, address(this).balance);
    }

    /// @notice Withdraws partial ETH balance to the recipient.
    /// @param _to     Address to receive the ETH balance.
    /// @param _amount Amount of ETH to withdraw.
    function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {
        // slither-disable-next-line reentrancy-unlimited-gas
        (bool success,) = _to.call{ value: _amount }("");
        success; // Suppress warning; We ignore the low-level call result.
        emit WithdrewETH(msg.sender, _to, _amount);
    }

    /// @notice Withdraws full ERC20 balance to the recipient.
    /// @param _asset ERC20 token to withdraw.
    /// @param _to    Address to receive the ERC20 balance.
    function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {
        withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));
    }

    /// @notice Withdraws partial ERC20 balance to the recipient.
    /// @param _asset  ERC20 token to withdraw.
    /// @param _to     Address to receive the ERC20 balance.
    /// @param _amount Amount of ERC20 to withdraw.
    function withdrawERC20(ERC20 _asset, address _to, uint256 _amount) public onlyOwner {
        // slither-disable-next-line unchecked-transfer
        _asset.transfer(_to, _amount);
        // slither-disable-next-line reentrancy-events
        emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);
    }

    /// @notice Withdraws ERC721 token to the recipient.
    /// @param _asset ERC721 token to withdraw.
    /// @param _to    Address to receive the ERC721 token.
    /// @param _id    Token ID of the ERC721 token to withdraw.
    function withdrawERC721(ERC721 _asset, address _to, uint256 _id) external onlyOwner {
        _asset.transferFrom(address(this), _to, _id);
        // slither-disable-next-line reentrancy-events
        emit WithdrewERC721(msg.sender, _to, address(_asset), _id);
    }
}

File 3 of 7 : IDripCheck.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IDripCheck {
    // DripCheck contracts that want to take parameters as inputs MUST expose a struct called
    // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it
    // possible to easily encode parameters on the client side. Solidity does not support generics
    // so it's not possible to do this with explicit typing.

    /// @notice Checks whether a drip should be executable.
    /// @param _params Encoded parameters for the drip check.
    /// @return execute_ Whether the drip should be executed.
    function check(bytes memory _params) external view returns (bool execute_);
}

File 4 of 7 : ERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 5 of 7 : ERC721.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /*//////////////////////////////////////////////////////////////
                         METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                         ERC721 APPROVAL STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];

        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        if (to.code.length != 0)
            require(
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                    ERC721TokenReceiver.onERC721Received.selector,
                "UNSAFE_RECIPIENT"
            );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        if (to.code.length != 0)
            require(
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                    ERC721TokenReceiver.onERC721Received.selector,
                "UNSAFE_RECIPIENT"
            );
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        if (to.code.length != 0)
            require(
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                    ERC721TokenReceiver.onERC721Received.selector,
                "UNSAFE_RECIPIENT"
            );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        if (to.code.length != 0)
            require(
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                    ERC721TokenReceiver.onERC721Received.selector,
                "UNSAFE_RECIPIENT"
            );
    }
}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}

File 6 of 7 : Transactor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol";

/// @title Transactor
/// @notice Transactor is a minimal contract that can send transactions.
contract Transactor is Owned {
    /// @param _owner Initial contract owner.
    constructor(address _owner) Owned(_owner) { }

    /// @notice Sends a CALL to a target address.
    /// @param _target Address to call.
    /// @param _data   Data to send with the call.
    /// @param _value  ETH value to send with the call.
    /// @return success_ Boolean success value.
    /// @return data_ Bytes data returned by the call.
    function CALL(
        address _target,
        bytes memory _data,
        uint256 _value
    )
        external
        payable
        onlyOwner
        returns (bool success_, bytes memory data_)
    {
        (success_, data_) = _target.call{ value: _value }(_data);
    }

    /// @notice Sends a DELEGATECALL to a target address.
    /// @param _target Address to call.
    /// @param _data   Data to send with the call.
    /// @return success_ Boolean success value.
    /// @return data_ Bytes data returned by the call.
    function DELEGATECALL(
        address _target,
        bytes memory _data
    )
        external
        payable
        onlyOwner
        returns (bool success_, bytes memory data_)
    {
        // slither-disable-next-line controlled-delegatecall
        (success_, data_) = _target.delegatecall(_data);
    }
}

File 7 of 7 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnerUpdated(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnerUpdated(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function setOwner(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnerUpdated(msg.sender, newOwner);
    }
}

Settings
{
  "remappings": [
    ".ignored_clones-with-immutable-args/=node_modules/.ignored_clones-with-immutable-args/src/",
    ".ignored_forge-std/=node_modules/.ignored_forge-std/src/",
    "@cwia/=lib/clones-with-immutable-args/src/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@rari-capital/solmate/=lib/solmate/",
    "clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "safe-contracts/=lib/safe-contracts/contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "metadata": {
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"nameref","type":"string"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"bool","name":"reentrant","type":"bool"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"contract IDripCheck","name":"dripcheck","type":"address"},{"internalType":"bytes","name":"checkparams","type":"bytes"},{"components":[{"internalType":"address payable","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Drippie.DripAction[]","name":"actions","type":"tuple[]"}],"indexed":false,"internalType":"struct Drippie.DripConfig","name":"config","type":"tuple"}],"name":"DripCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"nameref","type":"string"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DripExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"nameref","type":"string"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"enum Drippie.DripStatus","name":"status","type":"uint8"}],"name":"DripStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReceivedETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrewERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"WithdrewERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrewETH","type":"event"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"CALL","outputs":[{"internalType":"bool","name":"success_","type":"bool"},{"internalType":"bytes","name":"data_","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"DELEGATECALL","outputs":[{"internalType":"bool","name":"success_","type":"bool"},{"internalType":"bytes","name":"data_","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"components":[{"internalType":"bool","name":"reentrant","type":"bool"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"contract IDripCheck","name":"dripcheck","type":"address"},{"internalType":"bytes","name":"checkparams","type":"bytes"},{"components":[{"internalType":"address payable","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Drippie.DripAction[]","name":"actions","type":"tuple[]"}],"internalType":"struct Drippie.DripConfig","name":"_config","type":"tuple"}],"name":"create","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"drip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"drips","outputs":[{"internalType":"enum Drippie.DripStatus","name":"status","type":"uint8"},{"components":[{"internalType":"bool","name":"reentrant","type":"bool"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"contract IDripCheck","name":"dripcheck","type":"address"},{"internalType":"bytes","name":"checkparams","type":"bytes"},{"components":[{"internalType":"address payable","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Drippie.DripAction[]","name":"actions","type":"tuple[]"}],"internalType":"struct Drippie.DripConfig","name":"config","type":"tuple"},{"internalType":"uint256","name":"last","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"executable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"getDripStatus","outputs":[{"internalType":"enum Drippie.DripStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"enum Drippie.DripStatus","name":"_status","type":"uint8"}],"name":"status","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"_asset","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"_asset","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC721","name":"_asset","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"withdrawERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

Deployed Bytecode

0x6080604052600436106100ec5760003560e01c8063690d83201161008a5780639bc94d01116100595780639bc94d01146102e8578063e551cdaa14610308578063edee623914610328578063fc3e3eba1461033b57600080fd5b8063690d8320146102355780636e2d44ae146102555780638da5cb5b146102765780639456fbcc146102c857600080fd5b806344004cc1116100c657806344004cc1146101a55780634782f779146101c55780634d7fba6e146101e557806367148cd21461021557600080fd5b80630d8f46971461012d57806313af4035146101635780634025feb21461018557600080fd5b366101285760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561013957600080fd5b5061014d610148366004611dc1565b61036b565b60405161015a9190611e6d565b60405180910390f35b34801561016f57600080fd5b5061018361017e366004611e9d565b61039b565b005b34801561019157600080fd5b506101836101a0366004611ec1565b610491565b3480156101b157600080fd5b506101836101c0366004611ec1565b610623565b3480156101d157600080fd5b506101836101e0366004611f02565b6107b4565b3480156101f157600080fd5b50610205610200366004611ff1565b610904565b60405161015a94939291906120bc565b34801561022157600080fd5b50610183610230366004611dc1565b610b36565b34801561024157600080fd5b50610183610250366004611e9d565b610d59565b610268610263366004612212565b610de7565b60405161015a92919061226b565b34801561028257600080fd5b506000546102a39073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b3480156102d457600080fd5b506101836102e3366004612286565b610ee1565b3480156102f457600080fd5b506101836103033660046122bf565b610ffc565b34801561031457600080fd5b5061018361032336600461231a565b611537565b61026861033636600461237f565b6119bb565b34801561034757600080fd5b5061035b610356366004611dc1565b611ab1565b604051901515815260200161015a565b60006001838360405161037f9291906123cf565b9081526040519081900360200190205460ff1690505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314610512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a88460405161061691815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610719573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073d91906123ed565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa8460405161061691815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461088f576040519150601f19603f3d011682016040523d82523d6000602084013e610894565b606091505b505090508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc846040516108f791815260200190565b60405180910390a3505050565b805160208183018101805160018083529383019483019490942093905282546040805160a081018252938501805460ff90811615158652600287015494860194909452600386015473ffffffffffffffffffffffffffffffffffffffff169185019190915260048501805493909216949392909160608401916109869061240a565b80601f01602080910402602001604051908101604052809291908181526020018280546109b29061240a565b80156109ff5780601f106109d4576101008083540402835291602001916109ff565b820191906000526020600020905b8154815290600101906020018083116109e257829003601f168201915b5050505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b82821015610b1e576000848152602090819020604080516060810190915260038502909101805473ffffffffffffffffffffffffffffffffffffffff1682526001810180549293919291840191610a839061240a565b80601f0160208091040260200160405190810160405280929190818152602001828054610aaf9061240a565b8015610afc5780601f10610ad157610100808354040283529160200191610afc565b820191906000526020600020905b815481529060010190602001808311610adf57829003601f168201915b5050505050815260200160028201548152505081526020019060010190610a2d565b50505091525050600682015460079092015490919084565b600060018383604051610b4a9291906123cf565b90815260200160405180910390209050610b648383611ab1565b50426006820155600781018054906000610b7d8361248c565b9091555050600581015460005b81811015610cfd576000836001016004018281548110610bac57610bac6124c4565b6000918252602082206003909102018054600282015460405192945073ffffffffffffffffffffffffffffffffffffffff90911691610bef9060018601906124f3565b60006040518083038185875af1925050503d8060008114610c2c576040519150601f19603f3d011682016040523d82523d6000602084013e610c31565b606091505b5050905080610ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f447269707069653a20647269702077617320756e7375636365737366756c2c2060448201527f706c6561736520636865636b20796f757220636f6e66696775726174696f6e2060648201527f666f72206d697374616b65730000000000000000000000000000000000000000608482015260a401610418565b50508080610cf59061248c565b915050610b8a565b508383604051610d0e9291906123cf565b60405180910390207fea21435419aad9c54a9d90e2522b6f60bd566401f36fcef661f5f5a28cc0d2c685853342604051610d4b94939291906125d0565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b610de481476107b4565b50565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610e6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610e92919061260d565b60006040518083038185875af1925050503d8060008114610ecf576040519150601f19603f3d011682016040523d82523d6000602084013e610ed4565b606091505b5090969095509350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610ff8908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610fd4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c09190612629565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461107d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b600081600381111561109157611091611e03565b03611144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f447269707069653a2064726970207374617475732063616e206e65766572206260448201527f6520736574206261636b20746f204e4f4e45206166746572206372656174696f60648201527f6e00000000000000000000000000000000000000000000000000000000000000608482015260a401610418565b6000600184846040516111589291906123cf565b9081526040519081900360200190205460ff169050600081600381111561118157611181611e03565b03611234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f447269707069653a206472697020776974682074686174206e616d6520646f6560448201527f73206e6f7420657869737420616e642063616e6e6f742062652075706461746560648201527f6400000000000000000000000000000000000000000000000000000000000000608482015260a401610418565b600381600381111561124857611248611e03565b036112fc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f447269707069653a206472697020776974682074686174206e616d6520686173908201527f206265656e20617263686976656420616e642063616e6e6f742062652075706460648201527f6174656400000000000000000000000000000000000000000000000000000000608482015260a401610418565b81600381111561130e5761130e611e03565b81600381111561132057611320611e03565b036113d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f447269707069653a2063616e6e6f74207365742064726970207374617475732060448201527f746f207468652073616d6520737461747573206173206974732063757272656e60648201527f7420737461747573000000000000000000000000000000000000000000000000608482015260a401610418565b60038260038111156113e7576113e7611e03565b0361148d57600181600381111561140057611400611e03565b1461148d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f447269707069653a2064726970206d757374206669727374206265207061757360448201527f6564206265666f7265206265696e6720617263686976656400000000000000006064820152608401610418565b81600185856040516114a09291906123cf565b90815260405190819003602001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660018360038111156114e7576114e7611e03565b021790555083836040516114fc9291906123cf565b60405180910390207f407cb3ad05e60ec498fb39417c7a4f6b82d5ba80f82fe512a37b02c93181a2a1858585604051610d4b93929190612642565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b6000600184846040516115cc9291906123cf565b9081526040519081900360200190205460ff1660038111156115f0576115f0611e03565b1461167d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f447269707069653a206472697020776974682074686174206e616d6520616c7260448201527f65616479206578697374730000000000000000000000000000000000000000006064820152608401610418565b61168a6020820182612665565b1561172657602081013515611721576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f447269707069653a20696620616c6c6f77696e67207265656e7472616e74206460448201527f7269702c206d7573742073657420696e74657276616c20746f207a65726f00006064820152608401610418565b6117e1565b60008160200135116117e1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f447269707069653a20696e74657276616c206d75737420626520677265617465908201527f72207468616e207a65726f2069662064726970206973206e6f74207265656e7460648201527f72616e7400000000000000000000000000000000000000000000000000000000608482015260a401610418565b6000600184846040516117f59291906123cf565b9081526040516020918190038201902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001178155915061183c90830183612665565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055602082013560028201556118876060830160408401611e9d565b6003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556118db6060830183612682565b60048301916118eb919083612736565b5060005b6118fc6080840184612851565b905081101561196f57600582016119166080850185612851565b83818110611926576119266124c4565b905060200281019061193891906128b9565b81546001810183556000928352602090922090916003020161195a82826128ed565b505080806119679061248c565b9150506118ef565b5083836040516119809291906123cf565b60405180910390207fe38d8d98e6cc66f6f520d483c6c5a89289681f897799c4c29d767cf57e76d9a6858585604051610d4b93929190612be0565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314611a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610418565b8373ffffffffffffffffffffffffffffffffffffffff1683604051611a65919061260d565b600060405180830381855af49150503d8060008114611aa0576040519150601f19603f3d011682016040523d82523d6000602084013e611aa5565b606091505b50909590945092505050565b60008060018484604051611ac69291906123cf565b90815260405190819003602001902090506002815460ff166003811115611aef57611aef611e03565b14611b7e57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f447269707069653a2073656c6563746564206472697020646f6573206e6f742060448201527f6578697374206f72206973206e6f742063757272656e746c79206163746976656064820152608401610418565b600281015460068201544291611b9391612ce7565b1115611c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f447269707069653a206472697020696e74657276616c20686173206e6f74206560448201527f6c61707365642073696e6365206c6173742064726970000000000000000000006064820152608401610418565b60038101546040517fc64b3bb500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063c64b3bb590611c7b9060048086019101612cff565b602060405180830381865afa158015611c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cbc91906123ed565b611d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f447269707069653a2064726970636865636b206661696c656420736f2064726960448201527f70206973206e6f742079657420726561647920746f206265207472696767657260648201527f6564000000000000000000000000000000000000000000000000000000000000608482015260a401610418565b5060019392505050565b60008083601f840112611d8a57600080fd5b50813567ffffffffffffffff811115611da257600080fd5b602083019150836020828501011115611dba57600080fd5b9250929050565b60008060208385031215611dd457600080fd5b823567ffffffffffffffff811115611deb57600080fd5b611df785828601611d78565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611e69577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016103958284611e32565b73ffffffffffffffffffffffffffffffffffffffff81168114610de457600080fd5b600060208284031215611eaf57600080fd5b8135611eba81611e7b565b9392505050565b600080600060608486031215611ed657600080fd5b8335611ee181611e7b565b92506020840135611ef181611e7b565b929592945050506040919091013590565b60008060408385031215611f1557600080fd5b8235611f2081611e7b565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff80841115611f7857611f78611f2e565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611fbe57611fbe611f2e565b81604052809350858152868686011115611fd757600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561200357600080fd5b813567ffffffffffffffff81111561201a57600080fd5b8201601f8101841361202b57600080fd5b61203a84823560208401611f5d565b949350505050565b60005b8381101561205d578181015183820152602001612045565b8381111561206c576000848401525b50505050565b6000815180845261208a816020860160208601612042565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6120c68186611e32565b600060206080818401528551151560808401528086015160a084015260408087015173ffffffffffffffffffffffffffffffffffffffff80821660c0870152606091508189015160a060e0880152612122610120880182612072565b60808b01518882037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80016101008a0152805180835291925086019086830190600581901b8401880160005b828110156121d6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086830301845284518781511683528a810151898c8501526121b98a850182612072565b918b0151938b0193909352948a0194938a0193915060010161216d565b50968a019b909b52505050509093019390935250949350505050565b600082601f83011261220357600080fd5b611eba83833560208501611f5d565b60008060006060848603121561222757600080fd5b833561223281611e7b565b9250602084013567ffffffffffffffff81111561224e57600080fd5b61225a868287016121f2565b925050604084013590509250925092565b821515815260406020820152600061203a6040830184612072565b6000806040838503121561229957600080fd5b82356122a481611e7b565b915060208301356122b481611e7b565b809150509250929050565b6000806000604084860312156122d457600080fd5b833567ffffffffffffffff8111156122eb57600080fd5b6122f786828701611d78565b90945092505060208401356004811061230f57600080fd5b809150509250925092565b60008060006040848603121561232f57600080fd5b833567ffffffffffffffff8082111561234757600080fd5b61235387838801611d78565b9095509350602086013591508082111561236c57600080fd5b50840160a0818703121561230f57600080fd5b6000806040838503121561239257600080fd5b823561239d81611e7b565b9150602083013567ffffffffffffffff8111156123b957600080fd5b6123c5858286016121f2565b9150509250929050565b8183823760009101908152919050565b8015158114610de457600080fd5b6000602082840312156123ff57600080fd5b8151611eba816123df565b600181811c9082168061241e57607f821691505b602082108103612457577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036124bd576124bd61245d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083546125018161240a565b60018281168015612519576001811461254c5761257b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061257b565b8760005260208060002060005b858110156125725781548a820152908401908201612559565b50505082870194505b50929695505050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6060815260006125e4606083018688612587565b73ffffffffffffffffffffffffffffffffffffffff949094166020830152506040015292915050565b6000825161261f818460208701612042565b9190910192915050565b60006020828403121561263b57600080fd5b5051919050565b604081526000612656604083018587612587565b905061203a6020830184611e32565b60006020828403121561267757600080fd5b8135611eba816123df565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126126b757600080fd5b83018035915067ffffffffffffffff8211156126d257600080fd5b602001915036819003821315611dba57600080fd5b601f82111561273157600081815260208120601f850160051c8101602086101561270e5750805b601f850160051c820191505b8181101561272d5782815560010161271a565b5050505b505050565b67ffffffffffffffff83111561274e5761274e611f2e565b6127628361275c835461240a565b836126e7565b6000601f8411600181146127b4576000851561277e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561284a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561280357868501358255602094850194600190920191016127e3565b508682101561283e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261288657600080fd5b83018035915067ffffffffffffffff8211156128a157600080fd5b6020019150600581901b3603821315611dba57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261261f57600080fd5b81356128f881611e7b565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261297257600080fd5b8501803567ffffffffffffffff81111561298b57600080fd5b803603838301131561299c57600080fd5b6129b0816129aa865461240a565b866126e7565b6000601f821160018114612a0457600083156129ce57508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655612a99565b6000868152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0841690835b82811015612a5257868501880135825593870193908901908701612a33565b5084821015612a8f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b50505050505050604082013560028201555050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612ae357600080fd5b830160208101925035905067ffffffffffffffff811115612b0357600080fd5b803603821315611dba57600080fd5b81835260006020808501808196508560051b81019150846000805b88811015612bd2578385038a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1893603018112612b6b578283fd5b880160608135612b7a81611e7b565b73ffffffffffffffffffffffffffffffffffffffff168752612b9e82890183612aae565b828a8a0152612bb0838a018284612587565b6040948501359990940198909852505099860199945091850191600101612b2d565b509298975050505050505050565b604081526000612bf4604083018587612587565b82810360208401528335612c07816123df565b15158152602084810135908201526040840135612c2381611e7b565b73ffffffffffffffffffffffffffffffffffffffff166040820152612c4b6060850185612aae565b60a06060840152612c6060a084018284612587565b91505060808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1863603018112612c9857600080fd5b850160208101903567ffffffffffffffff811115612cb557600080fd5b8060051b3603821315612cc757600080fd5b8383036080850152612cda838284612b12565b9998505050505050505050565b60008219821115612cfa57612cfa61245d565b500190565b6000602080835260008454612d138161240a565b80848701526040600180841660008114612d345760018114612d6c57612d9a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550612d9a565b896000528660002060005b85811015612d925781548b8201860152908301908801612d77565b8a0184019650505b50939897505050505050505056fea164736f6c634300080f000a

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.