Source Code
Latest 25 from a total of 2,022 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Deposit | 24010775 | 5 days ago | IN | 0 ETH | 0.00027234 | ||||
| Withdraw | 23839653 | 29 days ago | IN | 0 ETH | 0.00101783 | ||||
| Withdraw | 23835642 | 30 days ago | IN | 0 ETH | 0.00474079 | ||||
| Withdraw | 23809955 | 33 days ago | IN | 0 ETH | 0.00010352 | ||||
| Withdraw | 23758438 | 40 days ago | IN | 0 ETH | 0.00010422 | ||||
| Withdraw | 23733449 | 44 days ago | IN | 0 ETH | 0.00012714 | ||||
| Withdraw | 23618066 | 60 days ago | IN | 0 ETH | 0.00042624 | ||||
| Deposit | 23604119 | 62 days ago | IN | 0 ETH | 0.00013174 | ||||
| Deposit | 23595617 | 63 days ago | IN | 0 ETH | 0.00004207 | ||||
| Deposit | 23591941 | 64 days ago | IN | 0 ETH | 0.00026182 | ||||
| Withdraw | 23588994 | 64 days ago | IN | 0 ETH | 0.00055678 | ||||
| Withdraw | 23555951 | 69 days ago | IN | 0 ETH | 0.00003713 | ||||
| Withdraw | 23535328 | 72 days ago | IN | 0 ETH | 0.00013318 | ||||
| Deposit | 23525017 | 73 days ago | IN | 0 ETH | 0.00013258 | ||||
| Withdraw | 23505884 | 76 days ago | IN | 0 ETH | 0.00007314 | ||||
| Withdraw | 23486819 | 78 days ago | IN | 0 ETH | 0.00042099 | ||||
| Withdraw | 23446231 | 84 days ago | IN | 0 ETH | 0.00005377 | ||||
| Withdraw | 23441324 | 85 days ago | IN | 0 ETH | 0.00016763 | ||||
| Withdraw | 23397889 | 91 days ago | IN | 0 ETH | 0.00014409 | ||||
| Withdraw | 23391146 | 92 days ago | IN | 0 ETH | 0.00041263 | ||||
| Deposit | 23382557 | 93 days ago | IN | 0 ETH | 0.00003935 | ||||
| Deposit | 23381233 | 93 days ago | IN | 0 ETH | 0.00009633 | ||||
| Withdraw | 23348574 | 98 days ago | IN | 0 ETH | 0.00014442 | ||||
| Deposit | 23340257 | 99 days ago | IN | 0 ETH | 0.00020803 | ||||
| Deposit | 23334236 | 100 days ago | IN | 0 ETH | 0.00150418 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60a06040 | 20091023 | 553 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GenesisNFTStaking
Compiler Version
v0.8.25+commit.b61c2a91
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: None
// Super Champs Foundation 2024
pragma solidity ^0.8.24;
import {IERC165, ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
/// @title Dirt Simple Non-Fungible Token Staking Contract
/// @author Chance Santana-Wees (Coelacanth/Coel.eth)
/// @notice Allows for the deposit and withdrawal of NFTs from a specified collection.
/// @dev Allows external query of all NFTs a user has staked with historical data on their last staked/unstaked timestamp.
contract GenesisNFTStaking is IERC721Receiver, ERC165 {
using EnumerableSet for EnumerableSet.UintSet;
IERC721 private immutable _underlying;
struct StakingData {
uint256 last_staked;
uint256 last_unstaked;
address last_staker;
}
mapping(uint256 => StakingData) public staking_data;
mapping(address => EnumerableSet.UintSet) staked_tokens;
error ERC721UnsupportedToken(address token);
error MustInitiateStakingFromSelf();
error TokenNotStakedByAddress(uint256 tokenID, address sender);
event TokenStaked(uint256 tokenID, address staker);
event TokenUnstaked(uint256 tokenID, address staker);
constructor(IERC721 underlyingToken) {
_underlying = underlyingToken;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) {
return
interfaceId == type(IERC721Receiver).interfaceId ||
super.supportsInterface(interfaceId);
}
function deposit(uint256[] memory tokenIds) public virtual returns (bool) {
uint256 length = tokenIds.length;
for (uint256 i = 0; i < length; ++i) {
underlying().safeTransferFrom(msg.sender, address(this), tokenIds[i]);
}
return true;
}
function withdraw(uint256[] memory tokenIds) public virtual returns (bool) {
uint256 length = tokenIds.length;
for (uint256 i = 0; i < length; ++i) {
uint256 tokenId = tokenIds[i];
if (staked_tokens[msg.sender].contains(tokenId)) {
staking_data[tokenId].last_unstaked = block.timestamp;
staked_tokens[msg.sender].remove(tokenId);
emit TokenUnstaked(tokenId, msg.sender);
underlying().safeTransferFrom(address(this), msg.sender, tokenId);
} else {
revert TokenNotStakedByAddress(tokenId, msg.sender);
}
}
return true;
}
/**
* @dev Used by front-end user to determine which tokens are CURRENTLY staked in the contract.
*/
function StakedTokens(address staker) public view returns (uint256[] memory ret) {
uint256 length = staked_tokens[staker].length();
ret = new uint256[](length);
for(uint i = 0; i < length; i++) {
ret[i] = staked_tokens[staker].at(i);
}
}
/**
* @dev Used by back-end system to query latest staking data from a list of token IDs.
*/
function TokenData(uint256[] memory tokenIds) public view returns (StakingData[] memory ret) {
uint256 length = tokenIds.length;
ret = new StakingData[](length);
for(uint i = 0; i < length; i++) {
ret[i] = staking_data[tokenIds[i]];
}
}
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be
* reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address,
address from,
uint256 tokenId,
bytes calldata
) external returns (bytes4) {
if (address(underlying()) != msg.sender) {
revert ERC721UnsupportedToken(msg.sender);
}
if (staking_data[tokenId].last_staker == address(0)) {
staking_data[tokenId] = StakingData(block.timestamp, 0, from);
} else {
staking_data[tokenId].last_staked = block.timestamp;
staking_data[tokenId].last_staker = from;
}
staked_tokens[from].add(tokenId);
emit TokenStaked(tokenId, from);
return IERC721Receiver.onERC721Received.selector;
}
/**
* @dev Returns the underlying token.
*/
function underlying() public view virtual returns (IERC721) {
return _underlying;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.20;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be
* reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.20;
import {IERC721} from "./IERC721.sol";
import {IERC721Receiver} from "./IERC721Receiver.sol";
import {IERC721Metadata} from "./extensions/IERC721Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {Strings} from "../../utils/Strings.sol";
import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol";
import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
mapping(uint256 tokenId => address) private _owners;
mapping(address owner => uint256) private _balances;
mapping(uint256 tokenId => address) private _tokenApprovals;
mapping(address owner => mapping(address operator => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual returns (uint256) {
if (owner == address(0)) {
revert ERC721InvalidOwner(address(0));
}
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual returns (address) {
return _requireOwned(tokenId);
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
_requireOwned(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual {
_approve(to, tokenId, _msgSender());
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual returns (address) {
_requireOwned(tokenId);
return _getApproved(tokenId);
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(address from, address to, uint256 tokenId) public virtual {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
// Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
// (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
address previousOwner = _update(to, tokenId, _msgSender());
if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
transferFrom(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*
* IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
* core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances
* consistent with ownership. The invariant to preserve is that for any address `a` the value returned by
* `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
*/
function _getApproved(uint256 tokenId) internal view virtual returns (address) {
return _tokenApprovals[tokenId];
}
/**
* @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
* particular (ignoring whether it is owned by `owner`).
*
* WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
* assumption.
*/
function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
return
spender != address(0) &&
(owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
}
/**
* @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
* Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets
* the `spender` for the specific `tokenId`.
*
* WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
* assumption.
*/
function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
if (!_isAuthorized(owner, spender, tokenId)) {
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else {
revert ERC721InsufficientApproval(spender, tokenId);
}
}
}
/**
* @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
*
* NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
* a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
*
* WARNING: Increasing an account's balance using this function tends to be paired with an override of the
* {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
* remain consistent with one another.
*/
function _increaseBalance(address account, uint128 value) internal virtual {
unchecked {
_balances[account] += value;
}
}
/**
* @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
* (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
*
* The `auth` argument is optional. If the value passed is non 0, then this function will check that
* `auth` is either the owner of the token, or approved to operate on the token (by the owner).
*
* Emits a {Transfer} event.
*
* NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
*/
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
address from = _ownerOf(tokenId);
// Perform (optional) operator check
if (auth != address(0)) {
_checkAuthorized(from, auth, tokenId);
}
// Execute the update
if (from != address(0)) {
// Clear approval. No need to re-authorize or emit the Approval event
_approve(address(0), tokenId, address(0), false);
unchecked {
_balances[from] -= 1;
}
}
if (to != address(0)) {
unchecked {
_balances[to] += 1;
}
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
return from;
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner != address(0)) {
revert ERC721InvalidSender(address(0));
}
}
/**
* @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
_mint(to, tokenId);
_checkOnERC721Received(address(0), to, tokenId, data);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
* This is an internal function that does not check if the sender is authorized to operate on the token.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal {
address previousOwner = _update(address(0), tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(address from, address to, uint256 tokenId) internal {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
* are aware of the ERC721 standard to prevent tokens from being forever locked.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is like {safeTransferFrom} in the sense that it invokes
* {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `tokenId` token must exist and be owned by `from`.
* - `to` cannot be the zero address.
* - `from` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(address from, address to, uint256 tokenId) internal {
_safeTransfer(from, to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
_transfer(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
* either the owner of the token, or approved to operate on all tokens held by this owner.
*
* Emits an {Approval} event.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address to, uint256 tokenId, address auth) internal {
_approve(to, tokenId, auth, true);
}
/**
* @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not
* emitted in the context of transfers.
*/
function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
// Avoid reading the owner unless necessary
if (emitEvent || auth != address(0)) {
address owner = _requireOwned(tokenId);
// We do not use _isAuthorized because single-token approvals should not be able to call approve
if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
revert ERC721InvalidApprover(auth);
}
if (emitEvent) {
emit Approval(owner, to, tokenId);
}
}
_tokenApprovals[tokenId] = to;
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Requirements:
* - operator can't be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC721InvalidOperator(operator);
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
* Returns the owner.
*
* Overrides to ownership logic should be done to {_ownerOf}.
*/
function _requireOwned(uint256 tokenId) internal view returns (address) {
address owner = _ownerOf(tokenId);
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
return owner;
}
/**
* @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the
* recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
*/
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
revert ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC721InvalidReceiver(to);
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableMap.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.
pragma solidity ^0.8.20;
import {EnumerableSet} from "./EnumerableSet.sol";
/**
* @dev Library for managing an enumerable variant of Solidity's
* https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
* type.
*
* Maps have the following properties:
*
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableMap for EnumerableMap.UintToAddressMap;
*
* // Declare a set state variable
* EnumerableMap.UintToAddressMap private myMap;
* }
* ```
*
* The following map types are supported:
*
* - `uint256 -> address` (`UintToAddressMap`) since v3.0.0
* - `address -> uint256` (`AddressToUintMap`) since v4.6.0
* - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0
* - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0
* - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableMap.
* ====
*/
library EnumerableMap {
using EnumerableSet for EnumerableSet.Bytes32Set;
// To implement this library for multiple types with as little code repetition as possible, we write it in
// terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions,
// and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map.
// This means that we can only create new EnumerableMaps for types that fit in bytes32.
/**
* @dev Query for a nonexistent map key.
*/
error EnumerableMapNonexistentKey(bytes32 key);
struct Bytes32ToBytes32Map {
// Storage of keys
EnumerableSet.Bytes32Set _keys;
mapping(bytes32 key => bytes32) _values;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
/**
* @dev Removes a key-value pair from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {
return map._keys.contains(key);
}
/**
* @dev Returns the number of key-value pairs in the map. O(1).
*/
function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {
return map._keys.length();
}
/**
* @dev Returns the key-value pair stored at position `index` in the map. O(1).
*
* Note that there are no guarantees on the ordering of entries inside the
* array, and it may change when more entries are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {
bytes32 key = map._keys.at(index);
return (key, map._values[key]);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {
bytes32 value = map._values[key];
if (value == bytes32(0)) {
return (contains(map, key), bytes32(0));
} else {
return (true, value);
}
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
bytes32 value = map._values[key];
if (value == 0 && !contains(map, key)) {
revert EnumerableMapNonexistentKey(key);
}
return value;
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {
return map._keys.values();
}
// UintToUintMap
struct UintToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {
return set(map._inner, bytes32(key), bytes32(value));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (uint256(key), uint256(value));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {
(bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
return (success, uint256(value));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(key)));
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintToAddressMap
struct UintToAddressMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToAddressMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(get(map._inner, bytes32(key)))));
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressToUintMap
struct AddressToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {
return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(AddressToUintMap storage map, address key) internal returns (bool) {
return remove(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(AddressToUintMap storage map, address key) internal view returns (bool) {
return contains(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(AddressToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (address(uint160(uint256(key))), uint256(value));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {
(bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));
return (success, uint256(value));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(AddressToUintMap storage map, address key) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(AddressToUintMap storage map) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// Bytes32ToUintMap
struct Bytes32ToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {
return set(map._inner, key, bytes32(value));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {
return remove(map._inner, key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {
return contains(map._inner, key);
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(Bytes32ToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {
(bytes32 key, bytes32 value) = at(map._inner, index);
return (key, uint256(value));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {
(bool success, bytes32 value) = tryGet(map._inner, key);
return (success, uint256(value));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {
return uint256(get(map._inner, key));
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {
bytes32[] memory store = keys(map._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
/**
* @dev The `value` string doesn't fit in the specified `length`.
*/
error StringsInsufficientHexLength(uint256 value, uint256 length);
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
* representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.20;
import {IERC721} from "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
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 subtraction of two unsigned integers, with an overflow flag.
*/
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.
*/
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.
*/
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.
*/
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 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 towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (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 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 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.
uint256 twos = denominator & (0 - denominator);
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 (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* 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)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 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) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}{
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IERC721","name":"underlyingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"ERC721UnsupportedToken","type":"error"},{"inputs":[],"name":"MustInitiateStakingFromSelf","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"address","name":"sender","type":"address"}],"name":"TokenNotStakedByAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"},{"indexed":false,"internalType":"address","name":"staker","type":"address"}],"name":"TokenStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"},{"indexed":false,"internalType":"address","name":"staker","type":"address"}],"name":"TokenUnstaked","type":"event"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"StakedTokens","outputs":[{"internalType":"uint256[]","name":"ret","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"TokenData","outputs":[{"components":[{"internalType":"uint256","name":"last_staked","type":"uint256"},{"internalType":"uint256","name":"last_unstaked","type":"uint256"},{"internalType":"address","name":"last_staker","type":"address"}],"internalType":"struct GenesisNFTStaking.StakingData[]","name":"ret","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"staking_data","outputs":[{"internalType":"uint256","name":"last_staked","type":"uint256"},{"internalType":"uint256","name":"last_unstaked","type":"uint256"},{"internalType":"address","name":"last_staker","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a060405234801561000f575f80fd5b50604051611697380380611697833981810160405281019061003191906100da565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610105565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100988261006f565b9050919050565b5f6100a98261008e565b9050919050565b6100b98161009f565b81146100c3575f80fd5b50565b5f815190506100d4816100b0565b92915050565b5f602082840312156100ef576100ee61006b565b5b5f6100fc848285016100c6565b91505092915050565b60805161157a61011d5f395f6105aa015261157a5ff3fe608060405234801561000f575f80fd5b5060043610610086575f3560e01c8063936e59fd11610059578063936e59fd14610138578063983d95ce14610168578063b7354a6a14610198578063d3da6ed5146101ca57610086565b806301ffc9a71461008a578063150b7a02146100ba578063598b8e71146100ea5780636f307dc31461011a575b5f80fd5b6100a4600480360381019061009f9190610d83565b6101fa565b6040516100b19190610dc8565b60405180910390f35b6100d460048036038101906100cf9190610ecf565b610273565b6040516100e19190610f62565b60405180910390f35b61010460048036038101906100ff91906110c3565b6104f6565b6040516101119190610dc8565b60405180910390f35b6101226105a7565b60405161012f9190611165565b60405180910390f35b610152600480360381019061014d91906110c3565b6105ce565b60405161015f9190611284565b60405180910390f35b610182600480360381019061017d91906110c3565b610704565b60405161018f9190610dc8565b60405180910390f35b6101b260048036038101906101ad91906112a4565b6108f3565b6040516101c1939291906112ed565b60405180910390f35b6101e460048036038101906101df9190611322565b610937565b6040516101f191906113f5565b60405180910390f35b5f7f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061026c575061026b82610a58565b5b9050919050565b5f3373ffffffffffffffffffffffffffffffffffffffff166102936105a7565b73ffffffffffffffffffffffffffffffffffffffff16146102eb57336040517fc7d837c60000000000000000000000000000000000000000000000000000000081526004016102e29190611415565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff165f808681526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036103f15760405180606001604052804281526020015f81526020018673ffffffffffffffffffffffffffffffffffffffff168152505f808681526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505061045a565b425f808681526020019081526020015f205f0181905550845f808681526020019081526020015f206002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6104a98460015f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610ac190919063ffffffff16565b507f7d2f41d944235f7c99290ca6f149e25aa6deb5397189be3882b8ddf71c51bbec84866040516104db92919061142e565b60405180910390a163150b7a0260e01b905095945050505050565b5f80825190505f5b8181101561059c5761050e6105a7565b73ffffffffffffffffffffffffffffffffffffffff166342842e0e333087858151811061053e5761053d611455565b5b60200260200101516040518463ffffffff1660e01b815260040161056493929190611482565b5f604051808303815f87803b15801561057b575f80fd5b505af115801561058d573d5f803e3d5ffd5b505050508060010190506104fe565b506001915050919050565b5f7f0000000000000000000000000000000000000000000000000000000000000000905090565b60605f825190508067ffffffffffffffff8111156105ef576105ee610f8b565b5b60405190808252806020026020018201604052801561062857816020015b610615610ce9565b81526020019060019003908161060d5790505b5091505f5b818110156106fd575f8085838151811061064a57610649611455565b5b602002602001015181526020019081526020015f206040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508382815181106106e5576106e4611455565b5b6020026020010181905250808060010191505061062d565b5050919050565b5f80825190505f5b818110156108e8575f84828151811061072857610727611455565b5b602002602001015190506107818160015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610ad890919063ffffffff16565b1561089d57425f808381526020019081526020015f20600101819055506107ed8160015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610aef90919063ffffffff16565b507f0bd399ae365ab45a4803bca8e95718b4f1ff0915b48493d790b2525603c0a092813360405161081f92919061142e565b60405180910390a161082f6105a7565b73ffffffffffffffffffffffffffffffffffffffff166342842e0e3033846040518463ffffffff1660e01b815260040161086b93929190611482565b5f604051808303815f87803b158015610882575f80fd5b505af1158015610894573d5f803e3d5ffd5b505050506108dc565b80336040517f7d5dad430000000000000000000000000000000000000000000000000000000081526004016108d392919061142e565b60405180910390fd5b5080600101905061070c565b506001915050919050565b5f602052805f5260405f205f91509050805f015490806001015490806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60605f61097f60015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610b06565b90508067ffffffffffffffff81111561099b5761099a610f8b565b5b6040519080825280602002602001820160405280156109c95781602001602082028036833780820191505090505b5091505f5b81811015610a5157610a258160015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610b1990919063ffffffff16565b838281518110610a3857610a37611455565b5b60200260200101818152505080806001019150506109ce565b5050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f610ad0835f01835f1b610b30565b905092915050565b5f610ae7835f01835f1b610b97565b905092915050565b5f610afe835f01835f1b610bb7565b905092915050565b5f610b12825f01610cb3565b9050919050565b5f610b26835f0183610cc2565b5f1c905092915050565b5f610b3b8383610b97565b610b8d57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f208190555060019050610b91565b5f90505b92915050565b5f80836001015f8481526020019081526020015f20541415905092915050565b5f80836001015f8481526020019081526020015f205490505f8114610ca8575f600182610be491906114e4565b90505f6001865f0180549050610bfa91906114e4565b9050808214610c60575f865f018281548110610c1957610c18611455565b5b905f5260205f200154905080875f018481548110610c3a57610c39611455565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f01805480610c7357610c72611517565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610cad565b5f9150505b92915050565b5f815f01805490509050919050565b5f825f018281548110610cd857610cd7611455565b5b905f5260205f200154905092915050565b60405180606001604052805f81526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681525090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610d6281610d2e565b8114610d6c575f80fd5b50565b5f81359050610d7d81610d59565b92915050565b5f60208284031215610d9857610d97610d26565b5b5f610da584828501610d6f565b91505092915050565b5f8115159050919050565b610dc281610dae565b82525050565b5f602082019050610ddb5f830184610db9565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e0a82610de1565b9050919050565b610e1a81610e00565b8114610e24575f80fd5b50565b5f81359050610e3581610e11565b92915050565b5f819050919050565b610e4d81610e3b565b8114610e57575f80fd5b50565b5f81359050610e6881610e44565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112610e8f57610e8e610e6e565b5b8235905067ffffffffffffffff811115610eac57610eab610e72565b5b602083019150836001820283011115610ec857610ec7610e76565b5b9250929050565b5f805f805f60808688031215610ee857610ee7610d26565b5b5f610ef588828901610e27565b9550506020610f0688828901610e27565b9450506040610f1788828901610e5a565b935050606086013567ffffffffffffffff811115610f3857610f37610d2a565b5b610f4488828901610e7a565b92509250509295509295909350565b610f5c81610d2e565b82525050565b5f602082019050610f755f830184610f53565b92915050565b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610fc182610f7b565b810181811067ffffffffffffffff82111715610fe057610fdf610f8b565b5b80604052505050565b5f610ff2610d1d565b9050610ffe8282610fb8565b919050565b5f67ffffffffffffffff82111561101d5761101c610f8b565b5b602082029050602081019050919050565b5f61104061103b84611003565b610fe9565b9050808382526020820190506020840283018581111561106357611062610e76565b5b835b8181101561108c57806110788882610e5a565b845260208401935050602081019050611065565b5050509392505050565b5f82601f8301126110aa576110a9610e6e565b5b81356110ba84826020860161102e565b91505092915050565b5f602082840312156110d8576110d7610d26565b5b5f82013567ffffffffffffffff8111156110f5576110f4610d2a565b5b61110184828501611096565b91505092915050565b5f819050919050565b5f61112d61112861112384610de1565b61110a565b610de1565b9050919050565b5f61113e82611113565b9050919050565b5f61114f82611134565b9050919050565b61115f81611145565b82525050565b5f6020820190506111785f830184611156565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6111b081610e3b565b82525050565b6111bf81610e00565b82525050565b606082015f8201516111d95f8501826111a7565b5060208201516111ec60208501826111a7565b5060408201516111ff60408501826111b6565b50505050565b5f61121083836111c5565b60608301905092915050565b5f602082019050919050565b5f6112328261117e565b61123c8185611188565b935061124783611198565b805f5b8381101561127757815161125e8882611205565b97506112698361121c565b92505060018101905061124a565b5085935050505092915050565b5f6020820190508181035f83015261129c8184611228565b905092915050565b5f602082840312156112b9576112b8610d26565b5b5f6112c684828501610e5a565b91505092915050565b6112d881610e3b565b82525050565b6112e781610e00565b82525050565b5f6060820190506113005f8301866112cf565b61130d60208301856112cf565b61131a60408301846112de565b949350505050565b5f6020828403121561133757611336610d26565b5b5f61134484828501610e27565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61138183836111a7565b60208301905092915050565b5f602082019050919050565b5f6113a38261134d565b6113ad8185611357565b93506113b883611367565b805f5b838110156113e85781516113cf8882611376565b97506113da8361138d565b9250506001810190506113bb565b5085935050505092915050565b5f6020820190508181035f83015261140d8184611399565b905092915050565b5f6020820190506114285f8301846112de565b92915050565b5f6040820190506114415f8301856112cf565b61144e60208301846112de565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6060820190506114955f8301866112de565b6114a260208301856112de565b6114af60408301846112cf565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6114ee82610e3b565b91506114f983610e3b565b9250828203905081811115611511576115106114b7565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212206fa4291ef513a23c408a2fc23ea8af3ecbab212a6c1c9a90d0488140aa6f598464736f6c63430008190033000000000000000000000000c71a0306a0a628c616dac42097bdc21ecdbc5d9d
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610086575f3560e01c8063936e59fd11610059578063936e59fd14610138578063983d95ce14610168578063b7354a6a14610198578063d3da6ed5146101ca57610086565b806301ffc9a71461008a578063150b7a02146100ba578063598b8e71146100ea5780636f307dc31461011a575b5f80fd5b6100a4600480360381019061009f9190610d83565b6101fa565b6040516100b19190610dc8565b60405180910390f35b6100d460048036038101906100cf9190610ecf565b610273565b6040516100e19190610f62565b60405180910390f35b61010460048036038101906100ff91906110c3565b6104f6565b6040516101119190610dc8565b60405180910390f35b6101226105a7565b60405161012f9190611165565b60405180910390f35b610152600480360381019061014d91906110c3565b6105ce565b60405161015f9190611284565b60405180910390f35b610182600480360381019061017d91906110c3565b610704565b60405161018f9190610dc8565b60405180910390f35b6101b260048036038101906101ad91906112a4565b6108f3565b6040516101c1939291906112ed565b60405180910390f35b6101e460048036038101906101df9190611322565b610937565b6040516101f191906113f5565b60405180910390f35b5f7f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061026c575061026b82610a58565b5b9050919050565b5f3373ffffffffffffffffffffffffffffffffffffffff166102936105a7565b73ffffffffffffffffffffffffffffffffffffffff16146102eb57336040517fc7d837c60000000000000000000000000000000000000000000000000000000081526004016102e29190611415565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff165f808681526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036103f15760405180606001604052804281526020015f81526020018673ffffffffffffffffffffffffffffffffffffffff168152505f808681526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505061045a565b425f808681526020019081526020015f205f0181905550845f808681526020019081526020015f206002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6104a98460015f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610ac190919063ffffffff16565b507f7d2f41d944235f7c99290ca6f149e25aa6deb5397189be3882b8ddf71c51bbec84866040516104db92919061142e565b60405180910390a163150b7a0260e01b905095945050505050565b5f80825190505f5b8181101561059c5761050e6105a7565b73ffffffffffffffffffffffffffffffffffffffff166342842e0e333087858151811061053e5761053d611455565b5b60200260200101516040518463ffffffff1660e01b815260040161056493929190611482565b5f604051808303815f87803b15801561057b575f80fd5b505af115801561058d573d5f803e3d5ffd5b505050508060010190506104fe565b506001915050919050565b5f7f000000000000000000000000c71a0306a0a628c616dac42097bdc21ecdbc5d9d905090565b60605f825190508067ffffffffffffffff8111156105ef576105ee610f8b565b5b60405190808252806020026020018201604052801561062857816020015b610615610ce9565b81526020019060019003908161060d5790505b5091505f5b818110156106fd575f8085838151811061064a57610649611455565b5b602002602001015181526020019081526020015f206040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508382815181106106e5576106e4611455565b5b6020026020010181905250808060010191505061062d565b5050919050565b5f80825190505f5b818110156108e8575f84828151811061072857610727611455565b5b602002602001015190506107818160015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610ad890919063ffffffff16565b1561089d57425f808381526020019081526020015f20600101819055506107ed8160015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610aef90919063ffffffff16565b507f0bd399ae365ab45a4803bca8e95718b4f1ff0915b48493d790b2525603c0a092813360405161081f92919061142e565b60405180910390a161082f6105a7565b73ffffffffffffffffffffffffffffffffffffffff166342842e0e3033846040518463ffffffff1660e01b815260040161086b93929190611482565b5f604051808303815f87803b158015610882575f80fd5b505af1158015610894573d5f803e3d5ffd5b505050506108dc565b80336040517f7d5dad430000000000000000000000000000000000000000000000000000000081526004016108d392919061142e565b60405180910390fd5b5080600101905061070c565b506001915050919050565b5f602052805f5260405f205f91509050805f015490806001015490806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60605f61097f60015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610b06565b90508067ffffffffffffffff81111561099b5761099a610f8b565b5b6040519080825280602002602001820160405280156109c95781602001602082028036833780820191505090505b5091505f5b81811015610a5157610a258160015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20610b1990919063ffffffff16565b838281518110610a3857610a37611455565b5b60200260200101818152505080806001019150506109ce565b5050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f610ad0835f01835f1b610b30565b905092915050565b5f610ae7835f01835f1b610b97565b905092915050565b5f610afe835f01835f1b610bb7565b905092915050565b5f610b12825f01610cb3565b9050919050565b5f610b26835f0183610cc2565b5f1c905092915050565b5f610b3b8383610b97565b610b8d57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f208190555060019050610b91565b5f90505b92915050565b5f80836001015f8481526020019081526020015f20541415905092915050565b5f80836001015f8481526020019081526020015f205490505f8114610ca8575f600182610be491906114e4565b90505f6001865f0180549050610bfa91906114e4565b9050808214610c60575f865f018281548110610c1957610c18611455565b5b905f5260205f200154905080875f018481548110610c3a57610c39611455565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f01805480610c7357610c72611517565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610cad565b5f9150505b92915050565b5f815f01805490509050919050565b5f825f018281548110610cd857610cd7611455565b5b905f5260205f200154905092915050565b60405180606001604052805f81526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681525090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610d6281610d2e565b8114610d6c575f80fd5b50565b5f81359050610d7d81610d59565b92915050565b5f60208284031215610d9857610d97610d26565b5b5f610da584828501610d6f565b91505092915050565b5f8115159050919050565b610dc281610dae565b82525050565b5f602082019050610ddb5f830184610db9565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e0a82610de1565b9050919050565b610e1a81610e00565b8114610e24575f80fd5b50565b5f81359050610e3581610e11565b92915050565b5f819050919050565b610e4d81610e3b565b8114610e57575f80fd5b50565b5f81359050610e6881610e44565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112610e8f57610e8e610e6e565b5b8235905067ffffffffffffffff811115610eac57610eab610e72565b5b602083019150836001820283011115610ec857610ec7610e76565b5b9250929050565b5f805f805f60808688031215610ee857610ee7610d26565b5b5f610ef588828901610e27565b9550506020610f0688828901610e27565b9450506040610f1788828901610e5a565b935050606086013567ffffffffffffffff811115610f3857610f37610d2a565b5b610f4488828901610e7a565b92509250509295509295909350565b610f5c81610d2e565b82525050565b5f602082019050610f755f830184610f53565b92915050565b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610fc182610f7b565b810181811067ffffffffffffffff82111715610fe057610fdf610f8b565b5b80604052505050565b5f610ff2610d1d565b9050610ffe8282610fb8565b919050565b5f67ffffffffffffffff82111561101d5761101c610f8b565b5b602082029050602081019050919050565b5f61104061103b84611003565b610fe9565b9050808382526020820190506020840283018581111561106357611062610e76565b5b835b8181101561108c57806110788882610e5a565b845260208401935050602081019050611065565b5050509392505050565b5f82601f8301126110aa576110a9610e6e565b5b81356110ba84826020860161102e565b91505092915050565b5f602082840312156110d8576110d7610d26565b5b5f82013567ffffffffffffffff8111156110f5576110f4610d2a565b5b61110184828501611096565b91505092915050565b5f819050919050565b5f61112d61112861112384610de1565b61110a565b610de1565b9050919050565b5f61113e82611113565b9050919050565b5f61114f82611134565b9050919050565b61115f81611145565b82525050565b5f6020820190506111785f830184611156565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6111b081610e3b565b82525050565b6111bf81610e00565b82525050565b606082015f8201516111d95f8501826111a7565b5060208201516111ec60208501826111a7565b5060408201516111ff60408501826111b6565b50505050565b5f61121083836111c5565b60608301905092915050565b5f602082019050919050565b5f6112328261117e565b61123c8185611188565b935061124783611198565b805f5b8381101561127757815161125e8882611205565b97506112698361121c565b92505060018101905061124a565b5085935050505092915050565b5f6020820190508181035f83015261129c8184611228565b905092915050565b5f602082840312156112b9576112b8610d26565b5b5f6112c684828501610e5a565b91505092915050565b6112d881610e3b565b82525050565b6112e781610e00565b82525050565b5f6060820190506113005f8301866112cf565b61130d60208301856112cf565b61131a60408301846112de565b949350505050565b5f6020828403121561133757611336610d26565b5b5f61134484828501610e27565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f61138183836111a7565b60208301905092915050565b5f602082019050919050565b5f6113a38261134d565b6113ad8185611357565b93506113b883611367565b805f5b838110156113e85781516113cf8882611376565b97506113da8361138d565b9250506001810190506113bb565b5085935050505092915050565b5f6020820190508181035f83015261140d8184611399565b905092915050565b5f6020820190506114285f8301846112de565b92915050565b5f6040820190506114415f8301856112cf565b61144e60208301846112de565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6060820190506114955f8301866112de565b6114a260208301856112de565b6114af60408301846112cf565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6114ee82610e3b565b91506114f983610e3b565b9250828203905081811115611511576115106114b7565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212206fa4291ef513a23c408a2fc23ea8af3ecbab212a6c1c9a90d0488140aa6f598464736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c71a0306a0a628c616dac42097bdc21ecdbc5d9d
-----Decoded View---------------
Arg [0] : underlyingToken (address): 0xC71a0306a0A628C616DAC42097bDc21EcDBc5d9d
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000c71a0306a0a628c616dac42097bdc21ecdbc5d9d
Deployed Bytecode Sourcemap
755:4203:13:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1574:235;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4102:695;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1815:284;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4861:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3307:284;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2105:683;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1031:51;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;2909:285;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1574:235;1667:4;1717:33;1702:48;;;:11;:48;;;;:100;;;;1766:36;1790:11;1766:23;:36::i;:::-;1702:100;1683:119;;1574:235;;;:::o;4102:695::-;4240:6;4287:10;4262:35;;4270:12;:10;:12::i;:::-;4262:35;;;4258:107;;4343:10;4320:34;;;;;;;;;;;:::i;:::-;;;;;;;;4258:107;4423:1;4378:47;;:12;:21;4391:7;4378:21;;;;;;;;;;;:33;;;;;;;;;;;;:47;;;4374:275;;4465:37;;;;;;;;4477:15;4465:37;;;;4494:1;4465:37;;;;4497:4;4465:37;;;;;4441:12;:21;4454:7;4441:21;;;;;;;;;;;:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4374:275;;;4569:15;4533:12;:21;4546:7;4533:21;;;;;;;;;;;:33;;:51;;;;4634:4;4598:12;:21;4611:7;4598:21;;;;;;;;;;;:33;;;:40;;;;;;;;;;;;;;;;;;4374:275;4659:32;4683:7;4659:13;:19;4673:4;4659:19;;;;;;;;;;;;;;;:23;;:32;;;;:::i;:::-;;4706:26;4718:7;4727:4;4706:26;;;;;;;:::i;:::-;;;;;;;;4749:41;;;4742:48;;4102:695;;;;;;;:::o;1815:284::-;1883:4;1899:14;1916:8;:15;1899:32;;1946:9;1941:131;1965:6;1961:1;:10;1941:131;;;1992:12;:10;:12::i;:::-;:29;;;2022:10;2042:4;2049:8;2058:1;2049:11;;;;;;;;:::i;:::-;;;;;;;;1992:69;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1973:3;;;;;1941:131;;;;2088:4;2081:11;;;1815:284;;;:::o;4861:95::-;4912:7;4938:11;4931:18;;4861:95;:::o;3307:284::-;3374:24;3410:14;3427:8;:15;3410:32;;3476:6;3458:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;3452:31;;3497:6;3493:92;3513:6;3509:1;:10;3493:92;;;3549:12;:25;3562:8;3571:1;3562:11;;;;;;;;:::i;:::-;;;;;;;;3549:25;;;;;;;;;;;3540:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:3;3544:1;3540:6;;;;;;;;:::i;:::-;;;;;;;:34;;;;3521:3;;;;;;;3493:92;;;;3400:191;3307:284;;;:::o;2105:683::-;2174:4;2190:14;2207:8;:15;2190:32;;2237:9;2232:528;2256:6;2252:1;:10;2232:528;;;2283:15;2301:8;2310:1;2301:11;;;;;;;;:::i;:::-;;;;;;;;2283:29;;2330:43;2365:7;2330:13;:25;2344:10;2330:25;;;;;;;;;;;;;;;:34;;:43;;;;:::i;:::-;2326:424;;;2431:15;2393:12;:21;2406:7;2393:21;;;;;;;;;;;:35;;:53;;;;2464:41;2497:7;2464:13;:25;2478:10;2464:25;;;;;;;;;;;;;;;:32;;:41;;;;:::i;:::-;;2528:34;2542:7;2551:10;2528:34;;;;;;;:::i;:::-;;;;;;;;2580:12;:10;:12::i;:::-;:29;;;2618:4;2625:10;2637:7;2580:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2326:424;;;2715:7;2724:10;2691:44;;;;;;;;;;;;:::i;:::-;;;;;;;;2326:424;2269:491;2264:3;;;;;2232:528;;;;2777:4;2770:11;;;2105:683;;;:::o;1031:51::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2909:285::-;2968:20;3000:14;3017:30;:13;:21;3031:6;3017:21;;;;;;;;;;;;;;;:28;:30::i;:::-;3000:47;;3077:6;3063:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3057:27;;3098:6;3094:94;3114:6;3110:1;:10;3094:94;;;3150:27;3175:1;3150:13;:21;3164:6;3150:21;;;;;;;;;;;;;;;:24;;:27;;;;:::i;:::-;3141:3;3145:1;3141:6;;;;;;;;:::i;:::-;;;;;;;:36;;;;;3122:3;;;;;;;3094:94;;;;2990:204;2909:285;;;:::o;762:146:7:-;838:4;876:25;861:40;;;:11;:40;;;;854:47;;762:146;;;:::o;10804:129:12:-;10871:4;10894:32;10899:3;:10;;10919:5;10911:14;;10894:4;:32::i;:::-;10887:39;;10804:129;;;;:::o;11317:144::-;11394:4;11417:37;11427:3;:10;;11447:5;11439:14;;11417:9;:37::i;:::-;11410:44;;11317:144;;;;:::o;11101:135::-;11171:4;11194:35;11202:3;:10;;11222:5;11214:14;;11194:7;:35::i;:::-;11187:42;;11101:135;;;;:::o;11542:112::-;11602:7;11628:19;11636:3;:10;;11628:7;:19::i;:::-;11621:26;;11542:112;;;:::o;11996:135::-;12067:7;12101:22;12105:3;:10;;12117:5;12101:3;:22::i;:::-;12093:31;;12086:38;;11996:135;;;;:::o;2241:406::-;2304:4;2325:21;2335:3;2340:5;2325:9;:21::i;:::-;2320:321;;2362:3;:11;;2379:5;2362:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2544:3;:11;;:18;;;;2520:3;:14;;:21;2535:5;2520:21;;;;;;;;;;;:42;;;;2583:4;2576:11;;;;2320:321;2625:5;2618:12;;2241:406;;;;;:::o;4264:129::-;4337:4;4385:1;4360:3;:14;;:21;4375:5;4360:21;;;;;;;;;;;;:26;;4353:33;;4264:129;;;;:::o;2815:1368::-;2881:4;2991:16;3010:3;:14;;:21;3025:5;3010:21;;;;;;;;;;;;2991:40;;3058:1;3046:8;:13;3042:1135;;3413:18;3445:1;3434:8;:12;;;;:::i;:::-;3413:33;;3460:17;3501:1;3480:3;:11;;:18;;;;:22;;;;:::i;:::-;3460:42;;3535:9;3521:10;:23;3517:378;;3564:17;3584:3;:11;;3596:9;3584:22;;;;;;;;:::i;:::-;;;;;;;;;;3564:42;;3731:9;3705:3;:11;;3717:10;3705:23;;;;;;;;:::i;:::-;;;;;;;;;:35;;;;3872:8;3844:3;:14;;:25;3859:9;3844:25;;;;;;;;;;;:36;;;;3546:349;3517:378;3973:3;:11;;:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4076:3;:14;;:21;4091:5;4076:21;;;;;;;;;;;4069:28;;;4119:4;4112:11;;;;;;;3042:1135;4161:5;4154:12;;;2815:1368;;;;;:::o;4474:107::-;4530:7;4556:3;:11;;:18;;;;4549:25;;4474:107;;;:::o;4923:118::-;4990:7;5016:3;:11;;5028:5;5016:18;;;;;;;;:::i;:::-;;;;;;;;;;5009:25;;4923:118;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:14:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:126::-;1555:7;1595:42;1588:5;1584:54;1573:65;;1518:126;;;:::o;1650:96::-;1687:7;1716:24;1734:5;1716:24;:::i;:::-;1705:35;;1650:96;;;:::o;1752:122::-;1825:24;1843:5;1825:24;:::i;:::-;1818:5;1815:35;1805:63;;1864:1;1861;1854:12;1805:63;1752:122;:::o;1880:139::-;1926:5;1964:6;1951:20;1942:29;;1980:33;2007:5;1980:33;:::i;:::-;1880:139;;;;:::o;2025:77::-;2062:7;2091:5;2080:16;;2025:77;;;:::o;2108:122::-;2181:24;2199:5;2181:24;:::i;:::-;2174:5;2171:35;2161:63;;2220:1;2217;2210:12;2161:63;2108:122;:::o;2236:139::-;2282:5;2320:6;2307:20;2298:29;;2336:33;2363:5;2336:33;:::i;:::-;2236:139;;;;:::o;2381:117::-;2490:1;2487;2480:12;2504:117;2613:1;2610;2603:12;2627:117;2736:1;2733;2726:12;2763:552;2820:8;2830:6;2880:3;2873:4;2865:6;2861:17;2857:27;2847:122;;2888:79;;:::i;:::-;2847:122;3001:6;2988:20;2978:30;;3031:18;3023:6;3020:30;3017:117;;;3053:79;;:::i;:::-;3017:117;3167:4;3159:6;3155:17;3143:29;;3221:3;3213:4;3205:6;3201:17;3191:8;3187:32;3184:41;3181:128;;;3228:79;;:::i;:::-;3181:128;2763:552;;;;;:::o;3321:963::-;3418:6;3426;3434;3442;3450;3499:3;3487:9;3478:7;3474:23;3470:33;3467:120;;;3506:79;;:::i;:::-;3467:120;3626:1;3651:53;3696:7;3687:6;3676:9;3672:22;3651:53;:::i;:::-;3641:63;;3597:117;3753:2;3779:53;3824:7;3815:6;3804:9;3800:22;3779:53;:::i;:::-;3769:63;;3724:118;3881:2;3907:53;3952:7;3943:6;3932:9;3928:22;3907:53;:::i;:::-;3897:63;;3852:118;4037:2;4026:9;4022:18;4009:32;4068:18;4060:6;4057:30;4054:117;;;4090:79;;:::i;:::-;4054:117;4203:64;4259:7;4250:6;4239:9;4235:22;4203:64;:::i;:::-;4185:82;;;;3980:297;3321:963;;;;;;;;:::o;4290:115::-;4375:23;4392:5;4375:23;:::i;:::-;4370:3;4363:36;4290:115;;:::o;4411:218::-;4502:4;4540:2;4529:9;4525:18;4517:26;;4553:69;4619:1;4608:9;4604:17;4595:6;4553:69;:::i;:::-;4411:218;;;;:::o;4635:102::-;4676:6;4727:2;4723:7;4718:2;4711:5;4707:14;4703:28;4693:38;;4635:102;;;:::o;4743:180::-;4791:77;4788:1;4781:88;4888:4;4885:1;4878:15;4912:4;4909:1;4902:15;4929:281;5012:27;5034:4;5012:27;:::i;:::-;5004:6;5000:40;5142:6;5130:10;5127:22;5106:18;5094:10;5091:34;5088:62;5085:88;;;5153:18;;:::i;:::-;5085:88;5193:10;5189:2;5182:22;4972:238;4929:281;;:::o;5216:129::-;5250:6;5277:20;;:::i;:::-;5267:30;;5306:33;5334:4;5326:6;5306:33;:::i;:::-;5216:129;;;:::o;5351:311::-;5428:4;5518:18;5510:6;5507:30;5504:56;;;5540:18;;:::i;:::-;5504:56;5590:4;5582:6;5578:17;5570:25;;5650:4;5644;5640:15;5632:23;;5351:311;;;:::o;5685:710::-;5781:5;5806:81;5822:64;5879:6;5822:64;:::i;:::-;5806:81;:::i;:::-;5797:90;;5907:5;5936:6;5929:5;5922:21;5970:4;5963:5;5959:16;5952:23;;6023:4;6015:6;6011:17;6003:6;5999:30;6052:3;6044:6;6041:15;6038:122;;;6071:79;;:::i;:::-;6038:122;6186:6;6169:220;6203:6;6198:3;6195:15;6169:220;;;6278:3;6307:37;6340:3;6328:10;6307:37;:::i;:::-;6302:3;6295:50;6374:4;6369:3;6365:14;6358:21;;6245:144;6229:4;6224:3;6220:14;6213:21;;6169:220;;;6173:21;5787:608;;5685:710;;;;;:::o;6418:370::-;6489:5;6538:3;6531:4;6523:6;6519:17;6515:27;6505:122;;6546:79;;:::i;:::-;6505:122;6663:6;6650:20;6688:94;6778:3;6770:6;6763:4;6755:6;6751:17;6688:94;:::i;:::-;6679:103;;6495:293;6418:370;;;;:::o;6794:539::-;6878:6;6927:2;6915:9;6906:7;6902:23;6898:32;6895:119;;;6933:79;;:::i;:::-;6895:119;7081:1;7070:9;7066:17;7053:31;7111:18;7103:6;7100:30;7097:117;;;7133:79;;:::i;:::-;7097:117;7238:78;7308:7;7299:6;7288:9;7284:22;7238:78;:::i;:::-;7228:88;;7024:302;6794:539;;;;:::o;7339:60::-;7367:3;7388:5;7381:12;;7339:60;;;:::o;7405:142::-;7455:9;7488:53;7506:34;7515:24;7533:5;7515:24;:::i;:::-;7506:34;:::i;:::-;7488:53;:::i;:::-;7475:66;;7405:142;;;:::o;7553:126::-;7603:9;7636:37;7667:5;7636:37;:::i;:::-;7623:50;;7553:126;;;:::o;7685:142::-;7751:9;7784:37;7815:5;7784:37;:::i;:::-;7771:50;;7685:142;;;:::o;7833:163::-;7936:53;7983:5;7936:53;:::i;:::-;7931:3;7924:66;7833:163;;:::o;8002:254::-;8111:4;8149:2;8138:9;8134:18;8126:26;;8162:87;8246:1;8235:9;8231:17;8222:6;8162:87;:::i;:::-;8002:254;;;;:::o;8262:143::-;8358:6;8392:5;8386:12;8376:22;;8262:143;;;:::o;8411:213::-;8539:11;8573:6;8568:3;8561:19;8613:4;8608:3;8604:14;8589:29;;8411:213;;;;:::o;8630:161::-;8726:4;8749:3;8741:11;;8779:4;8774:3;8770:14;8762:22;;8630:161;;;:::o;8797:108::-;8874:24;8892:5;8874:24;:::i;:::-;8869:3;8862:37;8797:108;;:::o;8911:::-;8988:24;9006:5;8988:24;:::i;:::-;8983:3;8976:37;8911:108;;:::o;9109:702::-;9254:4;9249:3;9245:14;9348:4;9341:5;9337:16;9331:23;9367:63;9424:4;9419:3;9415:14;9401:12;9367:63;:::i;:::-;9269:171;9531:4;9524:5;9520:16;9514:23;9550:63;9607:4;9602:3;9598:14;9584:12;9550:63;:::i;:::-;9450:173;9712:4;9705:5;9701:16;9695:23;9731:63;9788:4;9783:3;9779:14;9765:12;9731:63;:::i;:::-;9633:171;9223:588;9109:702;;:::o;9817:295::-;9944:10;9965:104;10065:3;10057:6;9965:104;:::i;:::-;10101:4;10096:3;10092:14;10078:28;;9817:295;;;;:::o;10118:142::-;10217:4;10249;10244:3;10240:14;10232:22;;10118:142;;;:::o;10354:964::-;10531:3;10560:83;10637:5;10560:83;:::i;:::-;10659:115;10767:6;10762:3;10659:115;:::i;:::-;10652:122;;10798:85;10877:5;10798:85;:::i;:::-;10906:7;10937:1;10922:371;10947:6;10944:1;10941:13;10922:371;;;11023:6;11017:13;11050:121;11167:3;11152:13;11050:121;:::i;:::-;11043:128;;11194:89;11276:6;11194:89;:::i;:::-;11184:99;;10982:311;10969:1;10966;10962:9;10957:14;;10922:371;;;10926:14;11309:3;11302:10;;10536:782;;;10354:964;;;;:::o;11324:489::-;11525:4;11563:2;11552:9;11548:18;11540:26;;11612:9;11606:4;11602:20;11598:1;11587:9;11583:17;11576:47;11640:166;11801:4;11792:6;11640:166;:::i;:::-;11632:174;;11324:489;;;;:::o;11819:329::-;11878:6;11927:2;11915:9;11906:7;11902:23;11898:32;11895:119;;;11933:79;;:::i;:::-;11895:119;12053:1;12078:53;12123:7;12114:6;12103:9;12099:22;12078:53;:::i;:::-;12068:63;;12024:117;11819:329;;;;:::o;12154:118::-;12241:24;12259:5;12241:24;:::i;:::-;12236:3;12229:37;12154:118;;:::o;12278:::-;12365:24;12383:5;12365:24;:::i;:::-;12360:3;12353:37;12278:118;;:::o;12402:442::-;12551:4;12589:2;12578:9;12574:18;12566:26;;12602:71;12670:1;12659:9;12655:17;12646:6;12602:71;:::i;:::-;12683:72;12751:2;12740:9;12736:18;12727:6;12683:72;:::i;:::-;12765;12833:2;12822:9;12818:18;12809:6;12765:72;:::i;:::-;12402:442;;;;;;:::o;12850:329::-;12909:6;12958:2;12946:9;12937:7;12933:23;12929:32;12926:119;;;12964:79;;:::i;:::-;12926:119;13084:1;13109:53;13154:7;13145:6;13134:9;13130:22;13109:53;:::i;:::-;13099:63;;13055:117;12850:329;;;;:::o;13185:114::-;13252:6;13286:5;13280:12;13270:22;;13185:114;;;:::o;13305:184::-;13404:11;13438:6;13433:3;13426:19;13478:4;13473:3;13469:14;13454:29;;13305:184;;;;:::o;13495:132::-;13562:4;13585:3;13577:11;;13615:4;13610:3;13606:14;13598:22;;13495:132;;;:::o;13633:179::-;13702:10;13723:46;13765:3;13757:6;13723:46;:::i;:::-;13801:4;13796:3;13792:14;13778:28;;13633:179;;;;:::o;13818:113::-;13888:4;13920;13915:3;13911:14;13903:22;;13818:113;;;:::o;13967:732::-;14086:3;14115:54;14163:5;14115:54;:::i;:::-;14185:86;14264:6;14259:3;14185:86;:::i;:::-;14178:93;;14295:56;14345:5;14295:56;:::i;:::-;14374:7;14405:1;14390:284;14415:6;14412:1;14409:13;14390:284;;;14491:6;14485:13;14518:63;14577:3;14562:13;14518:63;:::i;:::-;14511:70;;14604:60;14657:6;14604:60;:::i;:::-;14594:70;;14450:224;14437:1;14434;14430:9;14425:14;;14390:284;;;14394:14;14690:3;14683:10;;14091:608;;;13967:732;;;;:::o;14705:373::-;14848:4;14886:2;14875:9;14871:18;14863:26;;14935:9;14929:4;14925:20;14921:1;14910:9;14906:17;14899:47;14963:108;15066:4;15057:6;14963:108;:::i;:::-;14955:116;;14705:373;;;;:::o;15084:222::-;15177:4;15215:2;15204:9;15200:18;15192:26;;15228:71;15296:1;15285:9;15281:17;15272:6;15228:71;:::i;:::-;15084:222;;;;:::o;15312:332::-;15433:4;15471:2;15460:9;15456:18;15448:26;;15484:71;15552:1;15541:9;15537:17;15528:6;15484:71;:::i;:::-;15565:72;15633:2;15622:9;15618:18;15609:6;15565:72;:::i;:::-;15312:332;;;;;:::o;15650:180::-;15698:77;15695:1;15688:88;15795:4;15792:1;15785:15;15819:4;15816:1;15809:15;15836:442;15985:4;16023:2;16012:9;16008:18;16000:26;;16036:71;16104:1;16093:9;16089:17;16080:6;16036:71;:::i;:::-;16117:72;16185:2;16174:9;16170:18;16161:6;16117:72;:::i;:::-;16199;16267:2;16256:9;16252:18;16243:6;16199:72;:::i;:::-;15836:442;;;;;;:::o;16284:180::-;16332:77;16329:1;16322:88;16429:4;16426:1;16419:15;16453:4;16450:1;16443:15;16470:194;16510:4;16530:20;16548:1;16530:20;:::i;:::-;16525:25;;16564:20;16582:1;16564:20;:::i;:::-;16559:25;;16608:1;16605;16601:9;16593:17;;16632:1;16626:4;16623:11;16620:37;;;16637:18;;:::i;:::-;16620:37;16470:194;;;;:::o;16670:180::-;16718:77;16715:1;16708:88;16815:4;16812:1;16805:15;16839:4;16836:1;16829:15
Swarm Source
ipfs://6fa4291ef513a23c408a2fc23ea8af3ecbab212a6c1c9a90d0488140aa6f5984
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.