ETH Price: $2,948.39 (+1.23%)

Contract

0x2cb960D03080a42AC4d9d53C0cC87Cd6795Ec9b3

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
385067742026-01-24 11:45:332 hrs ago1769255133  Contract Creation0 ETH

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HeaderImpl

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion
// Copyright (C) Polytope Labs Ltd.
// SPDX-License-Identifier: Apache-2.0

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

import {StateCommitment} from "@hyperbridge/core/interfaces/IConsensus.sol";
import "@polytope-labs/solidity-merkle-trees/src/trie/Bytes.sol";
import "@polytope-labs/solidity-merkle-trees/src/trie/substrate/ScaleCodec.sol";

struct DigestItem {
    bytes4 consensusId;
    bytes data;
}

struct Digest {
    bool isPreRuntime;
    DigestItem preruntime;
    bool isConsensus;
    DigestItem consensus;
    bool isSeal;
    DigestItem seal;
    bool isOther;
    bytes other;
    bool isRuntimeEnvironmentUpdated;
}

struct Header {
    bytes32 parentHash;
    uint256 number;
    bytes32 stateRoot;
    bytes32 extrinsicRoot;
    Digest[] digests;
}

library HeaderImpl {
    /// Digest Item ID
    bytes4 public constant ISMP_CONSENSUS_ID = bytes4("ISMP");
    /// ConsensusID for aura
    bytes4 public constant AURA_CONSENSUS_ID = bytes4("aura");
    /// Slot duration in milliseconds
    uint256 public constant SLOT_DURATION = 12000;

    error TimestampNotFound();
    error ChildTrieRootNotFound();

    // Extracts the `StateCommitment` from the provided header.
    function stateCommitment(Header calldata self) public pure returns (StateCommitment memory) {
        bytes32 mmrRoot;
        bytes32 childTrieRoot;
        uint256 timestamp;

        for (uint256 j = 0; j < self.digests.length; j++) {
            if (self.digests[j].isConsensus && self.digests[j].consensus.consensusId == ISMP_CONSENSUS_ID) {
                mmrRoot = Bytes.toBytes32(self.digests[j].consensus.data[:32]);
                childTrieRoot = Bytes.toBytes32(self.digests[j].consensus.data[32:]);
            }

            if (self.digests[j].isPreRuntime && self.digests[j].preruntime.consensusId == AURA_CONSENSUS_ID) {
                uint256 slot = ScaleCodec.decodeUint256(self.digests[j].preruntime.data);
                timestamp = slot * SLOT_DURATION;
            }
        }

        // sanity check
        if (timestamp == 0) revert TimestampNotFound();
        if (childTrieRoot == bytes32(0)) revert ChildTrieRootNotFound();

        return StateCommitment({timestamp: timestamp, overlayRoot: mmrRoot, stateRoot: childTrieRoot});
    }
}

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

/**
 * @title StateCommitment
 * @notice Represents a commitment to an intermediate state in the state machine
 * @dev Contains metadata about the state machine including timestamp and merkle roots
 */
struct StateCommitment {
    /// @notice Unix timestamp of the state machine at the time of this commitment
    /// @dev Used for calculating request timeouts and enforcing time-based logic
    uint256 timestamp;
    /// @notice Merkle root of the overlay trie containing all ISMP requests and responses
    /// @dev Used to verify inclusion proofs for cross-chain messages
    bytes32 overlayRoot;
    /// @notice Merkle root of the state trie at the given block height
    /// @dev Represents the complete state of the state machine at this height
    bytes32 stateRoot;
}

/**
 * @title StateMachineHeight
 * @notice Uniquely identifies a specific height in a state machine
 * @dev Consensus clients may track multiple concurrent state machines, hence the need for an identifier
 */
struct StateMachineHeight {
    /// @notice Unique identifier for the state machine (e.g., parachain ID, chain ID)
    /// @dev Each blockchain or parachain in the network has a unique identifier
    uint256 stateMachineId;
    /// @notice Block height or number in the state machine
    /// @dev Represents the sequential position in the blockchain
    uint256 height;
}

/**
 * @title IntermediateState
 * @notice Represents an intermediate state in the state transition sequence of a state machine
 * @dev Used to track finalized states that have been verified through consensus
 */
struct IntermediateState {
    /// @notice Unique identifier for the state machine
    /// @dev Same as StateMachineHeight.stateMachineId
    uint256 stateMachineId;
    /// @notice Block height of this intermediate state
    /// @dev The specific height at which this state was committed
    uint256 height;
    /// @notice The state commitment at this height
    /// @dev Contains the timestamp and merkle roots for this state
    StateCommitment commitment;
}

/**
 * @title IConsensus
 * @author Polytope Labs ([email protected])
 * @notice Interface for consensus verification in the Hyperbridge protocol
 * @dev Consensus clients implement this interface to verify state transitions from different chains.
 * The internals are intentionally opaque to the ISMP framework, allowing consensus mechanisms
 * to evolve independently (e.g., GRANDPA for Polkadot, Sync Committee for Ethereum).
 * Different consensus mechanisms can be plugged in as long as they conform to this interface.
 */
interface IConsensus {
    /**
     * @notice Verifies a consensus proof and returns the updated consensus state
     * @dev This function is called by the Handler to verify incoming consensus updates.
     * The implementation details vary based on the consensus mechanism being verified.
     * @param trustedState The current trusted consensus state (encoded based on consensus type)
     * @param proof The consensus proof to be verified (e.g., validator signatures, merkle proofs)
     * @return The new consensus state after verification (encoded)
     * @return Array of newly finalized intermediate states that can be trusted
     */
    function verifyConsensus(bytes memory trustedState, bytes memory proof)
        external
        returns (bytes memory, IntermediateState[] memory);
}

// Copyright (C) Polytope Labs Ltd.
// SPDX-License-Identifier: Apache-2.0

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

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

struct ByteSlice {
    bytes data;
    uint256 offset;
}

library Bytes {
    uint256 internal constant BYTES_HEADER_SIZE = 32;

    // Checks if two `bytes memory` variables are equal. This is done using hashing,
    // which is much more gas efficient then comparing each byte individually.
    // Equality means that:
    //  - 'self.length == other.length'
    //  - For 'n' in '[0, self.length)', 'self[n] == other[n]'
    function equals(
        bytes memory self,
        bytes memory other
    ) internal pure returns (bool equal) {
        if (self.length != other.length) {
            return false;
        }
        uint256 addr;
        uint256 addr2;
        assembly {
            addr := add(self, /*BYTES_HEADER_SIZE*/ 32)
            addr2 := add(other, /*BYTES_HEADER_SIZE*/ 32)
        }
        equal = Memory.equals(addr, addr2, self.length);
    }

    function readByte(ByteSlice memory self) internal pure returns (uint8) {
        if (self.offset + 1 > self.data.length) {
            revert("Out of range");
        }

        uint8 b = uint8(self.data[self.offset]);
        self.offset += 1;

        return b;
    }

    // Copies 'len' bytes from 'self' into a new array, starting at the provided 'startIndex'.
    // Returns the new copy.
    // Requires that:
    //  - 'startIndex + len <= self.length'
    // The length of the substring is: 'len'
    function read(
        ByteSlice memory self,
        uint256 len
    ) internal pure returns (bytes memory) {
        require(self.offset + len <= self.data.length);
        if (len == 0) {
            return "";
        }
        uint256 addr = Memory.dataPtr(self.data);
        bytes memory slice = Memory.toBytes(addr + self.offset, len);
        self.offset += len;
        return slice;
    }

    // Copies a section of 'self' into a new array, starting at the provided 'startIndex'.
    // Returns the new copy.
    // Requires that 'startIndex <= self.length'
    // The length of the substring is: 'self.length - startIndex'
    function substr(
        bytes memory self,
        uint256 startIndex
    ) internal pure returns (bytes memory) {
        require(startIndex <= self.length);
        uint256 len = self.length - startIndex;
        uint256 addr = Memory.dataPtr(self);
        return Memory.toBytes(addr + startIndex, len);
    }

    // Copies 'len' bytes from 'self' into a new array, starting at the provided 'startIndex'.
    // Returns the new copy.
    // Requires that:
    //  - 'startIndex + len <= self.length'
    // The length of the substring is: 'len'
    function substr(
        bytes memory self,
        uint256 startIndex,
        uint256 len
    ) internal pure returns (bytes memory) {
        require(startIndex + len <= self.length);
        if (len == 0) {
            return "";
        }
        uint256 addr = Memory.dataPtr(self);
        return Memory.toBytes(addr + startIndex, len);
    }

    // Combines 'self' and 'other' into a single array.
    // Returns the concatenated arrays:
    //  [self[0], self[1], ... , self[self.length - 1], other[0], other[1], ... , other[other.length - 1]]
    // The length of the new array is 'self.length + other.length'
    function concat(
        bytes memory self,
        bytes memory other
    ) internal pure returns (bytes memory) {
        bytes memory ret = new bytes(self.length + other.length);
        uint256 src;
        uint256 srcLen;
        (src, srcLen) = Memory.fromBytes(self);
        uint256 src2;
        uint256 src2Len;
        (src2, src2Len) = Memory.fromBytes(other);
        uint256 dest;
        (dest, ) = Memory.fromBytes(ret);
        uint256 dest2 = dest + srcLen;
        Memory.copy(src, dest, srcLen);
        Memory.copy(src2, dest2, src2Len);
        return ret;
    }

    function toBytes32(bytes memory self) internal pure returns (bytes32 out) {
        require(self.length >= 32, "Bytes:: toBytes32: data is to short.");
        assembly {
            out := mload(add(self, 32))
        }
    }

    function toBytes16(
        bytes memory self,
        uint256 offset
    ) internal pure returns (bytes16 out) {
        for (uint256 i = 0; i < 16; i++) {
            out |= bytes16(bytes1(self[offset + i]) & 0xFF) >> (i * 8);
        }
    }

    function toBytes8(
        bytes memory self,
        uint256 offset
    ) internal pure returns (bytes8 out) {
        for (uint256 i = 0; i < 8; i++) {
            out |= bytes8(bytes1(self[offset + i]) & 0xFF) >> (i * 8);
        }
    }

    function toBytes4(
        bytes memory self,
        uint256 offset
    ) internal pure returns (bytes4) {
        bytes4 out;

        for (uint256 i = 0; i < 4; i++) {
            out |= bytes4(self[offset + i] & 0xFF) >> (i * 8);
        }
        return out;
    }

    function toBytes2(
        bytes memory self,
        uint256 offset
    ) internal pure returns (bytes2) {
        bytes2 out;

        for (uint256 i = 0; i < 2; i++) {
            out |= bytes2(self[offset + i] & 0xFF) >> (i * 8);
        }
        return out;
    }

    function removeLeadingZero(
        bytes memory data
    ) internal pure returns (bytes memory) {
        uint256 length = data.length;

        uint256 startIndex = 0;
        for (uint256 i = 0; i < length; i++) {
            if (data[i] != 0) {
                startIndex = i;
                break;
            }
        }

        return substr(data, startIndex);
    }

    function removeEndingZero(
        bytes memory data
    ) internal pure returns (bytes memory) {
        uint256 length = data.length;

        uint256 endIndex = 0;
        for (uint256 i = length - 1; i >= 0; i--) {
            if (data[i] != 0) {
                endIndex = i;
                break;
            }
        }

        return substr(data, 0, endIndex + 1);
    }

    function reverse(
        bytes memory inbytes
    ) internal pure returns (bytes memory) {
        uint256 inlength = inbytes.length;
        bytes memory outbytes = new bytes(inlength);

        for (uint256 i = 0; i <= inlength - 1; i++) {
            outbytes[i] = inbytes[inlength - i - 1];
        }

        return outbytes;
    }
}

// Copyright (C) Polytope Labs Ltd.
// SPDX-License-Identifier: Apache-2.0

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

import {Bytes, ByteSlice} from "../Bytes.sol";

library ScaleCodec {
    // Decodes a SCALE encoded uint256 by converting bytes (bid endian) to little endian format
    function decodeUint256(bytes memory data) internal pure returns (uint256) {
        uint256 number;
        for (uint256 i = data.length; i > 0; i--) {
            number =
                number +
                uint256(uint8(data[i - 1])) *
                (2 ** (8 * (i - 1)));
        }
        return number;
    }

    // Decodes a SCALE encoded compact unsigned integer
    function decodeUintCompact(
        ByteSlice memory data
    ) internal pure returns (uint256 v) {
        uint8 b = Bytes.readByte(data); // read the first byte
        uint8 mode = b % 4; // bitwise operation

        uint256 value;
        if (mode == 0) {
            // [0, 63]
            value = b >> 2; // right shift to remove mode bits
        } else if (mode == 1) {
            // [64, 16383]
            uint8 bb = Bytes.readByte(data); // read the second byte
            uint64 r = bb; // convert to uint64
            r <<= 6; // multiply by * 2^6
            r += b >> 2; // right shift to remove mode bits
            value = r;
        } else if (mode == 2) {
            // [16384, 1073741823]
            uint8 b2 = Bytes.readByte(data); // read the next 3 bytes
            uint8 b3 = Bytes.readByte(data);
            uint8 b4 = Bytes.readByte(data);

            uint32 x1 = uint32(b) | (uint32(b2) << 8); // convert to little endian
            uint32 x2 = x1 | (uint32(b3) << 16);
            uint32 x3 = x2 | (uint32(b4) << 24);

            x3 >>= 2; // remove the last 2 mode bits
            value = uint256(x3);
        } else if (mode == 3) {
            // [1073741824, 4503599627370496]
            uint8 l = (b >> 2) + 4; // remove mode bits
            require(l <= 8, "unexpected prefix decoding Compact<Uint>");
            return decodeUint256(Bytes.read(data, l));
        } else {
            revert("Code should be unreachable");
        }
        return value;
    }

    // Decodes a SCALE encoded compact unsigned integer
    function decodeUintCompact(
        bytes memory data
    ) internal pure returns (uint256 v, uint8 m) {
        uint8 b = readByteAtIndex(data, 0); // read the first byte
        uint8 mode = b & 3; // bitwise operation

        uint256 value;
        if (mode == 0) {
            // [0, 63]
            value = b >> 2; // right shift to remove mode bits
        } else if (mode == 1) {
            // [64, 16383]
            uint8 bb = readByteAtIndex(data, 1); // read the second byte
            uint64 r = bb; // convert to uint64
            r <<= 6; // multiply by * 2^6
            r += b >> 2; // right shift to remove mode bits
            value = r;
        } else if (mode == 2) {
            // [16384, 1073741823]
            uint8 b2 = readByteAtIndex(data, 1); // read the next 3 bytes
            uint8 b3 = readByteAtIndex(data, 2);
            uint8 b4 = readByteAtIndex(data, 3);

            uint32 x1 = uint32(b) | (uint32(b2) << 8); // convert to little endian
            uint32 x2 = x1 | (uint32(b3) << 16);
            uint32 x3 = x2 | (uint32(b4) << 24);

            x3 >>= 2; // remove the last 2 mode bits
            value = uint256(x3);
        } else if (mode == 3) {
            // [1073741824, 4503599627370496]
            uint8 l = b >> 2; // remove mode bits
            require(
                l > 32,
                "Not supported: number cannot be greater than 32 bytes"
            );
        } else {
            revert("Code should be unreachable");
        }
        return (value, mode);
    }

    // The biggest compact supported uint is 2 ** 536 - 1.
    // But the biggest value supported by this method is 2 ** 256 - 1(max of uint256)
    function encodeUintCompact(uint256 v) internal pure returns (bytes memory) {
        if (v < 64) {
            return abi.encodePacked(uint8(v << 2));
        } else if (v < 2 ** 14) {
            return abi.encodePacked(reverse16(uint16(((v << 2) + 1))));
        } else if (v < 2 ** 30) {
            return abi.encodePacked(reverse32(uint32(((v << 2) + 2))));
        } else {
            bytes memory valueBytes = Bytes.removeEndingZero(
                abi.encodePacked(reverse256(v))
            );

            uint256 length = valueBytes.length;
            uint8 prefix = uint8(((length - 4) << 2) + 3);

            return abi.encodePacked(prefix, valueBytes);
        }
    }

    // Read a byte at a specific index and return it as type uint8
    function readByteAtIndex(
        bytes memory data,
        uint8 index
    ) internal pure returns (uint8) {
        return uint8(data[index]);
    }

    // Sources:
    //   * https://ethereum.stackexchange.com/questions/15350/how-to-convert-an-bytes-to-address-in-solidity/50528
    //   * https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel

    function reverse256(uint256 input) internal pure returns (uint256 v) {
        v = input;

        // swap bytes
        v =
            ((v &
                0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >>
                8) |
            ((v &
                0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) <<
                8);

        // swap 2-byte long pairs
        v =
            ((v &
                0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >>
                16) |
            ((v &
                0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) <<
                16);

        // swap 4-byte long pairs
        v =
            ((v &
                0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >>
                32) |
            ((v &
                0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) <<
                32);

        // swap 8-byte long pairs
        v =
            ((v &
                0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >>
                64) |
            ((v &
                0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) <<
                64);

        // swap 16-byte long pairs
        v = (v >> 128) | (v << 128);
    }

    function reverse128(uint128 input) internal pure returns (uint128 v) {
        v = input;

        // swap bytes
        v =
            ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00) >> 8) |
            ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF) << 8);

        // swap 2-byte long pairs
        v =
            ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000) >> 16) |
            ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF) << 16);

        // swap 4-byte long pairs
        v =
            ((v & 0xFFFFFFFF00000000FFFFFFFF00000000) >> 32) |
            ((v & 0x00000000FFFFFFFF00000000FFFFFFFF) << 32);

        // swap 8-byte long pairs
        v = (v >> 64) | (v << 64);
    }

    function reverse64(uint64 input) internal pure returns (uint64 v) {
        v = input;

        // swap bytes
        v = ((v & 0xFF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF) << 8);

        // swap 2-byte long pairs
        v = ((v & 0xFFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF) << 16);

        // swap 4-byte long pairs
        v = (v >> 32) | (v << 32);
    }

    function reverse32(uint32 input) internal pure returns (uint32 v) {
        v = input;

        // swap bytes
        v = ((v & 0xFF00FF00) >> 8) | ((v & 0x00FF00FF) << 8);

        // swap 2-byte long pairs
        v = (v >> 16) | (v << 16);
    }

    function reverse16(uint16 input) internal pure returns (uint16 v) {
        v = input;

        // swap bytes
        v = (v >> 8) | (v << 8);
    }

    function encode256(uint256 input) internal pure returns (bytes32) {
        return bytes32(reverse256(input));
    }

    function encode128(uint128 input) internal pure returns (bytes16) {
        return bytes16(reverse128(input));
    }

    function encode64(uint64 input) internal pure returns (bytes8) {
        return bytes8(reverse64(input));
    }

    function encode32(uint32 input) internal pure returns (bytes4) {
        return bytes4(reverse32(input));
    }

    function encode16(uint16 input) internal pure returns (bytes2) {
        return bytes2(reverse16(input));
    }

    function encodeBytes(
        bytes memory input
    ) internal pure returns (bytes memory) {
        return abi.encodePacked(encodeUintCompact(input.length), input);
    }
}

// Copyright (C) Polytope Labs Ltd.
// SPDX-License-Identifier: Apache-2.0

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

library Memory {
    uint256 internal constant WORD_SIZE = 32;

    // Compares the 'len' bytes starting at address 'addr' in memory with the 'len'
    // bytes starting at 'addr2'.
    // Returns 'true' if the bytes are the same, otherwise 'false'.
    function equals(
        uint256 addr,
        uint256 addr2,
        uint256 len
    ) internal pure returns (bool equal) {
        assembly {
            equal := eq(keccak256(addr, len), keccak256(addr2, len))
        }
    }

    // Compares the 'len' bytes starting at address 'addr' in memory with the bytes stored in
    // 'bts'. It is allowed to set 'len' to a lower value then 'bts.length', in which case only
    // the first 'len' bytes will be compared.
    // Requires that 'bts.length >= len'

    function equals(
        uint256 addr,
        uint256 len,
        bytes memory bts
    ) internal pure returns (bool equal) {
        require(bts.length >= len);
        uint256 addr2;
        assembly {
            addr2 := add(bts, /*BYTES_HEADER_SIZE*/ 32)
        }
        return equals(addr, addr2, len);
    }
    // Returns a memory pointer to the data portion of the provided bytes array.

    function dataPtr(bytes memory bts) internal pure returns (uint256 addr) {
        assembly {
            addr := add(bts, /*BYTES_HEADER_SIZE*/ 32)
        }
    }

    // Creates a 'bytes memory' variable from the memory address 'addr', with the
    // length 'len'. The function will allocate new memory for the bytes array, and
    // the 'len bytes starting at 'addr' will be copied into that new memory.
    function toBytes(
        uint256 addr,
        uint256 len
    ) internal pure returns (bytes memory bts) {
        bts = new bytes(len);
        uint256 btsptr;
        assembly {
            btsptr := add(bts, /*BYTES_HEADER_SIZE*/ 32)
        }
        copy(addr, btsptr, len);
    }

    // Copies 'self' into a new 'bytes memory'.
    // Returns the newly created 'bytes memory'
    // The returned bytes will be of length '32'.
    function toBytes(bytes32 self) internal pure returns (bytes memory bts) {
        bts = new bytes(32);
        assembly {
            mstore(add(bts, /*BYTES_HEADER_SIZE*/ 32), self)
        }
    }

    // Copy 'len' bytes from memory address 'src', to address 'dest'.
    // This function does not check the or destination, it only copies
    // the bytes.
    function copy(uint256 src, uint256 dest, uint256 len) internal pure {
        // Copy word-length chunks while possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += WORD_SIZE;
            src += WORD_SIZE;
        }

        // Copy remaining bytes
        uint256 mask = len == 0
            ? 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
            : 256 ** (WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }

    // This function does the same as 'dataPtr(bytes memory)', but will also return the
    // length of the provided bytes array.
    function fromBytes(
        bytes memory bts
    ) internal pure returns (uint256 addr, uint256 len) {
        len = bts.length;
        assembly {
            addr := add(bts, /*BYTES_HEADER_SIZE*/ 32)
        }
    }
}

Settings
{
  "remappings": [
    "@hyperbridge/core/=node_modules/@hyperbridge/core/contracts/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@polytope-labs/=node_modules/@polytope-labs/",
    "@uniswap/=node_modules/@uniswap/",
    "stringutils/=lib/solidity-stringutils/src/",
    "@sp1-contracts/=lib/sp1-contracts/contracts/src/",
    "ds-test/=lib/solidity-stringutils/lib/ds-test/src/",
    "erc4626-tests/=lib/sp1-contracts/contracts/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/sp1-contracts/contracts/lib/openzeppelin-contracts/",
    "solidity-stringutils/=lib/solidity-stringutils/",
    "sp1-contracts/=lib/sp1-contracts/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"ChildTrieRootNotFound","type":"error"},{"inputs":[],"name":"TimestampNotFound","type":"error"},{"inputs":[],"name":"AURA_CONSENSUS_ID","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ISMP_CONSENSUS_ID","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SLOT_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"internalType":"bytes32","name":"extrinsicRoot","type":"bytes32"},{"components":[{"internalType":"bool","name":"isPreRuntime","type":"bool"},{"components":[{"internalType":"bytes4","name":"consensusId","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct DigestItem","name":"preruntime","type":"tuple"},{"internalType":"bool","name":"isConsensus","type":"bool"},{"components":[{"internalType":"bytes4","name":"consensusId","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct DigestItem","name":"consensus","type":"tuple"},{"internalType":"bool","name":"isSeal","type":"bool"},{"components":[{"internalType":"bytes4","name":"consensusId","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct DigestItem","name":"seal","type":"tuple"},{"internalType":"bool","name":"isOther","type":"bool"},{"internalType":"bytes","name":"other","type":"bytes"},{"internalType":"bool","name":"isRuntimeEnvironmentUpdated","type":"bool"}],"internalType":"struct Digest[]","name":"digests","type":"tuple[]"}],"internalType":"struct Header","name":"self","type":"tuple"}],"name":"stateCommitment","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"overlayRoot","type":"bytes32"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"}],"internalType":"struct StateCommitment","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"}]

6080806040523460195761061b908161001e823930815050f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c80634e9fdbec1461029d5780638b3e82b51461004f578063905c05111461004a5763babb311814610045575f80fd5b6102d0565b6102b9565b60203660031901126102995760043567ffffffffffffffff811161029957806004019060a0600319823603011261029957610088610326565b505f906084018180805b61009c8487610340565b9050811015610229576100c460406100be836100b8888b610340565b9061038a565b016103b2565b806101ee575b61018d575b83866100e76100e2846100b88585610340565b6103b2565b8061014d575b6100fc575b5050600101610092565b82935061013961013261012861011e6001966100b86101439761013e97610340565b60208101906103bf565b60208101906103e9565b3691610447565b610578565b6104b3565b91905083866100f2565b5061015c836100b88484610340565b636175726160e01b906001600160e01b031990610186906101819060208101906103bf565b6103d4565b16146100ed565b935090506101c36101be6101326101b86101286101ae886100b8898c610340565b60608101906103bf565b9061041c565b6104fb565b906101e86101be6101326101e16101286101ae896100b88a8d610340565b809161042a565b936100cf565b506101fd816100b88689610340565b63049534d560e41b906001600160e01b031990610222906101819060608101906103bf565b16146100ca565b5083811561028a57801561027b5761027792610243610301565b9283526020830152604082015260405191829182919091604080606083019480518452602081015160208501520151910152565b0390f35b6315666a0560e31b5f5260045ffd5b633eba99d160e21b5f5260045ffd5b5f80fd5b5f36600319011261029957636175726160e01b60805260206080f35b5f366003190112610299576020604051612ee08152f35b5f3660031901126102995760405163049534d560e41b8152602090f35b634e487b7160e01b5f52604160045260245ffd5b604051906060820182811067ffffffffffffffff82111761032157604052565b6102ed565b61032e610301565b905f82525f60208301525f6040830152565b903590601e1981360301821215610299570180359067ffffffffffffffff821161029957602001918160051b3603831361029957565b634e487b7160e01b5f52603260045260245ffd5b91908110156103ad5760051b8101359061011e1981360301821215610299570190565b610376565b3580151581036102995790565b903590603e1981360301821215610299570190565b356001600160e01b0319811681036102995790565b903590601e1981360301821215610299570180359067ffffffffffffffff82116102995760200191813603831361029957565b906020116102995790602090565b90929192836020116102995783116102995760200191601f190190565b92919267ffffffffffffffff82116103215760405191601f8101601f19908116603f0116830167ffffffffffffffff81118482101761032157604052829481845281830111610299578281602093845f960137010152565b634e487b7160e01b5f52601160045260245ffd5b90612ee0820291808304612ee014901517156104cb57565b61049f565b600381901b91906001600160fd1b038116036104cb57565b818102929181159184041417156104cb57565b602081511061050b576020015190565b60405162461bcd60e51b8152602060048201526024808201527f42797465733a3a20746f427974657333323a206461746120697320746f20736860448201526337b93a1760e11b6064820152608490fd5b60ff81116104cb576001901b90565b919082018092116104cb57565b80515f91815b61058757505090565b90915f198301908382116104cb5782518210156103ad57828401601f015160f81c918481116104cb576105d4926105c86105c36105ce936104d0565b61055c565b906104e8565b9061056b565b9180156104cb575f1901908161057e56fea2646970667358221220c41c44baf1d38ffaca0e991496c736432c86c721ba88389d2cfb282140d2dc6864736f6c634300081e0033

Deployed Bytecode

0x60806040526004361015610011575f80fd5b5f3560e01c80634e9fdbec1461029d5780638b3e82b51461004f578063905c05111461004a5763babb311814610045575f80fd5b6102d0565b6102b9565b60203660031901126102995760043567ffffffffffffffff811161029957806004019060a0600319823603011261029957610088610326565b505f906084018180805b61009c8487610340565b9050811015610229576100c460406100be836100b8888b610340565b9061038a565b016103b2565b806101ee575b61018d575b83866100e76100e2846100b88585610340565b6103b2565b8061014d575b6100fc575b5050600101610092565b82935061013961013261012861011e6001966100b86101439761013e97610340565b60208101906103bf565b60208101906103e9565b3691610447565b610578565b6104b3565b91905083866100f2565b5061015c836100b88484610340565b636175726160e01b906001600160e01b031990610186906101819060208101906103bf565b6103d4565b16146100ed565b935090506101c36101be6101326101b86101286101ae886100b8898c610340565b60608101906103bf565b9061041c565b6104fb565b906101e86101be6101326101e16101286101ae896100b88a8d610340565b809161042a565b936100cf565b506101fd816100b88689610340565b63049534d560e41b906001600160e01b031990610222906101819060608101906103bf565b16146100ca565b5083811561028a57801561027b5761027792610243610301565b9283526020830152604082015260405191829182919091604080606083019480518452602081015160208501520151910152565b0390f35b6315666a0560e31b5f5260045ffd5b633eba99d160e21b5f5260045ffd5b5f80fd5b5f36600319011261029957636175726160e01b60805260206080f35b5f366003190112610299576020604051612ee08152f35b5f3660031901126102995760405163049534d560e41b8152602090f35b634e487b7160e01b5f52604160045260245ffd5b604051906060820182811067ffffffffffffffff82111761032157604052565b6102ed565b61032e610301565b905f82525f60208301525f6040830152565b903590601e1981360301821215610299570180359067ffffffffffffffff821161029957602001918160051b3603831361029957565b634e487b7160e01b5f52603260045260245ffd5b91908110156103ad5760051b8101359061011e1981360301821215610299570190565b610376565b3580151581036102995790565b903590603e1981360301821215610299570190565b356001600160e01b0319811681036102995790565b903590601e1981360301821215610299570180359067ffffffffffffffff82116102995760200191813603831361029957565b906020116102995790602090565b90929192836020116102995783116102995760200191601f190190565b92919267ffffffffffffffff82116103215760405191601f8101601f19908116603f0116830167ffffffffffffffff81118482101761032157604052829481845281830111610299578281602093845f960137010152565b634e487b7160e01b5f52601160045260245ffd5b90612ee0820291808304612ee014901517156104cb57565b61049f565b600381901b91906001600160fd1b038116036104cb57565b818102929181159184041417156104cb57565b602081511061050b576020015190565b60405162461bcd60e51b8152602060048201526024808201527f42797465733a3a20746f427974657333323a206461746120697320746f20736860448201526337b93a1760e11b6064820152608490fd5b60ff81116104cb576001901b90565b919082018092116104cb57565b80515f91815b61058757505090565b90915f198301908382116104cb5782518210156103ad57828401601f015160f81c918481116104cb576105d4926105c86105c36105ce936104d0565b61055c565b906104e8565b9061056b565b9180156104cb575f1901908161057e56fea2646970667358221220c41c44baf1d38ffaca0e991496c736432c86c721ba88389d2cfb282140d2dc6864736f6c634300081e0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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