ETH Price: $4,167.87 (+0.49%)

Contract

0xb4Ef469c9d8317851270346070dA0ecE24616E6b

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Nominate Owner40443462025-06-24 17:45:5791 days ago1750787157IN
0xb4Ef469c...E24616E6b
0 ETH0.000000090.00105026

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
119257772025-09-23 23:03:083 hrs ago1758668588
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
119257772025-09-23 23:03:083 hrs ago1758668588
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
119257692025-09-23 23:03:003 hrs ago1758668580
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
119257692025-09-23 23:03:003 hrs ago1758668580
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40941962025-06-25 7:36:4790 days ago1750837007
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40941962025-06-25 7:36:4790 days ago1750837007
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40941902025-06-25 7:36:4190 days ago1750837001
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40941902025-06-25 7:36:4190 days ago1750837001
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40147742025-06-24 9:33:0591 days ago1750757585
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40147742025-06-24 9:33:0591 days ago1750757585
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40147682025-06-24 9:32:5991 days ago1750757579
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
40147682025-06-24 9:32:5991 days ago1750757579
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24832792025-06-06 16:08:10109 days ago1749226090
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24832792025-06-06 16:08:10109 days ago1749226090
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24832602025-06-06 16:07:51109 days ago1749226071
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24832602025-06-06 16:07:51109 days ago1749226071
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24832192025-06-06 16:07:10109 days ago1749226030
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24832192025-06-06 16:07:10109 days ago1749226030
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24831992025-06-06 16:06:50109 days ago1749226010
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24831992025-06-06 16:06:50109 days ago1749226010
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24821202025-06-06 15:48:51109 days ago1749224931
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24821202025-06-06 15:48:51109 days ago1749224931
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24821012025-06-06 15:48:32109 days ago1749224912
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24821012025-06-06 15:48:32109 days ago1749224912
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
24820542025-06-06 15:47:45109 days ago1749224865
0xb4Ef469c...E24616E6b
 Contract Creation0 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CapacitorFactory

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 1 : CapacitorFactory.sol
// SPDX-License-Identifier: GPL-3.0-only
// Sources flattened with hardhat v2.12.2 https://hardhat.org

// File contracts/interfaces/IDecapacitor.sol

pragma solidity 0.8.19;

/**
 * @title IDecapacitor interface
 * @notice Interface for a contract that verifies if a packed message is part of a packet or not
 */
interface IDecapacitor {
    /**
     * @notice Returns true if packed message is part of root.
     * @param root_ root hash of the packet.
     * @param packedMessage_ packed message which needs to be verified.
     * @param proof_ proof used to determine the inclusion
     * @dev This function is kept as view instead of pure, as in future we may have stateful decapacitors
     * @return isIncluded boolean indicating whether the message is included in the packet or not.
     */
    function verifyMessageInclusion(
        bytes32 root_,
        bytes32 packedMessage_,
        bytes calldata proof_
    ) external returns (bool isIncluded);
}


// File contracts/interfaces/ICapacitor.sol

pragma solidity 0.8.19;

/**
 * @title ICapacitor
 * @dev Interface for a Capacitor contract that stores and manages messages in packets
 */
interface ICapacitor {
    /**
     * @notice adds the packed message to a packet
     * @dev this should be only executable by socket
     * @param packedMessage the message packed with payload, fees and config
     */
    function addPackedMessage(bytes32 packedMessage) external;

    /**
     * @notice returns the latest packet details which needs to be sealed
     * @return root root hash of the latest packet which is not yet sealed
     * @return packetCount latest packet id which is not yet sealed
     */
    function getNextPacketToBeSealed()
        external
        view
        returns (bytes32 root, uint64 packetCount);

    /**
     * @notice returns the root of packet for given id
     * @param id the id assigned to packet
     * @return root root hash corresponding to given id
     */
    function getRootByCount(uint64 id) external view returns (bytes32 root);

    /**
     * @notice returns the maxPacketLength
     * @return maxPacketLength of the capacitor
     */
    function getMaxPacketLength()
        external
        view
        returns (uint256 maxPacketLength);

    /**
     * @notice seals the packet
     * @dev indicates the packet is ready to be shipped and no more messages can be added now.
     * @dev this should be called by socket only
     * @param batchSize_ used with packet batching capacitors
     * @return root root hash of the packet
     * @return packetCount id of the packed sealed
     */
    function sealPacket(
        uint256 batchSize_
    ) external returns (bytes32 root, uint64 packetCount);
}


// File contracts/interfaces/ICapacitorFactory.sol

pragma solidity 0.8.19;


/**
 * @title ICapacitorFactory
 * @notice Interface for a factory contract that deploys new instances of `ICapacitor` and `IDecapacitor` contracts.
 */
interface ICapacitorFactory {
    /**
     * @dev Emitted when an invalid capacitor type is requested during deployment.
     */
    error InvalidCapacitorType();

    /**
     * @notice Deploys a new instance of an `ICapacitor` and `IDecapacitor` contract with the specified parameters.
     * @param capacitorType The type of the capacitor to be deployed.
     * @param siblingChainSlug The identifier of the sibling chain.
     * @param maxPacketLength The maximum length of a packet.
     * @return Returns the deployed `ICapacitor` and `IDecapacitor` contract instances.
     */
    function deploy(
        uint256 capacitorType,
        uint32 siblingChainSlug,
        uint256 maxPacketLength
    ) external returns (ICapacitor, IDecapacitor);
}


// File lib/solmate/src/tokens/ERC20.sol

pragma solidity >=0.8.0;

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

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

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

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

    string public name;

    string public symbol;

    uint8 public immutable decimals;

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

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

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

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

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

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

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

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

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

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

        return true;
    }

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

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

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

        return true;
    }

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

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

        balanceOf[from] -= amount;

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

        emit Transfer(from, to, amount);

        return true;
    }

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

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

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

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

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

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

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

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

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

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

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

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

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

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


// File lib/solmate/src/utils/SafeTransferLib.sol

pragma solidity >=0.8.0;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}


// File contracts/libraries/RescueFundsLib.sol

pragma solidity 0.8.19;

error ZeroAddress();

/**
 * @title RescueFundsLib
 * @dev A library that provides a function to rescue funds from a contract.
 */

library RescueFundsLib {
    /**
     * @dev The address used to identify ETH.
     */
    address public constant ETH_ADDRESS =
        address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    /**
     * @dev thrown when the given token address don't have any code
     */
    error InvalidTokenAddress();

    /**
     * @dev Rescues funds from a contract.
     * @param token_ The address of the token contract.
     * @param rescueTo_ The address of the user.
     * @param amount_ The amount of tokens to be rescued.
     */
    function rescueFunds(
        address token_,
        address rescueTo_,
        uint256 amount_
    ) internal {
        if (rescueTo_ == address(0)) revert ZeroAddress();

        if (token_ == ETH_ADDRESS) {
            SafeTransferLib.safeTransferETH(rescueTo_, amount_);
        } else {
            if (token_.code.length == 0) revert InvalidTokenAddress();
            SafeTransferLib.safeTransfer(ERC20(token_), rescueTo_, amount_);
        }
    }
}


// File contracts/utils/AccessRoles.sol

pragma solidity 0.8.19;

// contains role hashes used in socket dl for various different operations

// used to rescue funds
bytes32 constant RESCUE_ROLE = keccak256("RESCUE_ROLE");
// used to withdraw fees
bytes32 constant WITHDRAW_ROLE = keccak256("WITHDRAW_ROLE");
// used to trip switchboards
bytes32 constant TRIP_ROLE = keccak256("TRIP_ROLE");
// used to un trip switchboards
bytes32 constant UN_TRIP_ROLE = keccak256("UN_TRIP_ROLE");
// used by governance
bytes32 constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");
//used by executors which executes message at destination
bytes32 constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
// used by transmitters who seal and propose packets in socket
bytes32 constant TRANSMITTER_ROLE = keccak256("TRANSMITTER_ROLE");
// used by switchboard watchers who work against transmitters
bytes32 constant WATCHER_ROLE = keccak256("WATCHER_ROLE");
// used by fee updaters responsible for updating fees at switchboards, transmit manager and execution manager
bytes32 constant FEES_UPDATER_ROLE = keccak256("FEES_UPDATER_ROLE");


// File contracts/utils/Ownable.sol

pragma solidity 0.8.19;

/**
 * @title Ownable
 * @dev The Ownable contract provides a simple way to manage ownership of a contract
 * and allows for ownership to be transferred to a nominated address.
 */
abstract contract Ownable {
    address private _owner;
    address private _nominee;

    event OwnerNominated(address indexed nominee);
    event OwnerClaimed(address indexed claimer);

    error OnlyOwner();
    error OnlyNominee();

    /**
     * @dev Sets the contract's owner to the address that is passed to the constructor.
     */
    constructor(address owner_) {
        _claimOwner(owner_);
    }

    /**
     * @dev Modifier that restricts access to only the contract's owner.
     * Throws an error if the caller is not the owner.
     */
    modifier onlyOwner() {
        if (msg.sender != _owner) revert OnlyOwner();
        _;
    }

    /**
     * @dev Returns the current owner of the contract.
     */
    function owner() external view returns (address) {
        return _owner;
    }

    /**
     * @dev Returns the current nominee for ownership of the contract.
     */
    function nominee() external view returns (address) {
        return _nominee;
    }

    /**
     * @dev Allows the current owner to nominate a new owner for the contract.
     * Throws an error if the caller is not the owner.
     * Emits an `OwnerNominated` event with the address of the nominee.
     */
    function nominateOwner(address nominee_) external {
        if (msg.sender != _owner) revert OnlyOwner();
        _nominee = nominee_;
        emit OwnerNominated(_nominee);
    }

    /**
     * @dev Allows the nominated owner to claim ownership of the contract.
     * Throws an error if the caller is not the nominee.
     * Sets the nominated owner as the new owner of the contract.
     * Emits an `OwnerClaimed` event with the address of the new owner.
     */
    function claimOwner() external {
        if (msg.sender != _nominee) revert OnlyNominee();
        _claimOwner(msg.sender);
    }

    /**
     * @dev Internal function that sets the owner of the contract to the specified address
     * and sets the nominee to address(0).
     */
    function _claimOwner(address claimer_) internal {
        _owner = claimer_;
        _nominee = address(0);
        emit OwnerClaimed(claimer_);
    }
}


// File contracts/utils/AccessControl.sol

pragma solidity 0.8.19;

/**
 * @title AccessControl
 * @dev This abstract contract implements access control mechanism based on roles.
 * Each role can have one or more addresses associated with it, which are granted
 * permission to execute functions with the onlyRole modifier.
 */
abstract contract AccessControl is Ownable {
    /**
     * @dev A mapping of roles to a mapping of addresses to boolean values indicating whether or not they have the role.
     */
    mapping(bytes32 => mapping(address => bool)) private _permits;

    /**
     * @dev Emitted when a role is granted to an address.
     */
    event RoleGranted(bytes32 indexed role, address indexed grantee);

    /**
     * @dev Emitted when a role is revoked from an address.
     */
    event RoleRevoked(bytes32 indexed role, address indexed revokee);

    /**
     * @dev Error message thrown when an address does not have permission to execute a function with onlyRole modifier.
     */
    error NoPermit(bytes32 role);

    /**
     * @dev Constructor that sets the owner of the contract.
     */
    constructor(address owner_) Ownable(owner_) {}

    /**
     * @dev Modifier that restricts access to addresses having roles
     * Throws an error if the caller do not have permit
     */
    modifier onlyRole(bytes32 role) {
        if (!_permits[role][msg.sender]) revert NoPermit(role);
        _;
    }

    /**
     * @dev Checks and reverts if an address do not have a specific role.
     * @param role_ The role to check.
     * @param address_ The address to check.
     */
    function _checkRole(bytes32 role_, address address_) internal virtual {
        if (!_hasRole(role_, address_)) revert NoPermit(role_);
    }

    /**
     * @dev Grants a role to a given address.
     * @param role_ The role to grant.
     * @param grantee_ The address to grant the role to.
     * Emits a RoleGranted event.
     * Can only be called by the owner of the contract.
     */
    function grantRole(
        bytes32 role_,
        address grantee_
    ) external virtual onlyOwner {
        _grantRole(role_, grantee_);
    }

    /**
     * @dev Revokes a role from a given address.
     * @param role_ The role to revoke.
     * @param revokee_ The address to revoke the role from.
     * Emits a RoleRevoked event.
     * Can only be called by the owner of the contract.
     */
    function revokeRole(
        bytes32 role_,
        address revokee_
    ) external virtual onlyOwner {
        _revokeRole(role_, revokee_);
    }

    /**
     * @dev Internal function to grant a role to a given address.
     * @param role_ The role to grant.
     * @param grantee_ The address to grant the role to.
     * Emits a RoleGranted event.
     */
    function _grantRole(bytes32 role_, address grantee_) internal {
        _permits[role_][grantee_] = true;
        emit RoleGranted(role_, grantee_);
    }

    /**
     * @dev Internal function to revoke a role from a given address.
     * @param role_ The role to revoke.
     * @param revokee_ The address to revoke the role from.
     * Emits a RoleRevoked event.
     */
    function _revokeRole(bytes32 role_, address revokee_) internal {
        _permits[role_][revokee_] = false;
        emit RoleRevoked(role_, revokee_);
    }

    /**
     * @dev Checks whether an address has a specific role.
     * @param role_ The role to check.
     * @param address_ The address to check.
     * @return A boolean value indicating whether or not the address has the role.
     */
    function hasRole(
        bytes32 role_,
        address address_
    ) external view returns (bool) {
        return _hasRole(role_, address_);
    }

    function _hasRole(
        bytes32 role_,
        address address_
    ) internal view returns (bool) {
        return _permits[role_][address_];
    }
}


// File contracts/decapacitors/SingleDecapacitor.sol

pragma solidity 0.8.19;




/**
 * @title SingleDecapacitor
 * @notice A decapacitor that verifies messages by checking if the packed message is equal to the root.
 * @dev This contract inherits from the `IDecapacitor` interface, which
 * defines the functions for verifying message inclusion.
 */
contract SingleDecapacitor is IDecapacitor, AccessControl {
    /**
     * @notice Initializes the SingleDecapacitor contract with an owner address.
     * @param owner_ The address of the contract owner
     */
    constructor(address owner_) AccessControl(owner_) {
        _grantRole(RESCUE_ROLE, owner_);
    }

    /**
     * @inheritdoc IDecapacitor
     * @dev Just checks if root equals packed message since each packet has single message.
     * @dev Proof is ignored in this capacitor.
     */
    function verifyMessageInclusion(
        bytes32 root_,
        bytes32 packedMessage_,
        bytes calldata /* proof */
    ) external pure override returns (bool isIncluded) {
        return root_ == packedMessage_;
    }

    /**
     * @notice Rescues funds from the contract if they are locked by mistake.
     * @param token_ The address of the token contract.
     * @param rescueTo_ The address where rescued tokens need to be sent.
     * @param amount_ The amount of tokens to be rescued.
     */
    function rescueFunds(
        address token_,
        address rescueTo_,
        uint256 amount_
    ) external onlyRole(RESCUE_ROLE) {
        RescueFundsLib.rescueFunds(token_, rescueTo_, amount_);
    }
}


// File contracts/capacitors/BaseCapacitor.sol

pragma solidity 0.8.19;




/**
 * @title BaseCapacitor
 * @dev Abstract base contract for the Capacitors. Implements shared functionality and provides
 * access control.
 */
abstract contract BaseCapacitor is ICapacitor, AccessControl {
    /// address of socket
    address public immutable socket;

    /// an incrementing count for the next packet that is being created
    uint64 internal _nextPacketCount;

    /// tracks the count of next packet that will be sealed
    uint64 internal _nextSealCount;

    /// maps the packet count with the root hash of that packet
    mapping(uint64 => bytes32) internal _roots;

    // Error triggered when not called by socket
    error OnlySocket();

    /**
     * @dev Throws if called by any account other than the socket.
     */
    modifier onlySocket() {
        if (msg.sender != socket) revert OnlySocket();
        _;
    }

    /**
     * @dev Initializes the contract with the specified socket address.
     * @param socket_ The address of the socket contract.
     * @param owner_ The address of the owner of the capacitor contract.
     */
    constructor(address socket_, address owner_) AccessControl(owner_) {
        socket = socket_;
        _grantRole(RESCUE_ROLE, owner_);
    }

    /**
     * @dev Returns the count of the latest packet that finished filling.
     * @dev Returns 0 in case 0 or 1 packets are filled, hence this case should be considered by the caller
     * @return lastFilledPacket count of the latest packet.
     */
    function getLastFilledPacket()
        external
        view
        returns (uint256 lastFilledPacket)
    {
        return _nextPacketCount == 0 ? 0 : _nextPacketCount - 1;
    }

    /**
     * @dev Rescues funds from the contract.
     * @param token_ The address of the token to rescue.
     * @param rescueTo_ The address of the user to rescue tokens for.
     * @param amount_ The amount of tokens to rescue.
     */
    function rescueFunds(
        address token_,
        address rescueTo_,
        uint256 amount_
    ) external onlyRole(RESCUE_ROLE) {
        RescueFundsLib.rescueFunds(token_, rescueTo_, amount_);
    }
}


// File contracts/capacitors/SingleCapacitor.sol

pragma solidity 0.8.19;

/**
 * @title SingleCapacitor
 * @notice A capacitor that adds a single message to each packet.
 * @dev This contract inherits from the `BaseCapacitor` contract, which provides the
 * basic storage and common function implementations.
 */
contract SingleCapacitor is BaseCapacitor {
    // Error triggered when no new packet/message is there to be sealed
    error NoPendingPacket();

    /**
     * @notice emitted when a new message is added to a packet
     * @param packedMessage the message packed with payload, fees and config
     * @param packetCount an incremental id assigned to each new packet created on this capacitor
     * @param newRootHash Hash of full packet. Same as packedMessage since this capacitor has one message per packet.
     */
    event MessageAdded(
        bytes32 packedMessage,
        uint64 packetCount,
        bytes32 newRootHash
    );

    /**
     * @dev Initializes the contract with the specified socket address.
     * @param socket_ The address of the socket contract.
     * @param owner_ The address of the owner of the capacitor contract.
     */
    constructor(
        address socket_,
        address owner_
    ) BaseCapacitor(socket_, owner_) {}

    /**
     * @inheritdoc ICapacitor
     */
    function getMaxPacketLength() external pure override returns (uint256) {
        return 1;
    }

    /**
     * @inheritdoc ICapacitor
     */
    function addPackedMessage(
        bytes32 packedMessage_
    ) external override onlySocket {
        uint64 packetCount = _nextPacketCount++;
        _roots[packetCount] = packedMessage_;

        // as it is a single capacitor, here root and packed message are same
        emit MessageAdded(packedMessage_, packetCount, packedMessage_);
    }

    /**
     * @inheritdoc ICapacitor
     */
    function sealPacket(
        uint256
    ) external override onlySocket returns (bytes32, uint64) {
        uint64 packetCount = _nextSealCount++;
        if (_roots[packetCount] == bytes32(0)) revert NoPendingPacket();

        bytes32 root = _roots[packetCount];
        return (root, packetCount);
    }

    /**
     * @inheritdoc ICapacitor
     */
    function getNextPacketToBeSealed()
        external
        view
        override
        returns (bytes32, uint64)
    {
        uint64 toSeal = _nextSealCount;
        return (_roots[toSeal], toSeal);
    }

    /**
     * @dev Returns the root hash of the packet with the specified count.
     * @param count_ The count of the packet.
     * @return The root hash of the packet.
     */
    function getRootByCount(
        uint64 count_
    ) external view override returns (bytes32) {
        return _roots[count_];
    }
}


// File contracts/CapacitorFactory.sol

pragma solidity 0.8.19;





/**
 * @title CapacitorFactory
 * @notice Factory contract for creating capacitor and decapacitor pairs.
 * @dev The capacitorType_ parameter determines the type of capacitor and decapacitor to deploy.
 * @dev More types can be introduced by deploying new contract and pointing to it on Socket.
 */
contract CapacitorFactory is ICapacitorFactory, AccessControl {
    uint256 private constant SINGLE_CAPACITOR = 1;

    // min packet length to avoid div by 0 in fee calculations
    uint256 public constant minAllowedPacketLength = 1;

    // admin initialized max value for max packet length
    uint256 public immutable maxAllowedPacketLength;

    error PacketLengthNotAllowed();

    /**
     * @notice initializes and grants RESCUE_ROLE to owner.
     * @param owner_ The address of the owner of the contract.
     * @param maxAllowedPacketLength_ The max length allowed for capacitors
     */
    constructor(
        address owner_,
        uint256 maxAllowedPacketLength_
    ) AccessControl(owner_) {
        _grantRole(RESCUE_ROLE, owner_);
        maxAllowedPacketLength = maxAllowedPacketLength_;
    }

    /**
     * @notice Creates a new capacitor and decapacitor pair based on the given type.
     * @dev It sets the CapacitorFactory owner as owner of new Capacitor and Decapacitor
     * @param capacitorType_ The type of capacitor to be created. Can be SINGLE_CAPACITOR or HASH_CHAIN_CAPACITOR.
     * @dev siblingChainSlug_ sibling chain slug can be used for chain specific capacitors, useful while expanding to non-EVM chains.
     * @param maxPacketLength_ is not being used with single capacitor system, will be useful with batching.
     */
    function deploy(
        uint256 capacitorType_,
        uint32 /** siblingChainSlug_ */,
        uint256 maxPacketLength_
    ) external override returns (ICapacitor, IDecapacitor) {
        if (
            maxPacketLength_ < minAllowedPacketLength ||
            maxPacketLength_ > maxAllowedPacketLength
        ) revert PacketLengthNotAllowed();

        // fetch the capacitor factory owner
        address owner = this.owner();

        if (capacitorType_ == SINGLE_CAPACITOR) {
            return (
                // msg.sender is socket address
                new SingleCapacitor(msg.sender, owner),
                new SingleDecapacitor(owner)
            );
        }
        revert InvalidCapacitorType();
    }

    /**
     * @notice Rescues funds from the contract if they are locked by mistake.
     * @param token_ The address of the token contract.
     * @param rescueTo_ The address where rescued tokens need to be sent.
     * @param amount_ The amount of tokens to be rescued.
     */
    function rescueFunds(
        address token_,
        address rescueTo_,
        uint256 amount_
    ) external onlyRole(RESCUE_ROLE) {
        RescueFundsLib.rescueFunds(token_, rescueTo_, amount_);
    }
}

Settings
{
  "libraries": {},
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"maxAllowedPacketLength_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidCapacitorType","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"NoPermit","type":"error"},{"inputs":[],"name":"OnlyNominee","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"PacketLengthNotAllowed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"OwnerClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominee","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"grantee","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"revokee","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"claimOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"capacitorType_","type":"uint256"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"maxPacketLength_","type":"uint256"}],"name":"deploy","outputs":[{"internalType":"contract ICapacitor","name":"","type":"address"},{"internalType":"contract IDecapacitor","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"grantee_","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"address_","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAllowedPacketLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAllowedPacketLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nominee_","type":"address"}],"name":"nominateOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"rescueTo_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"revokee_","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a060405234801561001057600080fd5b506040516126b73803806126b783398101604081905261002f9161011e565b818061003a81610070565b5061006790507fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f29253836100c3565b60805250610158565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000806040838503121561013157600080fd5b82516001600160a01b038116811461014857600080fd5b6020939093015192949293505050565b60805161253d61017a600039600081816102040152610235015261253d6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636ccae05411610081578063d547741f1161005b578063d547741f146101d6578063d6a47312146101e9578063f4ca9b24146101ff57600080fd5b80636ccae054146101825780638da5cb5b1461019557806391d14854146101b357600080fd5b80632f2ff15d116100b25780632f2ff15d146101525780633bd1adec146101675780635b94db271461016f57600080fd5b806320f99c0a146100ce578063284fb36314610112575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610125610120366004610a6b565b610226565b6040805173ffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610109565b610165610160366004610ad1565b6103e3565b005b610165610442565b61016561017d366004610b01565b61049e565b610165610190366004610b1e565b61055e565b60005473ffffffffffffffffffffffffffffffffffffffff166100e8565b6101c66101c1366004610ad1565b610601565b6040519015158152602001610109565b6101656101e4366004610ad1565b61063c565b6101f1600181565b604051908152602001610109565b6101f17f000000000000000000000000000000000000000000000000000000000000000081565b600080600183108061025757507f000000000000000000000000000000000000000000000000000000000000000083115b1561028e576040517f83d360ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ff9190610b4e565b9050600186036103a957338160405161031790610a51565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f080158015610357573d6000803e3d6000fd5b508160405161036590610a5e565b73ffffffffffffffffffffffffffffffffffffffff9091168152602001604051809103906000f08015801561039e573d6000803e3d6000fd5b5092509250506103db565b6040517f3935408900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610434576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61043e8282610697565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610493576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61049c3361071d565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ef576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166105f0576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6105fb848484610795565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461068d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61043e828261088a565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff82166107e2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff84160161082e57610829828261090d565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b60000361087f576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610829838383610982565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af1905080610829576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016105e7565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806105fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016105e7565b610edb80610b6c83390190565b610ac180611a4783390190565b600080600060608486031215610a8057600080fd5b83359250602084013563ffffffff81168114610a9b57600080fd5b929592945050506040919091013590565b73ffffffffffffffffffffffffffffffffffffffff81168114610ace57600080fd5b50565b60008060408385031215610ae457600080fd5b823591506020830135610af681610aac565b809150509250929050565b600060208284031215610b1357600080fd5b813561063581610aac565b600080600060608486031215610b3357600080fd5b8335610b3e81610aac565b92506020840135610a9b81610aac565b600060208284031215610b6057600080fd5b815161063581610aac56fe60a060405234801561001057600080fd5b50604051610edb380380610edb83398101604081905261002f91610148565b8181808061003c8161007e565b50506001600160a01b0382166080526100757fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f29253826100d1565b5050505061017b565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b80516001600160a01b038116811461014357600080fd5b919050565b6000806040838503121561015b57600080fd5b6101648361012c565b91506101726020840161012c565b90509250929050565b608051610d376101a4600039600081816101430152818161056301526106cb0152610d376000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80636ccae054116100975780639471651e116100665780639471651e14610215578063d1af313c1461025d578063d547741f14610287578063d7c9eaac1461029a57600080fd5b80636ccae054146101ae5780638da5cb5b146101c157806391d14854146101df578063920ee8a81461020257600080fd5b80632ff9f2c9116100d35780632ff9f2c91461017a5780633bd1adec1461018b5780635b94db27146101935780636afc0f38146101a657600080fd5b806320f99c0a146100fa57806322c8f6cd1461013e5780632f2ff15d14610165575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101147f000000000000000000000000000000000000000000000000000000000000000081565b610178610173366004610bbd565b6102ad565b005b60015b604051908152602001610135565b61017861030c565b6101786101a1366004610be9565b610368565b61017d610428565b6101786101bc366004610c04565b61046d565b60005473ffffffffffffffffffffffffffffffffffffffff16610114565b6101f26101ed366004610bbd565b610510565b6040519015158152602001610135565b610178610210366004610c40565b61054b565b60035468010000000000000000900467ffffffffffffffff16600081815260046020526040902054905b6040805192835267ffffffffffffffff909116602083015201610135565b61017d61026b366004610c59565b67ffffffffffffffff1660009081526004602052604090205490565b610178610295366004610bbd565b610655565b61023f6102a8366004610c40565b6106b0565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102fe576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826107da565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461035d576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61036633610860565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103b9576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b60035460009067ffffffffffffffff161561045b576003546104569060019067ffffffffffffffff16610cb2565b61045e565b60005b67ffffffffffffffff16905090565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166104ff576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61050a8484846108d8565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105ba576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009167ffffffffffffffff90911690826105d883610cda565b82546101009290920a67ffffffffffffffff818102199093169183160217909155811660008181526004602090815260409182902086905581518681529081019290925281018490529091507f9ed9683bfff0f737f91f20945e98c912976d94e76860b05b48b15bc0d589be1f9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a6576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826109cd565b6000803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610722576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546000916801000000000000000090910467ffffffffffffffff1690600861074c83610cda565b82546101009290920a67ffffffffffffffff81810219909316918316021790915581166000908152600460205260409020549091506107b7576040517fa902392300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526004602052604090205492509050915091565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff8216610925576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016109715761096c8282610a50565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b6000036109c2576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096c838383610ac5565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af190508061096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016104f6565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061050a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016104f6565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb857600080fd5b919050565b60008060408385031215610bd057600080fd5b82359150610be060208401610b94565b90509250929050565b600060208284031215610bfb57600080fd5b61054482610b94565b600080600060608486031215610c1957600080fd5b610c2284610b94565b9250610c3060208501610b94565b9150604084013590509250925092565b600060208284031215610c5257600080fd5b5035919050565b600060208284031215610c6b57600080fd5b813567ffffffffffffffff8116811461054457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610cd357610cd3610c83565b5092915050565b600067ffffffffffffffff808316818103610cf757610cf7610c83565b600101939250505056fea26469706673582212200e9ad1c7907b958bd17050e3a3e7333638ad97b82c9cf9912b5a59c257132e1f64736f6c63430008130033608060405234801561001057600080fd5b50604051610ac1380380610ac183398101604081905261002f9161011b565b808061003a8161006d565b5061006790507fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f29253826100c0565b5061014b565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b60006020828403121561012d57600080fd5b81516001600160a01b038116811461014457600080fd5b9392505050565b6109678061015a6000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80635b94db27116100765780638da5cb5b1161005b5780638da5cb5b1461015357806391d1485414610171578063d547741f1461018457600080fd5b80635b94db271461012d5780636ccae0541461014057600080fd5b806320f99c0a146100a85780632d095c43146100ec5780632f2ff15d146101105780633bd1adec14610125575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101006100fa366004610805565b50501490565b60405190151581526020016100e3565b61012361011e3660046108ae565b610197565b005b6101236101f6565b61012361013b3660046108da565b610252565b61012361014e3660046108f5565b610312565b60005473ffffffffffffffffffffffffffffffffffffffff166100c2565b61010061017f3660046108ae565b6103b5565b6101236101923660046108ae565b6103f0565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101e8576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f2828261044b565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610247576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610250336104d1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102a3576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166103a4576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6103af848484610549565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610441576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f2828261063e565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff8216610596576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016105e2576105dd82826106c1565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b600003610633576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105dd838383610736565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af19050806105dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c454400000000000000000000000000604482015260640161039b565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806103af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c45440000000000000000000000000000000000604482015260640161039b565b6000806000806060858703121561081b57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561084157600080fd5b818701915087601f83011261085557600080fd5b81358181111561086457600080fd5b88602082850101111561087657600080fd5b95989497505060200194505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108a957600080fd5b919050565b600080604083850312156108c157600080fd5b823591506108d160208401610885565b90509250929050565b6000602082840312156108ec57600080fd5b6103e982610885565b60008060006060848603121561090a57600080fd5b61091384610885565b925061092160208501610885565b915060408401359050925092509256fea2646970667358221220b917ec53e94feb877107d694f6da6360b795610f2218c1647ae6a87c371e46bc64736f6c63430008130033a2646970667358221220583c22f22968be0212c7ff60d875a454e4c97b9d1a6944dc43b4396c0277f93664736f6c63430008130033000000000000000000000000b0bbff6311b7f245761a7846d3ce7b1b100c1836000000000000000000000000000000000000000000000000000000000000000a

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100c95760003560e01c80636ccae05411610081578063d547741f1161005b578063d547741f146101d6578063d6a47312146101e9578063f4ca9b24146101ff57600080fd5b80636ccae054146101825780638da5cb5b1461019557806391d14854146101b357600080fd5b80632f2ff15d116100b25780632f2ff15d146101525780633bd1adec146101675780635b94db271461016f57600080fd5b806320f99c0a146100ce578063284fb36314610112575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610125610120366004610a6b565b610226565b6040805173ffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610109565b610165610160366004610ad1565b6103e3565b005b610165610442565b61016561017d366004610b01565b61049e565b610165610190366004610b1e565b61055e565b60005473ffffffffffffffffffffffffffffffffffffffff166100e8565b6101c66101c1366004610ad1565b610601565b6040519015158152602001610109565b6101656101e4366004610ad1565b61063c565b6101f1600181565b604051908152602001610109565b6101f17f000000000000000000000000000000000000000000000000000000000000000a81565b600080600183108061025757507f000000000000000000000000000000000000000000000000000000000000000a83115b1561028e576040517f83d360ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ff9190610b4e565b9050600186036103a957338160405161031790610a51565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f080158015610357573d6000803e3d6000fd5b508160405161036590610a5e565b73ffffffffffffffffffffffffffffffffffffffff9091168152602001604051809103906000f08015801561039e573d6000803e3d6000fd5b5092509250506103db565b6040517f3935408900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610434576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61043e8282610697565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610493576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61049c3361071d565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ef576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166105f0576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6105fb848484610795565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461068d576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61043e828261088a565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff82166107e2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff84160161082e57610829828261090d565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b60000361087f576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610829838383610982565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af1905080610829576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016105e7565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806105fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016105e7565b610edb80610b6c83390190565b610ac180611a4783390190565b600080600060608486031215610a8057600080fd5b83359250602084013563ffffffff81168114610a9b57600080fd5b929592945050506040919091013590565b73ffffffffffffffffffffffffffffffffffffffff81168114610ace57600080fd5b50565b60008060408385031215610ae457600080fd5b823591506020830135610af681610aac565b809150509250929050565b600060208284031215610b1357600080fd5b813561063581610aac565b600080600060608486031215610b3357600080fd5b8335610b3e81610aac565b92506020840135610a9b81610aac565b600060208284031215610b6057600080fd5b815161063581610aac56fe60a060405234801561001057600080fd5b50604051610edb380380610edb83398101604081905261002f91610148565b8181808061003c8161007e565b50506001600160a01b0382166080526100757fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f29253826100d1565b5050505061017b565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b80516001600160a01b038116811461014357600080fd5b919050565b6000806040838503121561015b57600080fd5b6101648361012c565b91506101726020840161012c565b90509250929050565b608051610d376101a4600039600081816101430152818161056301526106cb0152610d376000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80636ccae054116100975780639471651e116100665780639471651e14610215578063d1af313c1461025d578063d547741f14610287578063d7c9eaac1461029a57600080fd5b80636ccae054146101ae5780638da5cb5b146101c157806391d14854146101df578063920ee8a81461020257600080fd5b80632ff9f2c9116100d35780632ff9f2c91461017a5780633bd1adec1461018b5780635b94db27146101935780636afc0f38146101a657600080fd5b806320f99c0a146100fa57806322c8f6cd1461013e5780632f2ff15d14610165575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101147f000000000000000000000000000000000000000000000000000000000000000081565b610178610173366004610bbd565b6102ad565b005b60015b604051908152602001610135565b61017861030c565b6101786101a1366004610be9565b610368565b61017d610428565b6101786101bc366004610c04565b61046d565b60005473ffffffffffffffffffffffffffffffffffffffff16610114565b6101f26101ed366004610bbd565b610510565b6040519015158152602001610135565b610178610210366004610c40565b61054b565b60035468010000000000000000900467ffffffffffffffff16600081815260046020526040902054905b6040805192835267ffffffffffffffff909116602083015201610135565b61017d61026b366004610c59565b67ffffffffffffffff1660009081526004602052604090205490565b610178610295366004610bbd565b610655565b61023f6102a8366004610c40565b6106b0565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102fe576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826107da565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461035d576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61036633610860565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103b9576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b60035460009067ffffffffffffffff161561045b576003546104569060019067ffffffffffffffff16610cb2565b61045e565b60005b67ffffffffffffffff16905090565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166104ff576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61050a8484846108d8565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105ba576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009167ffffffffffffffff90911690826105d883610cda565b82546101009290920a67ffffffffffffffff818102199093169183160217909155811660008181526004602090815260409182902086905581518681529081019290925281018490529091507f9ed9683bfff0f737f91f20945e98c912976d94e76860b05b48b15bc0d589be1f9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a6576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826109cd565b6000803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610722576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546000916801000000000000000090910467ffffffffffffffff1690600861074c83610cda565b82546101009290920a67ffffffffffffffff81810219909316918316021790915581166000908152600460205260409020549091506107b7576040517fa902392300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526004602052604090205492509050915091565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff8216610925576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016109715761096c8282610a50565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b6000036109c2576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096c838383610ac5565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af190508061096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016104f6565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061050a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016104f6565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb857600080fd5b919050565b60008060408385031215610bd057600080fd5b82359150610be060208401610b94565b90509250929050565b600060208284031215610bfb57600080fd5b61054482610b94565b600080600060608486031215610c1957600080fd5b610c2284610b94565b9250610c3060208501610b94565b9150604084013590509250925092565b600060208284031215610c5257600080fd5b5035919050565b600060208284031215610c6b57600080fd5b813567ffffffffffffffff8116811461054457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610cd357610cd3610c83565b5092915050565b600067ffffffffffffffff808316818103610cf757610cf7610c83565b600101939250505056fea26469706673582212200e9ad1c7907b958bd17050e3a3e7333638ad97b82c9cf9912b5a59c257132e1f64736f6c63430008130033608060405234801561001057600080fd5b50604051610ac1380380610ac183398101604081905261002f9161011b565b808061003a8161006d565b5061006790507fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f29253826100c0565b5061014b565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b60006020828403121561012d57600080fd5b81516001600160a01b038116811461014457600080fd5b9392505050565b6109678061015a6000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80635b94db27116100765780638da5cb5b1161005b5780638da5cb5b1461015357806391d1485414610171578063d547741f1461018457600080fd5b80635b94db271461012d5780636ccae0541461014057600080fd5b806320f99c0a146100a85780632d095c43146100ec5780632f2ff15d146101105780633bd1adec14610125575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101006100fa366004610805565b50501490565b60405190151581526020016100e3565b61012361011e3660046108ae565b610197565b005b6101236101f6565b61012361013b3660046108da565b610252565b61012361014e3660046108f5565b610312565b60005473ffffffffffffffffffffffffffffffffffffffff166100c2565b61010061017f3660046108ae565b6103b5565b6101236101923660046108ae565b6103f0565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101e8576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f2828261044b565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610247576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610250336104d1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102a3576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166103a4576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6103af848484610549565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610441576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f2828261063e565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff8216610596576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016105e2576105dd82826106c1565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b600003610633576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105dd838383610736565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af19050806105dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c454400000000000000000000000000604482015260640161039b565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806103af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c45440000000000000000000000000000000000604482015260640161039b565b6000806000806060858703121561081b57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561084157600080fd5b818701915087601f83011261085557600080fd5b81358181111561086457600080fd5b88602082850101111561087657600080fd5b95989497505060200194505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108a957600080fd5b919050565b600080604083850312156108c157600080fd5b823591506108d160208401610885565b90509250929050565b6000602082840312156108ec57600080fd5b6103e982610885565b60008060006060848603121561090a57600080fd5b61091384610885565b925061092160208501610885565b915060408401359050925092509256fea2646970667358221220b917ec53e94feb877107d694f6da6360b795610f2218c1647ae6a87c371e46bc64736f6c63430008130033a2646970667358221220583c22f22968be0212c7ff60d875a454e4c97b9d1a6944dc43b4396c0277f93664736f6c63430008130033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000b0bbff6311b7f245761a7846d3ce7b1b100c1836000000000000000000000000000000000000000000000000000000000000000a

-----Decoded View---------------
Arg [0] : owner_ (address): 0xB0BBff6311B7F245761A7846d3Ce7B1b100C1836
Arg [1] : maxAllowedPacketLength_ (uint256): 10

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b0bbff6311b7f245761a7846d3ce7b1b100c1836
Arg [1] : 000000000000000000000000000000000000000000000000000000000000000a


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
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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