Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SortedPositions
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 1 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import "../interfaces/core/IPositionManager.sol";
/**
@title Sorted Positions
@notice Based on Liquity's `SortedPositions`:
https://github.com/liquity/dev/blob/main/packages/contracts/contracts/SortedTroves.sol
Originally derived from `SortedDoublyLinkedList`:
https://github.com/livepeer/protocol/blob/master/contracts/libraries/SortedDoublyLL.sol
*/
contract SortedPositions {
IPositionManager public positionManager;
Data public data;
// Information for a node in the list
struct Node {
bool exists;
address nextId; // Id of next node (smaller NICR) in the list
address prevId; // Id of previous node (larger NICR) in the list
}
// Information for the list
struct Data {
address head; // Head of the list. Also the node in the list with the largest NICR
address tail; // Tail of the list. Also the node in the list with the smallest NICR
uint256 size; // Current size of the list
mapping(address => Node) nodes; // Track the corresponding ids for each node in the list
}
event NodeAdded(address _id, uint256 _NICR);
event NodeRemoved(address _id);
function setAddresses(address _positionManagerAddress) external {
require(_positionManagerAddress != address(0), "SortedPositions: 0 address");
require(address(positionManager) == address(0), "Already set");
positionManager = IPositionManager(_positionManagerAddress);
}
/*
* @dev Add a node to the list
* @param _id Node's id
* @param _NICR Node's NICR
* @param _prevId Id of previous node for the insert position
* @param _nextId Id of next node for the insert position
*/
function insert(address _id, uint256 _NICR, address _prevId, address _nextId) external {
IPositionManager positionManagerCached = positionManager;
_requireCallerIsPositionManager(positionManagerCached);
Node storage node = data.nodes[_id];
// List must not already contain node
require(!node.exists, "SortedPositions: List already contains the node");
// Node id must not be null
require(_id != address(0), "SortedPositions: Id cannot be zero");
_insert(node, positionManagerCached, _id, _NICR, _prevId, _nextId);
}
function _insert(
Node storage node,
IPositionManager _positionManager,
address _id,
uint256 _NICR,
address _prevId,
address _nextId
) internal {
// NICR must be non-zero
require(_NICR > 0, "SortedPositions: NICR must be positive");
address prevId = _prevId;
address nextId = _nextId;
if (!_validInsertPosition(_positionManager, _NICR, prevId, nextId)) {
// Sender's hint was not a valid insert position
// Use sender's hint to find a valid insert position
(prevId, nextId) = _findInsertPosition(_positionManager, _NICR, prevId, nextId);
}
node.exists = true;
if (prevId == address(0) && nextId == address(0)) {
// Insert as head and tail
data.head = _id;
data.tail = _id;
} else if (prevId == address(0)) {
// Insert before `prevId` as the head
address head = data.head;
node.nextId = head;
data.nodes[head].prevId = _id;
data.head = _id;
} else if (nextId == address(0)) {
// Insert after `nextId` as the tail
address tail = data.tail;
node.prevId = tail;
data.nodes[tail].nextId = _id;
data.tail = _id;
} else {
// Insert at insert position between `prevId` and `nextId`
node.nextId = nextId;
node.prevId = prevId;
data.nodes[prevId].nextId = _id;
data.nodes[nextId].prevId = _id;
}
data.size = data.size + 1;
emit NodeAdded(_id, _NICR);
}
function remove(address _id) external {
_requireCallerIsPositionManager(positionManager);
_remove(data.nodes[_id], _id);
}
/*
* @dev Remove a node from the list
* @param _id Node's id
*/
function _remove(Node storage node, address _id) internal {
// List must contain the node
require(node.exists, "SortedPositions: List does not contain the id");
if (data.size > 1) {
// List contains more than a single node
if (_id == data.head) {
// The removed node is the head
// Set head to next node
address head = node.nextId;
data.head = head;
// Set prev pointer of new head to null
data.nodes[head].prevId = address(0);
} else if (_id == data.tail) {
address tail = node.prevId;
// The removed node is the tail
// Set tail to previous node
data.tail = tail;
// Set next pointer of new tail to null
data.nodes[tail].nextId = address(0);
} else {
address prevId = node.prevId;
address nextId = node.nextId;
// The removed node is neither the head nor the tail
// Set next pointer of previous node to the next node
data.nodes[prevId].nextId = nextId;
// Set prev pointer of next node to the previous node
data.nodes[nextId].prevId = prevId;
}
} else {
// List contains a single node
// Set the head and tail to null
data.head = address(0);
data.tail = address(0);
}
delete data.nodes[_id];
data.size = data.size - 1;
emit NodeRemoved(_id);
}
/*
* @dev Re-insert the node at a new position, based on its new NICR
* @param _id Node's id
* @param _newNICR Node's new NICR
* @param _prevId Id of previous node for the new insert position
* @param _nextId Id of next node for the new insert position
*/
function reInsert(address _id, uint256 _newNICR, address _prevId, address _nextId) external {
IPositionManager positionManagerCached = positionManager;
_requireCallerIsPositionManager(positionManagerCached);
Node storage node = data.nodes[_id];
// Remove node from the list
_remove(node, _id);
_insert(node, positionManagerCached, _id, _newNICR, _prevId, _nextId);
}
/*
* @dev Checks if the list contains a node
*/
function contains(address _id) public view returns (bool) {
return data.nodes[_id].exists;
}
/*
* @dev Checks if the list is empty
*/
function isEmpty() public view returns (bool) {
return data.size == 0;
}
/*
* @dev Returns the current size of the list
*/
function getSize() external view returns (uint256) {
return data.size;
}
/*
* @dev Returns the first node in the list (node with the largest NICR)
*/
function getFirst() external view returns (address) {
return data.head;
}
/*
* @dev Returns the last node in the list (node with the smallest NICR)
*/
function getLast() external view returns (address) {
return data.tail;
}
/*
* @dev Returns the next node (with a smaller NICR) in the list for a given node
* @param _id Node's id
*/
function getNext(address _id) external view returns (address) {
return data.nodes[_id].nextId;
}
/*
* @dev Returns the previous node (with a larger NICR) in the list for a given node
* @param _id Node's id
*/
function getPrev(address _id) external view returns (address) {
return data.nodes[_id].prevId;
}
/*
* @dev Check if a pair of nodes is a valid insertion point for a new node with the given NICR
* @param _NICR Node's NICR
* @param _prevId Id of previous node for the insert position
* @param _nextId Id of next node for the insert position
*/
function validInsertPosition(uint256 _NICR, address _prevId, address _nextId) external view returns (bool) {
return _validInsertPosition(positionManager, _NICR, _prevId, _nextId);
}
function _validInsertPosition(
IPositionManager _positionManager,
uint256 _NICR,
address _prevId,
address _nextId
) internal view returns (bool) {
if (_prevId == address(0) && _nextId == address(0)) {
// `(null, null)` is a valid insert position if the list is empty
return isEmpty();
} else if (_prevId == address(0)) {
// `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list
return data.head == _nextId && _NICR >= _positionManager.getNominalICR(_nextId);
} else if (_nextId == address(0)) {
// `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list
return data.tail == _prevId && _NICR <= _positionManager.getNominalICR(_prevId);
} else {
// `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_NICR` falls between the two nodes' NICRs
return
data.nodes[_prevId].nextId == _nextId &&
_positionManager.getNominalICR(_prevId) >= _NICR &&
_NICR >= _positionManager.getNominalICR(_nextId);
}
}
/*
* @dev Descend the list (larger NICRs to smaller NICRs) to find a valid insert position
* @param _positionManager PositionManager contract, passed in as param to save SLOAD’s
* @param _NICR Node's NICR
* @param _startId Id of node to start descending the list from
*/
function _descendList(
IPositionManager _positionManager,
uint256 _NICR,
address _startId
) internal view returns (address, address) {
// If `_startId` is the head, check if the insert position is before the head
if (data.head == _startId && _NICR >= _positionManager.getNominalICR(_startId)) {
return (address(0), _startId);
}
address prevId = _startId;
address nextId = data.nodes[prevId].nextId;
// Descend the list until we reach the end or until we find a valid insert position
while (prevId != address(0) && !_validInsertPosition(_positionManager, _NICR, prevId, nextId)) {
prevId = data.nodes[prevId].nextId;
nextId = data.nodes[prevId].nextId;
}
return (prevId, nextId);
}
/*
* @dev Ascend the list (smaller NICRs to larger NICRs) to find a valid insert position
* @param _positionManager PositionManager contract, passed in as param to save SLOAD’s
* @param _NICR Node's NICR
* @param _startId Id of node to start ascending the list from
*/
function _ascendList(
IPositionManager _positionManager,
uint256 _NICR,
address _startId
) internal view returns (address, address) {
// If `_startId` is the tail, check if the insert position is after the tail
if (data.tail == _startId && _NICR <= _positionManager.getNominalICR(_startId)) {
return (_startId, address(0));
}
address nextId = _startId;
address prevId = data.nodes[nextId].prevId;
// Ascend the list until we reach the end or until we find a valid insertion point
while (nextId != address(0) && !_validInsertPosition(_positionManager, _NICR, prevId, nextId)) {
nextId = data.nodes[nextId].prevId;
prevId = data.nodes[nextId].prevId;
}
return (prevId, nextId);
}
/*
* @dev Find the insert position for a new node with the given NICR
* @param _NICR Node's NICR
* @param _prevId Id of previous node for the insert position
* @param _nextId Id of next node for the insert position
*/
function findInsertPosition(
uint256 _NICR,
address _prevId,
address _nextId
) external view returns (address, address) {
return _findInsertPosition(positionManager, _NICR, _prevId, _nextId);
}
function _findInsertPosition(
IPositionManager _positionManager,
uint256 _NICR,
address _prevId,
address _nextId
) internal view returns (address, address) {
address prevId = _prevId;
address nextId = _nextId;
if (prevId != address(0)) {
if (!contains(prevId) || _NICR > _positionManager.getNominalICR(prevId)) {
// `prevId` does not exist anymore or now has a smaller NICR than the given NICR
prevId = address(0);
}
}
if (nextId != address(0)) {
if (!contains(nextId) || _NICR < _positionManager.getNominalICR(nextId)) {
// `nextId` does not exist anymore or now has a larger NICR than the given NICR
nextId = address(0);
}
}
if (prevId == address(0) && nextId == address(0)) {
// No hint - descend list starting from head
return _descendList(_positionManager, _NICR, data.head);
} else if (prevId == address(0)) {
// No `prevId` for hint - ascend list starting from `nextId`
return _ascendList(_positionManager, _NICR, nextId);
} else if (nextId == address(0)) {
// No `nextId` for hint - descend list starting from `prevId`
return _descendList(_positionManager, _NICR, prevId);
} else {
// Descend list starting from `prevId`
return _descendList(_positionManager, _NICR, prevId);
}
}
function _requireCallerIsPositionManager(IPositionManager _positionManager) internal view {
require(msg.sender == address(_positionManager), "SortedPositions: Caller is not the PositionManager");
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC3156FlashBorrower} from "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IFactory} from "./IFactory.sol";
interface IPositionManager {
event BaseRateUpdated(uint256 _baseRate);
event CollateralSent(address _to, uint256 _amount);
event LTermsUpdated(uint256 _L_collateral, uint256 _L_debt);
event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);
event Redemption(
address indexed _redeemer,
uint256 _attemptedDebtAmount,
uint256 _actualDebtAmount,
uint256 _collateralSent,
uint256 _collateralFee
);
event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);
event TotalStakesUpdated(uint256 _newTotalStakes);
event PositionIndexUpdated(address _borrower, uint256 _newIndex);
event PositionSnapshotsUpdated(uint256 _L_collateral, uint256 _L_debt);
event PositionUpdated(address indexed _borrower, uint256 _debt, uint256 _coll, uint256 _stake, uint8 _operation);
function addCollateralSurplus(address borrower, uint256 collSurplus) external;
function applyPendingRewards(address _borrower) external returns (uint256 coll, uint256 debt);
function claimCollateral(address borrower, address _receiver) external;
function closePosition(address _borrower, address _receiver, uint256 collAmount, uint256 debtAmount) external;
function closePositionByLiquidation(address _borrower) external;
function setCollVaultRouter(address _collVaultRouter) external;
function collectInterests() external;
function decayBaseRateAndGetBorrowingFee(uint256 _debt) external returns (uint256);
function decreaseDebtAndSendCollateral(address account, uint256 debt, uint256 coll) external;
function fetchPrice() external view returns (uint256);
function finalizeLiquidation(
address _liquidator,
uint256 _debt,
uint256 _coll,
uint256 _collSurplus,
uint256 _debtGasComp,
uint256 _collGasComp
) external;
function getEntireSystemBalances() external view returns (uint256, uint256, uint256);
function movePendingPositionRewardsToActiveBalances(uint256 _debt, uint256 _collateral) external;
function openPosition(
address _borrower,
uint256 _collateralAmount,
uint256 _compositeDebt,
uint256 NICR,
address _upperHint,
address _lowerHint
) external returns (uint256 stake, uint256 arrayIndex);
function redeemCollateral(
uint256 _debtAmount,
address _firstRedemptionHint,
address _upperPartialRedemptionHint,
address _lowerPartialRedemptionHint,
uint256 _partialRedemptionHintNICR,
uint256 _maxIterations,
uint256 _maxFeePercentage
) external;
function setAddresses(address _priceFeedAddress, address _sortedPositionsAddress, address _collateralToken) external;
function setParameters(
IFactory.DeploymentParams calldata _params
) external;
function setPaused(bool _paused) external;
function setPriceFeed(address _priceFeedAddress) external;
function startSunset() external;
function updateBalances() external;
function updatePositionFromAdjustment(
bool _isDebtIncrease,
uint256 _debtChange,
uint256 _netDebtChange,
bool _isCollIncrease,
uint256 _collChange,
address _upperHint,
address _lowerHint,
address _borrower,
address _receiver
) external returns (uint256, uint256, uint256);
function DEBT_GAS_COMPENSATION() external view returns (uint256);
function DECIMAL_PRECISION() external view returns (uint256);
function L_collateral() external view returns (uint256);
function L_debt() external view returns (uint256);
function MCR() external view returns (uint256);
function PERCENT_DIVISOR() external view returns (uint256);
function CORE() external view returns (address);
function SUNSETTING_INTEREST_RATE() external view returns (uint256);
function Positions(
address
)
external
view
returns (
uint256 debt,
uint256 coll,
uint256 stake,
uint8 status,
uint128 arrayIndex,
uint256 activeInterestIndex
);
function activeInterestIndex() external view returns (uint256);
function baseRate() external view returns (uint256);
function borrowerOperations() external view returns (address);
function borrowingFeeFloor() external view returns (uint256);
function collateralToken() external view returns (address);
function debtToken() external view returns (address);
function collVaultRouter() external view returns (address);
function defaultedCollateral() external view returns (uint256);
function defaultedDebt() external view returns (uint256);
function getBorrowingFee(uint256 _debt) external view returns (uint256);
function getBorrowingFeeWithDecay(uint256 _debt) external view returns (uint256);
function getBorrowingRate() external view returns (uint256);
function getBorrowingRateWithDecay() external view returns (uint256);
function getCurrentICR(address _borrower, uint256 _price) external view returns (uint256);
function getEntireDebtAndColl(
address _borrower
) external view returns (uint256 debt, uint256 coll, uint256 pendingDebtReward, uint256 pendingCollateralReward);
function getEntireSystemColl() external view returns (uint256);
function getEntireSystemDebt() external view returns (uint256);
function getNominalICR(address _borrower) external view returns (uint256);
function getPendingCollAndDebtRewards(address _borrower) external view returns (uint256, uint256);
function getRedemptionFeeWithDecay(uint256 _collateralDrawn) external view returns (uint256);
function getRedemptionRate() external view returns (uint256);
function getRedemptionRateWithDecay() external view returns (uint256);
function getTotalActiveCollateral() external view returns (uint256);
function getTotalActiveDebt() external view returns (uint256);
function getPositionCollAndDebt(address _borrower) external view returns (uint256 coll, uint256 debt);
function getPositionFromPositionOwnersArray(uint256 _index) external view returns (address);
function getPositionOwnersCount() external view returns (uint256);
function getPositionStake(address _borrower) external view returns (uint256);
function getPositionStatus(address _borrower) external view returns (uint256);
function guardian() external view returns (address);
function hasPendingRewards(address _borrower) external view returns (bool);
function interestPayable() external view returns (uint256);
function interestRate() external view returns (uint256);
function lastActiveIndexUpdate() external view returns (uint256);
function lastCollateralError_Redistribution() external view returns (uint256);
function lastDebtError_Redistribution() external view returns (uint256);
function lastFeeOperationTime() external view returns (uint256);
function liquidationManager() external view returns (address);
function maxBorrowingFee() external view returns (uint256);
function maxRedemptionFee() external view returns (uint256);
function maxSystemDebt() external view returns (uint256);
function minuteDecayFactor() external view returns (uint256);
function owner() external view returns (address);
function paused() external view returns (bool);
function priceFeed() external view returns (address);
function redemptionFeeFloor() external view returns (uint256);
function rewardSnapshots(address) external view returns (uint256 collateral, uint256 debt);
function sortedPositions() external view returns (address);
function sunsetting() external view returns (bool);
function surplusBalances(address) external view returns (uint256);
function systemDeploymentTime() external view returns (uint256);
function totalCollateralSnapshot() external view returns (uint256);
function totalStakes() external view returns (uint256);
function totalStakesSnapshot() external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC3156 FlashBorrower, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashBorrower {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "IERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
interface IFactory {
// commented values are suggested default parameters
struct DeploymentParams {
uint256 minuteDecayFactor; // 999037758833783000 (half life of 12 hours)
uint256 redemptionFeeFloor; // 1e18 / 1000 * 5 (0.5%)
uint256 maxRedemptionFee; // 1e18 (100%)
uint256 borrowingFeeFloor; // 1e18 / 1000 * 5 (0.5%)
uint256 maxBorrowingFee; // 1e18 / 100 * 5 (5%)
uint256 interestRateInBps; // 100 (1%)
uint256 maxDebt;
uint256 MCR; // 12 * 1e17 (120%)
address collVaultRouter; // set to address(0) if PositionManager coll is not CollateralVault
}
event NewDeployment(address collateral, address priceFeed, address positionManager, address sortedPositions);
function deployNewInstance(
address collateral,
address priceFeed,
address customPositionManagerImpl,
address customSortedPositionsImpl,
DeploymentParams calldata params,
uint64 unlockRatePerSecond,
bool forceThroughLspBalanceCheck
) external;
function setImplementations(address _positionManagerImpl, address _sortedPositionsImpl) external;
function CORE() external view returns (address);
function borrowerOperations() external view returns (address);
function debtToken() external view returns (address);
function guardian() external view returns (address);
function liquidationManager() external view returns (address);
function owner() external view returns (address);
function sortedPositionsImpl() external view returns (address);
function liquidStabilityPool() external view returns (address);
function positionManagerCount() external view returns (uint256);
function positionManagerImpl() external view returns (address);
function positionManagers(uint256) external view returns (address);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin-upgradeable/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
"solady/=lib/solady/src/",
"@solmate/=lib/solmate/src/",
"@chimera/=lib/chimera/src/",
"forge-std/=lib/forge-std/src/",
"@uniswap/v3-core/=lib/v3-core/",
"@uniswap/v3-periphery/=lib/v3-periphery/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"chimera/=lib/chimera/src/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"rewards/=lib/rewards/",
"solmate/=lib/solmate/src/",
"uniswap/=lib/uniswap/",
"v3-core/=lib/v3-core/contracts/",
"v3-periphery/=lib/v3-periphery/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 1
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_id","type":"address"},{"indexed":false,"internalType":"uint256","name":"_NICR","type":"uint256"}],"name":"NodeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_id","type":"address"}],"name":"NodeRemoved","type":"event"},{"inputs":[{"internalType":"address","name":"_id","type":"address"}],"name":"contains","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"data","outputs":[{"internalType":"address","name":"head","type":"address"},{"internalType":"address","name":"tail","type":"address"},{"internalType":"uint256","name":"size","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_NICR","type":"uint256"},{"internalType":"address","name":"_prevId","type":"address"},{"internalType":"address","name":"_nextId","type":"address"}],"name":"findInsertPosition","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFirst","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLast","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_id","type":"address"}],"name":"getNext","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_id","type":"address"}],"name":"getPrev","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_id","type":"address"},{"internalType":"uint256","name":"_NICR","type":"uint256"},{"internalType":"address","name":"_prevId","type":"address"},{"internalType":"address","name":"_nextId","type":"address"}],"name":"insert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isEmpty","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionManager","outputs":[{"internalType":"contract IPositionManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_id","type":"address"},{"internalType":"uint256","name":"_newNICR","type":"uint256"},{"internalType":"address","name":"_prevId","type":"address"},{"internalType":"address","name":"_nextId","type":"address"}],"name":"reInsert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_id","type":"address"}],"name":"remove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_positionManagerAddress","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_NICR","type":"uint256"},{"internalType":"address","name":"_prevId","type":"address"},{"internalType":"address","name":"_nextId","type":"address"}],"name":"validInsertPosition","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052348015600e575f80fd5b506111c38061001c5f395ff3fe608060405234801561000f575f80fd5b50600436106100c3575f3560e01c80631e223143146100c757806329092d0e146100ea5780632be21260146100ff5780633fce12d514610112578063416980dc1461013557806346f7cf87146101685780634d6228311461017b5780635dbe47e81461018c578063681fe70c1461019f57806373d4a13a146101a8578063765e0159146101ec578063791b98bc1461021c57806381d3c4351461022e578063b72703ac14610241578063de8fa4311461026f575b5f80fd5b6001546001600160a01b03165b6040516100e19190611064565b60405180910390f35b6100fd6100f8366004611093565b610280565b005b6100fd61010d3660046110b3565b6102b8565b6101256101203660046110fd565b610303565b60405190151581526020016100e1565b6101486101433660046110fd565b610323565b604080516001600160a01b039384168152929091166020830152016100e1565b6100fd6101763660046110b3565b61034a565b6002546001600160a01b03166100d4565b61012561019a366004611093565b610445565b60035415610125565b6001546002546003546101c6926001600160a01b0390811692169083565b604080516001600160a01b039485168152939092166020840152908201526060016100e1565b6100d46101fa366004611093565b6001600160a01b039081165f9081526004602052604090205461010090041690565b5f546100d4906001600160a01b031681565b6100fd61023c366004611093565b610462565b6100d461024f366004611093565b6001600160a01b039081165f908152600460205260409020600101541690565b6003546040519081526020016100e1565b5f54610294906001600160a01b031661051c565b6001600160a01b0381165f9081526004602052604090206102b5908261058f565b50565b5f546001600160a01b03166102cc8161051c565b6001600160a01b0385165f9081526004602052604090206102ed818761058f565b6102fb8183888888886107b2565b505050505050565b5f805461031b906001600160a01b0316858585610a2e565b949350505050565b5f8054819061033d906001600160a01b0316868686610c62565b915091505b935093915050565b5f546001600160a01b031661035e8161051c565b6001600160a01b0385165f908152600460205260409020805460ff16156103e45760405162461bcd60e51b815260206004820152602f60248201527f536f72746564506f736974696f6e733a204c69737420616c726561647920636f60448201526e6e7461696e7320746865206e6f646560881b60648201526084015b60405180910390fd5b6001600160a01b0386166102ed5760405162461bcd60e51b815260206004820152602260248201527f536f72746564506f736974696f6e733a2049642063616e6e6f74206265207a65604482015261726f60f01b60648201526084016103db565b6001600160a01b03165f9081526004602052604090205460ff1690565b6001600160a01b0381166104b55760405162461bcd60e51b815260206004820152601a602482015279536f72746564506f736974696f6e733a2030206164647265737360301b60448201526064016103db565b5f546001600160a01b0316156104fb5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b60448201526064016103db565b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b038216146102b55760405162461bcd60e51b815260206004820152603260248201527f536f72746564506f736974696f6e733a2043616c6c6572206973206e6f7420746044820152713432902837b9b4ba34b7b726b0b730b3b2b960711b60648201526084016103db565b815460ff166105f65760405162461bcd60e51b815260206004820152602d60248201527f536f72746564506f736974696f6e733a204c69737420646f6573206e6f74206360448201526c1bdb9d185a5b881d1a19481a59609a1b60648201526084016103db565b60035460011015610711576001546001600160a01b0390811690821603610656578154600180546101009092046001600160a01b03166001600160a01b0319928316811782555f908152600460205260409020018054909116905561072e565b6002546001600160a01b03908116908216036106b0576001820154600280546001600160a01b0319166001600160a01b0390921691821790555f9081526004602052604090208054610100600160a81b031916905561072e565b60018281015483546001600160a01b039182165f818152600460205260408082208054610100600160a81b031916610100958690049096169485029590951790945591825291902090910180546001600160a01b031916909117905561072e565b600180546001600160a01b03199081169091556002805490911690555b6001600160a01b0381165f90815260046020526040902080546001600160a81b0319168155600190810180546001600160a01b0319169055600354610773919061114a565b6003556040517fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b906107a6908390611064565b60405180910390a15050565b5f83116108105760405162461bcd60e51b815260206004820152602660248201527f536f72746564506f736974696f6e733a204e494352206d75737420626520706f60448201526573697469766560d01b60648201526084016103db565b818161081e87868484610a2e565b6108345761082e87868484610c62565b90925090505b875460ff191660011788556001600160a01b03821615801561085d57506001600160a01b038116155b1561089257600180546001600160a01b0388166001600160a01b031991821681179092556002805490911690911790556109d1565b6001600160a01b0382166108f957600180548954610100600160a81b0319166101006001600160a01b03928316908102919091178b555f908152600460205260409020820180546001600160a01b0319908116928a169283179091558254161790556109d1565b6001600160a01b03811661095f576002805460018a0180546001600160a01b039283166001600160a01b031991821681179092555f918252600460205260409091208054610100600160a81b031916610100938b169384021790558254161790556109d1565b87546001600160a01b03808316610100818102610100600160a81b0319948516178c556001808d0180548886166001600160a01b031991821681179092555f918252600460205260408083208054978f1695860297909816969096179096559283529290912090910180549092161790555b6003546109df906001611163565b600355604080516001600160a01b0388168152602081018790527fe02b43adbee0c123de070a04554a71877a0007e2fc161466299cae3c094fe82f910160405180910390a15050505050505050565b5f6001600160a01b038316158015610a4d57506001600160a01b038216155b15610a5e57600354155b905061031b565b6001600160a01b038316610af9576001546001600160a01b038381169116148015610a57575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610ab0908590600401611064565b602060405180830381865afa158015610acb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aef9190611176565b841015905061031b565b6001600160a01b038216610b94576002546001600160a01b038481169116148015610a57575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610b4b908690600401611064565b602060405180830381865afa158015610b66573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8a9190611176565b841115905061031b565b6001600160a01b038381165f9081526004602052604090205461010090048116908316148015610c2f575060405163b0d8e18160e01b815284906001600160a01b0387169063b0d8e18190610bed908790600401611064565b602060405180830381865afa158015610c08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c2c9190611176565b10155b8015610a57575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610ab0908590600401611064565b5f8083836001600160a01b03821615610cfc57610c7e82610445565b1580610cf3575060405163b0d8e18160e01b81526001600160a01b0389169063b0d8e18190610cb1908590600401611064565b602060405180830381865afa158015610ccc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf09190611176565b87115b15610cfc575f91505b6001600160a01b03811615610d9157610d1481610445565b1580610d89575060405163b0d8e18160e01b81526001600160a01b0389169063b0d8e18190610d47908490600401611064565b602060405180830381865afa158015610d62573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d869190611176565b87105b15610d9157505f5b6001600160a01b038216158015610daf57506001600160a01b038116155b15610dd857600154610dcd90899089906001600160a01b0316610e1e565b935093505050610e15565b6001600160a01b038216610df157610dcd888883610f44565b6001600160a01b038116610e0a57610dcd888884610e1e565b610dcd888884610e1e565b94509492505050565b6001545f9081906001600160a01b038481169116148015610ea9575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610e66908690600401611064565b602060405180830381865afa158015610e81573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea59190611176565b8410155b15610eb857505f905081610342565b6001600160a01b038084165f908152600460205260409020548491610100909104165b6001600160a01b03821615801590610efc5750610efa87878484610a2e565b155b15610f3857506001600160a01b039081165f90815260046020526040808220546101009081900484168084529190922054909291900416610edb565b90969095509350505050565b6002545f9081906001600160a01b038481169116148015610fcf575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610f8c908690600401611064565b602060405180830381865afa158015610fa7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fcb9190611176565b8411155b15610fde57508190505f610342565b6001600160a01b038084165f908152600460205260409020600101548491165b6001600160a01b0382161580159061101f575061101d87878385610a2e565b155b1561105957506001600160a01b039081165f9081526004602052604080822060019081015484168084529190922090910154909116610ffe565b969095509350505050565b6001600160a01b0391909116815260200190565b80356001600160a01b038116811461108e575f80fd5b919050565b5f602082840312156110a3575f80fd5b6110ac82611078565b9392505050565b5f805f80608085870312156110c6575f80fd5b6110cf85611078565b9350602085013592506110e460408601611078565b91506110f260608601611078565b905092959194509250565b5f805f6060848603121561110f575f80fd5b8335925061111f60208501611078565b915061112d60408501611078565b90509250925092565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561115d5761115d611136565b92915050565b8082018082111561115d5761115d611136565b5f60208284031215611186575f80fd5b505191905056fea26469706673582212201c7b1354ae741fb34312b399deb1c084bf16b7ddc20f7b8547ce533758258fc964736f6c634300081a0033
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100c3575f3560e01c80631e223143146100c757806329092d0e146100ea5780632be21260146100ff5780633fce12d514610112578063416980dc1461013557806346f7cf87146101685780634d6228311461017b5780635dbe47e81461018c578063681fe70c1461019f57806373d4a13a146101a8578063765e0159146101ec578063791b98bc1461021c57806381d3c4351461022e578063b72703ac14610241578063de8fa4311461026f575b5f80fd5b6001546001600160a01b03165b6040516100e19190611064565b60405180910390f35b6100fd6100f8366004611093565b610280565b005b6100fd61010d3660046110b3565b6102b8565b6101256101203660046110fd565b610303565b60405190151581526020016100e1565b6101486101433660046110fd565b610323565b604080516001600160a01b039384168152929091166020830152016100e1565b6100fd6101763660046110b3565b61034a565b6002546001600160a01b03166100d4565b61012561019a366004611093565b610445565b60035415610125565b6001546002546003546101c6926001600160a01b0390811692169083565b604080516001600160a01b039485168152939092166020840152908201526060016100e1565b6100d46101fa366004611093565b6001600160a01b039081165f9081526004602052604090205461010090041690565b5f546100d4906001600160a01b031681565b6100fd61023c366004611093565b610462565b6100d461024f366004611093565b6001600160a01b039081165f908152600460205260409020600101541690565b6003546040519081526020016100e1565b5f54610294906001600160a01b031661051c565b6001600160a01b0381165f9081526004602052604090206102b5908261058f565b50565b5f546001600160a01b03166102cc8161051c565b6001600160a01b0385165f9081526004602052604090206102ed818761058f565b6102fb8183888888886107b2565b505050505050565b5f805461031b906001600160a01b0316858585610a2e565b949350505050565b5f8054819061033d906001600160a01b0316868686610c62565b915091505b935093915050565b5f546001600160a01b031661035e8161051c565b6001600160a01b0385165f908152600460205260409020805460ff16156103e45760405162461bcd60e51b815260206004820152602f60248201527f536f72746564506f736974696f6e733a204c69737420616c726561647920636f60448201526e6e7461696e7320746865206e6f646560881b60648201526084015b60405180910390fd5b6001600160a01b0386166102ed5760405162461bcd60e51b815260206004820152602260248201527f536f72746564506f736974696f6e733a2049642063616e6e6f74206265207a65604482015261726f60f01b60648201526084016103db565b6001600160a01b03165f9081526004602052604090205460ff1690565b6001600160a01b0381166104b55760405162461bcd60e51b815260206004820152601a602482015279536f72746564506f736974696f6e733a2030206164647265737360301b60448201526064016103db565b5f546001600160a01b0316156104fb5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b60448201526064016103db565b5f80546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b038216146102b55760405162461bcd60e51b815260206004820152603260248201527f536f72746564506f736974696f6e733a2043616c6c6572206973206e6f7420746044820152713432902837b9b4ba34b7b726b0b730b3b2b960711b60648201526084016103db565b815460ff166105f65760405162461bcd60e51b815260206004820152602d60248201527f536f72746564506f736974696f6e733a204c69737420646f6573206e6f74206360448201526c1bdb9d185a5b881d1a19481a59609a1b60648201526084016103db565b60035460011015610711576001546001600160a01b0390811690821603610656578154600180546101009092046001600160a01b03166001600160a01b0319928316811782555f908152600460205260409020018054909116905561072e565b6002546001600160a01b03908116908216036106b0576001820154600280546001600160a01b0319166001600160a01b0390921691821790555f9081526004602052604090208054610100600160a81b031916905561072e565b60018281015483546001600160a01b039182165f818152600460205260408082208054610100600160a81b031916610100958690049096169485029590951790945591825291902090910180546001600160a01b031916909117905561072e565b600180546001600160a01b03199081169091556002805490911690555b6001600160a01b0381165f90815260046020526040902080546001600160a81b0319168155600190810180546001600160a01b0319169055600354610773919061114a565b6003556040517fcfc24166db4bb677e857cacabd1541fb2b30645021b27c5130419589b84db52b906107a6908390611064565b60405180910390a15050565b5f83116108105760405162461bcd60e51b815260206004820152602660248201527f536f72746564506f736974696f6e733a204e494352206d75737420626520706f60448201526573697469766560d01b60648201526084016103db565b818161081e87868484610a2e565b6108345761082e87868484610c62565b90925090505b875460ff191660011788556001600160a01b03821615801561085d57506001600160a01b038116155b1561089257600180546001600160a01b0388166001600160a01b031991821681179092556002805490911690911790556109d1565b6001600160a01b0382166108f957600180548954610100600160a81b0319166101006001600160a01b03928316908102919091178b555f908152600460205260409020820180546001600160a01b0319908116928a169283179091558254161790556109d1565b6001600160a01b03811661095f576002805460018a0180546001600160a01b039283166001600160a01b031991821681179092555f918252600460205260409091208054610100600160a81b031916610100938b169384021790558254161790556109d1565b87546001600160a01b03808316610100818102610100600160a81b0319948516178c556001808d0180548886166001600160a01b031991821681179092555f918252600460205260408083208054978f1695860297909816969096179096559283529290912090910180549092161790555b6003546109df906001611163565b600355604080516001600160a01b0388168152602081018790527fe02b43adbee0c123de070a04554a71877a0007e2fc161466299cae3c094fe82f910160405180910390a15050505050505050565b5f6001600160a01b038316158015610a4d57506001600160a01b038216155b15610a5e57600354155b905061031b565b6001600160a01b038316610af9576001546001600160a01b038381169116148015610a57575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610ab0908590600401611064565b602060405180830381865afa158015610acb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aef9190611176565b841015905061031b565b6001600160a01b038216610b94576002546001600160a01b038481169116148015610a57575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610b4b908690600401611064565b602060405180830381865afa158015610b66573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8a9190611176565b841115905061031b565b6001600160a01b038381165f9081526004602052604090205461010090048116908316148015610c2f575060405163b0d8e18160e01b815284906001600160a01b0387169063b0d8e18190610bed908790600401611064565b602060405180830381865afa158015610c08573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c2c9190611176565b10155b8015610a57575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610ab0908590600401611064565b5f8083836001600160a01b03821615610cfc57610c7e82610445565b1580610cf3575060405163b0d8e18160e01b81526001600160a01b0389169063b0d8e18190610cb1908590600401611064565b602060405180830381865afa158015610ccc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf09190611176565b87115b15610cfc575f91505b6001600160a01b03811615610d9157610d1481610445565b1580610d89575060405163b0d8e18160e01b81526001600160a01b0389169063b0d8e18190610d47908490600401611064565b602060405180830381865afa158015610d62573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d869190611176565b87105b15610d9157505f5b6001600160a01b038216158015610daf57506001600160a01b038116155b15610dd857600154610dcd90899089906001600160a01b0316610e1e565b935093505050610e15565b6001600160a01b038216610df157610dcd888883610f44565b6001600160a01b038116610e0a57610dcd888884610e1e565b610dcd888884610e1e565b94509492505050565b6001545f9081906001600160a01b038481169116148015610ea9575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610e66908690600401611064565b602060405180830381865afa158015610e81573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea59190611176565b8410155b15610eb857505f905081610342565b6001600160a01b038084165f908152600460205260409020548491610100909104165b6001600160a01b03821615801590610efc5750610efa87878484610a2e565b155b15610f3857506001600160a01b039081165f90815260046020526040808220546101009081900484168084529190922054909291900416610edb565b90969095509350505050565b6002545f9081906001600160a01b038481169116148015610fcf575060405163b0d8e18160e01b81526001600160a01b0386169063b0d8e18190610f8c908690600401611064565b602060405180830381865afa158015610fa7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fcb9190611176565b8411155b15610fde57508190505f610342565b6001600160a01b038084165f908152600460205260409020600101548491165b6001600160a01b0382161580159061101f575061101d87878385610a2e565b155b1561105957506001600160a01b039081165f9081526004602052604080822060019081015484168084529190922090910154909116610ffe565b969095509350505050565b6001600160a01b0391909116815260200190565b80356001600160a01b038116811461108e575f80fd5b919050565b5f602082840312156110a3575f80fd5b6110ac82611078565b9392505050565b5f805f80608085870312156110c6575f80fd5b6110cf85611078565b9350602085013592506110e460408601611078565b91506110f260608601611078565b905092959194509250565b5f805f6060848603121561110f575f80fd5b8335925061111f60208501611078565b915061112d60408501611078565b90509250925092565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561115d5761115d611136565b92915050565b8082018082111561115d5761115d611136565b5f60208284031215611186575f80fd5b505191905056fea26469706673582212201c7b1354ae741fb34312b399deb1c084bf16b7ddc20f7b8547ce533758258fc964736f6c634300081a0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.