Contract 0xec9769362dcb3d6c5515cef199f117fcf6cb1354

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xef8695cb9329648a4eb423356dc881403fa0631f820b3bbaf726c23ab16efe6b0x610a5061658300872023-03-01 19:28:3490 days 2 hrs ago0xf93daf052aa145bdec8c29483e52030c668514cc IN  Create: MinLinkedListLib0 ETH0.00084590.1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x2526fe3a37942df76cf2fd9006b7cd5ede6f51eea4c4e1260180c2ed9d300764720866622023-03-21 10:18:4670 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xf031f757c0f04d9d4161612bfa1be5179cf82ee55eb2ae1163f2ddf2b1a6e742720866512023-03-21 10:18:4470 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xd326b24130f2b394e00d8ff841cbedfd6e729971049da82a3d949589b9c62307720866272023-03-21 10:18:3870 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x4c8b824bd8bb1042b9d069adc1e6278b5a912bc4a27ace2790d93e0af91abe7b720866242023-03-21 10:18:3770 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x4c8b824bd8bb1042b9d069adc1e6278b5a912bc4a27ace2790d93e0af91abe7b720866242023-03-21 10:18:3770 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x4c8b824bd8bb1042b9d069adc1e6278b5a912bc4a27ace2790d93e0af91abe7b720866242023-03-21 10:18:3770 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x4c8b824bd8bb1042b9d069adc1e6278b5a912bc4a27ace2790d93e0af91abe7b720866242023-03-21 10:18:3770 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x4c8b824bd8bb1042b9d069adc1e6278b5a912bc4a27ace2790d93e0af91abe7b720866242023-03-21 10:18:3770 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xf9ca1a7fd591567ccfbba58084d20b3d8cbe12fcdb4fe1c8fc598c13d127d182720866222023-03-21 10:18:3670 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x8f19b038efc64b00b9268617aa09c95eb3a0ea3e995c4c0151d0640deaf912de720866182023-03-21 10:18:3570 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x8f19b038efc64b00b9268617aa09c95eb3a0ea3e995c4c0151d0640deaf912de720866182023-03-21 10:18:3570 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x8f19b038efc64b00b9268617aa09c95eb3a0ea3e995c4c0151d0640deaf912de720866182023-03-21 10:18:3570 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x8f19b038efc64b00b9268617aa09c95eb3a0ea3e995c4c0151d0640deaf912de720866182023-03-21 10:18:3570 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x8f19b038efc64b00b9268617aa09c95eb3a0ea3e995c4c0151d0640deaf912de720866182023-03-21 10:18:3570 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x9c994739b99da8f95d3060eb81a1755fc0e974ece2855915e5fbc920f3aa31fe720865902023-03-21 10:18:2870 days 11 hrs ago 0x7c30dadc489cc7c54254cb6453ee9a9886cc95c5 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x9d516d19622762f7716825ace25f1d61d180648cdd885cd4371701c9c2040c9e720865892023-03-21 10:18:2870 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x9d8a2d8506414dcb8b44714155bd6617b6519569286604680957880e3ece87e4720865862023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x9d8a2d8506414dcb8b44714155bd6617b6519569286604680957880e3ece87e4720865862023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x9d8a2d8506414dcb8b44714155bd6617b6519569286604680957880e3ece87e4720865862023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0x9d8a2d8506414dcb8b44714155bd6617b6519569286604680957880e3ece87e4720865862023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xaae3d0cd68ef95ebc4a3be5357e3e1d8e9e0d27bcb62e0856562863d895b3915720865832023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xaae3d0cd68ef95ebc4a3be5357e3e1d8e9e0d27bcb62e0856562863d895b3915720865832023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xaae3d0cd68ef95ebc4a3be5357e3e1d8e9e0d27bcb62e0856562863d895b3915720865832023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xaae3d0cd68ef95ebc4a3be5357e3e1d8e9e0d27bcb62e0856562863d895b3915720865832023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
0xaae3d0cd68ef95ebc4a3be5357e3e1d8e9e0d27bcb62e0856562863d895b3915720865832023-03-21 10:18:2770 days 11 hrs ago 0xb8df652ccb5cb39ac1cd98a899639f8463b103a8 0xec9769362dcb3d6c5515cef199f117fcf6cb13540 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MinLinkedListLib

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 3 : LinkedList.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./FullMath.sol";

/// @notice Struct containing limit order data
struct LimitOrder {
    uint32 id;
    address owner;
    uint256 amount0;
    uint256 amount1;
}

/// @notice Struct for linked list node
/// @dev Each order id is mapped to a Node in the linked list
struct Node {
    uint32 prev;
    uint32 next;
    bool active;
}

/// @notice Struct for linked list sorted by price in non-decreasing order.
/// Used to store ask limit orders in the order book.
/// @dev Each order id is mapped to a Node and a LimitOrder
struct MinLinkedList {
    mapping(uint32 => Node) list;
    mapping(uint32 => LimitOrder) idToLimitOrder;
}

/// @notice Struct for linked list sorted in non-increasing order
/// Used to store bid limit orders in the order book.
/// @dev Each order id is mapped to a Node and a Limit Order
struct MaxLinkedList {
    mapping(uint32 => Node) list;
    mapping(uint32 => LimitOrder) idToLimitOrder;
}

/// @title MinLinkedListLib
/// @notice Library for linked list sorted in non-decreasing order
/// @dev Order ids 0 and 1 are special values. The first node of the
/// linked list has order id 0 and the last node has order id 1.
/// Order 0 should be initalized (in OrderBook.sol) with the lowest
/// possible price, and order 1 should be initialized with the highest
library MinLinkedListLib {
    /// @notice Comparison function for linked list. Returns true
    /// if the price of order id0 is strictly less than the price of order id1
    function compare(
        MinLinkedList storage listData,
        uint32 id0,
        uint32 id1
    ) internal view returns (bool) {
        return
            FullMath.mulCompare(
                listData.idToLimitOrder[id0].amount1,
                listData.idToLimitOrder[id1].amount0,
                listData.idToLimitOrder[id1].amount1,
                listData.idToLimitOrder[id0].amount0
            );
    }

    /// @notice Find the order id to the left of where the new order
    /// should be inserted
    /// @param orderId The order id to insert
    /// @param hintId The order id to start searching from
    function findIndexToInsert(
        MinLinkedList storage listData,
        uint32 orderId,
        uint32 hintId
    ) internal view returns (uint32) {
        // No element in the linked list can have next = 0, it means hintId is not in the linked list
        require(listData.list[hintId].next != 0, "Invalid hint id");

        while (!listData.list[hintId].active) {
            hintId = listData.list[hintId].next;
        }

        // After the two while loops, hintId will be the order id to the
        // left of where the new order should be inserted.
        while (hintId != 1) {
            uint32 nextId = listData.list[hintId].next;
            if (compare(listData, orderId, nextId)) break;
            hintId = nextId;
        }

        while (hintId != 0) {
            uint32 prevId = listData.list[hintId].prev;
            if (!compare(listData, orderId, hintId)) break;
            hintId = prevId;
        }

        return hintId;
    }

    /// @notice Inserts an order id into the linked list in sorted order
    /// @param orderId The order id to insert
    /// @param hintId The order id to begin searching for the position to
    /// insert the new order. Can be 0, 1, or the id of an actual order
    function insert(
        MinLinkedList storage listData,
        uint32 orderId,
        uint32 hintId
    ) public {
        uint32 indexToInsert = findIndexToInsert(listData, orderId, hintId);

        uint32 next = listData.list[indexToInsert].next;
        listData.list[orderId] = Node({
            prev: indexToInsert,
            next: next,
            active: true
        });
        listData.list[indexToInsert].next = orderId;
        listData.list[next].prev = orderId;
    }

    /// @notice Remove an order id from the linked list
    /// @dev Updates the linked list but does not delete the order id from
    /// the idToLimitOrder mapping
    /// @param orderId The order id to remove
    function erase(MinLinkedList storage listData, uint32 orderId) public {
        require(orderId > 1, "Cannot erase dummy orders");
        require(
            listData.list[orderId].active,
            "Cannot cancel an already inactive order"
        );

        uint32 prev = listData.list[orderId].prev;
        uint32 next = listData.list[orderId].next;

        listData.list[prev].next = next;
        listData.list[next].prev = prev;
        listData.list[orderId].active = false;
    }

    /// @notice Get the first order id in the linked list. Since the linked
    /// list is sorted, this gets the order id with the lowest price, if all
    /// the orders are dummy orders, returns 1
    /// @dev Order id 0 is a dummy value and should not be returned
    function getFirstNode(MinLinkedList storage listData)
        internal
        view
        returns (uint32)
    {
        return listData.list[0].next;
    }

    /// @notice Get the LimitOrder data struct for the first order
    function getTopLimitOrder(MinLinkedList storage listData)
        public
        view
        returns (LimitOrder storage)
    {
        require(!isEmpty(listData), "Book side is empty");
        return listData.idToLimitOrder[getFirstNode(listData)];
    }

    /// @notice Returns true if the linked list has no orders
    /// @dev Order id 0 and 1 are dummy values, so the linked list
    /// is empty if those are the only two orders
    function isEmpty(MinLinkedList storage listData)
        public
        view
        returns (bool)
    {
        return getFirstNode(listData) == 1;
    }

    /// @notice Returns the number of orders in the linked list
    /// @dev Order id 0 and 1 are dummy values, so the number of
    /// orders does not include them
    function size(MinLinkedList storage listData) public view returns (uint32) {
        uint32 listSize = 0;
        for (
            uint32 pointer = getFirstNode(listData);
            pointer != 1;
            pointer = listData.list[pointer].next
        ) ++listSize;
        return listSize;
    }

    /// @notice Returns a list of LimitOrder data structs for each
    /// order in the linked list
    /// @dev Order id 0 and 1 are dummy values, so the returned list
    /// does not include them
    function getOrders(MinLinkedList storage listData)
        public
        view
        returns (LimitOrder[] memory orders)
    {
        orders = new LimitOrder[](size(listData));
        uint32 i = 0;
        for (
            uint32 pointer = getFirstNode(listData);
            pointer != 1;
            pointer = listData.list[pointer].next
        ) {
            orders[i] = listData.idToLimitOrder[pointer];
            ++i;
        }
    }

    /// @notice Comparison function for linked list. Returns true if the
    /// price of amount0 to amount1 is less than the price of order id1
    function mockCompare(
        MinLinkedList storage listData,
        uint256 amount0,
        uint256 amount1,
        uint32 id1
    ) internal view returns (bool) {
        return
            FullMath.mulCompare(
                amount1,
                listData.idToLimitOrder[id1].amount0,
                listData.idToLimitOrder[id1].amount1,
                amount0
            );
    }

    /// @notice Find the order id to the left of where the new order
    /// should be inserted. Meant to be used off-chain to find the
    /// hintId for the insert function
    /// @param amount0 The amount of token0 in the new order
    /// @param amount1 The amount of token1 in the new order
    function getMockIndexToInsert(
        MinLinkedList storage listData,
        uint256 amount0,
        uint256 amount1
    ) public view returns (uint32) {
        uint32 hintId = 0;

        // After the two while loops, hintId will be the order id to the
        // left of where the new order should be inserted.
        while (hintId != 1) {
            uint32 nextId = listData.list[hintId].next;
            if (mockCompare(listData, amount0, amount1, nextId)) break;
            hintId = nextId;
        }

        while (hintId != 0) {
            uint32 prevId = listData.list[hintId].prev;
            if (!mockCompare(listData, amount0, amount1, hintId)) break;
            hintId = prevId;
        }

        return hintId;
    }
}

/// @title MaxLinkedListLib
/// @notice Library for linked list sorted in non-increasing order
/// @dev Order ids 0 and 1 are special values. The first node of the
/// linked list has order id 0 and the last node has order id 1.
/// Order 0 should be initalized (in OrderBook.sol) with the highest
/// possible price, and order 1 should be initialized with the lowest
library MaxLinkedListLib {
    /// @notice Comparison function for linked list. Returns true
    /// if the price of order id0 is strictly greater than the price of order id1
    function compare(
        MaxLinkedList storage listData,
        uint32 id0,
        uint32 id1
    ) internal view returns (bool) {
        return
            FullMath.mulCompare(
                listData.idToLimitOrder[id1].amount1,
                listData.idToLimitOrder[id0].amount0,
                listData.idToLimitOrder[id1].amount0,
                listData.idToLimitOrder[id0].amount1
            );
    }

    /// @notice Find the order id to the left of where the new order
    /// should be inserted
    /// @param orderId The order id to insert
    /// @param hintId The order id to start searching from
    function findIndexToInsert(
        MaxLinkedList storage listData,
        uint32 orderId,
        uint32 hintId
    ) internal view returns (uint32) {
        // No element in the linked list can have next = 0, it means hintId is not in the linked list
        require(listData.list[hintId].next != 0, "Invalid hint id");

        while (!listData.list[hintId].active) {
            hintId = listData.list[hintId].next;
        }

        // After the two while loops, hintId will be the order id to the
        // left of where the new order should be inserted.
        while (hintId != 1) {
            uint32 nextId = listData.list[hintId].next;
            if (compare(listData, orderId, nextId)) break;
            hintId = nextId;
        }

        while (hintId != 0) {
            uint32 prevId = listData.list[hintId].prev;
            if (!compare(listData, orderId, hintId)) break;
            hintId = prevId;
        }

        return hintId;
    }

    /// @notice Inserts an order id into the linked list in sorted order
    /// @param orderId The order id to insert
    /// @param hintId The order id to begin searching for the position to
    /// insert the new order. Can be 0, 1, or the id of an actual order
    function insert(
        MaxLinkedList storage listData,
        uint32 orderId,
        uint32 hintId
    ) public {
        uint32 indexToInsert = findIndexToInsert(listData, orderId, hintId);

        uint32 next = listData.list[indexToInsert].next;
        listData.list[orderId] = Node({
            prev: indexToInsert,
            next: next,
            active: true
        });
        listData.list[indexToInsert].next = orderId;
        listData.list[next].prev = orderId;
    }

    /// @notice Remove an order id from the linked list
    /// @dev Updates the linked list but does not delete the order id from
    /// the idToLimitOrder mapping
    /// @param orderId The order id to remove
    function erase(MaxLinkedList storage listData, uint32 orderId) public {
        require(orderId > 1, "Cannot erase dummy orders");
        require(
            listData.list[orderId].active,
            "Cannot cancel an already inactive order"
        );

        uint32 prev = listData.list[orderId].prev;
        uint32 next = listData.list[orderId].next;

        listData.list[prev].next = next;
        listData.list[next].prev = prev;
        listData.list[orderId].active = false;
    }

    /// @notice Get the first order id in the linked list. Since the linked
    /// list is sorted, this gets the order id with the highest price, if all
    /// the orders are dummy orders, returns 1
    /// @dev Order id 0 is a dummy value and should not be returned
    function getFirstNode(MaxLinkedList storage listData)
        internal
        view
        returns (uint32)
    {
        return listData.list[0].next;
    }

    /// @notice Get the LimitOrder data struct for the first order
    function getTopLimitOrder(MaxLinkedList storage listData)
        public
        view
        returns (LimitOrder storage)
    {
        require(!isEmpty(listData), "Book side is empty");
        return listData.idToLimitOrder[getFirstNode(listData)];
    }

    /// @notice Returns true if the linked list has no orders
    /// @dev Order id 0 and 1 are dummy values, so the linked list
    /// is empty if those are the only two orders
    function isEmpty(MaxLinkedList storage listData)
        public
        view
        returns (bool)
    {
        return getFirstNode(listData) == 1;
    }

    /// @notice Returns the number of orders in the linked list
    /// @dev Order id 0 and 1 are dummy values, so the number of
    /// orders does not include them
    function size(MaxLinkedList storage listData) public view returns (uint32) {
        uint32 listSize = 0;
        for (
            uint32 pointer = getFirstNode(listData);
            pointer != 1;
            pointer = listData.list[pointer].next
        ) ++listSize;
        return listSize;
    }

    /// @notice Returns a list of LimitOrder data structs for each
    /// order in the linked list
    /// @dev Order id 0 and 1 are dummy values, so the returned list
    /// does not include them
    function getOrders(MaxLinkedList storage listData)
        public
        view
        returns (LimitOrder[] memory orders)
    {
        orders = new LimitOrder[](size(listData));
        uint32 i = 0;
        for (
            uint32 pointer = getFirstNode(listData);
            pointer != 1;
            pointer = listData.list[pointer].next
        ) {
            orders[i] = listData.idToLimitOrder[pointer];
            ++i;
        }
    }

    /// @notice Comparison function for linked list. Returns true if the
    /// price of amount0 to amount1 is greater than the price of order id1
    function mockCompare(
        MaxLinkedList storage listData,
        uint256 amount0,
        uint256 amount1,
        uint32 id1
    ) internal view returns (bool) {
        return
            FullMath.mulCompare(
                listData.idToLimitOrder[id1].amount1,
                amount0,
                listData.idToLimitOrder[id1].amount0,
                amount1
            );
    }

    /// @notice Find the order id to the left of where the new order
    /// should be inserted. Meant to be used off-chain to find the
    /// hintId for the insert function
    /// @param amount0 The amount of token0 in the new order
    /// @param amount1 The amount of token1 in the new order
    function getMockIndexToInsert(
        MaxLinkedList storage listData,
        uint256 amount0,
        uint256 amount1
    ) public view returns (uint32) {
        uint32 hintId = 0;

        // After the two while loops, hintId will be the order id to the
        // left of where the new order should be inserted.

        while (hintId != 1) {
            uint32 nextId = listData.list[hintId].next;
            if (mockCompare(listData, amount0, amount1, nextId)) break;
            hintId = nextId;
        }

        while (hintId != 0) {
            uint32 prevId = listData.list[hintId].prev;
            if (!mockCompare(listData, amount0, amount1, hintId)) break;
            hintId = prevId;
        }

        return hintId;
    }
}

File 2 of 3 : FullMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "@openzeppelin/contracts/utils/math/Math.sol";

library FullMath {
    /// @notice Returns a*b/denominator, throws if remainder is not 0
    function mulDiv(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        require(denominator != 0, "Can not divide with 0");
        uint256 remainder = 0;
        assembly {
            remainder := mulmod(a, b, denominator)
        }
        require(remainder == 0, "Divison has a positive remainder");
        return Math.mulDiv(a, b, denominator);
    }

    /// @notice Returns true if a*b < c*d
    function mulCompare(
        uint256 a,
        uint256 b,
        uint256 c,
        uint256 d
    ) internal pure returns (bool result) {
        uint256 prod0; // Least significant 256 bits of the product a*b
        uint256 prod1; // Most significant 256 bits of the product a*b
        assembly {
            let mm := mulmod(a, b, not(0))
            prod0 := mul(a, b)
            prod1 := sub(sub(mm, prod0), lt(mm, prod0))
        }

        uint256 prod2; // Least significant 256 bits of the product c*d
        uint256 prod3; // Most significant 256 bits of the product c*d
        assembly {
            let mm := mulmod(c, d, not(0))
            prod2 := mul(c, d)
            prod3 := sub(sub(mm, prod2), lt(mm, prod2))
        }

        if (prod1 < prod3) return true;
        if (prod3 < prod1) return false;
        if (prod0 < prod2) return true;
        return false;
    }
}

File 3 of 3 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`.
        // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.
        // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.
        // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a
        // good first aproximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1;
        uint256 x = a;
        if (x >> 128 > 0) {
            x >>= 128;
            result <<= 64;
        }
        if (x >> 64 > 0) {
            x >>= 64;
            result <<= 32;
        }
        if (x >> 32 > 0) {
            x >>= 32;
            result <<= 16;
        }
        if (x >> 16 > 0) {
            x >>= 16;
            result <<= 8;
        }
        if (x >> 8 > 0) {
            x >>= 8;
            result <<= 4;
        }
        if (x >> 4 > 0) {
            x >>= 4;
            result <<= 2;
        }
        if (x >> 2 > 0) {
            result <<= 1;
        }

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        uint256 result = sqrt(a);
        if (rounding == Rounding.Up && result * result < a) {
            result += 1;
        }
        return result;
    }
}

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

Contract ABI

[]

610a5061003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100775760003560e01c806330d085931461007c5780633bd9f5c3146100a557806376140987146100c75780639bd84f0a146100e7578063a2c385dc1461010f578063a9f4c25f14610132578063c54da68414610145575b600080fd5b61008f61008a366004610884565b610166565b60405161009c919061089d565b60405180910390f35b8180156100b157600080fd5b506100c56100c0366004610929565b6102b3565b005b8180156100d357600080fd5b506100c56100e2366004610955565b6103f0565b6100fa6100f5366004610884565b6104b7565b60405163ffffffff909116815260200161009c565b61012261011d366004610884565b61050c565b604051901515815260200161009c565b6100fa610140366004610991565b610527565b610158610153366004610884565b6105bf565b60405190815260200161009c565b6060610171826104b7565b63ffffffff1667ffffffffffffffff81111561018f5761018f6109bd565b6040519080825280602002602001820160405280156101e157816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816101ad5790505b5090506000806101f084610637565b90505b8063ffffffff166001146102ac5763ffffffff818116600090815260018681016020908152604092839020835160808101855281548087168252600160201b90046001600160a01b0316928101929092529182015492810192909252600201546060820152845190918591908516908110610270576102706109d3565b602002602001018190525081610285906109e9565b63ffffffff918216600090815260208690526040902054909250600160201b9004166101f3565b5050919050565b60018163ffffffff161161030a5760405162461bcd60e51b815260206004820152601960248201527843616e6e6f742065726173652064756d6d79206f726465727360381b60448201526064015b60405180910390fd5b63ffffffff8116600090815260208390526040902054600160401b900460ff166103865760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f742063616e63656c20616e20616c726561647920696e6163746976604482015266329037b93232b960c91b6064820152608401610301565b63ffffffff908116600081815260209390935260408084208054808516808752838720805467ffffffff000000001916600160201b93849004909716928302969096179095558552908420805463ffffffff1916909317909255909152805460ff60401b19169055565b60006103fd848484610657565b63ffffffff90811660008181526020878152604080832080548251606081018452958652600160201b90819004871686850181815260018886019081529b89168088529c9095528386209651875495519b511515600160401b0260ff60401b199c8a16840267ffffffffffffffff199097169190991617949094179990991695909517909355835496880267ffffffff0000000019979097169690961790925593815292909220805463ffffffff19169093179092555050565b600080806104c484610637565b90505b8063ffffffff16600114610505576104de826109e9565b63ffffffff918216600090815260208690526040902054909250600160201b9004166104c7565b5092915050565b600061051782610637565b63ffffffff166001149050919050565b6000805b8063ffffffff166001146105765763ffffffff808216600090815260208790526040902054600160201b9004166105648686868461078f565b1561056f5750610576565b905061052b565b63ffffffff8116156105b75763ffffffff808216600090815260208790526040902054166105a68686868561078f565b6105b057506105b7565b9050610576565b949350505050565b60006105ca8261050c565b1561060c5760405162461bcd60e51b8152602060048201526012602482015271426f6f6b207369646520697320656d70747960701b6044820152606401610301565b81600101600061061b84610637565b63ffffffff168152602081019190915260400160002092915050565b60008080526020919091526040902054600160201b900463ffffffff1690565b63ffffffff8082166000908152602085905260408120549091600160201b9091041681036106b95760405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081a1a5b9d081a59608a1b6044820152606401610301565b5b63ffffffff8216600090815260208590526040902054600160401b900460ff166107055763ffffffff918216600090815260208590526040902054600160201b9004909116906106ba565b8163ffffffff1660011461074f5763ffffffff808316600090815260208690526040902054600160201b90041661073d8585836107c6565b15610748575061074f565b9150610705565b63ffffffff8216156105055763ffffffff8083166000908152602086905260409020541661077e8585856107c6565b6107885750610505565b915061074f565b63ffffffff81166000908152600180860160205260408220908101546002909101546107bd91859187610805565b95945050505050565b63ffffffff8083166000818152600180870160205260408083206002808201549688168552918420808401549201549484529091015491936105b79390925b600080806000198688098787029250828110908390030390506000806000198688098688029250828110838203039150508083101561084b5760019450505050506105b7565b828110156108605760009450505050506105b7565b818410156108755760019450505050506105b7565b50600098975050505050505050565b60006020828403121561089657600080fd5b5035919050565b602080825282518282018190526000919060409081850190868401855b82811015610903578151805163ffffffff168552868101516001600160a01b031687860152858101518686015260609081015190850152608090930192908501906001016108ba565b5091979650505050505050565b803563ffffffff8116811461092457600080fd5b919050565b6000806040838503121561093c57600080fd5b8235915061094c60208401610910565b90509250929050565b60008060006060848603121561096a57600080fd5b8335925061097a60208501610910565b915061098860408501610910565b90509250925092565b6000806000606084860312156109a657600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600063ffffffff808316818103610a1057634e487b7160e01b600052601160045260246000fd5b600101939250505056fea26469706673582212207cc529588ca1fd497f91ccce880969f34d151f44e6f76927118d150ed67cda0764736f6c63430008100033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.