S Price: $0.443613 (-9.79%)

Contract

0xA306462ec7b5f4ce91Fa05Af3Ea1F9dCcCCB5fC3

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

4 Internal Transactions found.

Latest 4 internal transactions

Parent Transaction Hash Block From To
21932382025-01-01 20:18:2232 days ago1735762702
0xA306462e...CcCCB5fC3
 Contract Creation0 S
21932382025-01-01 20:18:2232 days ago1735762702
0xA306462e...CcCCB5fC3
 Contract Creation0 S
21932312025-01-01 20:18:1532 days ago1735762695
0xA306462e...CcCCB5fC3
 Contract Creation0 S
21932312025-01-01 20:18:1532 days ago1735762695
0xA306462e...CcCCB5fC3
 Contract Creation0 S
Loading...
Loading

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

Contract Name:
TrieFactory

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion, BSL 1.1 license
File 1 of 5 : TrieFactory.sol
// SPDX-License-Identifier: BUSL-1.1
// Central Limit Order Book (CLOB) exchange
// (c) Long Gamma Labs, 2023.
pragma solidity ^0.8.26;


import {Trie} from "./Trie.sol";
import {ITrieFactory} from "./ITrieFactory.sol";


/// @title Trie Factory for  Protocol
/// @dev Factory for creating instances of Trie
contract TrieFactory is ITrieFactory {

    /// @dev Creates a new Trie
    /// @param lob The address to pass to the Trie constructor
    /// @return The address of the newly created Trie
    function createTrie(address lob) external returns (address) {
        Trie trie = new Trie(lob);
        return address(trie);
    }
}

File 2 of 5 : Trie.sol
// SPDX-License-Identifier: BUSL-1.1
// Central Limit Order Book (CLOB) exchange
// (c) Long Gamma Labs, 2023.
pragma solidity ^0.8.26;


import {Errors} from "./Errors.sol";
import {ITrie} from "./ITrie.sol";


struct Node {
    uint64 left;
    uint64 right;
    uint64 total_shares_value_ptr;
}


struct Leaf {
    uint64 trader_id;
    uint128 remain_shares;
    uint64 initial_shares_value_ptr;
}


struct ExecutionResult {
    uint128 executed_shares;
    uint128 executed_value;
    uint128 total_shares;
    uint128 total_value;
    uint64 right_child;
    uint64 xor_map;
}


/// @title Trie data structure for  Protocol
/// @dev This contract implements a trie for efficient order management in an on-chain limit order book.
contract Trie is ITrie {
    address immutable lob_address;

    // Since we have a prefix tree, we can immediately get all the keys in the rightmost branch.
    // Each right key represents a part of best_offer, the length of which is determined
    // by the non-zero bit in rightmost_map.  That is, the number of non-zero bits 
    // in rightmost_map equals the number of nodes in the rightmost branch.
    uint64 public best_offer = 0;
    uint64 public rightmost_map = 0x0;
    // The rightmost branch is unique: it only stores the total_shares and total_amount of the left child,
    // so deleting or adding new nodes can start directly from the corresponding node on the rightmost branch.

    uint64 highest_allocated_pointer;
    uint64 last_free_pointer;

    mapping (uint64 => Leaf) leaves;
    mapping (uint64 => Node) nodes;
    mapping (uint64 => uint256) arena;

    modifier onlyLOBPermission() {
        require(msg.sender == lob_address, Errors.Forbidden());
        _;
    }

    constructor(address _lob_address) {
        lob_address = _lob_address;
    }

    /// @dev Adds an order to the order book.
    /// @param trader_id The ID of the trader placing the order, must be be greater than 0.
    /// @param order_id The ID of the order being placed, must be unique and be pointer to leaf.
    /// @param shares The total number of shares in the order, must be greater than 0.
    /// @param value The total value of the order, must be greater than 0.
    /// All restrictions on parameters must be satisfied by the logic of the LOB contract
    function addOrder(uint64 trader_id, uint64 order_id, uint128 shares, uint128 value) virtual public onlyLOBPermission {
        uint64 ptr = allocateMemory();
        saveSharesValueToArena(ptr, shares, value);
        
        leaves[order_id] = Leaf({
            trader_id: trader_id,
            remain_shares: shares,
            initial_shares_value_ptr: ptr
        });

        uint256 map = rightmost_map;

        if (map == 0x0) {
            // This means the trie is empty.
            best_offer = order_id;
            rightmost_map = 0x1;
            return;
        }

        // We climb the rightmost branch until we go through it all, which means we need to add a new root, 
        // or to a node that matches our added order_id.
        (uint64 node_id, bool success) = findRightmostMatchingNode(order_id);
        if (success) {
            // We found the node that matches order_id.
            addOrderToNodes(order_id, node_id, shares, value);
        } else {
            // We have reached the root of the tree, we need to add a new node,  which will become the new root 
            // of the tree. New node`s descendant will be new order_id leaf.

            // note: node_id here is the root node_id
            addOrderAndUpdateRoot(order_id, node_id, shares, value);
        }
    }

    /// @dev Removes an order with a specific order_id associated with a trader identified by order_trader_id.
    /// @param order_id The ID of the order to be removed.
    /// @param order_trader_id The ID of the trader associated with the order. 
    /// Only needed for verification purposes.
    /// @return total_shares The total number of shares for the order.
    /// @return remain_shares The remaining number of shares for the order.
    function removeOrder(uint64 order_id, uint64 order_trader_id) virtual public onlyLOBPermission 
        returns (uint128 total_shares, uint128 remain_shares) {
        Leaf memory leaf = leaves[order_id];

        require(leaf.trader_id != 0x0, Errors.EmptyOrderError());

        // An important validation check for the provided address. It prevents unauthorized order removal.
        require(leaf.trader_id == order_trader_id, Errors.WrongOwner());

        uint128 total_value;
        (total_shares, total_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);

        remain_shares = leaf.remain_shares;
        uint128 remain_value = uint128(uint256(remain_shares) * uint256(total_value) / uint256(total_shares));

        // To prevent double claims.
        delete leaves[order_id];
        freeMemory(leaf.initial_shares_value_ptr);

        uint64 local_best_offer = best_offer;
        if (order_id > local_best_offer) {
            return (total_shares, 0);
        }

        if (order_id == local_best_offer) {
            removeBestOffer();
            return (total_shares, remain_shares);
        }

        (uint64 node_id, bool success) = findRightmostMatchingNode(order_id);

        if (!success) {
            return (total_shares, 0);
        }

        bool found = removeOrderFromNodes(order_id, node_id, remain_shares, remain_value);
        if (found) {
            return (total_shares, remain_shares);
        } else {
            return (total_shares, 0);
        }
    }

    /// @dev Claims executed shares for an order with a specific order_id associated with a trader identified 
    /// by order_trader_id. This operation does not remove the order from the order book.
    /// @param order_id The ID of the order for which executed shares are being claimed.
    /// @param order_trader_id The ID of the trader associated with the order. 
    /// Only needed for verification purposes.
    /// @return executed_shares The number of executed shares for the order.
    /// @return remain_shares The remaining number of shares for the order after execution.
    function claimExecuted(uint64 order_id, uint64 order_trader_id) virtual public onlyLOBPermission
        returns (uint128 executed_shares, uint128 remain_shares) {
        Leaf memory leaf = leaves[order_id];

        if (leaf.trader_id == 0x0) {
            return (0, 0);
        }

        // An important validation check for the provided address. It prevents unauthorized order claim.
        require(leaf.trader_id == order_trader_id, Errors.WrongOwner());

        remain_shares = leaf.remain_shares;
        (uint128 total_shares, uint128 total_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);

        uint64 local_best_offer = best_offer;
        if (order_id > local_best_offer) {
            remain_shares = 0;
        } else {
            (uint64 node_id, bool success) = findRightmostMatchingNode(order_id);

            if (!success || !isOrderInTree(node_id, order_id)) {
                remain_shares = 0;
            }
        }

        executed_shares = total_shares - remain_shares;
        if (executed_shares == 0) {
            return (0, remain_shares);
        }

        if (remain_shares == 0) {
            delete leaves[order_id];
            freeMemory(leaf.initial_shares_value_ptr);
        } else {
            uint128 remain_value = uint128(
                uint256(remain_shares) * uint256(total_value) / uint256(total_shares)
            );
            saveSharesValueToArena(
                leaf.initial_shares_value_ptr,
                remain_shares,
                remain_value
            );
        }
    }

    /// @dev Retrieves information about an order based on the given order_id.
    /// @param order_id The ID of the order to retrieve information for.
    /// @return total_shares The total number of shares for the order.
    /// @return remain_shares The remaining number of shares for the order.
    /// Unlike removeOrder, it does not require the existence of an order and works even on claimed and canceled 
    /// orders, returning zeros.
    function getOrderInfo(uint64 order_id) public view 
        returns (uint128 total_shares, uint128 remain_shares) {
        Leaf memory leaf = leaves[order_id];

        if (leaf.trader_id == 0x0) {
            return (0, 0);
        }

        remain_shares = leaf.remain_shares;
        (total_shares, ) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);

        // works correctly in case of empty trie too: best_offer = 0x0
        if (order_id > best_offer) {
            return (total_shares, 0);
        }

        (uint64 node_id, bool success) = findRightmostMatchingNode(order_id);

        if (!success) { 
            return (total_shares, 0);
        }

        if (isOrderInTree(node_id, order_id)) {
            return (total_shares, remain_shares);
        } else {
            return (total_shares, 0);
        }
    }

    /// @dev Executes matching orders using a "right" approach, striving to fulfill orders 
    /// as much as possible towards the right side.
    /// @param order_id The price identifier of the order, not associated with a real order ID.
    /// @param order_total_shares The total number of shares for the order being executed.
    function executeRight(uint64 order_id, uint128 order_total_shares) virtual public onlyLOBPermission 
        returns (uint128 executed_shares, uint128 executed_value) {
        // Conceptually the most complex function in the contract.
        // Since we have to rebuild rightmost branch.

        uint64 local_best_offer = best_offer;

        // Works correctly in case of empty trie too: best_offer = 0x0
        if (order_id > local_best_offer) {
            return (0, 0);
        }

        // Here we climb up the rightmost branch, similar to how it happens in findRightmostMatchingNode.
        // But, unfortunately, here we can no longer limit yourself to just node_id, and we have to read the node 
        // completely. This happens because node_id contains information only about the price of orders, 
        // but not about volumes.

        // Starting with rightmost leaf.
        Leaf memory leaf = leaves[local_best_offer];
        (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);
        uint128 remain_shares = leaf.remain_shares;

        if (order_total_shares < remain_shares) {
            executed_shares = order_total_shares;
            executed_value = uint128(uint256(executed_shares) * uint256(initial_value) / uint256(initial_shares));
                                                                    // initial_value / initial_shares is exact price
            unchecked {
                leaf.remain_shares -= executed_shares;
            }
            leaves[local_best_offer] = leaf;

            return (executed_shares, executed_value);
        }

        // Full execution of rightmost leaf.
        executed_shares = remain_shares;
        executed_value = uint128(uint256(remain_shares) * uint256(initial_value) / uint256(initial_shares));
        
        uint64 map = rightmost_map;
        (uint64 node_id, uint64 k) = calcNextRightMostNodeId(local_best_offer, map);

        uint64 xor_map = 0x1;

        // Now climbing on nodes.
        while (node_id != 0x0) {
            // We ascend along the rightmost branch from the bottom and attempt to execute the entire subtree at once.

            // Initially, we try to execute the order - the rightmost descendant.
            // Then, at each step, we essentially try to execute the entire subtree with the top at the left child
            // of the current node on the rightmost branch.

            // Since we have a prefix tree, we can guarantee that the keys of all descendants
            // of any node are not less than the key of the node itself. To improve this estimation, we can take
            // not the node_id of the node itself, but the node_id of its left child.

            xor_map ^= k;
            Node memory node = nodes[node_id];
            uint64 ptr = node.total_shares_value_ptr;
            (uint128 node_total_shares, uint128 node_total_value) = loadSharesValueFromArena(ptr);

            uint64 price_key = extractKeyFrom(node.left);
            
            // we can fully execute subtree if
            if (((order_id ^ 0x1) <= price_key)  
                    // all its leaves has higher or equal price than our order's price
                 && // (we are using price_key as lower bound) and
                (order_total_shares >= (node_total_shares + executed_shares))
                // it has less or equal shares than our order's
            ) {
                // full execution
                executed_shares += node_total_shares;
                executed_value += node_total_value;
                eraseNode(node_id, ptr);
            } else {
                ExecutionResult memory execution_result = executeRightRec(
                    order_id, node.left, (order_total_shares - executed_shares)
                );
                executed_shares += execution_result.executed_shares;
                executed_value += execution_result.executed_value;

                xor_map ^= execution_result.xor_map;
                if (execution_result.right_child != 0x0) {
                    // we are partially executed, dont need to execute anymore
                    (node_id, ) = calcNextRightMostNodeId(node_id, map);
                    if (node_id != 0x0) {
                        nodes[node_id].right = execution_result.right_child;
                    }
                    break;
                }
            }

            (node_id, k) = calcNextRightMostNodeId(node_id, map);
        }
 
        if (xor_map != 0x0) {
            // we have to change the rightmost map
            rightmost_map ^= xor_map;
            if (rightmost_map == 0x0) {
                best_offer = 0x0;
            }
        }
    }

    /// @dev Preview the execution of an order on the right.
    /// @param order_id The ID of the order to be executed.
    /// @param max_shares The maximum number of shares to execute.
    /// @param max_value The maximum value of shares to execute.
    /// @return executed_shares The number of shares executed.
    /// @return executed_value The value of the executed shares.
    function previewExecuteRight(uint64 order_id, uint128 max_shares, uint128 max_value) public view 
        returns (uint128 executed_shares, uint128 executed_value) {
        uint64 local_best_offer = best_offer;
        if (order_id > local_best_offer || max_shares == 0 || max_value == 0) {
            return (0, 0);
        }

        uint64 node_id = local_best_offer;
        uint64 k = 0x1;
        uint64 path_map = rightmost_map ^ 0x1;

        // This is a depth-first search implementation. Same idea in assembleOrderbookFromOrders.
        while (true) {
            if ((node_id & 0x1) == 0x1) {
                // leaf case
                (uint128 leaf_executed_shares, uint128 leaf_executed_value, bool full) = previewExecuteLeaf(
                    order_id,
                    node_id,
                    max_shares - executed_shares,
                    max_value - executed_value
                );
                executed_shares += leaf_executed_shares;
                executed_value += leaf_executed_value;

                if (!full) {
                    break;
                }
            } else {
                // node case
                (uint128 node_shares, uint128 node_value) = loadSharesValueFromArena(
                    nodes[node_id].total_shares_value_ptr
                );
                uint64 price_key = extractKeyFrom(nodes[node_id].left);

                // check if we can execute this node fully
                if (((order_id ^ 0x1) > price_key)
                    || ((max_shares - executed_shares) < node_shares)
                    || ((max_value - executed_value) < node_value)
                ) {
                    // we cant
                    unchecked {
                        k = ~(node_id - 1) & node_id;
                    }
                    path_map ^= k;
                    node_id = nodes[node_id].right;

                    continue;
                } else {
                    // we can
                    executed_shares += node_shares;
                    executed_value += node_value;
                }
            }

            (node_id, k) = calcNextRightMostNodeId(node_id, path_map);
            if (node_id == 0x0) {
                break;
            }
            path_map ^= k;

            node_id = nodes[node_id].left;
        }
    }

    /// @dev Assembles an order book from the orders in the trie.
    /// @param max_price_levels The maximum number of price levels to include in the order book.
    /// @return array_price_ids An array of price IDs for each level in the order book.
    /// @return array_shares An array of the total shares for each level in the order book.
    function assembleOrderbookFromOrders(uint24 max_price_levels) external view
        returns (uint24[] memory array_price_ids, uint128[] memory array_shares) {
        uint64 local_best_offer = best_offer;
        if (local_best_offer == 0x0 || max_price_levels == 0) {
            array_price_ids = new uint24[](0);
            array_shares = new uint128[](0);
            return (array_price_ids, array_shares);
        }

        array_price_ids = new uint24[](max_price_levels);
        array_shares = new uint128[](max_price_levels);

        array_price_ids[0] = uint24(local_best_offer >> 40);

        uint24 price_level = 0;

        uint64 node_id = local_best_offer;
        uint64 k = 0x1;
        uint64 path_map = rightmost_map ^ 0x1;

        // This is a depth-first search implementation. However, we don't start from the root, but 
        // from the far right element, as if we had already descended here.
        while (true) {
            if ((node_id & type(uint40).max) != 0x0) {
                uint24 c_price = uint24(node_id >> 40);

                if (c_price != array_price_ids[price_level]) {
                    ++price_level;
                    if (price_level == max_price_levels) {
                        return (array_price_ids, array_shares);
                    }
                    array_price_ids[price_level] = c_price;
                }
                
                (uint128 total_shares, ) = extractSharesValueForNode(node_id);
                array_shares[price_level] += total_shares;

                (node_id, k) = calcNextRightMostNodeId(node_id, path_map);
                if (node_id == 0x0) {
                    break;
                }
                path_map ^= k;

                node_id = nodes[node_id].left;  // this is why it works for rightmost branch nodes too
            } else {
                unchecked {
                    k = ~(node_id - 1) & node_id;
                }
                path_map ^= k;
                node_id = nodes[node_id].right;
            }
        }

        uint24 actual_length = price_level + 1;
        if (actual_length < max_price_levels) {
            // Cropping the returned arrays to their actual length.
            uint24[] memory cropped_array_price_ids = new uint24[](actual_length);
            uint128[] memory cropped_array_shares = new uint128[](actual_length);

            for(uint24 i = 0; i < actual_length; ++i) {
                cropped_array_price_ids[i] = array_price_ids[i];
                cropped_array_shares[i] = array_shares[i];
            }

            return (cropped_array_price_ids, cropped_array_shares);
        }
    }

    /// @dev Finds the rightmost node that matches the given order_id.
    /// @param order_id The ID of the order to find the matching node for.
    /// @return node_id The ID of the found node or root.
    /// @return success Indicates whether the search was successful.
    /// This algo finds the lowest node in branch that meets the given criteria.
    function findRightmostMatchingNode(uint64 order_id) internal view returns (uint64 node_id, bool success) {
        uint256 map = rightmost_map;
        uint64 local_best_offer = best_offer;

        // We climb the rightmost branch until we go through it all.
        uint256 mask = ~uint256(0x1);
        while (true) {
            if (((local_best_offer ^ order_id) & mask) == 0x0) {
                // We found the node that matches order_id.

                uint256 k = (~mask & (mask >> 1));
                // Extracts the bit that determines the length.
                // Shifting works correctly for the case of 64 bits.
                node_id = uint64((local_best_offer & mask) ^ k);

                return (node_id, true);
            }

            map = map & mask;
            if (map == 0x0) {
                // We have reached the root of the tree,

                uint256 k = (~mask & (mask >> 1));
                // Extracts the bit that determines the length.
                // Shifting works correctly for the case of 64 bits.
                uint64 root_node_id = uint64((local_best_offer & mask) ^ k);

                return (root_node_id, false);
            }

            unchecked {  // we just checked that map != 0
                mask = ~(map ^ (map - 1));
            }
        }
    }

    /// @dev Normalizes the branch of the tree up to the specified stop node.
    /// @param stop_node_id The ID of the node where normalization stops, must exist.
    /// @return extra_total_shares The total number of extra shares added during normalization.
    /// @return extra_total_value The total value associated with the extra shares added during normalization.
    /// @return new_rightmost_map The new rightmost map after normalization.
    function normalizeBranch(uint64 stop_node_id)
        internal returns (uint128 extra_total_shares, uint128 extra_total_value, uint64 new_rightmost_map) {

        uint256 map = rightmost_map;
        uint64 local_best_offer = best_offer;
        
        // loading leaf data
        Leaf memory leaf = leaves[local_best_offer];
        (uint128 initial_shares, uint128  initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);

        extra_total_shares = leaf.remain_shares;
        extra_total_value = uint128(uint256(extra_total_shares) * uint256(initial_value) / uint256(initial_shares));

        map ^= 0x1;

        if (stop_node_id == local_best_offer) {
            return (extra_total_shares, extra_total_value, uint64(map));
        }

        uint256 mask;
        unchecked {  // we are guaranteed to have a stop order higher
            mask = ~(map ^ (map - 1));
        }
        while (true) {
            uint256 k = (~mask & (mask >> 1));
            // Shifting works correctly for the case of 64 bits.
            map ^= k;

            uint64 node_id = uint64((local_best_offer & mask) ^ k);
            uint64 node_ptr = nodes[node_id].total_shares_value_ptr;
            (uint128 node_total_shares, uint128 node_total_value) = loadSharesValueFromArena(node_ptr);

            uint128 initial_total_shares = node_total_shares;
            uint128 initial_total_value = node_total_value;

            node_total_shares += extra_total_shares;
            node_total_value += extra_total_value;
            
            saveSharesValueToArena(node_ptr, node_total_shares, node_total_value);

            extra_total_shares += initial_total_shares;
            extra_total_value += initial_total_value;

            if (node_id == stop_node_id) {
                break;
            }

            unchecked {  // we are guaranteed to have a stop order higher
                mask = ~(map ^ (map - 1));
            }
        }

        new_rightmost_map = uint64(map);
    }

    /// @dev Converts the regular right branch to rightmost branch starting from the given start_node_id.
    /// @param start_node_id The starting node_id for the conversion. Must me on the rightmost branch.
    /// @return xor_map The XOR diff with rightmost map generated during the conversion.
    function convertToRightmost(uint64 start_node_id) internal returns (uint64 xor_map) {
        xor_map = 0x1;  // including leaf node

        uint64 node_id = start_node_id;
        Node memory node;

        while ((node_id & 0x1) != 0x1) {
            // untill we reach leaf
            node = nodes[node_id];
            uint64 ptr = node.total_shares_value_ptr;

            uint64 child_node_id = node.right;
            (uint128 child_shares, uint128 child_value) = extractSharesValueForNode(child_node_id);
            removeFromArenaValues(ptr, child_shares, child_value);

            uint64 k;
            unchecked {
                k = ~(node_id - 1) & node_id;
                // Extracts the bit that determines the length.
                // Valid node always is greater than 0.
            }
            xor_map ^= k;

            node_id = child_node_id;
        }

        best_offer = node_id;
    }

    /// @dev Updates root node and adds a new order as a descendant of new root.
    /// @param order_id The ID of the new order.
    /// @param root_node_id The ID of the root node in the tree.
    /// @param shares The number of shares for the new order.
    /// @param value The value associated with the new order.
    function addOrderAndUpdateRoot(uint64 order_id, uint64 root_node_id, uint128 shares, uint128 value) internal {
        uint64 extra_node_id = calcCommonParent(order_id, root_node_id);
        Node memory extra_node;

        uint64 extra_node_k;
        unchecked {
            extra_node_k = ~(extra_node_id - 1) & extra_node_id;
            // Extracts the bit that determines the length.
            // Valid node always is greater than 0.
        }

        uint64 free_ptr = allocateMemory();

        uint64 new_rightmost_map;
        if (root_node_id < order_id) {
            // inserting node to the right
            uint128 extra_total_shares;
            uint128 extra_total_value;

            (extra_total_shares, extra_total_value, new_rightmost_map) = normalizeBranch(root_node_id);
            saveSharesValueToArena(free_ptr, extra_total_shares, extra_total_value);
            extra_node = Node({
                left: root_node_id, 
                right: order_id,
                total_shares_value_ptr: free_ptr
            });

            new_rightmost_map ^= extra_node_k ^ 0x1;  // 0x1 for new leaf

            best_offer = order_id;
        } else {
            // inserting node to the left
            saveSharesValueToArena(free_ptr, shares, value);
            extra_node = Node({
                left: order_id,
                right: root_node_id,
                total_shares_value_ptr: free_ptr
            });
            new_rightmost_map = rightmost_map ^ extra_node_k;
        }

        rightmost_map = new_rightmost_map;
        nodes[extra_node_id] = extra_node;
    }

    /// @dev Adds an order to the nodes based on the provided order_id, node_id, shares, and value.
    /// @param order_id The ID of the order to add.
    /// @param node_id The ID of the node where the order should be added. Must be the lowest node in rightmost branch 
    /// that matches order_id.
    /// @param shares The number of shares for the order.
    /// @param value The value associated with the order.
    function addOrderToNodes(uint64 order_id, uint64 node_id, uint128 shares, uint128 value) internal {
        // we now for sure that node_id is not a leaf
        Node memory node = nodes[node_id];

        if (matchesNode(order_id, node.left)) {
            uint64 node_ptr = node.total_shares_value_ptr;
            addToArenaValues(node_ptr, shares, value);

            addOrderToNonRightmostNodeDescendants(node.left, order_id, shares, value);
            return;
        }  // node.right can't match order_id
           // so no "else" logic needs here

        // so we are inserting new node here, in current node
        uint64 extra_node_id;
        Node memory extra_node;
        uint64 free_ptr = allocateMemory();
        if (order_id < node_id) {
            uint64 node_ptr = node.total_shares_value_ptr;
            addToArenaValues(node_ptr, shares, value);

            extra_node_id = calcCommonParent(order_id, node.left);
            if (node.left > order_id) {
                extra_node = Node(order_id, node.left, free_ptr);
            } else {
                extra_node = Node(node.left, order_id, free_ptr);
            }
            (uint128 child_shares, uint128 child_value) = extractSharesValueForNode(node.left);
            saveSharesValueToArena(free_ptr, shares + child_shares, value + child_value);

            node.left = extra_node_id;
        } else {
            // here we must properly rebuild the rightmost branch
            extra_node_id = calcCommonParent(order_id, node.right);

            uint64 extra_node_k;
            unchecked {
                extra_node_k = ~(extra_node_id - 1) & extra_node_id;
                // Extracts the bit that determines the length.
                // Valid node always is greater than 0.
            }

            if (node.right > order_id) {
                saveSharesValueToArena(free_ptr, shares, value);
                extra_node = Node(order_id, node.right, free_ptr);
                rightmost_map ^= extra_node_k;
            } else {
                (uint128 extra_total_shares, uint128 extra_total_value, uint64 new_rightmost_map)
                 = normalizeBranch(node.right);

                rightmost_map = new_rightmost_map ^ extra_node_k ^ 0x1;  // 0x1 for new leaf;

                best_offer = order_id;

                saveSharesValueToArena(free_ptr, extra_total_shares, extra_total_value);
                extra_node = Node(node.right, order_id, free_ptr);
            }

            node.right = extra_node_id;
        }

        nodes[node_id] = node;
        nodes[extra_node_id] = extra_node;
    }

    /// @dev Adds an order to the descendants of a node that is not the rightmost node.
    /// @param node_id The ID of the node from which to start updating. It must match order_id.
    /// @param order_id The ID of the order to add.
    /// @param shares The total shares associated with the order.
    /// @param value The total value associated with the order.
    function addOrderToNonRightmostNodeDescendants(
        uint64 node_id, 
        uint64 order_id, 
        uint128 shares, 
        uint128 value
    ) internal {
        uint64 next_node_id;
        Node memory node;

        // Descending the tree starting from node_id until neither child matches order_id, 
        // indicating a new node insertion point.
        while (true) {
            node = nodes[node_id];

            uint64 ptr = node.total_shares_value_ptr;
            addToArenaValues(ptr, shares, value);

            if (matchesNode(order_id, node.left)) {
                next_node_id = node.left;
            } else if (matchesNode(order_id, node.right)) {
                next_node_id = node.right;
            } else {
                break;
            }

            node_id = next_node_id;
        }

        uint64 extra_node_id;
        Node memory extra_node;
        uint64 free_ptr = allocateMemory();
        uint64 child_node_id;
        if (order_id < node_id) {
            // Inserting new (extra) node to the left.
            extra_node_id = calcCommonParent(order_id, node.left);
            if (node.left > order_id) {
                extra_node = Node(order_id, node.left, free_ptr);
            } else {
                extra_node = Node(node.left, order_id, free_ptr);
            }

            child_node_id = node.left;

            node.left = extra_node_id;
        } else {
            // Inserting new (extra) node to the right.
            extra_node_id = calcCommonParent(order_id, node.right);
            if (node.right > order_id) {
                extra_node = Node(order_id, node.right, free_ptr);
            } else {
                extra_node = Node(node.right, order_id, free_ptr);
            }

            child_node_id = node.right;

            node.right = extra_node_id;
        }
        
        (uint128 child_shares, uint128 child_value) = extractSharesValueForNode(child_node_id);
        saveSharesValueToArena(free_ptr, shares + child_shares, value + child_value);

        nodes[node_id] = node;
        nodes[extra_node_id] = extra_node;
    }

    /// @dev Checks if a given order is present in the tree.
    /// @param node_id The ID of the starting node identifier from which the search begins.
    /// @param order_id The ID of the order to search for in the tree.
    /// @return isPresent A boolean value indicating whether the order is present in the tree.
    function isOrderInTree(uint64 node_id, uint64 order_id) internal view returns (bool isPresent) {
        if (node_id == order_id) {
            return true;
        }
        Node memory node;
        while (true) {
            node = nodes[node_id];
            if (node.left == order_id || node.right == order_id) {
                return true;
            }
            if (matchesNode(order_id, node.left)) {
                node_id = node.left;
            } else if (matchesNode(order_id, node.right)) {
                node_id = node.right;
            } else {
                return false;
            }
        }
    }

    /// @dev Removes best offer order and rebuild rightmost branch if needed.
    function removeBestOffer() internal {
        uint64 local_best_offer = best_offer;
        uint64 map = rightmost_map;

        if (map == 0x1) {
            // This means there is only one order in the trie.
            // We remove it and leave the trie empty.
            rightmost_map = 0x0;
            best_offer = 0x0;
            return;
        }

        // We need to find the parent node and remove it as well.
        // It exists because there are more than one leaf in the tree.
        map ^= 0x1;
        uint64 mask;
        unchecked {
            // map > 0 since there are more than one leaf in the tree
            mask = ~(map ^ (map - 1));
        }
        uint64 k = (((mask >> 1) | 0x8000000000000000) & ~mask);

        // Removing this node from rightmost map too.
        map ^= k;

        uint64 node_id = (local_best_offer & mask) ^ k;
        Node memory node = nodes[node_id];
        eraseNode(node_id, node.total_shares_value_ptr);

        uint64 new_right_child = node.left;

        // and we have new rightmost branch
        uint64 new_rightmost_map = map ^ convertToRightmost(new_right_child);
        rightmost_map = new_rightmost_map;

        // This means that the node being removed has no "grandfather" node.
        if (new_rightmost_map == 0x1) {
            return;
        }

        // We also need to update the right child of the ancestor's ancestor of our order, as we have just removed it.
        unchecked {
            // map > 0 since there are at least one more ancestor
            mask = ~(map ^ (map - 1));
        }
        k = (((mask >> 1) | 0x8000000000000000) & ~mask);
        node_id = (local_best_offer & mask) ^ k;

        nodes[node_id].right = new_right_child;
    }

    /// @dev Removes an order from the nodes based on the provided order_id, node_id, remaining shares, and remaining value.
    /// @param order_id The ID of the order to remove.
    /// @param node_id The ID of the node from which to remove the order.
    /// @param remain_shares The remaining shares of the order.
    /// @param remain_value The remaining value of the order.
    /// @return found Indicates if the order was found and removed.
    function removeOrderFromNodes(
        uint64 order_id,
        uint64 node_id,
        uint128 remain_shares,
        uint128 remain_value
    ) internal returns (bool found) {
        Node memory node = nodes[node_id];

        if (node.left == order_id) {
            eraseNode(node_id, node.total_shares_value_ptr);

            uint64 k;
            unchecked {
                // valid node_id is always greater than 0
                k = ~(node_id - 1) & node_id;
            }

            uint64 map = rightmost_map;
            rightmost_map = map ^ k;

            uint64 mask;
            unchecked {
                mask = ~(k ^ (k - 1));  // k > 0
            }
            map = map & mask;

            if (map == 0x0) {
                // same case in removeBestOffer - no "grandfather" node.
                return true;
            }

            unchecked {
                k = ~(map - 1) & map;  // we just checked that map > 0
                mask = ~(k ^ (k - 1)); // k > 0
            }

            uint64 new_right_child = node.right;

            node_id = (node_id & mask) ^ k;
            nodes[node_id].right = new_right_child;

            return true;
        }

        if (!matchesNode(order_id, node.left)) {
            return false;
        }

        uint64 returned_child;
        (found, returned_child) = removeOrderFromNonRightmostNodeDescendants(
            node.left, order_id, remain_shares, remain_value
        );
        if (found) {
            removeFromArenaValues(node.total_shares_value_ptr, remain_shares, remain_value);

            if (node.left != returned_child){
                node.left = returned_child;
                nodes[node_id] = node;
            }
        }
    }

    /// @dev Recursively removes an order from the descendants of a non-rightmost node.
    /// @param node_id The ID  of the current node being processed. Must be not a leaf.
    /// @param order_id The ID of the order to be removed.
    /// @param shares The number of shares associated with the order.
    /// @param value The value associated with the order.
    /// @return found Indicates if the order was found and removed.
    /// @return returned_child The identifier of the child node returned after removal.
    function removeOrderFromNonRightmostNodeDescendants(
        uint64 node_id, 
        uint64 order_id, 
        uint128 shares, 
        uint128 value
    ) internal returns (bool found, uint64 returned_child) {
        Node memory node = nodes[node_id];

        if (node.left == order_id) {
            eraseNode(node_id, node.total_shares_value_ptr);
            return (true, node.right);
        } else if (node.right == order_id) {
            eraseNode(node_id, node.total_shares_value_ptr);
            return (true, node.left);
        }

        if (matchesNode(order_id, node.left)) {
            (found, returned_child) = removeOrderFromNonRightmostNodeDescendants(node.left, order_id, shares, value);
            if (!found) {
                return (false, 0x0);
            }

            removeFromArenaValues(node.total_shares_value_ptr, shares, value);

            if (node.left != returned_child){
                node.left = returned_child;
                nodes[node_id] = node;
            }

            return (true, node_id);
        } else if (matchesNode(order_id, node.right)) {
            (found, returned_child) = removeOrderFromNonRightmostNodeDescendants(node.right, order_id, shares, value);
            if (!found) {
                return (false, 0x0);
            }

            removeFromArenaValues(node.total_shares_value_ptr, shares, value);

            if (node.left != returned_child){
                node.right = returned_child;
                nodes[node_id] = node;
            }

            return (true, node_id);
        } else {
            return (false, 0x0);
        }
    }

    /// @dev Extracts key and mask from a given node_id.
    /// @param node_id The ID of the node from which to extract key and mask.
    /// @return key The extracted key.
    /// @return mask The extracted mask.
    function extractKeyAndMaskFrom(uint64 node_id) internal pure returns (uint64 key, uint64 mask) {
        unchecked {
            // valid node_id is always greater than 0
            mask = ~((node_id - 1) ^ node_id);
        }
        key = node_id & mask;
        return (key, mask);
    }

    /// @dev Extracts key from a given node_id.
    /// @param node_id The ID of the node from which to extract key.
    /// @return key The extracted key.
    function extractKeyFrom(uint64 node_id) internal pure returns (uint64 key) {
        uint64 k;
        unchecked {
            // valid node_id is always greater than 0
            k = ~(node_id - 1) & node_id;
        }
        return node_id ^ k;
    }

    /// @dev Calculates the common parent node for a given order_id and node_id.
    /// @param order_id The ID of the order to calculate the common parent for.
    /// @param node_id The ID of the node to calculate the common parent for.
    /// @return The calculated common parent node.
    function calcCommonParent(uint64 order_id, uint64 node_id) internal pure returns (uint64) {
        uint64 key = extractKeyFrom(node_id);

        uint256 diff = (order_id ^ 0x1) ^ key;
        uint256 mask = ~uint256(type(uint64).max);

        uint256 t;
        t = mask >> 32; if ((t & diff) == 0x0) { mask = t; }
        t = mask >> 16; if ((t & diff) == 0x0) { mask = t; }
        t = mask >> 8; if ((t & diff) == 0x0) { mask = t; }
        t = mask >> 4; if ((t & diff) == 0x0) { mask = t; }
        t = mask >> 2; if ((t & diff) == 0x0) { mask = t; }
        t = mask >> 1; if ((t & diff) == 0x0) { mask = t; }

        uint256 k = ((mask >> 1) & ~mask);
        return uint64((order_id & mask) ^ k);
    }

    /// @dev Checks if the order_id is a descendant of the node_id.
    /// @param order_id The ID of the order to compare with the node_id.
    /// @param node_id The ID of the node to compare with the order_id.
    /// @return True if the order_id matches the node_id, false otherwise.
    function matchesNode(uint64 order_id, uint64 node_id) internal pure returns (bool) {
        uint64 mask;
        unchecked {
            // valid node_id is always greater than 0
            mask = ~((node_id - 1) ^ node_id);
        }
        return ((order_id ^ node_id) & mask) == 0x0;
    }

    /// @dev Erases the node with the specified node_id.
    /// @param node_id The ID of the node of the node to erase.
    function eraseNode(uint64 node_id, uint64 ptr) internal virtual {
        // Requires a more thoughtful strategy than just erasing everything.
        // if ((node_id & 0x1) != 0x1) {
        //     delete nodes[node_id];
        // }
        freeMemory(ptr);
    }

    /// @dev Recursively executes orders using a "right" approach within the order matching process.
    /// @param order_id The price identifier of the order, not necessarily associated with a real order ID.
    /// @param node_id The ID of the node within the order.
    /// @param rest_total_shares The remaining total shares to be executed.
    /// @return execution_result An ExecutionResult struct containing the result of the execution.
    function executeRightRec(uint64 order_id, uint64 node_id, uint128 rest_total_shares)
        internal returns (ExecutionResult memory execution_result) {

        if ((node_id & 0x1) == 0x1) {
            // leaf execution
            return executeLeaf(order_id, node_id, rest_total_shares);
        }

        // node execution
        Node memory node = nodes[node_id];
        uint64 node_ptr = node.total_shares_value_ptr;
        (uint128 node_shares, uint128 node_value) = loadSharesValueFromArena(node_ptr);

        // node.left != 0x0 since it node, not a leaf
        uint64 price_key = extractKeyFrom(node.left);

        // the same condition in executeRight 
        if (((order_id ^ 0x1) > price_key) || (rest_total_shares < node_shares)) {
            ExecutionResult memory right_execution_result = executeRightRec(order_id, node.right, rest_total_shares);
            rest_total_shares -= right_execution_result.executed_shares;

            if (right_execution_result.right_child != 0x0) {
                removeFromArenaValues(
                    node_ptr,
                    right_execution_result.total_shares + right_execution_result.executed_shares,
                    right_execution_result.total_value + right_execution_result.executed_value
                );
                if (node.right != right_execution_result.right_child) {
                    node.right = right_execution_result.right_child;
                    nodes[node_id] = node;
                }

                uint64 k;
                unchecked {
                    k = ~(node_id - 1) & node_id;
                    // Extracts the bit that determines the length.
                    // Valid node always is greater than 0.
                }

                execution_result = ExecutionResult({
                    executed_shares: right_execution_result.executed_shares,
                    executed_value: right_execution_result.executed_value,
                    total_shares: node_shares - right_execution_result.executed_shares,
                    total_value: node_value - right_execution_result.executed_value,
                    right_child: node_id,
                    xor_map: right_execution_result.xor_map ^ k
                });
            } else {
                execution_result = executeRightRec(order_id, node.left, rest_total_shares);
                execution_result.executed_shares += right_execution_result.executed_shares;
                execution_result.executed_value += right_execution_result.executed_value;
            }
        } else {
            // full execution
            execution_result = ExecutionResult({
                executed_shares: node_shares,
                executed_value: node_value,
                total_shares: 0,
                total_value: 0,
                right_child: 0x0,
                xor_map: 0x0
            });
            eraseNode(node_id, node_ptr);
        }
    }

    /// @dev Executes a leaf node within the order matching process.
    /// @param order_id The price identifier of the order, not associated with a real order ID.
    /// @param leaf_node_id The ID of the leaf node within the order.
    /// @param rest_total_shares The remaining total shares to be executed.
    /// @return execution_result An ExecutionResult struct containing the result of the execution.
    function executeLeaf(uint64 order_id, uint64 leaf_node_id, uint128 rest_total_shares) 
        internal returns (ExecutionResult memory execution_result) {
        Leaf memory leaf = leaves[leaf_node_id];
        (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);
        uint128 remain_shares = leaf.remain_shares;
        uint128 remain_value = uint128(uint256(remain_shares) * uint256(initial_value) / uint256(initial_shares));

        if (leaf_node_id >= order_id) {  // both end on 0x1 bit, so we can compare them
            // we can execute current leaf
            if (remain_shares <= rest_total_shares) {
                // full execution
                execution_result = ExecutionResult({
                    executed_shares: remain_shares,
                    executed_value: remain_value,
                    total_shares: 0,
                    total_value: 0,
                    right_child: 0x0,
                    xor_map: 0x0
                });
            } else {
                // partial execution
                uint128 executed_shares = rest_total_shares;
                // Since the operation node.total_value = node.total_shares * price is expected,
                // the quotient will always be an integer.
                uint128 executed_value = uint128(uint256(rest_total_shares)
                     * uint256(remain_value) / uint256(remain_shares));
                     // remain_value / remain_shares = price

                unchecked {
                    leaf.remain_shares -= executed_shares;
                }
                leaves[leaf_node_id] = leaf;

                execution_result = ExecutionResult({
                    executed_shares: executed_shares,
                    executed_value: executed_value,
                    total_shares: remain_shares - executed_shares,
                    total_value: remain_value - executed_value,
                    right_child: leaf_node_id,
                    xor_map: 0x1
                });

                best_offer = leaf_node_id;
            }
        } else {
            // we can't execute current leaf at all
            execution_result = ExecutionResult({
                executed_shares: 0,
                executed_value: 0,
                total_shares: remain_shares,
                total_value: remain_value,
                right_child: leaf_node_id,
                xor_map: 0x1
            });

            best_offer = leaf_node_id;
        }

        // A brief comment explaining why in some cases we equate the best offer to the current leaf.
        // When executing multiple orders, only one of them may be partially executed. This partially executed order 
        // becomes the best offer.

        // An entirely unexecuted order becomes the best because our algorithm, encountering such behavior, 
        // stops trying to execute other orders - they are guaranteed to be worse. On the other hand, 
        // all better orders have already been fully executed.
    }

    /// @dev Preview the execution of a leaf node.
    /// @param order_id The ID of the order to be executed.
    /// @param leaf_node_id The ID of the leaf node to be executed.
    /// @param rest_shares The remaining shares of the order.
    /// @param rest_value The remaining value of shares of the order.
    /// @return executed_shares The number of shares executed.
    /// @return executed_value The value of the executed shares.
    /// @return full A boolean indicating whether the leaf was fully executed (true) or partially executed (false).
    function previewExecuteLeaf(uint64 order_id, uint64 leaf_node_id, uint128 rest_shares, uint128 rest_value) 
        internal view returns (uint128 executed_shares, uint128 executed_value, bool full) {
        Leaf memory leaf = leaves[leaf_node_id];
        (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);
        uint128 leaf_shares = leaf.remain_shares;
        uint128 leaf_value = uint128(uint256(leaf_shares) * uint256(initial_value) / uint256(initial_shares));

        if (leaf_node_id >= order_id) {  // both end on 0x1 bit, so we can compare them
            // we can execute current leaf

            // The order of these checks is important and should not be changed.
            // We first check if we need to adjust shares based on value,
            // then we check if we need to adjust value based on shares.
            // This ensures correct handling of partial executions and rounding.

            if (rest_value < leaf_value) {
                uint128 shares = uint128(uint256(rest_value) * uint256(leaf_shares) / uint256(leaf_value));
                // note: This division may not result in an integer, and rounding down is implied
                if (shares < rest_shares) {
                    rest_shares = shares;
                }
            }

            if (rest_shares < leaf_shares) {
                uint128 value = uint128(uint256(rest_shares) * uint256(leaf_value) / uint256(leaf_shares));
                if (value < rest_value) {
                    rest_value = value;
                }
            }

            if (rest_shares < leaf_shares) {
                // partial execution
                return (rest_shares, rest_value, false);
            } else {
                // full execution
                return (leaf_shares, leaf_value, true);
            }
        } else {
            // we can't execute current leaf at all
            return (0, 0, false);
        }
    }

    /// @dev Calculates the next rightmost node ID and its associated k-bit based on the given node ID and map.
    /// @param node_id The node ID.
    /// @param map The map used for calculation.
    /// @return The next rightmost node ID and its associated k-bit.
    function calcNextRightMostNodeId(uint64 node_id, uint64 map) internal pure returns (uint64, uint64) {
        uint64 mask;
        unchecked {
            mask = ~(node_id ^ (node_id - 1));  // valid node_id is always greater than 0
            map &= mask;
        }
        if (map == 0x0) {
            return (0, 0);
        }
        unchecked {
            mask = ~(map ^ (map - 1));  // we just checker map > 0
        }
        uint64 k = (((mask >> 1) | 0x8000000000000000) & ~mask);
        
        return ((node_id & mask) ^ k, k);
    }

    /// @dev Packs two uint128 values into a single uint256.
    /// @param a The first uint128 value.
    /// @param b The second uint128 value.
    /// @return p The packed uint256 value.
    function packTwoUintsToWord(uint128 a, uint128 b) internal pure returns (uint256 p) {
        p = uint256(a) ^ (uint256(b) << 128);
    }

    /// @dev Unpacks a uint256 value into two uint128 values.
    /// @param p The packed uint256 value.
    /// @return a The first unpacked uint128 value.
    /// @return b The second unpacked uint128 value.
    function unPackTwoUintsFromWord(uint256 p) internal pure returns (uint128 a, uint128 b) {
        a = uint128(p & 0xffffffffffffffffffffffffffffffff);
        b = uint128(p >> 128);
    }

    /// @dev Allocates memory for storing data.
    /// @return ptr The pointer to the allocated memory.
    function allocateMemory() internal returns (uint64 ptr) {
        if (last_free_pointer == 0x0) {
            return (++highest_allocated_pointer);
        }
        ptr = last_free_pointer;
        last_free_pointer = uint64(arena[ptr]);
    }

    /// @dev Frees the memory at the given pointer.
    /// @param ptr The pointer to the memory to be freed.
    function freeMemory(uint64 ptr) internal {
        require(last_free_pointer != ptr, Errors.PointerAlreadyFreed());
        arena[ptr] = packTwoUintsToWord(last_free_pointer, 0x1);
        last_free_pointer = ptr;
    }

    /// @dev Saves the shares and value to the memory at the given pointer.
    /// @param ptr The pointer to the memory where the data will be saved.
    /// @param shares The shares to be saved.
    /// @param value The value to be saved.
    function saveSharesValueToArena(uint64 ptr, uint128 shares, uint128 value) internal {
        arena[ptr] = packTwoUintsToWord(shares, value);
    }

    /// @dev Loads the shares and value from the memory at the given pointer.
    /// @param ptr The pointer to the memory from where the data will be loaded.
    /// @return The shares and value loaded from the memory.
    function loadSharesValueFromArena(uint64 ptr) internal view returns (uint128, uint128) {
        return unPackTwoUintsFromWord(arena[ptr]);
    }

    /// @dev Adds shares and value to the data at the given pointer in memory.
    /// @param ptr The pointer to the memory where the data will be added.
    /// @param adding_shares The shares to be added.
    /// @param adding_value The value to be added.
    function addToArenaValues(uint64 ptr, uint128 adding_shares, uint128 adding_value) internal {
        (uint128 shares, uint128 value) = unPackTwoUintsFromWord(arena[ptr]);

        shares += adding_shares;
        value += adding_value;
        
        arena[ptr] = packTwoUintsToWord(shares, value);
    }

    /// @dev Removes shares and value from the data at the given pointer in memory.
    /// @param ptr The pointer to the memory from where the data will be removed.
    /// @param removing_shares The shares to be removed.
    /// @param removing_value The value to be removed.
    function removeFromArenaValues(uint64 ptr, uint128 removing_shares, uint128 removing_value) internal {
        (uint128 shares, uint128 value) = unPackTwoUintsFromWord(arena[ptr]);

        shares -= removing_shares;
        value -= removing_value;
        
        arena[ptr] = packTwoUintsToWord(shares, value);
    }

    /// @dev Extracts the shares and value for a given node.
    /// @param node_id The ID of the node.
    /// @return The shares and value for the node.
    function extractSharesValueForNode(uint64 node_id) internal view returns (uint128, uint128) {
        if ((node_id & 0x1) == 0x1) {
            // leaf case
            Leaf memory leaf = leaves[node_id];
            (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr);
            uint128 remain_shares = leaf.remain_shares;
            uint128 remain_value = uint128(uint256(remain_shares) * uint256(initial_value) / uint256(initial_shares));
            return (remain_shares, remain_value);
        }

        uint64 ptr = nodes[node_id].total_shares_value_ptr;
        return loadSharesValueFromArena(ptr);
    }
}

File 3 of 5 : ITrieFactory.sol
// SPDX-License-Identifier: BUSL-1.1
// Central Limit Order Book (CLOB) exchange
// (c) Long Gamma Labs, 2023.
pragma solidity ^0.8.26;


interface ITrieFactory {
    function createTrie(address lob) external returns (address);
}

File 4 of 5 : Errors.sol
// SPDX-License-Identifier: BUSL-1.1
// Central Limit Order Book (CLOB) exchange
// (c) Long Gamma Labs, 2023.
pragma solidity ^0.8.26;


contract Errors {
    error AddressIsZero();
    error ArrayLengthMismatch();
    error ChainIsUnstableForTrades();
    error ClaimNotAllowed();
    error CommissionParamTooHigh();
    error Disabled();
    error EmptyOrderError();
    error ExcessiveSignificantFigures();
    error Expired();
    error Forbidden();
    error FractionalNumbersNotAllowed();
    error InsufficientTokenXBalance();
    error InsufficientTokenYBalance();
    error InvalidCommissionRate();
    error InvalidFloatingPointRepresentation();
    error InvalidMarketMaker();
    error InvalidPriceRange();
    error InvalidTransfer();
    error MarketOnlyAndPostOnlyFlagsConflict();
    error MaxCommissionFailure();
    error NativeETHDisabled();
    error NonceExhaustedFailure();
    error NotImplementedYet();
    error OnlyOwnerCanCancelOrders();
    error PointerAlreadyFreed();
    error PriceExceedsMaximumAllowedValue();
    error TransferFailed();
    error UnknownOrderId();
    error UnknownTrader();
    error WrongOwner();
    error ZeroMaxDelayNotAllowed();
    error ZeroRecoveryTimeNotAllowed();
    error ZeroTokenTransferNotAllowed();
}

File 5 of 5 : ITrie.sol
// SPDX-License-Identifier: BUSL-1.1
// Central Limit Order Book (CLOB) exchange
// (c) Long Gamma Labs, 2023.
pragma solidity ^0.8.26;


interface ITrie {
    function best_offer() external view returns (uint64);
    function rightmost_map() external view returns (uint64);
    function addOrder(uint64 trader_id, uint64 order_id, uint128 shares, uint128 value) external;
    function removeOrder(uint64 order_id, uint64 order_trader_id) external returns (uint128 total_shares, uint128 remain_shares);
    function claimExecuted(uint64 order_id, uint64 order_trader_id) external returns (uint128 executed_shares, uint128 remain_shares);
    function getOrderInfo(uint64 order_id) external view returns (uint128 total_shares, uint128 remain_shares);
    function executeRight(uint64 order_id, uint128 order_total_shares) external returns (uint128 executed_shares, uint128 executed_value);
    function previewExecuteRight(uint64 order_id, uint128 max_shares, uint128 max_value) external view returns (uint128 executed_shares, uint128 executed_value);
    function assembleOrderbookFromOrders(uint24 max_price_levels) external view returns (uint24[] memory array_price_ids, uint128[] memory array_shares);
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@solmate/src/=lib/solmate/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"lob","type":"address"}],"name":"createTrie","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x60808060405260043610156011575f80fd5b5f3560e01c6330b9c351146023575f80fd5b3460a857602036600319011260a8576004356001600160a01b0381169081900360a857612d7b80830183811067ffffffffffffffff82111760945760209284926100ad843981520301905ff080156089576040516001600160a01b039091168152602090f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b5f80fdfe60a03461008d57601f612d7b38819003918201601f19168301916001600160401b038311848410176100915780849260209460405283398101031261008d57516001600160a01b038116810361008d575f80546001600160801b0319169055608052604051612cd590816100a6823960805181818160a20152818161019a015281816101f601526102500152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c9081630d1cf14614610363575080632e2866831461033e5780635e9dd46a146102875780638f94fa521461022d578063a558898f146101d3578063b23264221461015b578063c4dca4221461013a578063e146af47146101085763fa1e9ec81461007f575f80fd5b3461010457604036600319011261010457610098610388565b6100a061039e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576100d9916111f8565b604080516001600160801b039384168152919092166020820152f35b631dd2188d60e31b5f5260045ffd5b5f80fd5b34610104576060366003190112610104576100d9610124610388565b61012c6103b4565b6101346103ca565b91610fd4565b34610104576020366003190112610104576100d9610156610388565b610f1e565b3461010457608036600319011261010457610174610388565b61017c61039e565b6101846103ca565b606435916001600160801b0383168303610104577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576101d193610d08565b005b34610104576040366003190112610104576101ec610388565b6101f46103b4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576100d991610985565b3461010457604036600319011261010457610246610388565b61024e61039e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576100d9916107af565b346101045760203660031901126101045760043562ffffff81168103610104576102b0906104f7565b90604051918291604083016040845281518091526020606085019201905f5b818110610320575050508281036020840152602080835192838152019201905f5b8181106102fe575050500390f35b82516001600160801b03168452859450602093840193909201916001016102f0565b825162ffffff168452869550602093840193909201916001016102cf565b34610104575f3660031901126101045760206001600160401b035f5416604051908152f35b34610104575f366003190112610104576020906001600160401b035f5460401c168152f35b600435906001600160401b038216820361010457565b602435906001600160401b038216820361010457565b602435906001600160801b038216820361010457565b604435906001600160801b038216820361010457565b60405190606082018281106001600160401b038211176103ff57604052565b634e487b7160e01b5f52604160045260245ffd5b6040519060c082018281106001600160401b038211176103ff57604052565b6040519190601f01601f191682016001600160401b038111838210176103ff57604052565b6001600160401b0381116103ff5760051b60200190565b9061048061047b83610457565b610432565b8281528092610491601f1991610457565b0190602036910137565b80518210156104af5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b906001600160801b03809116911601906001600160801b0382116104e357565b634e487b7160e01b5f52601160045260245ffd5b5f54916001600160401b0383169182158015610751575b6107245762ffffff16906105218261046e565b9061052b8361046e565b908251156104af576020839694960162ffffff8560281c16905260016001600160401b035f969560401c1618935b64ffffffffff8116156106ee5762ffffff8160281c1662ffffff871662ffffff610583828861049b565b511682036106a3575b50506105dc85826105a46001600160401b0394611323565b506001600160801b036105d36105cc62ffffff8d1693836105c5868d61049b565b51166104c3565b928961049b565b911690526113c7565b91169485156106045718935f5260026020526001600160401b0360405f205416955b95610559565b505092509262ffffff600191959295160162ffffff81116104e35762ffffff1690811061062e5750565b90916106398261046e565b6106428361046e565b945f5b62ffffff8116858110156106995762ffffff9181836106666001948761049b565b5116610672828861049b565b526106916001600160801b03610688838a61049b565b5116918b61049b565b520116610645565b5050509150509190565b90965062ffffff81146104e3576001019562ffffff87168881146106e1576001600160401b03926105dc926106d989938961049b565b52925061058c565b5050509350935090509190565b936001600160401b03908186815f198201161916161894165f5260026020526001600160401b0360405f205460401c16956105fe565b5091505060209061073482610432565b5f81525f36813761074483610432565b925f8452505f3681379190565b5062ffffff81161561050e565b906001600160801b03809116911603906001600160801b0382116104e357565b818102929181159184041417156104e357565b811561079b570490565b634e487b7160e01b5f52601260045260245ffd5b90916001600160401b038216805f52600160205260405f206107cf6103e0565b9054946001600160401b03861690818352604060208401936001600160801b0389831c168552019660c01c87528115610925576001600160401b031603610916576001600160801b039051169361082f6001600160401b03825116611428565b9590946001600160401b035f541684115f146108df5750505f935b610854858261075e565b956001600160801b038716156108d6578591906001600160801b038316908161089e57505050506001600160401b039061089c925f5260016020525f6040812055511661162b565b565b61089c95506001600160401b03926001600160801b036108c58194826108cd95169061077e565b911690610791565b169251166115fe565b505f9550505050565b6108eb8196929661144f565b1591908215610904575b50501561084a575f945061084a565b61090e92506114f2565b155f806108f5565b635d652eb160e01b5f5260045ffd5b505f9550859450505050565b906001600160401b036109426103e0565b92548181168452818160401c16602085015260801c166040830152565b90600160401b600160801b0382549160401b1690600160401b600160801b031916179055565b916001600160401b035f541691826001600160401b03851611610cff57825f52600160205260405f20936109b76103e0565b94546001600160401b038116865260208601906001600160801b038160401c16825260c01c956109ed6040820197808952611428565b9790916001600160801b03845116916001600160801b03871694838610610c5a575050506001600160801b0391826108c58382610a2c959c169061077e565b16610a456001600160401b035f5460401c1680976113c7565b906001915b6001600160401b038216928315610c4c5718915f52600260205260405f20986001600160401b03610a796103e0565b9a548181168c52818160401c1660208d015260801c16998a6040820152610a9f8b611428565b9290916001600160401b03610ac7818351166001600160401b0381815f198201161916161890565b166001600160401b0360018b1816111580610c30575b15610b125750610aff8b93610af9610b0a9694610b05946104c3565b976104c3565b9b61162b565b6113c7565b929892610a4a565b610b6991959c506001600160401b03935060809250610b4284610b54925116610b3b888d61075e565b908b611708565b956001600160801b03875116906104c3565b956001600160801b03602087015116906104c3565b9a8260a086015116189301511680610b86575087610b0a916113c7565b9450610ba09298979195506001600160401b0393506113c7565b50169081610c15575b50505b6001600160401b038116610bbd5750565b600160401b600160801b035f54916001600160401b038360401c161860401b16906001600160401b0382600160401b600160801b0319831617805f5560401c1615610c06575050565b6001600160801b031916175f55565b610c29915f52600260205260405f2061095f565b5f80610ba9565b506001600160801b03610c4383856104c3565b16881015610add565b965050505094505050610bac565b9250926001600160801b03919550610c8890826108c56001600160401b039782610cfb9b9c9d9e169061077e565b16976001600160801b038781845116031682525f526001602052828060405f2095511616831985541617845551600160401b600160c01b0384549160401b1690600160401b600160c01b03191617835551168154906001600160401b0360c01b9060c01b169060018060c01b0316179055565b9190565b505f9250829150565b92919092610d9f610d17611aec565b91610d238585856115fe565b6001600160401b03610d336103e0565b911681526001600160801b03841660208083019182526001600160401b0394851660408085019182528987165f8181526001909452928190209451935191516001600160c01b031960c09190911b1693909616600160401b600160c01b039190961b1694909417179055565b5f546001600160401b038160401c1615610f015750610dbd8461144f565b90919015610dcf575061089c93611b6d565b909291610ddf8461089c966127df565b92610de86114d8565b506001600160401b0384815f1982011619161694610e04611aec565b916001600160401b038216938585105f14610ec3575050946001600160401b0394939285600193610e37610e3f996128b1565b9a91836115fe565b610e476103e0565b9283528560208401521660408201529518189083195f5416175f555b600160401b600160801b035f549160401b1690600160401b600160801b031916175f55165f5260026020526001600160401b036040805f20928280825116168319855416178455610eba836020830151168561095f565b015116906116b1565b8392506001600160401b0396959491610edd9188956115fe565b610ee56103e0565b938452602084015216604082015292825f5460401c1618610e63565b6001600160801b0319161768010000000000000000175f55505050565b906040916001600160401b03811690815f526001602052835f20610f406103e0565b9054906001600160401b038216908181526001600160801b0383881c169283602083015260c01c968791015215610fc957610f7b9094611428565b5080926001600160401b035f541610610fc05750610f988161144f565b15610fb65790610fa7916114f2565b15610fb0579190565b91505f90565b5050909150905f90565b93505f92915050565b50505090505f905f90565b9291925f5f915f54956001600160401b038716806001600160401b0384161180156111e7575b80156111d6575b6111c857949660401c6001600160401b031660011893925b6001868116036110b2579461105a8661104b61103961105498998c61075e565b611043888761075e565b9085886120ca565b989190926104c3565b956104c3565b94156110a857611072866001600160401b03926113c7565b911695861561109d5718945f5260026020526001600160401b0360405f205416965b96949392611019565b505050509350919050565b5050509350919050565b92936001600160401b03861695865f5260026020526110e06001600160401b0360405f205460801c16611428565b90885f5260026020526001600160401b036111118160405f2054166001600160401b0381815f198201161916161890565b166001600160401b0360018818161180156111aa575b801561118c575b156111675750506001600160401b0390815f1982011619161618945f5260026020526001600160401b0360405f205460401c1696611094565b8398506001600160401b039391610af961118692611072959a996104c3565b966113c7565b50611197888661075e565b6001600160801b0380841691161061112e565b506111b5878c61075e565b6001600160801b03808316911610611127565b50505050505090505f905f90565b506001600160801b03821615611001565b506001600160801b03861615610ffa565b9190916001600160401b03811692835f52600160205260405f209161121b6103e0565b9254916001600160401b0383169384815260208101946001600160801b038560401c168652604082019460c01c855215611314576001600160401b0380915116911603610916576112756001600160401b03835116611428565b956112bd6001600160401b036001600160801b036112a661129d8280889b51169c168c61077e565b82871690610791565b1695835f5260016020525f6040812055511661162b565b6001600160401b035f5416918282116113085750146112fe576112df8161144f565b919091156112f357610fa7929186916123a7565b505050909150905f90565b5050610cfb6121fc565b96505f95945050505050565b63f37b890d60e01b5f5260045ffd5b60018082161461135a576001600160401b03165f5260026020526113566001600160401b0360405f205460801c16611428565b9091565b906001600160401b036001600160801b0392165f526001602052816113c360405f20826108c5816113b6604061138e6103e0565b9554956001600160401b038716815260208101968481841c16885260c01c9182910152611428565b989094511697168761077e565b1690565b91906001600160401b0390815f1985011684181916168015611420576001600160401b035f198201161819916001600160401b0380808516196001603f1b677fffffffffffffff8760011c161716169384921616189190565b505f91508190565b6001600160401b03165f52600360205260405f2054906001600160801b0382169160801c90565b905f546001600160401b038160401c166001600160401b038216600119915b6001600160401b03838784181616156114b957821691821561149857505f1982018218199161146e565b6001600160401b0394955084925080915060011c8119169216161816905f90565b50509081166001600160401b039081168219600193841c161816925090565b6114e06103e0565b905f82525f60208301525f6040830152565b90916001600160401b03831691826001600160401b038216146115f5576001600160401b03906115206114d8565b505b165f52600260205260405f206115366103e0565b9054906001600160401b038216908181526001600160401b03808460401c169384602084015260801c1660408201525083811480156115ec575b6115e25761159381866001600160401b039180835f198201161819911816161590565b156115a7576001600160401b039150611522565b506115c781856001600160401b039180835f198201161819911816161590565b156115da576001600160401b0390611522565b509150505f90565b5050915050600190565b50838214611570565b50915050600190565b91906001600160801b036001600160401b039281199060801b1691161891165f52600360205260405f2055565b5f5460c01c6001600160401b0382169081811461167657600160801b18905f52600360205260405f20555f54906001600160401b0360c01b9060c01b169060018060c01b0316175f55565b637fa3fb5160e01b5f5260045ffd5b61168d610413565b905f82525f60208301525f60408301525f60608301525f60808301525f60a0830152565b805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b6001600160401b03604061089c938280825116168319855416178455610eba836020830151168561095f565b90929192611714611685565b50600180821614611ae15761174261173d826001600160401b03165f52600260205260405f2090565b610931565b9061175760408301516001600160401b031690565b61176081611428565b9490936001600160401b0361179561177f83516001600160401b031690565b6001600160401b0381815f198201161916161890565b166001600160401b036001841816118015611ac6575b15611a7257602081016117cf896117c983516001600160401b031690565b85611708565b6117eb90996117e58b516001600160801b031690565b9061075e565b60808a01936001600160401b0361180986516001600160401b031690565b16156119d75750506119869493611976938a936119669361188661185161183f6119969d9e9f604001516001600160801b031690565b88516001600160801b03165b906104c3565b9461186660608901516001600160801b031690565b9561188060208a019761184b89516001600160801b031690565b9161278c565b6118a861189a82516001600160401b031690565b93516001600160401b031690565b926001600160401b03808516911603611999575b5050506119566119036118d685516001600160801b031690565b9a6117e56118f58d6118ef87516001600160801b031690565b9c61075e565b94516001600160801b031690565b9361192a60a06001600160401b0389815f198201161916169201516001600160401b031690565b1897611946611937610413565b6001600160801b03909c168c52565b6001600160801b031660208b0152565b6001600160801b03166040890152565b6001600160801b03166060870152565b6001600160401b03166080850152565b6001600160401b031660a0830152565b90565b6119cf926119af91906001600160401b03169052565b6119ca876001600160401b03165f52600260205260405f2090565b6116dc565b5f80806118bc565b955095505090506119fb94506119f59150516001600160401b031690565b90611708565b611a4c602061089c9294611a3e611a31611a1c83516001600160801b031690565b88516001600160801b03166104c3565b6104c3565b6001600160801b03168752565b01516001600160801b031690565b611a656020850191611a2c83516001600160801b031690565b6001600160801b03169052565b5050945050611aa861089c92611a98611a89610413565b6001600160801b039094168452565b6001600160801b03166020830152565b5f60408201525f60608201525f60808201525f60a08201529261162b565b506001600160801b0385166001600160801b038916106117ab565b61199692939161258b565b5f548060c01c15611b2a57505f54908160c01c91825f5260036020526001600160401b0360c01b60405f205460c01b169060018060c01b0316175f55565b6001600160401b038160801c166001600160401b0381146104e357600101906001600160401b0360801b8260801b16906001600160401b0360801b1916175f5590565b906001600160401b031690815f52600260205260405f2092611b8d6103e0565b9354946001600160401b0386168086526001600160401b036020870197818160401c16895260801c16611bdc6040880192828452866001600160401b039180835f198201161819911816161590565b611e7e5750611be96114d8565b50611bf2611aec565b926001600160401b03851686811015611d5257908291611c1f85836001600160401b038c98975116612a04565b611c346001600160401b0386511680986127df565b9681811115611d06575084516001600160401b0316611c516103e0565b91825260208201526001600160401b03861660408201529761089c996001600160401b0398611ca3611cd2988b97611c9d611cca97611c97611c978c809a5b5116611323565b926104c3565b916115fe565b82891687525b5f526002602052818060405f2097511616821987541617865551168461095f565b5116906116b1565b165f5260026020526001600160401b036040805f20928280825116168319855416178455610eba836020830151168561095f565b90611d0f6103e0565b91825260208201526001600160401b03861660408201529761089c996001600160401b0398611ca3611cd2988b97611c9d611cca97611c97611c978c809a611c90565b9094959693889293611d726001600160401b0361089c9b511680996127df565b966001600160401b0388815f19820116191616988481115f14611e045750936001600160401b039899611cd29796948a85611db48299968397611cca996115fe565b81855116611dc06103e0565b93845260208401521660408201529a600160401b600160801b035f5491858360401c161860401b1690600160401b600160801b031916175f555b8289168252611ca9565b6001600160401b03809a8197935081945094611e5d611cca96600189600160401b600160801b03611e3a611cd29f9e9c986128b1565b92919490955f5493181860401b16906001600160801b03191617175f55836115fe565b8184511692611e6a6103e0565b938452602084015216604082015299611dfa565b8397506001600160401b039495508298969390611e9c939250612a04565b5116611ea66114d8565b505b6001600160401b0381165f52600260205260405f2090611ec66103e0565b9154916001600160401b03831681526001600160401b03806020830194818160401c16865260801c1691826040820152611f0289898395612a04565b511692611f2484866001600160401b039180835f198201161819911816161590565b15611f3157505050611ea8565b516001600160401b0390811693509091908484185f19850182168518191616611f5b575050611ea8565b61089c9593925095909395611f6e6114d8565b506001600160401b03611f7f611aec565b9116916001600160401b03841683811015612040578692611cd29492611c9d611ff593611fb96001600160401b03809b9c5116809a6127df565b9881811115612021575089875116611fcf6103e0565b91825260208201528984166040820152995b611c97611c978b8951168c8c168a52611323565b5f526002602052836040805f20928280825116168319855416178455610eba836020830151168561095f565b9061202a6103e0565b9182526020820152898416604082015299611fe1565b8692611cd29492611c9d6001600160401b0398611c97611c978b9a611ff59760206120739f019e8f9d8e511680936127df565b9c818311156120ab578e919250511661208a6103e0565b91825260208201528c871660408201529c5b8c815116908d8d169052611323565b506120b46103e0565b91825260208201528c871660408201529c61209c565b906001600160401b036001600160801b039195949516805f5260016020526001600160401b038261213860405f20826108c58161212b604061210a6103e0565b955495898716815260208101968481841c16885260c01c9182910152611428565b999094511698168861077e565b169316116121ef57806001600160801b0386168381106121b6575b6001600160801b038516848382109384612183575b505050505f1461217a57505091905f90565b93509160019150565b61219861219d926001600160801b039461077e565b610791565b169081106121ae575b808484612168565b95505f6121a6565b906121cd846121986001600160801b03938561077e565b166001600160801b03851681106121e7575b508190612153565b9350816121df565b50505090505f905f905f90565b5f546001600160401b038160401c1660018114612398576001600160401b036001815f19828518011683181819918180808516196001603f1b677fffffffffffffff8760011c161716168092189385161618165f5260026020526001600160401b0360405f2061228f8261226e6103e0565b92548181168452818160401c16602085015260801c1680604084015261162b565b51169081600161229d6114d8565b505b600180831603612335576001600160401b0390600192835f54928618189183600160401b600160801b038460401b169216906001600160801b03191617175f5516146123305761089c926001600160401b0360018193825f19838318011618181981808216196001603f1b677fffffffffffffff8460011c1617161692161618165f52600260205260405f2061095f565b505050565b6001600160401b0382165f5260026020526001600160401b0360405f209261238961235e6103e0565b945494838616815283808760401c169687602084015260801c16908160408201525061188086611323565b5f19810182161916161861229f565b506001600160801b0319165f55565b9392936001600160401b03821691825f52600260205260405f20926123ca6103e0565b9354926001600160401b038416928386526001600160401b036020870195818160401c16875260801c1660408701948186526001600160401b038416146124c757505084516001600160401b03908116908282185f198301821683181916166124bb5786612439928a92612a3e565b9590978861244b575b50505050505050565b61245f916001600160401b0385511661278c565b6001600160401b0380855116951680950361247c575b8080612442565b6001600160401b038093611cca926124b19787525f526002602052818060405f2097511616821987541617865551168461095f565b5f80808080612475565b505f9750505050505050565b9497985095505050506124da915061162b565b6001600160401b0381815f198201161916165f54908160401c91600160401b600160801b03826001600160401b0385161860401b1690600160401b600160801b031916175f556001600160401b035f19820116181916916001600160401b038316908115612582576001600160401b0380808061257d978180975f1901161916161692511693815f19840116831819161618165f52600260205260405f2061095f565b600190565b50505050600190565b90916001600160401b03612613936125a1611685565b501690815f52600160205260405f20906125b96103e0565b9154906001600160401b038216835260208301916001600160801b038160401c16835260c01c926001600160401b036001600160801b036126006040840196808852611428565b9990826108c581808a51169d168d61077e565b169616851061274a576001600160801b0382169384881161265f5750505050505061263c610413565b91825260208201525f60408201525f60608201525f60808201525f60a082015290565b9461270887938961270361270e956001600160401b036001600160801b039b879f9e6126958d9f918f9d9e8e936121989161077e565b169b8c988c8881845116031682525f526001602052828060405f2095511616831985541617845551600160401b600160c01b0384549160401b1690600160401b600160c01b03191617835551168154906001600160401b0360c01b9060c01b169060018060c01b0316179055565b61075e565b9261075e565b92612717610413565b9586526020860152166040840152166060820152826080820152600160a0820152916001600160401b03195f5416175f55565b50505050929190612759610413565b915f83525f602084015260408301526060820152826080820152600160a0820152916001600160401b03195f5416175f55565b6127c66001600160401b036001600160801b03921693845f5260036020526127c060405f2054948486169560801c9561075e565b9361075e565b81199060801b16911618905f52600360205260405f2055565b6001600160401b0391829067ffffffffffffffff19905f1981018316198116831618831860011867ffffffff0000000081161561289e575b8160101c838282161615612896575b508160081c83828216161561288e575b508160041c838282161615612886575b508160021c83828216161561287e575b50828260011c9182161615612876575b5080198160011c16921616181690565b90505f612866565b91505f612856565b91505f612846565b91505f612836565b91505f612826565b640100000000600160e01b039150612817565b6001600160801b035f54926001600160401b038460401c169283906001600160401b03861691825f5260016020526001600160401b0360018661293160405f20826108c58161292460406129036103e0565b9554958a8716815260208101968481841c16885260c01c9182910152611428565b9d909451169c168c61077e565b16971892169283146129f1576129b2611a2c6129ac6001600160401b03600187955f9b9a9b505f198801181819955b818760011c881916809218978d1616181698895f5260026020526001600160401b0360405f205460801c169061299582611428565b9490926129a283856104c3565b611c9d8d886104c3565b966104c3565b95146129df579293925f1981018118199082906129b290611a2c906129ac906001600160401b0390612960565b90506001600160401b03919294501690565b50929450506001600160401b0390911690565b6127c66001600160401b036001600160801b03921693845f526003602052612a3860405f2054948486169560801c956104c3565b936104c3565b9190612a5e61173d846001600160401b03165f52600260205260405f2090565b936001600160401b03612a7886516001600160401b031690565b83821691168103612abd575050505050602081612aaa612aa56040612ab89501516001600160401b031690565b61162b565b01516001600160401b031690565b600191565b612ae4612ad86020889697999801516001600160401b031690565b6001600160401b031690565b14612c715783612b19612afe85516001600160401b031690565b846001600160401b039180835f198201161819911816161590565b15612bc15790612b3b918193612b3686516001600160401b031690565b612a3e565b939015612bb55790612b6091612b5b60408501516001600160401b031690565b61278c565b80516001600160401b03838116911603612b7d575b505060019190565b612b93612bae9282906001600160401b03169052565b6119ca846001600160401b03165f52600260205260405f2090565b5f80612b75565b5050505090505f905f90565b506020830191612bd883516001600160401b031690565b612bf781836001600160401b039180835f198201161819911816161590565b156111c85785612c08928492612a3e565b949015612c645790612c2891612b5b60408601516001600160401b031690565b81516001600160401b03848116911603612c46575b50505060019190565b612c5c92612b9391906001600160401b03169052565b5f8080612c3d565b505050505090505f905f90565b50509050612ab8919250612c92612aa560408301516001600160401b031690565b516001600160401b03169056fea26469706673582212208cfcacc5e1a529ebf0fcdf9254e84504f7511e5db7c567bdad1b03249b26671764736f6c634300081c0033a2646970667358221220d6de167b9393a116407f94a7de5fd4b2dfbc1c6eeb2d7df3f323e0e632566f5b64736f6c634300081c0033

Deployed Bytecode Sourcemap

308:327:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;308:327:4;;;;;;-1:-1:-1;;;;;308:327:4;;;;;;;;583:13;;;;;;;;;;;;;308:327;583:13;;;;;;308:327;;583:13;;;308:327;583:13;;;;;308:327;;-1:-1:-1;;;;;308:327:4;;;;;;;;583:13;308:327;;;;;;;;;583:13;308:327;;;;;;;;;;;;;;

Swarm Source

ipfs://d6de167b9393a116407f94a7de5fd4b2dfbc1c6eeb2d7df3f323e0e632566f5b

Block Transaction 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
[ 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.