Base Sepolia Testnet

Contract

0x8A26dA63B7300f93c18A472cE440508C284C77d6
Source Code Source Code

Overview

ETH Balance

0 ETH

More Info

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To Amount
290693862025-07-30 20:24:20198 days ago1753907060  Contract Creation0 ETH

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
InstructionStorage

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 1000 runs

Other Settings:
cancun EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

import {Constants} from "../libraries/Constants.sol";
import {InstructionLib} from "../libraries/Instruction.sol";

import {IInstructionStorage} from "./interfaces/IInstructionStorage.sol";

/// @title InstructionStorage
/// @author Otim Labs, Inc.
/// @notice external storage contract for storing Instruction execution state
contract InstructionStorage is IInstructionStorage {
    //slither-disable-start too-many-digits

    /// @notice hash of the "delegation designator" i.e. keccak256(0xef0100 || delegate_address)
    bytes32 public immutable designatorHash;

    /// @notice reverts if the modified function is not called from within the code of a delegated EOA
    /// @dev if the EOA codehash matches `designator`, the EOA is delegated to some contract,
    ///      and if msg.sender is not equal to tx.origin, the EOA has not called the function directly
    modifier fromDelegateCodeOnly() {
        // IInstructionStorage.DataCorruptionAttempted.selector = 0xabdc7b7a

        bytes32 designatorHash_ = designatorHash;

        assembly {
            // revert if msg.sender == tx.origin OR msg.sender.codehash != delegateCodehash
            // from innermost to outermost:
            // 1. retrieve the codehash of the msg.sender
            // 2. load `delegateCodehash` from storage (slot 0 is the address of the `owner` and slot 1 is the `delegateCodehash`)
            // 3. compare the codehash of msg.sender to the `delegateCodehash`
            // 4. if they are not equal, revert
            // 5. compare msg.sender to tx.origin
            // 6. if they are equal, revert
            if or(eq(caller(), origin()), iszero(eq(extcodehash(caller()), designatorHash_))) {
                // store `IInstructionStorage.DataCorruptionAttempted.selector` in memory.
                // memory bytes [0, 27] are zero and bytes [28, 31] are the 4-byte-long selector
                mstore(0x0, 0xabdc7b7a)
                // decoding this revert statement: we revert starting at memory byte 28 with a length of 4
                // to return the selector as the reason for the revert
                revert(0x1c, 0x4)
            }
        }
        _;
    }

    constructor() {
        // construct the "delegation designator", then hash it.
        // OtimDelegate will deploy this contract so msg.sender will be the address of the delegate contract
        designatorHash = keccak256(abi.encodePacked(Constants.EIP7702_PREFIX, msg.sender));
    }

    /// @inheritdoc IInstructionStorage
    function incrementExecutionCounter(bytes32 instructionId) external fromDelegateCodeOnly {
        assembly {
            // store msg.sender in memory: bytes [0, 11] are 0, bytes [12, 31] are msg.sender address
            mstore(0x0, caller())
            // store `instructionId` in memory bytes [32, 63]
            mstore(0x20, instructionId)
            // compute the keccak256 hash of memory bytes [0, 63] to use as the storage `key`
            let key := keccak256(0x0, 0x40)
            // from innermost to outermost:
            // 1. load the storage value at `key`. This value is structured as follows:
            //    byte 0 is free,
            //    byte 1 is the `deactivated` boolean,
            //    bytes [2, 16] are the `counter`,
            //    bytes [17, 31] are the `lastExecuted` timestamp
            // 2. discard `lastExecuted` by masking out the last 15 bytes
            // 3. increment `counter` by 1 (add 1 left-shifted by 15 bytes to the retrieved storage value)
            // 4. set the last 15 bytes of the storage value to the current block.timestamp
            // 5. store the updated storage value at `key`
            /// @dev casting `block.timestamp` from uint256 to uint120 is safe because it will only overflow
            ///      2^120 seconds after epoch which is approximately 40 Octillion years from now... we'll have a v2 by then :)
            ///      Similarly, using a uint120 for the `counter` is safe because it will only overflow after
            ///      2^120 executions (approximately 1 Undecillion executions). Also, despite this being completely infeasible,
            ///      if `counter` were to overflow, it would simply set the `deactivated` boolean to true, making it
            ///      impossible to execute the Instruction again.
            sstore(
                key,
                or(
                    add(
                        and(sload(key), 0xffffffffffffffffffffffffffffffffff000000000000000000000000000000),
                        0x1000000000000000000000000000000
                    ),
                    timestamp()
                )
            )
        }
    }

    /// @inheritdoc IInstructionStorage
    function incrementAndDeactivate(bytes32 instructionId) external fromDelegateCodeOnly {
        assembly {
            // store msg.sender in memory: bytes [0, 11] are 0, bytes [12, 31] are msg.sender address
            mstore(0x0, caller())
            // store `instructionId` in memory bytes [32, 63]
            mstore(0x20, instructionId)
            // compute the keccak256 hash of memory bytes [0, 63] to use as the storage `key`
            let key := keccak256(0x0, 0x40)
            // from innermost to outermost:
            // 1. load the storage value at `key`. This value is structured as follows:
            //    byte 0 is free,
            //    byte 1 is the `deactivated` boolean,
            //    bytes [2, 16] are the `counter`,
            //    bytes [17, 31] are the `lastExecuted` timestamp
            // 2. discard `lastExecuted` by masking out the last 15 bytes
            // 3. increment `counter` by 1 (add 1 left-shifted by 15 bytes to the retrieved storage value)
            // 4. set the last 15 bytes of the storage value to the current block.timestamp
            // 5. set the `deactivated` boolean to true
            // 6. store the updated storage value at `key`
            sstore(
                key,
                or(
                    or(
                        add(
                            and(sload(key), 0xffffffffffffffffffffffffffffffffff000000000000000000000000000000),
                            0x1000000000000000000000000000000
                        ),
                        timestamp()
                    ),
                    0x1000000000000000000000000000000000000000000000000000000000000
                )
            )
        }
    }

    /// @inheritdoc IInstructionStorage
    function deactivateStorage(bytes32 instructionId) external fromDelegateCodeOnly {
        assembly {
            // store msg.sender in memory: bytes [0, 11] are 0, bytes [12, 31] are msg.sender address
            mstore(0x0, caller())
            // store `instructionId` in memory bytes [32, 63]
            mstore(0x20, instructionId)
            // compute the keccak256 hash of memory bytes [0, 63] to use as the storage `key`
            let key := keccak256(0x0, 0x40)
            // 1. load the storage value at `key`
            // 2. set the `deactivated` boolean to true
            // 3. store the updated storage value at `key`
            sstore(key, or(sload(key), 0x1000000000000000000000000000000000000000000000000000000000000))
        }
    }

    /// @inheritdoc IInstructionStorage
    function isDeactivated(bytes32 instructionId) external view returns (bool) {
        assembly {
            // store msg.sender in memory: bytes [0, 11] are 0, bytes [12, 31] are msg.sender address
            mstore(0x0, caller())
            // store `instructionId` in memory bytes [32, 63]
            mstore(0x20, instructionId)
            // compute the keccak256 hash of memory bytes [0, 63] to use as the storage `key`
            let key := keccak256(0x0, 0x40)
            // 1. load the storage value at `key`
            // 2. right-shift the loaded storage value by 30 bytes to get the `deactivated` boolean
            // 3. store the `deactivated` boolean in memory bytes [0, 31]
            mstore(0x0, shr(0xf0, sload(key)))
            // return the `deactivated` boolean (memory starting at 0 with a length of 32)
            return(0x0, 0x20)
        }
    }

    /// @inheritdoc IInstructionStorage
    function getExecutionState(bytes32 instructionId) external view returns (InstructionLib.ExecutionState memory) {
        assembly {
            // store msg.sender in memory: bytes [0, 11] are 0, bytes [12, 31] are msg.sender address
            mstore(0x0, caller())
            // store `instructionId` in memory bytes [32, 63]
            mstore(0x20, instructionId)
            // compute the keccak256 hash of memory bytes [0, 63] to use as the storage `key`
            let key := keccak256(0x0, 0x40)
            // load the storage value at `key` into `value`
            let value := sload(key)
            // load the 32-byte word at memory location 0x40 into `ptr`. This is the location of the next free slot in memory
            /// @dev we have to use free memory slots to store return values here because they are more than 64 bytes
            let ptr := mload(0x40)
            // 1. right-shift `value` by 30 bytes to get the `deactivated` boolean
            // 2. store this at memory location `ptr`
            mstore(ptr, shr(0xf0, value))
            // 1. right-shift `value` by 15 bytes to get rid of `lastExecuted`
            // 2. mask out the first 17 bytes of `value` to get `counter`
            // 3. store this at memory location `ptr` + 32 bytes
            mstore(add(ptr, 0x20), and(0xffffffffffffffffffffffffffffff, shr(0x78, value)))
            // 1. mask out the first 17 bytes of `value` to get `lastExecuted`
            // 2. store this at memory location `ptr` + 64 bytes
            mstore(add(ptr, 0x40), and(0xffffffffffffffffffffffffffffff, value))
            // return `deactivated`, `counter`, and `lastExecuted` as separate values
            // by returning memory starting at `ptr` with a length of 96 bytes
            return(ptr, 0x60)
        }
    }

    /// @notice returns the execution state of an Instruction for a particular user
    /// @param instructionId - unique identifier for an Instruction
    /// @param user - address of the EOA to return execution state for
    /// @return executionState - the current execution state of the Instruction
    function getExecutionState(address user, bytes32 instructionId)
        external
        view
        returns (InstructionLib.ExecutionState memory)
    {
        assembly {
            // store `user` in memory: bytes [0, 11] are 0, bytes [12, 31] are `user`
            mstore(0x0, user)
            // store `instructionId` in memory bytes [32, 63]
            mstore(0x20, instructionId)
            // compute the keccak256 hash of memory bytes [0, 63] to use as the storage `key`
            let key := keccak256(0x0, 0x40)
            // load the storage value at `key` into `value`
            let value := sload(key)
            // load the 32-byte word at memory location 0x40 into `ptr`. This is the location of the next free slot in memory
            let ptr := mload(0x40)
            // 1. right-shift `value` by 30 bytes to get the `deactivated` boolean
            // 2. store this at memory location `ptr`
            mstore(ptr, shr(0xf0, value))
            // 1. right-shift `value` by 15 bytes to get rid of `lastExecuted`
            // 2. mask out the first 17 bytes of `value` to get `counter`
            // 3. store this at memory location `ptr` + 32 bytes
            mstore(add(ptr, 0x20), and(0xffffffffffffffffffffffffffffff, shr(0x78, value)))
            // 1. mask out the first 17 bytes of `value` to get `lastExecuted`
            // 2. store this at memory location `ptr` + 64 bytes
            mstore(add(ptr, 0x40), and(0xffffffffffffffffffffffffffffff, value))
            // return `deactivated`, `counter`, and `lastExecuted` as separate values
            // by returning memory starting at `ptr` with a length of 96 bytes
            return(ptr, 0x60)
        }
    }
    //slither-disable-end too-many-digits
}

File 2 of 4 : Constants.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

/// @title Constants
/// @author Otim Labs, Inc.
/// @notice a library defining constants used throughout the protocol
library Constants {
    /// @notice the EIP-712 signature prefix
    bytes2 public constant EIP712_PREFIX = 0x1901;

    /// @notice the EIP-7702 delegation designator prefix
    bytes3 public constant EIP7702_PREFIX = 0xef0100;
}

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

import {Constants} from "./Constants.sol";

/// @title InstructionLib
/// @author Otim Labs, Inc.
/// @notice a library defining the Instruction datatype and util functions
library InstructionLib {
    /// @notice defines a signature
    struct Signature {
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    /// @notice defines the ExecutionState datatype
    /// @param deactivated - whether the Instruction has been deactivated
    /// @param executionCount - the number of times the Instruction has been executed
    /// @param lastExecuted - the unix timestamp of the last time the Instruction was executed
    struct ExecutionState {
        bool deactivated;
        uint120 executionCount;
        uint120 lastExecuted;
    }

    /// @notice defines the Instruction datatype
    /// @param salt - a number to ensure the uniqueness of the Instruction
    /// @param maxExecutions - the maximum number of times the Instruction can be executed
    /// @param action - the address of the Action contract to be executed
    /// @param arguments - the arguments to be passed to the Action contract
    struct Instruction {
        uint256 salt;
        uint256 maxExecutions;
        address action;
        bytes arguments;
    }

    /// @notice abi.encodes and hashes an Instruction struct to create a unique Instruction identifier
    /// @param instruction - an Instruction struct to hash
    /// @return instructionId - unique identifier for the Instruction
    function id(Instruction calldata instruction) internal pure returns (bytes32) {
        return keccak256(abi.encode(instruction));
    }

    /// @notice calculates the EIP-712 hash for activating an Instruction
    /// @param instruction - an Instruction struct to hash
    /// @param domainSeparator - the EIP-712 domain separator for the verifying contract
    /// @return hash - EIP-712 hash for activating `instruction`
    function signingHash(
        Instruction calldata instruction,
        bytes32 domainSeparator,
        bytes32 instructionTypeHash,
        bytes32 argumentsHash
    ) internal pure returns (bytes32) {
        return keccak256(
            abi.encodePacked(
                Constants.EIP712_PREFIX,
                domainSeparator,
                keccak256(
                    abi.encode(
                        instructionTypeHash,
                        instruction.salt,
                        instruction.maxExecutions,
                        instruction.action,
                        argumentsHash
                    )
                )
            )
        );
    }

    /// @notice defines a deactivation instruction
    /// @param instructionId - the unique identifier of the Instruction to deactivate
    struct InstructionDeactivation {
        bytes32 instructionId;
    }

    /// @notice the EIP-712 type-hash for an InstructionDeactivation
    bytes32 public constant DEACTIVATION_TYPEHASH = keccak256("InstructionDeactivation(bytes32 instructionId)");

    /// @notice calculates the EIP-712 hash for a InstructionDeactivation
    /// @param deactivation - an InstructionDeactivation struct to hash
    /// @param domainSeparator - the EIP-712 domain separator for the verifying contract
    /// @return hash - EIP-712 hash for the `deactivation`
    function signingHash(InstructionDeactivation calldata deactivation, bytes32 domainSeparator)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(
            abi.encodePacked(
                Constants.EIP712_PREFIX,
                domainSeparator,
                keccak256(abi.encode(DEACTIVATION_TYPEHASH, deactivation.instructionId))
            )
        );
    }
}

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.26;

import {InstructionLib} from "../../libraries/Instruction.sol";

/// @title IInstructionStorage
/// @author Otim Labs, Inc.
/// @notice interface for InstructionStorage contract
interface IInstructionStorage {
    error DataCorruptionAttempted();

    /// @notice increments the execution counter for an Instruction and sets `lastExecuted` to current block.timestamp
    /// @param instructionId - unique identifier for an Instruction
    function incrementExecutionCounter(bytes32 instructionId) external;

    /// @notice increments the execution counter for an Instruction, sets `lastExecuted` to current block.timestamp, and deactivates
    /// @param instructionId - unique identifier for an Instruction
    function incrementAndDeactivate(bytes32 instructionId) external;

    /// @notice deactivates an Instruction's execution state in storage
    /// @param instructionId - unique identifier for an Instruction
    function deactivateStorage(bytes32 instructionId) external;

    /// @notice returns the execution state of an Instruction for a particular user
    /// @param user - the user the Instruction pertains to
    /// @param instructionId - unique identifier for an Instruction
    /// @return executionState - the current execution state of the Instruction
    function getExecutionState(address user, bytes32 instructionId)
        external
        view
        returns (InstructionLib.ExecutionState memory);

    /// @notice returns the execution state of an Instruction for msg.sender
    /// @param instructionId - unique identifier for an Instruction
    /// @return executionState - the current execution state of the Instruction
    function getExecutionState(bytes32 instructionId) external view returns (InstructionLib.ExecutionState memory);

    /// @notice checks if an Instruction is deactivated for msg.sender
    /// @param instructionId - unique identifier for an Instruction
    /// @return deactivated - true if the Instruction is deactivated
    function isDeactivated(bytes32 instructionId) external view returns (bool);
}

Settings
{
  "remappings": [
    "@chainlink-contracts/=dependencies/smartcontractkit-chainlink-2.25.0/contracts/",
    "@openzeppelin-contracts/=dependencies/@openzeppelin-contracts-5.4.0/",
    "@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.4.0/",
    "@uniswap-universal-router/=dependencies/@uniswap-universal-router-2.0.0/",
    "@uniswap-v3-core/=dependencies/@uniswap-v3-core-1.0.2-solc-0.8-simulate/",
    "@uniswap-v3-periphery/=dependencies/@uniswap-v3-periphery-1.4.4/",
    "forge-std/=dependencies/forge-std-1.10.0/",
    "@openzeppelin-contracts-5.4.0/=dependencies/@openzeppelin-contracts-5.4.0/",
    "@uniswap-universal-router-2.0.0/=dependencies/@uniswap-universal-router-2.0.0/",
    "@uniswap-v3-core-1.0.2-solc-0.8-simulate/=dependencies/@uniswap-v3-core-1.0.2-solc-0.8-simulate/contracts/",
    "@uniswap-v3-periphery-1.4.4/=dependencies/@uniswap-v3-periphery-1.4.4/contracts/",
    "@uniswap/=dependencies/@uniswap-v3-periphery-1.4.4/node_modules/@uniswap/",
    "ds-test/=dependencies/@uniswap-universal-router-2.0.0/lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=dependencies/@uniswap-universal-router-2.0.0/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-gas-snapshot/=dependencies/@uniswap-universal-router-2.0.0/lib/permit2/lib/forge-gas-snapshot/src/",
    "forge-std-1.10.0/=dependencies/forge-std-1.10.0/src/",
    "openzeppelin-contracts/=dependencies/@uniswap-universal-router-2.0.0/lib/permit2/lib/openzeppelin-contracts/",
    "permit2/=dependencies/@uniswap-universal-router-2.0.0/lib/permit2/",
    "smartcontractkit-chainlink-2.25.0/=dependencies/smartcontractkit-chainlink-2.25.0/",
    "solmate/=dependencies/@uniswap-universal-router-2.0.0/lib/solmate/src/",
    "v3-periphery/=dependencies/@uniswap-universal-router-2.0.0/lib/v3-periphery/contracts/",
    "v4-core/=dependencies/@uniswap-universal-router-2.0.0/lib/v4-periphery/lib/v4-core/src/",
    "v4-periphery/=dependencies/@uniswap-universal-router-2.0.0/lib/v4-periphery/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false
}

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DataCorruptionAttempted","type":"error"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"deactivateStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"designatorHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"getExecutionState","outputs":[{"components":[{"internalType":"bool","name":"deactivated","type":"bool"},{"internalType":"uint120","name":"executionCount","type":"uint120"},{"internalType":"uint120","name":"lastExecuted","type":"uint120"}],"internalType":"struct InstructionLib.ExecutionState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"getExecutionState","outputs":[{"components":[{"internalType":"bool","name":"deactivated","type":"bool"},{"internalType":"uint120","name":"executionCount","type":"uint120"},{"internalType":"uint120","name":"lastExecuted","type":"uint120"}],"internalType":"struct InstructionLib.ExecutionState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"incrementAndDeactivate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"incrementExecutionCounter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"instructionId","type":"bytes32"}],"name":"isDeactivated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60a0604052348015600e575f80fd5b5060405161ef0160f01b60208201526001600160601b03193360601b16602382015260370160408051601f19818403018152919052805160209091012060805260805161040c61007b5f395f81816101490152818161017b015281816101f901526102db015261040c5ff3fe608060405234801561000f575f80fd5b506004361061007a575f3560e01c80638d5066a9116100585780638d5066a9146100fb578063cb4cf15b1461010e578063d300e03514610131578063f208d98914610144575f80fd5b806323fa8a4b1461007e5780633d71f9b91461009357806349d8033e146100a6575b5f80fd5b61009161008c3660046103b3565b610179565b005b6100916100a13660046103b3565b6101f7565b6100b96100b43660046103b3565b61026f565b604080518251151581526020808401516effffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060015b60405180910390f35b6100916101093660046103b3565b6102d9565b61012161011c3660046103b3565b610331565b60405190151581526020016100f2565b6100b961013f3660046103ca565b610349565b61016b7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100f2565b7f00000000000000000000000000000000000000000000000000000000000000003233908114903f82141517156101b75763abdc7b7a5f526004601cfd5b335f528160205260405f20600160f01b426f010000000000000000000000000000006effffffffffffffffffffffffffffff198454160117178155505050565b7f00000000000000000000000000000000000000000000000000000000000000003233908114903f82141517156102355763abdc7b7a5f526004601cfd5b335f528160205260405f20426f010000000000000000000000000000006effffffffffffffffffffffffffffff1983541601178155505050565b604080516060810182525f8082526020820181905291810191909152335f528160205260405f20805490506040518160f01c81528160781c6effffffffffffffffffffffffffffff166020820152816effffffffffffffffffffffffffffff166040820152606081f35b7f00000000000000000000000000000000000000000000000000000000000000003233908114903f82141517156103175763abdc7b7a5f526004601cfd5b335f528160205260405f20600160f01b8154178155505050565b5f335f528160205260405f20805460f01c5f5260205ff35b604080516060810182525f8082526020820181905291810191909152825f528160205260405f20805490506040518160f01c81528160781c6effffffffffffffffffffffffffffff166020820152816effffffffffffffffffffffffffffff166040820152606081f35b5f602082840312156103c3575f80fd5b5035919050565b5f80604083850312156103db575f80fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146103fe575f80fd5b94602093909301359350505056

Deployed Bytecode

0x608060405234801561000f575f80fd5b506004361061007a575f3560e01c80638d5066a9116100585780638d5066a9146100fb578063cb4cf15b1461010e578063d300e03514610131578063f208d98914610144575f80fd5b806323fa8a4b1461007e5780633d71f9b91461009357806349d8033e146100a6575b5f80fd5b61009161008c3660046103b3565b610179565b005b6100916100a13660046103b3565b6101f7565b6100b96100b43660046103b3565b61026f565b604080518251151581526020808401516effffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060015b60405180910390f35b6100916101093660046103b3565b6102d9565b61012161011c3660046103b3565b610331565b60405190151581526020016100f2565b6100b961013f3660046103ca565b610349565b61016b7f9b81987cf64360effca7ace696c28e35019fb60f68e9069af5db08f6411e1abd81565b6040519081526020016100f2565b7f9b81987cf64360effca7ace696c28e35019fb60f68e9069af5db08f6411e1abd3233908114903f82141517156101b75763abdc7b7a5f526004601cfd5b335f528160205260405f20600160f01b426f010000000000000000000000000000006effffffffffffffffffffffffffffff198454160117178155505050565b7f9b81987cf64360effca7ace696c28e35019fb60f68e9069af5db08f6411e1abd3233908114903f82141517156102355763abdc7b7a5f526004601cfd5b335f528160205260405f20426f010000000000000000000000000000006effffffffffffffffffffffffffffff1983541601178155505050565b604080516060810182525f8082526020820181905291810191909152335f528160205260405f20805490506040518160f01c81528160781c6effffffffffffffffffffffffffffff166020820152816effffffffffffffffffffffffffffff166040820152606081f35b7f9b81987cf64360effca7ace696c28e35019fb60f68e9069af5db08f6411e1abd3233908114903f82141517156103175763abdc7b7a5f526004601cfd5b335f528160205260405f20600160f01b8154178155505050565b5f335f528160205260405f20805460f01c5f5260205ff35b604080516060810182525f8082526020820181905291810191909152825f528160205260405f20805490506040518160f01c81528160781c6effffffffffffffffffffffffffffff166020820152816effffffffffffffffffffffffffffff166040820152606081f35b5f602082840312156103c3575f80fd5b5035919050565b5f80604083850312156103db575f80fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146103fe575f80fd5b94602093909301359350505056

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0x8A26dA63B7300f93c18A472cE440508C284C77d6
Loading...
Loading
Loading...
Loading
[ 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.