Contract 0xc45f6918f7bcac7abc8fe05302b3cdf39776cdeb 1

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xcf553904422b044eac4f7af951dd90a6343a5a2b3c988e473bac6595a0629b670x610ed86158563632022-02-11 13:25:10178 days 3 hrs agoLivepeer: Deployer IN  Create: SortedDoublyLL0 ETH0.00998915413 ETH
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xf6e50b490d0e679c21369c6cfe592d29fa2154866cc1315fbe0d38ff451f4cba197293292022-08-08 15:20:181 hr 6 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0xf6e50b490d0e679c21369c6cfe592d29fa2154866cc1315fbe0d38ff451f4cba197293292022-08-08 15:20:181 hr 6 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x46355588749829b557d989d83dc88f6485326ecfa18e429067cff5d6591c2987197284032022-08-08 15:07:001 hr 19 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x46355588749829b557d989d83dc88f6485326ecfa18e429067cff5d6591c2987197284032022-08-08 15:07:001 hr 19 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x46355588749829b557d989d83dc88f6485326ecfa18e429067cff5d6591c2987197284032022-08-08 15:07:001 hr 19 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x46355588749829b557d989d83dc88f6485326ecfa18e429067cff5d6591c2987197284032022-08-08 15:07:001 hr 19 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x615336a4903101081d2ffd545b690fd5a0e81cb139d66e568a122af498db0f28197246452022-08-08 14:22:222 hrs 4 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x615336a4903101081d2ffd545b690fd5a0e81cb139d66e568a122af498db0f28197246452022-08-08 14:22:222 hrs 4 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x83e54fbcde8945ceb25a1ab786d381dcf54c3d4d978edfae81b6b78571f433bc197241522022-08-08 14:16:192 hrs 10 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x83e54fbcde8945ceb25a1ab786d381dcf54c3d4d978edfae81b6b78571f433bc197241522022-08-08 14:16:192 hrs 10 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x91b461101c5f176411c95fa78c7e4252d5a3ce9a2497f0bcaeb7ecf93eea6e35197238572022-08-08 14:12:122 hrs 14 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x91b461101c5f176411c95fa78c7e4252d5a3ce9a2497f0bcaeb7ecf93eea6e35197238572022-08-08 14:12:122 hrs 14 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x91b461101c5f176411c95fa78c7e4252d5a3ce9a2497f0bcaeb7ecf93eea6e35197238572022-08-08 14:12:122 hrs 14 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x91b461101c5f176411c95fa78c7e4252d5a3ce9a2497f0bcaeb7ecf93eea6e35197238572022-08-08 14:12:122 hrs 14 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x371f8e5bdf5e59105a69a9ee30d694d2c0e7e1d6bd8c90f791e537a0d9d9fc6b197230602022-08-08 14:04:142 hrs 22 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x371f8e5bdf5e59105a69a9ee30d694d2c0e7e1d6bd8c90f791e537a0d9d9fc6b197230602022-08-08 14:04:142 hrs 22 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x371f8e5bdf5e59105a69a9ee30d694d2c0e7e1d6bd8c90f791e537a0d9d9fc6b197230602022-08-08 14:04:142 hrs 22 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x371f8e5bdf5e59105a69a9ee30d694d2c0e7e1d6bd8c90f791e537a0d9d9fc6b197230602022-08-08 14:04:142 hrs 22 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x5e03c59a56b3ba8ac4da6ac1aa02f2c24d295556d10b36ebd6faeca42c64bda9197178222022-08-08 13:03:523 hrs 22 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x5e03c59a56b3ba8ac4da6ac1aa02f2c24d295556d10b36ebd6faeca42c64bda9197178222022-08-08 13:03:523 hrs 22 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0xd5b5977dda709a2e4ec2443f44babfce2e63e25e9e4b2f5e9c7a8c3ca2adbf4d197067182022-08-08 10:53:135 hrs 33 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0xd5b5977dda709a2e4ec2443f44babfce2e63e25e9e4b2f5e9c7a8c3ca2adbf4d197067182022-08-08 10:53:135 hrs 33 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0xd5b5977dda709a2e4ec2443f44babfce2e63e25e9e4b2f5e9c7a8c3ca2adbf4d197067182022-08-08 10:53:135 hrs 33 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x81176ad46250e27eea3af11f1f73ae6e16f3cdb8064ab488196775829977a0f0197034582022-08-08 10:10:216 hrs 16 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
0x81176ad46250e27eea3af11f1f73ae6e16f3cdb8064ab488196775829977a0f0197034582022-08-08 10:10:216 hrs 16 mins ago Livepeer: Proxy Bonding Manager Livepeer: Sorted Doubly LL0 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SortedDoublyLL

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 2 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 2 of 2 : SortedDoublyLL.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

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

/**
 * @title A sorted doubly linked list with nodes sorted in descending order. Optionally accepts insert position hints
 *
 * Given a new node with a `key`, a hint is of the form `(prevId, nextId)` s.t. `prevId` and `nextId` are adjacent in the list.
 * `prevId` is a node with a key >= `key` and `nextId` is a node with a key <= `key`. If the sender provides a hint that is a valid insert position
 * the insert operation is a constant time storage write. However, the provided hint in a given transaction might be a valid insert position, but if other transactions are included first, when
 * the given transaction is executed the provided hint may no longer be a valid insert position. For example, one of the nodes referenced might be removed or their keys may
 * be updated such that the the pair of nodes in the hint no longer represent a valid insert position. If one of the nodes in the hint becomes invalid, we still try to use the other
 * valid node as a starting point for finding the appropriate insert position. If both nodes in the hint become invalid, we use the head of the list as a starting point
 * to find the appropriate insert position.
 */
library SortedDoublyLL {
    using SafeMath for uint256;

    // Information for a node in the list
    struct Node {
        uint256 key; // Node's key used for sorting
        address nextId; // Id of next node (smaller key) in the list
        address prevId; // Id of previous node (larger key) in the list
    }

    // Information for the list
    struct Data {
        address head; // Head of the list. Also the node in the list with the largest key
        address tail; // Tail of the list. Also the node in the list with the smallest key
        uint256 maxSize; // Maximum size of the list
        uint256 size; // Current size of the list
        mapping(address => Node) nodes; // Track the corresponding ids for each node in the list
    }

    /**
     * @dev Set the maximum size of the list
     * @param _size Maximum size
     */
    function setMaxSize(Data storage self, uint256 _size) public {
        require(_size > self.maxSize, "new max size must be greater than old max size");

        self.maxSize = _size;
    }

    /**
     * @dev Add a node to the list
     * @param _id Node's id
     * @param _key Node's key
     * @param _prevId Id of previous node for the insert position
     * @param _nextId Id of next node for the insert position
     */
    function insert(
        Data storage self,
        address _id,
        uint256 _key,
        address _prevId,
        address _nextId
    ) public {
        // List must not be full
        require(!isFull(self), "list is full");
        // List must not already contain node
        require(!contains(self, _id), "node already in list");
        // Node id must not be null
        require(_id != address(0), "node id is null");
        // Key must be non-zero
        require(_key > 0, "key is zero");

        address prevId = _prevId;
        address nextId = _nextId;

        if (!validInsertPosition(self, _key, prevId, nextId)) {
            // Sender's hint was not a valid insert position
            // Use sender's hint to find a valid insert position
            (prevId, nextId) = findInsertPosition(self, _key, prevId, nextId);
        }

        self.nodes[_id].key = _key;

        if (prevId == address(0) && nextId == address(0)) {
            // Insert as head and tail
            self.head = _id;
            self.tail = _id;
        } else if (prevId == address(0)) {
            // Insert before `prevId` as the head
            self.nodes[_id].nextId = self.head;
            self.nodes[self.head].prevId = _id;
            self.head = _id;
        } else if (nextId == address(0)) {
            // Insert after `nextId` as the tail
            self.nodes[_id].prevId = self.tail;
            self.nodes[self.tail].nextId = _id;
            self.tail = _id;
        } else {
            // Insert at insert position between `prevId` and `nextId`
            self.nodes[_id].nextId = nextId;
            self.nodes[_id].prevId = prevId;
            self.nodes[prevId].nextId = _id;
            self.nodes[nextId].prevId = _id;
        }

        self.size = self.size.add(1);
    }

    /**
     * @dev Remove a node from the list
     * @param _id Node's id
     */
    function remove(Data storage self, address _id) public {
        // List must contain the node
        require(contains(self, _id), "node not in list");

        if (self.size > 1) {
            // List contains more than a single node
            if (_id == self.head) {
                // The removed node is the head
                // Set head to next node
                self.head = self.nodes[_id].nextId;
                // Set prev pointer of new head to null
                self.nodes[self.head].prevId = address(0);
            } else if (_id == self.tail) {
                // The removed node is the tail
                // Set tail to previous node
                self.tail = self.nodes[_id].prevId;
                // Set next pointer of new tail to null
                self.nodes[self.tail].nextId = address(0);
            } else {
                // The removed node is neither the head nor the tail
                // Set next pointer of previous node to the next node
                self.nodes[self.nodes[_id].prevId].nextId = self.nodes[_id].nextId;
                // Set prev pointer of next node to the previous node
                self.nodes[self.nodes[_id].nextId].prevId = self.nodes[_id].prevId;
            }
        } else {
            // List contains a single node
            // Set the head and tail to null
            self.head = address(0);
            self.tail = address(0);
        }

        delete self.nodes[_id];
        self.size = self.size.sub(1);
    }

    /**
     * @dev Update the key of a node in the list
     * @param _id Node's id
     * @param _newKey Node's new key
     * @param _prevId Id of previous node for the new insert position
     * @param _nextId Id of next node for the new insert position
     */
    function updateKey(
        Data storage self,
        address _id,
        uint256 _newKey,
        address _prevId,
        address _nextId
    ) public {
        // List must contain the node
        require(contains(self, _id), "node not in list");

        // Remove node from the list
        remove(self, _id);

        if (_newKey > 0) {
            // Insert node if it has a non-zero key
            insert(self, _id, _newKey, _prevId, _nextId);
        }
    }

    /**
     * @dev Checks if the list contains a node
     * @param _id Address of transcoder
     * @return true if '_id' is in list
     */
    function contains(Data storage self, address _id) public view returns (bool) {
        // List only contains non-zero keys, so if key is non-zero the node exists
        return self.nodes[_id].key > 0;
    }

    /**
     * @dev Checks if the list is full
     * @return true if list is full
     */
    function isFull(Data storage self) public view returns (bool) {
        return self.size == self.maxSize;
    }

    /**
     * @dev Checks if the list is empty
     * @return true if list is empty
     */
    function isEmpty(Data storage self) public view returns (bool) {
        return self.size == 0;
    }

    /**
     * @dev Returns the current size of the list
     * @return current size of the list
     */
    function getSize(Data storage self) public view returns (uint256) {
        return self.size;
    }

    /**
     * @dev Returns the maximum size of the list
     */
    function getMaxSize(Data storage self) public view returns (uint256) {
        return self.maxSize;
    }

    /**
     * @dev Returns the key of a node in the list
     * @param _id Node's id
     * @return key for node with '_id'
     */
    function getKey(Data storage self, address _id) public view returns (uint256) {
        return self.nodes[_id].key;
    }

    /**
     * @dev Returns the first node in the list (node with the largest key)
     * @return address for the head of the list
     */
    function getFirst(Data storage self) public view returns (address) {
        return self.head;
    }

    /**
     * @dev Returns the last node in the list (node with the smallest key)
     * @return address for the tail of the list
     */
    function getLast(Data storage self) public view returns (address) {
        return self.tail;
    }

    /**
     * @dev Returns the next node (with a smaller key) in the list for a given node
     * @param _id Node's id
     * @return address for the node following node in list with '_id'
     */
    function getNext(Data storage self, address _id) public view returns (address) {
        return self.nodes[_id].nextId;
    }

    /**
     * @dev Returns the previous node (with a larger key) in the list for a given node
     * @param _id Node's id
     * address for the node before node in list with '_id'
     */
    function getPrev(Data storage self, address _id) public view returns (address) {
        return self.nodes[_id].prevId;
    }

    /**
     * @dev Check if a pair of nodes is a valid insertion point for a new node with the given key
     * @param _key Node's key
     * @param _prevId Id of previous node for the insert position
     * @param _nextId Id of next node for the insert position
     * @return if the insert position is valid
     */
    function validInsertPosition(
        Data storage self,
        uint256 _key,
        address _prevId,
        address _nextId
    ) public view returns (bool) {
        if (_prevId == address(0) && _nextId == address(0)) {
            // `(null, null)` is a valid insert position if the list is empty
            return isEmpty(self);
        } else if (_prevId == address(0)) {
            // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list
            return self.head == _nextId && _key >= self.nodes[_nextId].key;
        } else if (_nextId == address(0)) {
            // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list
            return self.tail == _prevId && _key <= self.nodes[_prevId].key;
        } else {
            // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_key` falls between the two nodes' keys
            return
                self.nodes[_prevId].nextId == _nextId &&
                self.nodes[_prevId].key >= _key &&
                _key >= self.nodes[_nextId].key;
        }
    }

    /**
     * @dev Descend the list (larger keys to smaller keys) to find a valid insert position
     * @param _key Node's key
     * @param _startId Id of node to start ascending the list from
     */
    function descendList(
        Data storage self,
        uint256 _key,
        address _startId
    ) private view returns (address, address) {
        // If `_startId` is the head, check if the insert position is before the head
        if (self.head == _startId && _key >= self.nodes[_startId].key) {
            return (address(0), _startId);
        }

        address prevId = _startId;
        address nextId = self.nodes[prevId].nextId;

        // Descend the list until we reach the end or until we find a valid insert position
        while (prevId != address(0) && !validInsertPosition(self, _key, prevId, nextId)) {
            prevId = self.nodes[prevId].nextId;
            nextId = self.nodes[prevId].nextId;
        }

        return (prevId, nextId);
    }

    /**
     * @dev Ascend the list (smaller keys to larger keys) to find a valid insert position
     * @param _key Node's key
     * @param _startId Id of node to start descending the list from
     */
    function ascendList(
        Data storage self,
        uint256 _key,
        address _startId
    ) private view returns (address, address) {
        // If `_startId` is the tail, check if the insert position is after the tail
        if (self.tail == _startId && _key <= self.nodes[_startId].key) {
            return (_startId, address(0));
        }

        address nextId = _startId;
        address prevId = self.nodes[nextId].prevId;

        // Ascend the list until we reach the end or until we find a valid insertion point
        while (nextId != address(0) && !validInsertPosition(self, _key, prevId, nextId)) {
            nextId = self.nodes[nextId].prevId;
            prevId = self.nodes[nextId].prevId;
        }

        return (prevId, nextId);
    }

    /**
     * @dev Find the insert position for a new node with the given key
     * @param _key Node's key
     * @param _prevId Id of previous node for the insert position
     * @param _nextId Id of next node for the insert position
     */
    function findInsertPosition(
        Data storage self,
        uint256 _key,
        address _prevId,
        address _nextId
    ) private view returns (address, address) {
        address prevId = _prevId;
        address nextId = _nextId;

        if (prevId != address(0)) {
            if (!contains(self, prevId) || _key > self.nodes[prevId].key) {
                // `prevId` does not exist anymore or now has a smaller key than the given key
                prevId = address(0);
            }
        }

        if (nextId != address(0)) {
            if (!contains(self, nextId) || _key < self.nodes[nextId].key) {
                // `nextId` does not exist anymore or now has a larger key than the given key
                nextId = address(0);
            }
        }

        if (prevId == address(0) && nextId == address(0)) {
            // No hint - descend list starting from head
            return descendList(self, _key, self.head);
        } else if (prevId == address(0)) {
            // No `prevId` for hint - ascend list starting from `nextId`
            return ascendList(self, _key, nextId);
        } else if (nextId == address(0)) {
            // No `nextId` for hint - descend list starting from `prevId`
            return descendList(self, _key, prevId);
        } else {
            // Descend list starting from `prevId`
            return descendList(self, _key, prevId);
        }
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[]

610ed861003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100ff5760003560e01c8063735bc2ca116100a1578063be6f92d411610070578063be6f92d414610267578063d86811281461027d578063e189dedb146102aa578063fe1ee719146102de57600080fd5b8063735bc2ca146101fc578063a176adaf1461021f578063b0138c471461023f578063b32ece581461025257600080fd5b80634aa12990116100dd5780634aa12990146101815780634fbaa9a61461019e5780635d35e007146101be57806372e40b26146101de57600080fd5b80632ebb2fed1461010457806338237efe1461013c5780633a5c20441461015e575b600080fd5b61011f610112366004610d3d565b546001600160a01b031690565b6040516001600160a01b0390911681526020015b60405180910390f35b81801561014857600080fd5b5061015c610157366004610d72565b610312565b005b61017161016c366004610dc9565b610384565b6040519015158152602001610133565b61017161018f366004610d3d565b60028101546003909101541490565b8180156101aa57600080fd5b5061015c6101b9366004610d72565b6104c6565b8180156101ca57600080fd5b5061015c6101d9366004610e0f565b6107c4565b61011f6101ec366004610d3d565b600101546001600160a01b031690565b61021161020a366004610d3d565b6002015490565b604051908152602001610133565b81801561022b57600080fd5b5061015c61023a366004610e3b565b6109b7565b61017161024d366004610e0f565b610a29565b610211610260366004610d3d565b6003015490565b610171610275366004610d3d565b600301541590565b61021161028b366004610e0f565b6001600160a01b03166000908152600491909101602052604090205490565b61011f6102b8366004610e0f565b6001600160a01b0380821660009081526004840160205260409020600101541692915050565b61011f6102ec366004610e0f565b6001600160a01b0380821660009081526004840160205260409020600201541692915050565b61031c8585610a29565b6103605760405162461bcd60e51b815260206004820152601060248201526f1b9bd919481b9bdd081a5b881b1a5cdd60821b60448201526064015b60405180910390fd5b61036a85856107c4565b821561037d5761037d85858585856104c6565b5050505050565b60006001600160a01b0383161580156103a457506001600160a01b038216155b156103b7576003850154155b90506104be565b6001600160a01b0383166104005784546001600160a01b0383811691161480156103b05750506001600160a01b03811660009081526004850160205260409020548310156104be565b6001600160a01b03821661044c5760018501546001600160a01b0384811691161480156103b05750506001600160a01b03821660009081526004850160205260409020548311156104be565b6001600160a01b038381166000908152600487016020526040902060010154811690831614801561049757506001600160a01b03831660009081526004860160205260409020548411155b80156103b05750506001600160a01b03811660009081526004850160205260409020548310155b949350505050565b60028501546003860154141561050d5760405162461bcd60e51b815260206004820152600c60248201526b1b1a5cdd081a5cc8199d5b1b60a21b6044820152606401610357565b6105178585610a29565b1561055b5760405162461bcd60e51b81526020600482015260146024820152731b9bd91948185b1c9958591e481a5b881b1a5cdd60621b6044820152606401610357565b6001600160a01b0384166105a35760405162461bcd60e51b815260206004820152600f60248201526e1b9bd919481a59081a5cc81b9d5b1b608a1b6044820152606401610357565b600083116105e15760405162461bcd60e51b815260206004820152600b60248201526a6b6579206973207a65726f60a81b6044820152606401610357565b81816105ef87868484610384565b610605576105ff87868484610a4a565b90925090505b6001600160a01b0380871660009081526004890160205260409020869055821615801561063957506001600160a01b038116155b1561066b5786546001600160a01b0387166001600160a01b0319918216811789556001890180549092161790556107a3565b6001600160a01b0382166106d15786546001600160a01b03878116600081815260048b01602052604080822060010180549585166001600160a01b03199687161790558b54909316815291909120600201805483168217905588549091161787556107a3565b6001600160a01b03811661073c57600187810180546001600160a01b03898116600081815260048d01602052604080822060020180549585166001600160a01b03199687161790558554909316815291909120909301805482168417905581541690911790556107a3565b6001600160a01b03808716600081815260048a016020526040808220600180820180548789166001600160a01b0319918216811790925560029384018054988b16988216891790559685528385209091018054871686179055835291200180549092161790555b60038701546107b3906001610b6a565b876003018190555050505050505050565b6107ce8282610a29565b61080d5760405162461bcd60e51b815260206004820152601060248201526f1b9bd919481b9bdd081a5b881b1a5cdd60821b6044820152606401610357565b6001826003015411156109415781546001600160a01b0382811691161415610876576001600160a01b03818116600090815260048401602052604080822060010154855493166001600160a01b031993841681178655825290206002018054909116905561095d565b60018201546001600160a01b03828116911614156108dc576001600160a01b03808216600090815260048401602052604080822060020154600180870180546001600160a01b03199081169390961692831790559083529120018054909116905561095d565b6001600160a01b03818116600090815260048401602052604080822060018082018054600293840180548816875285872090930180549188166001600160a01b031992831617905591549054861685529290932001805491909316911617905561095d565b81546001600160a01b0319908116835560018301805490911690555b6001600160a01b03811660009081526004830160205260408120908155600180820180546001600160a01b03199081169091556002909201805490921690915560038301546109ab91610b7d565b82600301819055505050565b81600201548111610a215760405162461bcd60e51b815260206004820152602e60248201527f6e6577206d61782073697a65206d75737420626520677265617465722074686160448201526d6e206f6c64206d61782073697a6560901b6064820152608401610357565b600290910155565b6001600160a01b031660009081526004919091016020526040902054151590565b60008083836001600160a01b03821615610a9757610a688883610a29565b1580610a8d57506001600160a01b038216600090815260048901602052604090205487115b15610a9757600091505b6001600160a01b03811615610ade57610ab08882610a29565b1580610ad557506001600160a01b038116600090815260048901602052604090205487105b15610ade575060005b6001600160a01b038216158015610afc57506001600160a01b038116155b15610b24578754610b1990899089906001600160a01b0316610b89565b935093505050610b61565b6001600160a01b038216610b3d57610b19888883610c63565b6001600160a01b038116610b5657610b19888884610b89565b610b19888884610b89565b94509492505050565b6000610b768284610e73565b9392505050565b6000610b768284610e8b565b825460009081906001600160a01b038481169116148015610bc457506001600160a01b03831660009081526004860160205260409020548410155b15610bd457506000905081610c5b565b6001600160a01b0380841660009081526004870160205260409020600101548491165b6001600160a01b03821615801590610c185750610c1687878484610384565b155b15610c5557506001600160a01b03908116600090815260048701602052604080822060019081015484168084529190922090910154909116610bf7565b90925090505b935093915050565b600183015460009081906001600160a01b038481169116148015610ca157506001600160a01b03831660009081526004860160205260409020548411155b15610cb157508190506000610c5b565b6001600160a01b0380841660009081526004870160205260409020600201548491165b6001600160a01b03821615801590610cf55750610cf387878385610384565b155b15610d3257506001600160a01b03908116600090815260048701602052604080822060029081015484168084529190922090910154909116610cd4565b969095509350505050565b600060208284031215610d4f57600080fd5b5035919050565b80356001600160a01b0381168114610d6d57600080fd5b919050565b600080600080600060a08688031215610d8a57600080fd5b85359450610d9a60208701610d56565b935060408601359250610daf60608701610d56565b9150610dbd60808701610d56565b90509295509295909350565b60008060008060808587031215610ddf57600080fd5b8435935060208501359250610df660408601610d56565b9150610e0460608601610d56565b905092959194509250565b60008060408385031215610e2257600080fd5b82359150610e3260208401610d56565b90509250929050565b60008060408385031215610e4e57600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b60008219821115610e8657610e86610e5d565b500190565b600082821015610e9d57610e9d610e5d565b50039056fea2646970667358221220e20e81e7781abb2e1ab19eefe9ca78212a9966cb0f1d21e6ee8a0394974a28dc64736f6c63430008090033

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.