false
false
0
The new Blockscout UI is now open source! Learn how to deploy it here

Contract Address Details

0xe8B040f8D2cE65538f96b246Ce90a9B9Fd8BfFe2

Contract Name
SingleCapacitor
Creator
0xfe9dcb–d96f04 at 0x3571cc–e81f0a
Balance
0 ETH
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
1177104
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
SingleCapacitor




Optimization enabled
true
Compiler version
v0.8.19+commit.7dd6d404




Optimization runs
999999
EVM Version
default




Verified at
2024-12-17T15:38:10.220620Z

Constructor Arguments

0x0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f00000000000000000000000044a44837894b5edc2bde64567fc62599b3b88f4c

Arg [0] (address) : 0x5c4186d343eef952c9ed886e45f8243edf0a503f
Arg [1] (address) : 0x44a44837894b5edc2bde64567fc62599b3b88f4c

              

contracts/capacitors/SingleCapacitor.sol

// SPDX-License-Identifier: GPL-3.0-only
// Sources flattened with hardhat v2.12.2 https://hardhat.org

// 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/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/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/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/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_];
    }
}
        

Compiler Settings

{"outputSelection":{"*":{"*":["*"]}},"optimizer":{"runs":999999,"enabled":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"socket_","internalType":"address"},{"type":"address","name":"owner_","internalType":"address"}]},{"type":"error","name":"InvalidTokenAddress","inputs":[]},{"type":"error","name":"NoPendingPacket","inputs":[]},{"type":"error","name":"NoPermit","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"error","name":"OnlyNominee","inputs":[]},{"type":"error","name":"OnlyOwner","inputs":[]},{"type":"error","name":"OnlySocket","inputs":[]},{"type":"error","name":"ZeroAddress","inputs":[]},{"type":"event","name":"MessageAdded","inputs":[{"type":"bytes32","name":"packedMessage","internalType":"bytes32","indexed":false},{"type":"uint64","name":"packetCount","internalType":"uint64","indexed":false},{"type":"bytes32","name":"newRootHash","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"OwnerClaimed","inputs":[{"type":"address","name":"claimer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnerNominated","inputs":[{"type":"address","name":"nominee","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"grantee","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"revokee","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addPackedMessage","inputs":[{"type":"bytes32","name":"packedMessage_","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"lastFilledPacket","internalType":"uint256"}],"name":"getLastFilledPacket","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMaxPacketLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"},{"type":"uint64","name":"","internalType":"uint64"}],"name":"getNextPacketToBeSealed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRootByCount","inputs":[{"type":"uint64","name":"count_","internalType":"uint64"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role_","internalType":"bytes32"},{"type":"address","name":"grantee_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role_","internalType":"bytes32"},{"type":"address","name":"address_","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"nominateOwner","inputs":[{"type":"address","name":"nominee_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"nominee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueFunds","inputs":[{"type":"address","name":"token_","internalType":"address"},{"type":"address","name":"rescueTo_","internalType":"address"},{"type":"uint256","name":"amount_","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role_","internalType":"bytes32"},{"type":"address","name":"revokee_","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"},{"type":"uint64","name":"","internalType":"uint64"}],"name":"sealPacket","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"socket","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x60a060405234801561001057600080fd5b50604051610edb380380610edb83398101604081905261002f91610148565b8181808061003c8161007e565b50506001600160a01b0382166080526100757fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f29253826100d1565b5050505061017b565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60008281526002602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b80516001600160a01b038116811461014357600080fd5b919050565b6000806040838503121561015b57600080fd5b6101648361012c565b91506101726020840161012c565b90509250929050565b608051610d376101a4600039600081816101430152818161056301526106cb0152610d376000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80636ccae054116100975780639471651e116100665780639471651e14610215578063d1af313c1461025d578063d547741f14610287578063d7c9eaac1461029a57600080fd5b80636ccae054146101ae5780638da5cb5b146101c157806391d14854146101df578063920ee8a81461020257600080fd5b80632ff9f2c9116100d35780632ff9f2c91461017a5780633bd1adec1461018b5780635b94db27146101935780636afc0f38146101a657600080fd5b806320f99c0a146100fa57806322c8f6cd1461013e5780632f2ff15d14610165575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101147f000000000000000000000000000000000000000000000000000000000000000081565b610178610173366004610bbd565b6102ad565b005b60015b604051908152602001610135565b61017861030c565b6101786101a1366004610be9565b610368565b61017d610428565b6101786101bc366004610c04565b61046d565b60005473ffffffffffffffffffffffffffffffffffffffff16610114565b6101f26101ed366004610bbd565b610510565b6040519015158152602001610135565b610178610210366004610c40565b61054b565b60035468010000000000000000900467ffffffffffffffff16600081815260046020526040902054905b6040805192835267ffffffffffffffff909116602083015201610135565b61017d61026b366004610c59565b67ffffffffffffffff1660009081526004602052604090205490565b610178610295366004610bbd565b610655565b61023f6102a8366004610c40565b6106b0565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102fe576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826107da565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461035d576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61036633610860565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103b9576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b60035460009067ffffffffffffffff161561045b576003546104569060019067ffffffffffffffff16610cb2565b61045e565b60005b67ffffffffffffffff16905090565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166104ff576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61050a8484846108d8565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105ba576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009167ffffffffffffffff90911690826105d883610cda565b82546101009290920a67ffffffffffffffff818102199093169183160217909155811660008181526004602090815260409182902086905581518681529081019290925281018490529091507f9ed9683bfff0f737f91f20945e98c912976d94e76860b05b48b15bc0d589be1f9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a6576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826109cd565b6000803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610722576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546000916801000000000000000090910467ffffffffffffffff1690600861074c83610cda565b82546101009290920a67ffffffffffffffff81810219909316918316021790915581166000908152600460205260409020549091506107b7576040517fa902392300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526004602052604090205492509050915091565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff8216610925576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016109715761096c8282610a50565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b6000036109c2576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096c838383610ac5565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af190508061096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016104f6565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061050a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016104f6565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb857600080fd5b919050565b60008060408385031215610bd057600080fd5b82359150610be060208401610b94565b90509250929050565b600060208284031215610bfb57600080fd5b61054482610b94565b600080600060608486031215610c1957600080fd5b610c2284610b94565b9250610c3060208501610b94565b9150604084013590509250925092565b600060208284031215610c5257600080fd5b5035919050565b600060208284031215610c6b57600080fd5b813567ffffffffffffffff8116811461054457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610cd357610cd3610c83565b5092915050565b600067ffffffffffffffff808316818103610cf757610cf7610c83565b600101939250505056fea26469706673582212204cb05dc3b3ddf0cdb1ee482aee5d1adcd7c91129c89540c1d8e044cdc99ded4964736f6c634300081300330000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f00000000000000000000000044a44837894b5edc2bde64567fc62599b3b88f4c

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80636ccae054116100975780639471651e116100665780639471651e14610215578063d1af313c1461025d578063d547741f14610287578063d7c9eaac1461029a57600080fd5b80636ccae054146101ae5780638da5cb5b146101c157806391d14854146101df578063920ee8a81461020257600080fd5b80632ff9f2c9116100d35780632ff9f2c91461017a5780633bd1adec1461018b5780635b94db27146101935780636afc0f38146101a657600080fd5b806320f99c0a146100fa57806322c8f6cd1461013e5780632f2ff15d14610165575b600080fd5b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101147f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f81565b610178610173366004610bbd565b6102ad565b005b60015b604051908152602001610135565b61017861030c565b6101786101a1366004610be9565b610368565b61017d610428565b6101786101bc366004610c04565b61046d565b60005473ffffffffffffffffffffffffffffffffffffffff16610114565b6101f26101ed366004610bbd565b610510565b6040519015158152602001610135565b610178610210366004610c40565b61054b565b60035468010000000000000000900467ffffffffffffffff16600081815260046020526040902054905b6040805192835267ffffffffffffffff909116602083015201610135565b61017d61026b366004610c59565b67ffffffffffffffff1660009081526004602052604090205490565b610178610295366004610bbd565b610655565b61023f6102a8366004610c40565b6106b0565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102fe576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826107da565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461035d576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61036633610860565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103b9576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b60035460009067ffffffffffffffff161561045b576003546104569060019067ffffffffffffffff16610cb2565b61045e565b60005b67ffffffffffffffff16905090565b3360009081527f4933f7bec34ee32db93e9f5cd7e0519781b395282211f4f6857489046ea38f7660205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166104ff576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61050a8484846108d8565b50505050565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f16146105ba576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003805460009167ffffffffffffffff90911690826105d883610cda565b82546101009290920a67ffffffffffffffff818102199093169183160217909155811660008181526004602090815260409182902086905581518681529081019290925281018490529091507f9ed9683bfff0f737f91f20945e98c912976d94e76860b05b48b15bc0d589be1f9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106a6576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030882826109cd565b6000803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005c4186d343eef952c9ed886e45f8243edf0a503f1614610722576040517f503284dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380546000916801000000000000000090910467ffffffffffffffff1690600861074c83610cda565b82546101009290920a67ffffffffffffffff81810219909316918316021790915581166000908152600460205260409020549091506107b7576040517fa902392300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526004602052604090205492509050915091565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b73ffffffffffffffffffffffffffffffffffffffff8216610925576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016109715761096c8282610a50565b505050565b8273ffffffffffffffffffffffffffffffffffffffff163b6000036109c2576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61096c838383610ac5565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b600080600080600085875af190508061096c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016104f6565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061050a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016104f6565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bb857600080fd5b919050565b60008060408385031215610bd057600080fd5b82359150610be060208401610b94565b90509250929050565b600060208284031215610bfb57600080fd5b61054482610b94565b600080600060608486031215610c1957600080fd5b610c2284610b94565b9250610c3060208501610b94565b9150604084013590509250925092565b600060208284031215610c5257600080fd5b5035919050565b600060208284031215610c6b57600080fd5b813567ffffffffffffffff8116811461054457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610cd357610cd3610c83565b5092915050565b600067ffffffffffffffff808316818103610cf757610cf7610c83565b600101939250505056fea26469706673582212204cb05dc3b3ddf0cdb1ee482aee5d1adcd7c91129c89540c1d8e044cdc99ded4964736f6c63430008130033