ETH Price: $2,841.89 (-3.29%)

Contract

0xCbb2b55ab9309af49Acc1689B3015b0d64150Ca5

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
322209762025-11-12 17:42:1574 days ago1762969335  Contract Creation0 ETH

Cross-Chain Transactions
Loading...
Loading

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

Contract Name:
PolymerProver

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

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

import {BaseProver} from "./BaseProver.sol";
import {Semver} from "../libs/Semver.sol";
import {ICrossL2ProverV2} from "../interfaces/ICrossL2ProverV2.sol";
import {AddressConverter} from "../libs/AddressConverter.sol";
import {Whitelist} from "../libs/Whitelist.sol";

/**
 * @title PolymerProver
 * @notice Prover implementation using Polymer's cross-chain messaging system
 * @dev Processes proof messages from Polymer's CrossL2ProverV2 and records proven intents
 */
contract PolymerProver is BaseProver, Whitelist, Semver {
    using AddressConverter for bytes32;
    using AddressConverter for address;

    // Constants
    string public constant PROOF_TYPE = "Polymer";
    bytes32 public constant PROOF_SELECTOR =
        keccak256("IntentFulfilledFromSource(uint64,bytes)");
    uint256 public constant EXPECTED_TOPIC_LENGTH = 64; // 2 topics * 32 bytes each
    uint256 public constant MAX_LOG_DATA_SIZE_GUARD = 32 * 1024;

    // Events
    event IntentFulfilledFromSource(uint64 indexed source, bytes encodedProofs);

    // Errors
    error InvalidEventSignature();
    error InvalidEmittingContract(address emittingContract);
    error InvalidSourceChain();
    error InvalidDestinationChain();
    error InvalidTopicsLength();
    error ZeroAddress();
    error SizeMismatch();
    error MaxDataSizeExceeded();
    error InvalidMaxLogDataSize();
    error EmptyProofData();
    error OnlyPortal();

    // State variables
    ICrossL2ProverV2 public immutable CROSS_L2_PROVER_V2;
    uint256 public MAX_LOG_DATA_SIZE;

    /**
     * @notice Initializes the PolymerProver contract
     * @param _portal Address of the Portal contract
     * @param _crossL2ProverV2 Address of the CrossL2ProverV2 contract
     * @param _maxLogDataSize Maximum allowed size for encodedProofs in IntentFulfilledFromSource event data
     * @param _proverAddresses Array of whitelisted prover addresses as bytes32
     */
    constructor(
        address _portal,
        address _crossL2ProverV2,
        uint256 _maxLogDataSize,
        bytes32[] memory _proverAddresses
    ) BaseProver(_portal) Whitelist(_proverAddresses) {
        if (_crossL2ProverV2 == address(0)) revert ZeroAddress();
        if (_maxLogDataSize == 0 || _maxLogDataSize > MAX_LOG_DATA_SIZE_GUARD) {
            revert InvalidMaxLogDataSize();
        }
        MAX_LOG_DATA_SIZE = _maxLogDataSize;
        CROSS_L2_PROVER_V2 = ICrossL2ProverV2(_crossL2ProverV2);
    }

    // ------------- LOG EVENT PROOF VALIDATION -------------

    /**
     * @notice Validates multiple proofs in a batch
     * @param proofs Array of proof data to validate
     */
    function validateBatch(bytes[] calldata proofs) external {
        for (uint256 i = 0; i < proofs.length; i++) {
            validate(proofs[i]);
        }
    }

    /**
     * @notice Validates a single proof and processes contained intents
     * @param proof Proof of an IntentFulfilledFromSource event
     */
    function validate(bytes calldata proof) public {
        (
            uint32 destinationChainId,
            address emittingContract,
            bytes memory topics,
            bytes memory data
        ) = CROSS_L2_PROVER_V2.validateEvent(proof);

        if (!isWhitelisted(emittingContract.toBytes32())) {
            revert InvalidEmittingContract(emittingContract);
        }

        if (topics.length != EXPECTED_TOPIC_LENGTH)
            revert InvalidTopicsLength();

        if (data.length == 0) {
            revert EmptyProofData();
        }

        // ABI-decode the unindexedData as per Polymer documentation
        // The data parameter contains ABI-encoded bytes from the event
        bytes memory decodedData = abi.decode(data, (bytes));

        if ((decodedData.length - 8) % 64 != 0) {
            revert ArrayLengthMismatch();
        }

        bytes32 eventSignature;
        uint64 eventSourceChainId;
        uint64 proofDataChainId;

        assembly {
            let topicsPtr := add(topics, 32)
            let dataPtr := add(decodedData, 32)

            eventSignature := mload(topicsPtr)
            eventSourceChainId := mload(add(topicsPtr, 32))
            proofDataChainId := shr(192, mload(dataPtr)) // Extract first 8 bytes (64 bits) from the 32-byte word
        }

        if (eventSignature != PROOF_SELECTOR) revert InvalidEventSignature();
        if (eventSourceChainId != block.chainid) revert InvalidSourceChain();

        // Verify the chain ID from proof data matches the destination chain from validateEvent
        if (proofDataChainId != uint64(destinationChainId))
            revert InvalidDestinationChain();

        uint256 numPairs = (decodedData.length - 8) / 64;
        for (uint256 i = 0; i < numPairs; i++) {
            uint256 offset = 8 + i * 64;

            bytes32 intentHash;
            bytes32 claimantBytes;

            assembly {
                let dataPtr := add(decodedData, 32)
                intentHash := mload(add(dataPtr, offset))
                claimantBytes := mload(add(dataPtr, add(offset, 32)))
            }

            if (claimantBytes >> 160 != 0) continue;

            address claimant = claimantBytes.toAddress();
            processIntent(intentHash, claimant, destinationChainId);
        }
    }

    // ------------- INTERNAL FUNCTIONS - INTENT PROCESSING -------------

    /**
     * @notice Processes a single intent proof
     * @param intentHash Hash of the intent being proven
     * @param claimant Address that fulfilled the intent and should receive rewards
     * @param destination Destination chain ID for the intent
     */
    function processIntent(
        bytes32 intentHash,
        address claimant,
        uint64 destination
    ) internal {
        ProofData storage proof = _provenIntents[intentHash];
        if (proof.claimant != address(0)) {
            emit IntentAlreadyProven(intentHash);

            return;
        }
        proof.claimant = claimant;
        proof.destination = destination;

        emit IntentProven(intentHash, claimant, destination);
    }

    // ------------- INTERFACE IMPLEMENTATION -------------

    /**
     * @notice Returns the proof type used by this prover
     * @dev Implementation of IProver interface method
     * @return string The type of proof mechanism (Polymer)
     */
    function getProofType() external pure override returns (string memory) {
        return PROOF_TYPE;
    }

    // ------------ EXTERNAL PROVE FUNCTION -------------

    /**
     * @notice Emits IntentFulfilledFromSource events that can be proven by Polymer
     * @dev Only callable by the Portal contract
     * @param sourceChainDomainID Domain ID of the source chain (treated as chain ID for Polymer)
     * @param encodedProofs Encoded (intentHash, claimant) pairs as bytes
     */
    function prove(
        address /* unused */,
        uint64 sourceChainDomainID,
        bytes calldata encodedProofs,
        bytes calldata /* unused */
    ) external payable {
        if (msg.sender != PORTAL) revert OnlyPortal();
        if (encodedProofs.length > MAX_LOG_DATA_SIZE) {
            revert MaxDataSizeExceeded();
        }

        emit IntentFulfilledFromSource(sourceChainDomainID, encodedProofs);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IProver} from "../interfaces/IProver.sol";
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {AddressConverter} from "../libs/AddressConverter.sol";

/**
 * @title BaseProver
 * @notice Base implementation for intent proving contracts
 * @dev Provides core storage and functionality for tracking proven intents
 * and their claimants
 */
abstract contract BaseProver is IProver, ERC165 {
    using AddressConverter for bytes32;
    /**
     * @notice Address of the Portal contract
     * @dev Immutable to prevent unauthorized changes
     */

    address public immutable PORTAL;

    /**
     * @notice Mapping from intent hash to proof data
     * @dev Empty struct (zero claimant) indicates intent hasn't been proven
     */
    mapping(bytes32 => ProofData) internal _provenIntents;

    /**
     * @notice Get proof data for an intent
     * @param intentHash The intent hash to query
     * @return ProofData struct containing claimant and destination
     */
    function provenIntents(
        bytes32 intentHash
    ) external view returns (ProofData memory) {
        return _provenIntents[intentHash];
    }

    /**
     * @notice Initializes the BaseProver contract
     * @param portal Address of the Portal contract
     */
    constructor(address portal) {
        if (portal == address(0)) {
            revert ZeroPortal();
        }

        PORTAL = portal;
    }

    /**
     * @notice Process intent proofs from a cross-chain message
     * @param data Encoded (intentHash, claimant) pairs (without chain ID prefix)
     * @param destination Chain ID where the intent is being proven
     */
    function _processIntentProofs(
        bytes calldata data,
        uint64 destination
    ) internal {
        // If data is empty, just return early
        if (data.length == 0) return;

        // Ensure data length is multiple of 64 bytes (32 for hash + 32 for claimant)
        if (data.length % 64 != 0) {
            revert ArrayLengthMismatch();
        }

        uint256 numPairs = data.length / 64;

        for (uint256 i = 0; i < numPairs; i++) {
            uint256 offset = i * 64;

            // Extract intentHash and claimant using slice
            bytes32 intentHash = bytes32(data[offset:offset + 32]);
            bytes32 claimantBytes = bytes32(data[offset + 32:offset + 64]);

            // Check if the claimant bytes32 represents a valid Ethereum address
            if (!claimantBytes.isValidAddress()) {
                // Skip non-EVM addresses that can't be converted
                continue;
            }

            address claimant = claimantBytes.toAddress();

            // Validate claimant is not zero address
            if (claimant == address(0)) {
                continue; // Skip invalid claimants
            }

            // Skip rather than revert for already proven intents
            if (_provenIntents[intentHash].claimant != address(0)) {
                emit IntentAlreadyProven(intentHash);
            } else {
                _provenIntents[intentHash] = ProofData({
                    claimant: claimant,
                    destination: destination
                });
                emit IntentProven(intentHash, claimant, destination);
            }
        }
    }

    /**
     * @notice Challenge an intent proof if destination chain ID doesn't match
     * @dev Can be called by anyone to remove invalid proofs. This is a safety mechanism to ensure
     *      intents are only claimable when executed on their intended destination chains.
     * @param destination The intended destination chain ID
     * @param routeHash The hash of the intent's route
     * @param rewardHash The hash of the reward specification
     */
    function challengeIntentProof(
        uint64 destination,
        bytes32 routeHash,
        bytes32 rewardHash
    ) external {
        bytes32 intentHash = keccak256(
            abi.encodePacked(destination, routeHash, rewardHash)
        );

        ProofData memory proof = _provenIntents[intentHash];

        // Only challenge if proof exists and destination chain ID doesn't match
        if (proof.claimant != address(0) && proof.destination != destination) {
            delete _provenIntents[intentHash];

            emit IntentProofInvalidated(intentHash);
        }
    }

    /**
     * @notice Checks if this contract supports a given interface
     * @dev Implements ERC165 interface detection
     * @param interfaceId Interface identifier to check
     * @return True if the interface is supported
     */
    function supportsInterface(
        bytes4 interfaceId
    ) public view override returns (bool) {
        return
            interfaceId == type(IProver).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

File 3 of 10 : Semver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

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

/**
 * @title Semver
 * @notice Implements semantic versioning for contracts
 * @dev Abstract contract that provides a standard way to access version information
 */
abstract contract Semver is ISemver {
    /**
     * @notice Returns the semantic version of the contract
     * @dev Implementation of ISemver interface
     * @return Current version string in semantic format
     */
    function version() external pure returns (string memory) {
        return "3.2";
    }
}

// SPDX-License-Identifier: Apache-2.0
/*
 * Copyright 2024, Polymer Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
pragma solidity ^0.8.2;

/**
 * @title ICrossL2Prover
 * @author Polymer Labs
 * @notice A contract that can prove peptides state. Since peptide is an aggregator of many chains' states, this
 * contract can in turn be used to prove any arbitrary events and/or storage on counterparty chains.
 */
interface ICrossL2ProverV2 {
    /**
     * @notice A a log at a given raw rlp encoded receipt at a given logIndex within the receipt.
     * @notice the receiptRLP should first be validated by calling validateReceipt.
     * @param proof: The proof of a given rlp bytes for the receipt, returned from the receipt MMPT of a block.
     * @return chainId The chainID that the proof proves the log for
     * @return emittingContract The address of the contract that emitted the log on the source chain
     * @return topics The topics of the event. First topic is the event signature that can be calculated by
     * Event.selector. The remaining elements in this array are the indexed parameters of the event.
     * @return unindexedData // The abi encoded non-indexed parameters of the event.
     */
    function validateEvent(
        bytes calldata proof
    )
        external
        view
        returns (
            uint32 chainId,
            address emittingContract,
            bytes calldata topics,
            bytes calldata unindexedData
        );

    /**
     * Return srcChain, Block Number, Receipt Index, and Local Index for a requested proof
     */
    function inspectLogIdentifier(
        bytes calldata proof
    )
        external
        pure
        returns (
            uint32 srcChain,
            uint64 blockNumber,
            uint16 receiptIndex,
            uint8 logIndex
        );

    /**
     * Return polymer state root, height , and signature over height and root which can be verified by
     * crypto.pubkey(keccak(peptideStateRoot, peptideHeight))
     */
    function inspectPolymerState(
        bytes calldata proof
    )
        external
        pure
        returns (bytes32 stateRoot, uint64 height, bytes memory signature);
}

/* -*- c-basic-offset: 4 -*- */
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/**
 * @title AddressConverter
 * @notice Utility library for converting between address and bytes32 types
 * @dev Provides simple functions to convert between address (20 bytes) and bytes32 (32 bytes)
 */
library AddressConverter {
    error InvalidAddress(bytes32 value);

    /**
     * @notice Convert an Ethereum address to bytes32
     * @dev Pads the 20-byte address to 32 bytes by converting to uint160, then uint256, then bytes32
     * @param addr The address to convert
     * @return The bytes32 representation of the address
     */
    function toBytes32(address addr) internal pure returns (bytes32) {
        return bytes32(uint256(uint160(addr)));
    }

    /**
     * @notice Convert bytes32 to an Ethereum address
     * @dev Truncates the 32-byte value to 20 bytes by converting to uint256, then uint160, then address
     * @param b The bytes32 value to convert
     * @return The address representation of the bytes32 value
     */
    function toAddress(bytes32 b) internal pure returns (address) {
        if (!isValidAddress(b)) {
            revert InvalidAddress(b);
        }

        return address(uint160(uint256(b)));
    }

    /**
     * @notice Check if a bytes32 value represents a valid Ethereum address
     * @dev An Ethereum address must have the top 12 bytes as zero
     * @param b The bytes32 value to check
     * @return True if the bytes32 value can be safely converted to an Ethereum address
     */
    function isValidAddress(bytes32 b) internal pure returns (bool) {
        // The top 12 bytes must be zero for a valid Ethereum address
        return uint256(b) >> 160 == 0;
    }
}

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

/**
 * @title Whitelist
 * @notice Abstract contract providing immutable whitelist functionality
 * @dev Uses immutable arrays to store up to 20 whitelisted addresses as bytes32 for cross-VM compatibility
 *
 * This contract provides a gas-efficient, immutable approach to whitelisting:
 * - The whitelist is configured ONCE at construction time
 * - After deployment, the whitelist CANNOT be modified (addresses cannot be added or removed)
 * - Maximum of 20 addresses can be whitelisted
 * - Uses immutable slots for each whitelisted address (lower gas cost than storage)
 * - Optimized for early exit when checking whitelist membership
 * - Uses bytes32 for cross-VM compatibility (Ethereum addresses and Solana public keys)
 */
abstract contract Whitelist {
    /**
     * @notice Error thrown when an address is not whitelisted
     * @param addr The address that was not found in the whitelist
     */
    error AddressNotWhitelisted(bytes32 addr);

    /**
     * @notice Whitelist size exceeds maximum allowed
     * @param size Attempted whitelist size
     * @param maxSize Maximum allowed size
     */
    error WhitelistSizeExceeded(uint256 size, uint256 maxSize);

    /// @dev Maximum number of addresses that can be whitelisted
    uint256 private constant MAX_WHITELIST_SIZE = 20;

    /// @dev Number of addresses actually in the whitelist
    uint256 private immutable WHITELIST_SIZE;

    /// @dev Immutable storage for whitelisted addresses (up to 20)
    bytes32 private immutable ADDRESS_1;
    bytes32 private immutable ADDRESS_2;
    bytes32 private immutable ADDRESS_3;
    bytes32 private immutable ADDRESS_4;
    bytes32 private immutable ADDRESS_5;
    bytes32 private immutable ADDRESS_6;
    bytes32 private immutable ADDRESS_7;
    bytes32 private immutable ADDRESS_8;
    bytes32 private immutable ADDRESS_9;
    bytes32 private immutable ADDRESS_10;
    bytes32 private immutable ADDRESS_11;
    bytes32 private immutable ADDRESS_12;
    bytes32 private immutable ADDRESS_13;
    bytes32 private immutable ADDRESS_14;
    bytes32 private immutable ADDRESS_15;
    bytes32 private immutable ADDRESS_16;
    bytes32 private immutable ADDRESS_17;
    bytes32 private immutable ADDRESS_18;
    bytes32 private immutable ADDRESS_19;
    bytes32 private immutable ADDRESS_20;

    /**
     * @notice Initializes the whitelist with a set of addresses
     * @param addresses Array of addresses to whitelist (as bytes32 for cross-VM compatibility)
     */
    // solhint-disable-next-line function-max-lines
    constructor(bytes32[] memory addresses) {
        if (addresses.length > MAX_WHITELIST_SIZE) {
            revert WhitelistSizeExceeded(addresses.length, MAX_WHITELIST_SIZE);
        }

        // Store whitelist size
        WHITELIST_SIZE = addresses.length;

        // Initialize all addresses to zero
        ADDRESS_1 = addresses.length > 0 ? addresses[0] : bytes32(0);
        ADDRESS_2 = addresses.length > 1 ? addresses[1] : bytes32(0);
        ADDRESS_3 = addresses.length > 2 ? addresses[2] : bytes32(0);
        ADDRESS_4 = addresses.length > 3 ? addresses[3] : bytes32(0);
        ADDRESS_5 = addresses.length > 4 ? addresses[4] : bytes32(0);
        ADDRESS_6 = addresses.length > 5 ? addresses[5] : bytes32(0);
        ADDRESS_7 = addresses.length > 6 ? addresses[6] : bytes32(0);
        ADDRESS_8 = addresses.length > 7 ? addresses[7] : bytes32(0);
        ADDRESS_9 = addresses.length > 8 ? addresses[8] : bytes32(0);
        ADDRESS_10 = addresses.length > 9 ? addresses[9] : bytes32(0);
        ADDRESS_11 = addresses.length > 10 ? addresses[10] : bytes32(0);
        ADDRESS_12 = addresses.length > 11 ? addresses[11] : bytes32(0);
        ADDRESS_13 = addresses.length > 12 ? addresses[12] : bytes32(0);
        ADDRESS_14 = addresses.length > 13 ? addresses[13] : bytes32(0);
        ADDRESS_15 = addresses.length > 14 ? addresses[14] : bytes32(0);
        ADDRESS_16 = addresses.length > 15 ? addresses[15] : bytes32(0);
        ADDRESS_17 = addresses.length > 16 ? addresses[16] : bytes32(0);
        ADDRESS_18 = addresses.length > 17 ? addresses[17] : bytes32(0);
        ADDRESS_19 = addresses.length > 18 ? addresses[18] : bytes32(0);
        ADDRESS_20 = addresses.length > 19 ? addresses[19] : bytes32(0);
    }

    /**
     * @notice Checks if an address is whitelisted
     * @param addr Address to check (as bytes32 for cross-VM compatibility)
     * @return True if the address is whitelisted, false otherwise
     */
    // solhint-disable-next-line function-max-lines
    function isWhitelisted(bytes32 addr) public view returns (bool) {
        // Short circuit check for empty whitelist
        if (WHITELIST_SIZE == 0) return false;

        // Short circuit check for zero address
        if (addr == bytes32(0)) return false;

        if (ADDRESS_1 == addr) return true;
        if (WHITELIST_SIZE <= 1) return false;

        if (ADDRESS_2 == addr) return true;
        if (WHITELIST_SIZE <= 2) return false;

        if (ADDRESS_3 == addr) return true;
        if (WHITELIST_SIZE <= 3) return false;

        if (ADDRESS_4 == addr) return true;
        if (WHITELIST_SIZE <= 4) return false;

        if (ADDRESS_5 == addr) return true;
        if (WHITELIST_SIZE <= 5) return false;

        if (ADDRESS_6 == addr) return true;
        if (WHITELIST_SIZE <= 6) return false;

        if (ADDRESS_7 == addr) return true;
        if (WHITELIST_SIZE <= 7) return false;

        if (ADDRESS_8 == addr) return true;
        if (WHITELIST_SIZE <= 8) return false;

        if (ADDRESS_9 == addr) return true;
        if (WHITELIST_SIZE <= 9) return false;

        if (ADDRESS_10 == addr) return true;
        if (WHITELIST_SIZE <= 10) return false;

        if (ADDRESS_11 == addr) return true;
        if (WHITELIST_SIZE <= 11) return false;

        if (ADDRESS_12 == addr) return true;
        if (WHITELIST_SIZE <= 12) return false;

        if (ADDRESS_13 == addr) return true;
        if (WHITELIST_SIZE <= 13) return false;

        if (ADDRESS_14 == addr) return true;
        if (WHITELIST_SIZE <= 14) return false;

        if (ADDRESS_15 == addr) return true;
        if (WHITELIST_SIZE <= 15) return false;

        if (ADDRESS_16 == addr) return true;
        if (WHITELIST_SIZE <= 16) return false;

        if (ADDRESS_17 == addr) return true;
        if (WHITELIST_SIZE <= 17) return false;

        if (ADDRESS_18 == addr) return true;
        if (WHITELIST_SIZE <= 18) return false;

        if (ADDRESS_19 == addr) return true;
        if (WHITELIST_SIZE <= 19) return false;

        return ADDRESS_20 == addr;
    }

    /**
     * @notice Validates that an address is whitelisted, reverting if not
     * @param addr Address to validate (as bytes32 for cross-VM compatibility)
     */
    function validateWhitelisted(bytes32 addr) internal view {
        if (!isWhitelisted(addr)) {
            revert AddressNotWhitelisted(addr);
        }
    }

    /**
     * @notice Returns the list of whitelisted addresses
     * @return whitelist Array of whitelisted addresses (as bytes32 for cross-VM compatibility)
     */
    function getWhitelist() public view returns (bytes32[] memory) {
        bytes32[] memory whitelist = new bytes32[](WHITELIST_SIZE);

        if (WHITELIST_SIZE > 0) whitelist[0] = ADDRESS_1;
        if (WHITELIST_SIZE > 1) whitelist[1] = ADDRESS_2;
        if (WHITELIST_SIZE > 2) whitelist[2] = ADDRESS_3;
        if (WHITELIST_SIZE > 3) whitelist[3] = ADDRESS_4;
        if (WHITELIST_SIZE > 4) whitelist[4] = ADDRESS_5;
        if (WHITELIST_SIZE > 5) whitelist[5] = ADDRESS_6;
        if (WHITELIST_SIZE > 6) whitelist[6] = ADDRESS_7;
        if (WHITELIST_SIZE > 7) whitelist[7] = ADDRESS_8;
        if (WHITELIST_SIZE > 8) whitelist[8] = ADDRESS_9;
        if (WHITELIST_SIZE > 9) whitelist[9] = ADDRESS_10;
        if (WHITELIST_SIZE > 10) whitelist[10] = ADDRESS_11;
        if (WHITELIST_SIZE > 11) whitelist[11] = ADDRESS_12;
        if (WHITELIST_SIZE > 12) whitelist[12] = ADDRESS_13;
        if (WHITELIST_SIZE > 13) whitelist[13] = ADDRESS_14;
        if (WHITELIST_SIZE > 14) whitelist[14] = ADDRESS_15;
        if (WHITELIST_SIZE > 15) whitelist[15] = ADDRESS_16;
        if (WHITELIST_SIZE > 16) whitelist[16] = ADDRESS_17;
        if (WHITELIST_SIZE > 17) whitelist[17] = ADDRESS_18;
        if (WHITELIST_SIZE > 18) whitelist[18] = ADDRESS_19;
        if (WHITELIST_SIZE > 19) whitelist[19] = ADDRESS_20;

        return whitelist;
    }

    /**
     * @notice Returns the number of whitelisted addresses
     * @return Number of addresses in the whitelist
     */
    function getWhitelistSize() public view returns (uint256) {
        return WHITELIST_SIZE;
    }
}

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

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

/**
 * @title IProver
 * @notice Interface for proving intent fulfillment
 * @dev Defines required functionality for proving intent execution with different
 * proof mechanisms (storage or Hyperlane)
 */
interface IProver is ISemver {
    /**
     * @notice Proof data stored for each proven intent
     * @param claimant Address eligible to claim the intent rewards
     * @param destination Chain ID where the intent was proven
     */
    struct ProofData {
        address claimant;
        uint64 destination;
    }

    /**
     * @notice Arrays of intent hashes and claimants must have the same length
     */
    error ArrayLengthMismatch();

    /**
     * @notice Portal address cannot be zero
     */
    error ZeroPortal();

    /**
     * @notice Chain ID is too large to fit in uint64
     * @param chainId The chain ID that is too large
     */
    error ChainIdTooLarge(uint256 chainId);

    /**
     * @notice Emitted when an intent is successfully proven
     * @dev Emitted by the Prover on the source chain.
     * @param intentHash Hash of the proven intent
     * @param claimant Address eligible to claim the intent rewards
     * @param destination Destination chain ID where the intent was proven
     */
    event IntentProven(
        bytes32 indexed intentHash,
        address indexed claimant,
        uint64 destination
    );

    /**
     * @notice Emitted when an intent proof is invalidated
     * @param intentHash Hash of the invalidated intent
     */
    event IntentProofInvalidated(bytes32 indexed intentHash);

    /**
     * @notice Emitted when attempting to prove an already-proven intent
     * @dev Event instead of error to allow batch processing to continue
     * @param intentHash Hash of the already proven intent
     */
    event IntentAlreadyProven(bytes32 intentHash);

    /**
     * @notice Gets the proof mechanism type used by this prover
     * @return string indicating the prover's mechanism
     */
    function getProofType() external pure returns (string memory);

    /**
     * @notice Initiates the proving process for intents from the destination chain
     * @dev Implemented by specific prover mechanisms (storage, Hyperlane, Metalayer)
     * @param sender Address of the original transaction sender
     * @param sourceChainDomainID Domain ID of the source chain
     * @param encodedProofs Encoded (intentHash, claimant) pairs as bytes
     * @param data Additional data specific to the proving implementation
     *
     * @dev WARNING: sourceChainDomainID is NOT necessarily the same as chain ID.
     *      Each bridge provider uses their own domain ID mapping system:
     *      - Hyperlane: Uses custom domain IDs that may differ from chain IDs
     *      - LayerZero: Uses endpoint IDs that map to chains differently
     *      - Metalayer: Uses domain IDs specific to their routing system
     *      - Polymer: Uses chainIDs
     *      You MUST consult the specific bridge provider's documentation to determine
     *      the correct domain ID for the source chain.
     */
    function prove(
        address sender,
        uint64 sourceChainDomainID,
        bytes calldata encodedProofs,
        bytes calldata data
    ) external payable;

    /**
     * @notice Returns the proof data for a given intent hash
     * @param intentHash Hash of the intent to query
     * @return ProofData containing claimant and destination chain ID
     */
    function provenIntents(
        bytes32 intentHash
    ) external view returns (ProofData memory);

    /**
     * @notice Challenge an intent proof if destination chain ID doesn't match
     * @dev Can be called by anyone to remove invalid proofs. This is a safety mechanism to ensure
     *      intents are only claimable when executed on their intended destination chains.
     * @param destination The intended destination chain ID
     * @param routeHash The hash of the intent's route
     * @param rewardHash The hash of the reward specification
     */
    function challengeIntentProof(
        uint64 destination,
        bytes32 routeHash,
        bytes32 rewardHash
    ) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

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

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 9 of 10 : ISemver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/**
 * @title Semver Interface
 * @dev An interface for a contract that has a version
 */
interface ISemver {
    function version() external pure returns (string memory);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
    "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
    "@hyperlane-xyz/core/=node_modules/@hyperlane-xyz/core/",
    "@eth-optimism/contracts-bedrock/=node_modules/@eth-optimism/contracts-bedrock/",
    "@metalayer/contracts/=node_modules/@metalayer/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": true
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_portal","type":"address"},{"internalType":"address","name":"_crossL2ProverV2","type":"address"},{"internalType":"uint256","name":"_maxLogDataSize","type":"uint256"},{"internalType":"bytes32[]","name":"_proverAddresses","type":"bytes32[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"addr","type":"bytes32"}],"name":"AddressNotWhitelisted","type":"error"},{"inputs":[],"name":"ArrayLengthMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"ChainIdTooLarge","type":"error"},{"inputs":[],"name":"EmptyProofData","type":"error"},{"inputs":[{"internalType":"bytes32","name":"value","type":"bytes32"}],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidDestinationChain","type":"error"},{"inputs":[{"internalType":"address","name":"emittingContract","type":"address"}],"name":"InvalidEmittingContract","type":"error"},{"inputs":[],"name":"InvalidEventSignature","type":"error"},{"inputs":[],"name":"InvalidMaxLogDataSize","type":"error"},{"inputs":[],"name":"InvalidSourceChain","type":"error"},{"inputs":[],"name":"InvalidTopicsLength","type":"error"},{"inputs":[],"name":"MaxDataSizeExceeded","type":"error"},{"inputs":[],"name":"OnlyPortal","type":"error"},{"inputs":[],"name":"SizeMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"maxSize","type":"uint256"}],"name":"WhitelistSizeExceeded","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroPortal","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"name":"IntentAlreadyProven","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"source","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"encodedProofs","type":"bytes"}],"name":"IntentFulfilledFromSource","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"name":"IntentProofInvalidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"claimant","type":"address"},{"indexed":false,"internalType":"uint64","name":"destination","type":"uint64"}],"name":"IntentProven","type":"event"},{"inputs":[],"name":"CROSS_L2_PROVER_V2","outputs":[{"internalType":"contract ICrossL2ProverV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXPECTED_TOPIC_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LOG_DATA_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LOG_DATA_SIZE_GUARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PORTAL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROOF_SELECTOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROOF_TYPE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"destination","type":"uint64"},{"internalType":"bytes32","name":"routeHash","type":"bytes32"},{"internalType":"bytes32","name":"rewardHash","type":"bytes32"}],"name":"challengeIntentProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getProofType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getWhitelist","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"addr","type":"bytes32"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint64","name":"sourceChainDomainID","type":"uint64"},{"internalType":"bytes","name":"encodedProofs","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"prove","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"name":"provenIntents","outputs":[{"components":[{"internalType":"address","name":"claimant","type":"address"},{"internalType":"uint64","name":"destination","type":"uint64"}],"internalType":"struct IProver.ProofData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"validate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"proofs","type":"bytes[]"}],"name":"validateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]

0x61036060405234610617576123968038038061001a81610632565b92833981016080828203126106175761003282610657565b9061003f60208401610657565b6040840151606085015190949193916001600160401b03821161061757019082601f83011215610617578151926001600160401b03841161061c578360051b92602061008c818601610632565b8096815201906020829582010192831161061757602001905b828210610607575050506001600160a01b038116156105f6576080528151601481116105dd5750815160a0528151156105d55781511561053957515b60c05260018151116000146105ce578051600110156105395760408101515b60e05260028151116000146105c7578051600210156105395760608101515b6101005260038151116000146105c0578051600310156105395760808101515b6101205260048151116000146105b9578051600410156105395760a08101515b6101405260058151116000146105b2578051600510156105395760c08101515b6101605260068151116000146105ab578051600610156105395760e08101515b6101805260078151116000146105a457805160071015610539576101008101515b6101a052600881511160001461059d57805160081015610539576101208101515b6101c052600981511160001461059657805160091015610539576101408101515b6101e052600a81511160001461058f578051600a1015610539576101608101515b61020052600b815111600014610588578051600b1015610539576101808101515b61022052600c815111600014610581578051600c1015610539576101a08101515b61024052600d81511160001461057a578051600d1015610539576101c08101515b61026052600e815111600014610573578051600e1015610539576101e08101515b61028052600f81511160001461056c578051600f1015610539576102008101515b6102a052601081511160001461056557805160101015610539576102208101515b6102c052601181511160001461055e57805160111015610539576102408101515b6102e052601281511160001461055757805160121015610539576102608101515b61030052601381511160001461054f578051601310156105395761028001515b610320526001600160a01b0316908115610528578015801561051d575b61050c5760015561034052604051611d2a908161066c82396080518181816102c20152610858015260a0518181816105c2015281816109e30152611043015260c051818181610e5a0152611071015260e051818181610e2a01526110a1015261010051818181610dfa01526110d1015261012051818181610dca0152611101015261014051818181610d9a0152611131015261016051818181610d6a0152611161015261018051818181610d3a015261119101526101a051818181610d0a01526111c101526101c051818181610cda01526111f101526101e051818181610caa0152611221015261020051818181610c7a0152611251015261022051818181610c4a0152611281015261024051818181610c1a01526112b1015261026051818181610bea01526112e1015261028051818181610bba015261131101526102a051818181610b8a015261134101526102c051818181610b5a015261137101526102e051818181610b2a01526113a1015261030051818181610afa01526113d1015261032051818181610aca01526113ff015261034051818181610ed301526117520152f35b6313a53f3960e11b60005260046000fd5b506180008111610368565b63d92e233d60e01b60005260046000fd5b634e487b7160e01b600052603260045260246000fd5b50600061034b565b600061032b565b600061030a565b60006102e9565b60006102c8565b60006102a7565b6000610286565b6000610265565b6000610244565b6000610223565b6000610202565b60006101e1565b60006101c0565b600061019f565b600061017f565b600061015f565b600061013f565b600061011f565b6000610100565b5060006100e1565b63059291f560e51b600052600452601460245260446000fd5b631b973f8d60e11b60005260046000fd5b81518152602091820191016100a5565b600080fd5b634e487b7160e01b600052604160045260246000fd5b6040519190601f01601f191682016001600160401b0381118382101761061c57604052565b51906001600160a01b03821682036106175756fe6080604052600436101561001257600080fd5b60003560e01c806301a5e3fe1461013257806301ffc9a71461012d578063079febfd146101285780630ff754ea146101235780631a9cb9931461011e578063396e95441461011957806354fd4d501461011457806394612cf71461010f57806399d145b21461010a57806399db89b5146101055780639bcd850f146100fb5780639c18c7b514610100578063bc8c7df2146100fb578063bcd58bd2146100f6578063c16e50ef146100f1578063d01f63f5146100ec578063e4b4bc3f146100e75763fc0eab91146100e257600080fd5b610ef7565b610e88565b6109af565b61091d565b6107bf565b6105e5565b61065b565b61058c565b6104bf565b610442565b6103c9565b610322565b6102e6565b610277565b61023c565b61017d565b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602061016e600435611041565b6040519015158152f35b600080fd5b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361017857807f42c7e0fe0000000000000000000000000000000000000000000000000000000060209214908115610212575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438610207565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040516180008152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576020600154604051908152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405160408152f35b60005b83811061036f5750506000910152565b818101518382015260200161035f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604093602084526103c2815180928160208801526020888801910161035c565b0116010190565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761043e604080519061040a8183610704565b600382527f332e3200000000000000000000000000000000000000000000000000000000006020830152519182918261037f565b0390f35b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff8111610178573660238201121561017857806004013567ffffffffffffffff8111610178573660248260051b840101116101785760246104bd9201611465565b005b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043560006020604051610501816106e3565b8281520152600052600060205261043e604060002067ffffffffffffffff6040519161052c836106e3565b5473ffffffffffffffffffffffffffffffffffffffff8116835260a01c16602082015260405191829182919091602067ffffffffffffffff81604084019573ffffffffffffffffffffffffffffffffffffffff8151168552015116910152565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761043e604051610625604082610704565b600781527f506f6c796d65720000000000000000000000000000000000000000000000000060208201526040519182918261037f565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fd493dde4de24066db29a754b1e9dc5dedf7084850c4abf76c23046ba9dad6b1d8152f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176106ff57604052565b6106b4565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176106ff57604052565b73ffffffffffffffffffffffffffffffffffffffff81160361017857565b6024359067ffffffffffffffff8216820361017857565b6004359067ffffffffffffffff8216820361017857565b9181601f840112156101785782359167ffffffffffffffff8311610178576020838186019501011161017857565b60807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576107f4600435610745565b6107fc610763565b60443567ffffffffffffffff81116101785761081c903690600401610791565b60649291923567ffffffffffffffff81116101785761083f903690600401610791565b505073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036108f35760015481116108c9577fd493dde4de24066db29a754b1e9dc5dedf7084850c4abf76c23046ba9dad6b1d916108c467ffffffffffffffff92604051938493169583611525565b0390a2005b7f249148e20000000000000000000000000000000000000000000000000000000060005260046000fd5b7f3d1b206c0000000000000000000000000000000000000000000000000000000060005260046000fd5b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff81116101785761096f6104bd913690600401610791565b906116fe565b602060408183019282815284518094520192019060005b8181106109995750505090565b825184526020938401939092019160010161098c565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761043e7f00000000000000000000000000000000000000000000000000000000000000006013610a0d82611a3d565b9180610e58575b60018111610e28575b60028111610df8575b60038111610dc8575b60048111610d98575b60058111610d68575b60068111610d38575b60078111610d08575b60088111610cd8575b60098111610ca8575b600a8111610c78575b600b8111610c48575b600c8111610c18575b600d8111610be8575b600e8111610bb8575b600f8111610b88575b60108111610b58575b60118111610b28575b60128111610af8575b11610ac8575b60405191829182610975565b7f0000000000000000000000000000000000000000000000000000000000000000610af282611bca565b52610abc565b7f0000000000000000000000000000000000000000000000000000000000000000610b2284611bb9565b52610ab6565b7f0000000000000000000000000000000000000000000000000000000000000000610b5284611ba8565b52610aad565b7f0000000000000000000000000000000000000000000000000000000000000000610b8284611b97565b52610aa4565b7f0000000000000000000000000000000000000000000000000000000000000000610bb284611b86565b52610a9b565b7f0000000000000000000000000000000000000000000000000000000000000000610be284611b75565b52610a92565b7f0000000000000000000000000000000000000000000000000000000000000000610c1284611b64565b52610a89565b7f0000000000000000000000000000000000000000000000000000000000000000610c4284611b53565b52610a80565b7f0000000000000000000000000000000000000000000000000000000000000000610c7284611b42565b52610a77565b7f0000000000000000000000000000000000000000000000000000000000000000610ca284611b31565b52610a6e565b7f0000000000000000000000000000000000000000000000000000000000000000610cd284611b20565b52610a65565b7f0000000000000000000000000000000000000000000000000000000000000000610d0284611b0f565b52610a5c565b7f0000000000000000000000000000000000000000000000000000000000000000610d3284611afe565b52610a53565b7f0000000000000000000000000000000000000000000000000000000000000000610d6284611aee565b52610a4a565b7f0000000000000000000000000000000000000000000000000000000000000000610d9284611ade565b52610a41565b7f0000000000000000000000000000000000000000000000000000000000000000610dc284611ace565b52610a38565b7f0000000000000000000000000000000000000000000000000000000000000000610df284611abe565b52610a2f565b7f0000000000000000000000000000000000000000000000000000000000000000610e2284611aae565b52610a26565b7f0000000000000000000000000000000000000000000000000000000000000000610e5284611a9e565b52610a1d565b7f0000000000000000000000000000000000000000000000000000000000000000610e8284611a8c565b52610a14565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b346101785760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857610f2e61077a565b6024356044356040519060208201927fffffffffffffffff0000000000000000000000000000000000000000000000008560c01b1684526028830152604882015260488152610f7e606882610704565b51902090610f9e610f99836000526000602052604060002090565b6114e9565b73ffffffffffffffffffffffffffffffffffffffff610fd1825173ffffffffffffffffffffffffffffffffffffffff1690565b1615159182611021575b5050610fe357005b6000610ff9826000526000602052604060002090565b557fae165391a85a2219c7e5367bc7775dc0a2bc5cdf1f35e95204d716f6d96c2758600080a2005b60209091015167ffffffffffffffff918216925081161614153880610fdb565b7f0000000000000000000000000000000000000000000000000000000000000000801561142f57811561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600181111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600281111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600381111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600481111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600581111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600681111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600781111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600881111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600981111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600a81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600b81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600c81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600d81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600e81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600f81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857601081111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857601181111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857601281111561142f57817f0000000000000000000000000000000000000000000000000000000000000000146114285760131015611422577f00000000000000000000000000000000000000000000000000000000000000001490565b50600090565b5050600190565b5050600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9160005b828110156114e35760008160051b8501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1863603018112156114df5785019081359167ffffffffffffffff83116114df576020019082360382136114dc5750600192916114d6916116fe565b01611469565b80fd5b5080fd5b50915050565b906040516114f6816106e3565b915473ffffffffffffffffffffffffffffffffffffffff8116835260a01c67ffffffffffffffff166020830152565b90601f836040947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe093602086528160208701528686013760008582860101520116010190565b81601f8201121561017857805167ffffffffffffffff81116106ff57604051926115bd601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200185610704565b81845260208284010111610178576115db916020808501910161035c565b90565b9060808282031261017857815163ffffffff811681036101785792602083015161160781610745565b92604081015167ffffffffffffffff8111610178578361162891830161156b565b92606082015167ffffffffffffffff8111610178576115db920161156b565b6040513d6000823e3d90fd5b9060208282031261017857815167ffffffffffffffff8111610178576115db920161156b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff882019182116116d557565b611679565b908160061b91808304604014901517156116d557565b60080190816008116116d557565b6117399160009160405193849283927f0b9ca54a00000000000000000000000000000000000000000000000000000000845260048401611525565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115611a205760009182839284926119f9575b506117af6117ab73ffffffffffffffffffffffffffffffffffffffff8316611041565b1590565b6119b65750604082510361198c5780511561196257806020806117d793518301019101611653565b916117eb6117e584516116a8565b603f1690565b61193857604060208301519201517fd493dde4de24066db29a754b1e9dc5dedf7084850c4abf76c23046ba9dad6b1d602085015160c01c930361190e5767ffffffffffffffff469116036118e45763ffffffff168091036118ba5761185961185383516116a8565b60061c90565b9160005b83811061186a5750505050565b8061187e6118796001936116da565b6116f0565b83018460406020830151920151916118968360a01c90565b6118b2576118a66118ac93611bdb565b90611c29565b0161185d565b5050506118ac565b7fb86ac1ef0000000000000000000000000000000000000000000000000000000060005260046000fd5b7f9284b1970000000000000000000000000000000000000000000000000000000060005260046000fd5b7f0a26b0220000000000000000000000000000000000000000000000000000000060005260046000fd5b7fa24a13a60000000000000000000000000000000000000000000000000000000060005260046000fd5b7f2e181c990000000000000000000000000000000000000000000000000000000060005260046000fd5b7f0fe8ff7a0000000000000000000000000000000000000000000000000000000060005260046000fd5b7fc72266ef0000000000000000000000000000000000000000000000000000000060005273ffffffffffffffffffffffffffffffffffffffff1660045260246000fd5b92505050611a18913d8091833e611a108183610704565b8101906115de565b909138611788565b611647565b67ffffffffffffffff81116106ff5760051b60200190565b90611a4782611a25565b611a546040519182610704565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611a828294611a25565b0190602036910137565b805115611a995760200190565b611436565b805160011015611a995760400190565b805160021015611a995760600190565b805160031015611a995760800190565b805160041015611a995760a00190565b805160051015611a995760c00190565b805160061015611a995760e00190565b805160071015611a99576101000190565b805160081015611a99576101200190565b805160091015611a99576101400190565b8051600a1015611a99576101600190565b8051600b1015611a99576101800190565b8051600c1015611a99576101a00190565b8051600d1015611a99576101c00190565b8051600e1015611a99576101e00190565b8051600f1015611a99576102000190565b805160101015611a99576102200190565b805160111015611a99576102400190565b805160121015611a99576102600190565b805160131015611a99576102800190565b8060a01c611bfc5773ffffffffffffffffffffffffffffffffffffffff1690565b7f2bf950650000000000000000000000000000000000000000000000000000000060005260045260246000fd5b919082600052600060205260406000209081549073ffffffffffffffffffffffffffffffffffffffff8216611cf9577fffffffff0000000000000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff90911690811760a084901b7bffffffffffffffff0000000000000000000000000000000000000000161790915560405167ffffffffffffffff909216825291907fa79bcebf1cb6259b008ad946df35c764dd6b25206bb5c47ec11976cdce4f014590602090a3565b5050505060207fc86ca07015d7e87a46a98098d36c9fc68bc3120761e5c7a2023fc6c6869e561191604051908152a156000000000000000000000000399dbd5df04f83103f77a58cba2b7c4d3cdede9700000000000000000000000095cceae71605c5d97a0ac0ea13013b058729d075000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cbb2b55ab9309af49acc1689b3015b0d64150ca500000000000000000000000018781e08e53c206eadb237fb3e6f46d955125ea40000000000000000000000006ab10c02d6f595d61084a5a706c88add730031fe

Deployed Bytecode

0x6080604052600436101561001257600080fd5b60003560e01c806301a5e3fe1461013257806301ffc9a71461012d578063079febfd146101285780630ff754ea146101235780631a9cb9931461011e578063396e95441461011957806354fd4d501461011457806394612cf71461010f57806399d145b21461010a57806399db89b5146101055780639bcd850f146100fb5780639c18c7b514610100578063bc8c7df2146100fb578063bcd58bd2146100f6578063c16e50ef146100f1578063d01f63f5146100ec578063e4b4bc3f146100e75763fc0eab91146100e257600080fd5b610ef7565b610e88565b6109af565b61091d565b6107bf565b6105e5565b61065b565b61058c565b6104bf565b610442565b6103c9565b610322565b6102e6565b610277565b61023c565b61017d565b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602061016e600435611041565b6040519015158152f35b600080fd5b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361017857807f42c7e0fe0000000000000000000000000000000000000000000000000000000060209214908115610212575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438610207565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040516180008152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000399dbd5df04f83103f77a58cba2b7c4d3cdede97168152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576020600154604051908152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405160408152f35b60005b83811061036f5750506000910152565b818101518382015260200161035f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604093602084526103c2815180928160208801526020888801910161035c565b0116010190565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761043e604080519061040a8183610704565b600382527f332e3200000000000000000000000000000000000000000000000000000000006020830152519182918261037f565b0390f35b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff8111610178573660238201121561017857806004013567ffffffffffffffff8111610178573660248260051b840101116101785760246104bd9201611465565b005b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043560006020604051610501816106e3565b8281520152600052600060205261043e604060002067ffffffffffffffff6040519161052c836106e3565b5473ffffffffffffffffffffffffffffffffffffffff8116835260a01c16602082015260405191829182919091602067ffffffffffffffff81604084019573ffffffffffffffffffffffffffffffffffffffff8151168552015116910152565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517f00000000000000000000000000000000000000000000000000000000000000038152f35b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761043e604051610625604082610704565b600781527f506f6c796d65720000000000000000000000000000000000000000000000000060208201526040519182918261037f565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fd493dde4de24066db29a754b1e9dc5dedf7084850c4abf76c23046ba9dad6b1d8152f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176106ff57604052565b6106b4565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176106ff57604052565b73ffffffffffffffffffffffffffffffffffffffff81160361017857565b6024359067ffffffffffffffff8216820361017857565b6004359067ffffffffffffffff8216820361017857565b9181601f840112156101785782359167ffffffffffffffff8311610178576020838186019501011161017857565b60807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576107f4600435610745565b6107fc610763565b60443567ffffffffffffffff81116101785761081c903690600401610791565b60649291923567ffffffffffffffff81116101785761083f903690600401610791565b505073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000399dbd5df04f83103f77a58cba2b7c4d3cdede971633036108f35760015481116108c9577fd493dde4de24066db29a754b1e9dc5dedf7084850c4abf76c23046ba9dad6b1d916108c467ffffffffffffffff92604051938493169583611525565b0390a2005b7f249148e20000000000000000000000000000000000000000000000000000000060005260046000fd5b7f3d1b206c0000000000000000000000000000000000000000000000000000000060005260046000fd5b346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff81116101785761096f6104bd913690600401610791565b906116fe565b602060408183019282815284518094520192019060005b8181106109995750505090565b825184526020938401939092019160010161098c565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761043e7f00000000000000000000000000000000000000000000000000000000000000036013610a0d82611a3d565b9180610e58575b60018111610e28575b60028111610df8575b60038111610dc8575b60048111610d98575b60058111610d68575b60068111610d38575b60078111610d08575b60088111610cd8575b60098111610ca8575b600a8111610c78575b600b8111610c48575b600c8111610c18575b600d8111610be8575b600e8111610bb8575b600f8111610b88575b60108111610b58575b60118111610b28575b60128111610af8575b11610ac8575b60405191829182610975565b7f0000000000000000000000000000000000000000000000000000000000000000610af282611bca565b52610abc565b7f0000000000000000000000000000000000000000000000000000000000000000610b2284611bb9565b52610ab6565b7f0000000000000000000000000000000000000000000000000000000000000000610b5284611ba8565b52610aad565b7f0000000000000000000000000000000000000000000000000000000000000000610b8284611b97565b52610aa4565b7f0000000000000000000000000000000000000000000000000000000000000000610bb284611b86565b52610a9b565b7f0000000000000000000000000000000000000000000000000000000000000000610be284611b75565b52610a92565b7f0000000000000000000000000000000000000000000000000000000000000000610c1284611b64565b52610a89565b7f0000000000000000000000000000000000000000000000000000000000000000610c4284611b53565b52610a80565b7f0000000000000000000000000000000000000000000000000000000000000000610c7284611b42565b52610a77565b7f0000000000000000000000000000000000000000000000000000000000000000610ca284611b31565b52610a6e565b7f0000000000000000000000000000000000000000000000000000000000000000610cd284611b20565b52610a65565b7f0000000000000000000000000000000000000000000000000000000000000000610d0284611b0f565b52610a5c565b7f0000000000000000000000000000000000000000000000000000000000000000610d3284611afe565b52610a53565b7f0000000000000000000000000000000000000000000000000000000000000000610d6284611aee565b52610a4a565b7f0000000000000000000000000000000000000000000000000000000000000000610d9284611ade565b52610a41565b7f0000000000000000000000000000000000000000000000000000000000000000610dc284611ace565b52610a38565b7f0000000000000000000000000000000000000000000000000000000000000000610df284611abe565b52610a2f565b7f0000000000000000000000006ab10c02d6f595d61084a5a706c88add730031fe610e2284611aae565b52610a26565b7f00000000000000000000000018781e08e53c206eadb237fb3e6f46d955125ea4610e5284611a9e565b52610a1d565b7f000000000000000000000000cbb2b55ab9309af49acc1689b3015b0d64150ca5610e8284611a8c565b52610a14565b346101785760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000095cceae71605c5d97a0ac0ea13013b058729d075168152f35b346101785760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857610f2e61077a565b6024356044356040519060208201927fffffffffffffffff0000000000000000000000000000000000000000000000008560c01b1684526028830152604882015260488152610f7e606882610704565b51902090610f9e610f99836000526000602052604060002090565b6114e9565b73ffffffffffffffffffffffffffffffffffffffff610fd1825173ffffffffffffffffffffffffffffffffffffffff1690565b1615159182611021575b5050610fe357005b6000610ff9826000526000602052604060002090565b557fae165391a85a2219c7e5367bc7775dc0a2bc5cdf1f35e95204d716f6d96c2758600080a2005b60209091015167ffffffffffffffff918216925081161614153880610fdb565b7f0000000000000000000000000000000000000000000000000000000000000003801561142f57811561142f57817f000000000000000000000000cbb2b55ab9309af49acc1689b3015b0d64150ca51461142857600181111561142f57817f00000000000000000000000018781e08e53c206eadb237fb3e6f46d955125ea41461142857600281111561142f57817f0000000000000000000000006ab10c02d6f595d61084a5a706c88add730031fe1461142857600381111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600481111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600581111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600681111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600781111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600881111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600981111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600a81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600b81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600c81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600d81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600e81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857600f81111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857601081111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857601181111561142f57817f00000000000000000000000000000000000000000000000000000000000000001461142857601281111561142f57817f0000000000000000000000000000000000000000000000000000000000000000146114285760131015611422577f00000000000000000000000000000000000000000000000000000000000000001490565b50600090565b5050600190565b5050600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9160005b828110156114e35760008160051b8501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1863603018112156114df5785019081359167ffffffffffffffff83116114df576020019082360382136114dc5750600192916114d6916116fe565b01611469565b80fd5b5080fd5b50915050565b906040516114f6816106e3565b915473ffffffffffffffffffffffffffffffffffffffff8116835260a01c67ffffffffffffffff166020830152565b90601f836040947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe093602086528160208701528686013760008582860101520116010190565b81601f8201121561017857805167ffffffffffffffff81116106ff57604051926115bd601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200185610704565b81845260208284010111610178576115db916020808501910161035c565b90565b9060808282031261017857815163ffffffff811681036101785792602083015161160781610745565b92604081015167ffffffffffffffff8111610178578361162891830161156b565b92606082015167ffffffffffffffff8111610178576115db920161156b565b6040513d6000823e3d90fd5b9060208282031261017857815167ffffffffffffffff8111610178576115db920161156b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff882019182116116d557565b611679565b908160061b91808304604014901517156116d557565b60080190816008116116d557565b6117399160009160405193849283927f0b9ca54a00000000000000000000000000000000000000000000000000000000845260048401611525565b038173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000095cceae71605c5d97a0ac0ea13013b058729d075165afa908115611a205760009182839284926119f9575b506117af6117ab73ffffffffffffffffffffffffffffffffffffffff8316611041565b1590565b6119b65750604082510361198c5780511561196257806020806117d793518301019101611653565b916117eb6117e584516116a8565b603f1690565b61193857604060208301519201517fd493dde4de24066db29a754b1e9dc5dedf7084850c4abf76c23046ba9dad6b1d602085015160c01c930361190e5767ffffffffffffffff469116036118e45763ffffffff168091036118ba5761185961185383516116a8565b60061c90565b9160005b83811061186a5750505050565b8061187e6118796001936116da565b6116f0565b83018460406020830151920151916118968360a01c90565b6118b2576118a66118ac93611bdb565b90611c29565b0161185d565b5050506118ac565b7fb86ac1ef0000000000000000000000000000000000000000000000000000000060005260046000fd5b7f9284b1970000000000000000000000000000000000000000000000000000000060005260046000fd5b7f0a26b0220000000000000000000000000000000000000000000000000000000060005260046000fd5b7fa24a13a60000000000000000000000000000000000000000000000000000000060005260046000fd5b7f2e181c990000000000000000000000000000000000000000000000000000000060005260046000fd5b7f0fe8ff7a0000000000000000000000000000000000000000000000000000000060005260046000fd5b7fc72266ef0000000000000000000000000000000000000000000000000000000060005273ffffffffffffffffffffffffffffffffffffffff1660045260246000fd5b92505050611a18913d8091833e611a108183610704565b8101906115de565b909138611788565b611647565b67ffffffffffffffff81116106ff5760051b60200190565b90611a4782611a25565b611a546040519182610704565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611a828294611a25565b0190602036910137565b805115611a995760200190565b611436565b805160011015611a995760400190565b805160021015611a995760600190565b805160031015611a995760800190565b805160041015611a995760a00190565b805160051015611a995760c00190565b805160061015611a995760e00190565b805160071015611a99576101000190565b805160081015611a99576101200190565b805160091015611a99576101400190565b8051600a1015611a99576101600190565b8051600b1015611a99576101800190565b8051600c1015611a99576101a00190565b8051600d1015611a99576101c00190565b8051600e1015611a99576101e00190565b8051600f1015611a99576102000190565b805160101015611a99576102200190565b805160111015611a99576102400190565b805160121015611a99576102600190565b805160131015611a99576102800190565b8060a01c611bfc5773ffffffffffffffffffffffffffffffffffffffff1690565b7f2bf950650000000000000000000000000000000000000000000000000000000060005260045260246000fd5b919082600052600060205260406000209081549073ffffffffffffffffffffffffffffffffffffffff8216611cf9577fffffffff0000000000000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff90911690811760a084901b7bffffffffffffffff0000000000000000000000000000000000000000161790915560405167ffffffffffffffff909216825291907fa79bcebf1cb6259b008ad946df35c764dd6b25206bb5c47ec11976cdce4f014590602090a3565b5050505060207fc86ca07015d7e87a46a98098d36c9fc68bc3120761e5c7a2023fc6c6869e561191604051908152a156

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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