ETH Price: $2,369.01 (-3.83%)

Contract

0xF4d150F3D03Fa1912aad168050694f0fA0e44532
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Safe Withdraw207467402024-09-14 5:23:3518 days ago1726291415IN
0xF4d150F3...fA0e44532
0 ETH0.0002522.01776252
Safe Withdraw206184892024-08-27 7:40:5936 days ago1724744459IN
0xF4d150F3...fA0e44532
0 ETH0.000135321.07392345
Safe Withdraw195568212024-03-31 22:25:47185 days ago1711923947IN
0xF4d150F3...fA0e44532
0 ETH0.0075975619.34493247
Safe Withdraw195009652024-03-24 0:51:23192 days ago1711241483IN
0xF4d150F3...fA0e44532
0 ETH0.002074216.30935054
Safe Withdraw189905372024-01-12 11:32:23264 days ago1705059143IN
0xF4d150F3...fA0e44532
0 ETH0.0033542226.61954326
Safe Withdraw189905302024-01-12 11:30:59264 days ago1705059059IN
0xF4d150F3...fA0e44532
0 ETH0.0042511829.70654486
Safe Withdraw188057832023-12-17 12:36:23290 days ago1702816583IN
0xF4d150F3...fA0e44532
0 ETH0.008248335.92718215
Safe Withdraw185238852023-11-08 1:13:11329 days ago1699405991IN
0xF4d150F3...fA0e44532
0 ETH0.0135336319.33426295
Safe Withdraw185131462023-11-06 13:09:47331 days ago1699276187IN
0xF4d150F3...fA0e44532
0 ETH0.0355095547.57557918
Safe Withdraw185021092023-11-05 0:02:11333 days ago1699142531IN
0xF4d150F3...fA0e44532
0 ETH0.0023830316.65226913
Safe Withdraw184942042023-11-03 21:26:35334 days ago1699046795IN
0xF4d150F3...fA0e44532
0 ETH0.0061596216.40195081
Safe Withdraw184942012023-11-03 21:25:59334 days ago1699046759IN
0xF4d150F3...fA0e44532
0 ETH0.0020790516.49964748
Safe Withdraw184941992023-11-03 21:25:35334 days ago1699046735IN
0xF4d150F3...fA0e44532
0 ETH0.0025075817.52259387
Safe Withdraw183725512023-10-17 20:43:35351 days ago1697575415IN
0xF4d150F3...fA0e44532
0 ETH0.0014107311.19579575
Safe Withdraw181935452023-09-22 19:45:47376 days ago1695411947IN
0xF4d150F3...fA0e44532
0 ETH0.001894188.21850586
Safe Withdraw181540752023-09-17 6:44:59381 days ago1694933099IN
0xF4d150F3...fA0e44532
0 ETH0.005224567.54999828
Safe Withdraw181540642023-09-17 6:42:47381 days ago1694932967IN
0xF4d150F3...fA0e44532
0 ETH0.005692698.22425216
Safe Withdraw181157412023-09-11 21:17:11387 days ago1694467031IN
0xF4d150F3...fA0e44532
0 ETH0.0020876818.96323787
Safe Withdraw180686862023-09-05 7:07:35393 days ago1693897655IN
0xF4d150F3...fA0e44532
0 ETH0.0070987210.39959951
Safe Withdraw180686722023-09-05 7:04:47393 days ago1693897487IN
0xF4d150F3...fA0e44532
0 ETH0.0078484911.09340058
Safe Withdraw180650782023-09-04 19:03:11394 days ago1693854191IN
0xF4d150F3...fA0e44532
0 ETH0.0026938924.46967137
Safe Withdraw179936782023-08-25 19:05:23404 days ago1692990323IN
0xF4d150F3...fA0e44532
0 ETH0.0034207623.903737
Safe Withdraw179600122023-08-21 2:05:11408 days ago1692583511IN
0xF4d150F3...fA0e44532
0 ETH0.0084731713.17142405
Safe Withdraw178316892023-08-03 3:08:23426 days ago1691032103IN
0xF4d150F3...fA0e44532
0 ETH0.0019479615.45926485
Safe Withdraw178256402023-08-02 6:51:35427 days ago1690959095IN
0xF4d150F3...fA0e44532
0 ETH0.0016702413.91924894
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
JumpPort

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 3 : JumpPort.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./OwnableBase.sol";

interface IERC721Transfers {
  function safeTransferFrom (
    address from,
    address to,
    uint256 tokenId
  ) external;

  function safeTransferFrom (
    address from,
    address to,
    uint256 tokenId,
    bytes calldata data
  ) external;

  function transferFrom (
    address from,
    address to,
    uint256 tokenId
  ) external;
}

contract JumpPort is IERC721Receiver, OwnableBase {
  bool public depositPaused;
  bytes32 public constant PORTAL_ROLE = keccak256("PORTAL_ROLE");

  struct LockRecord {
    address parentLock;
    bool isLocked;
  }

  /**
   * @dev Record an Owner's collection balance, and the block it was last updated.
   *
   * Stored as less than uint256 values to fit into one storage slot.
   *
   * This structure will work until approximately the year 2510840694154672305534315769283066566440942177785607
   * (when the block height becomes too large for a uint192), and for oners who don't have more than
   * 18,​446,​744,​073,​709,​551,​615 items from a single collection deposited.
   */
  struct BalanceRecord {
    uint64 balance;
    uint192 blockHeight;
  }

  mapping(address => bool) public lockOverride;
  mapping(address => bool) public executionBlocked;
  mapping(address => mapping(uint256 => mapping(address => LockRecord))) internal portalLocks; // collection address => token ID => portal address => LockRecord
  mapping(address => mapping(uint256 => address)) private currentLock; // collection address => token ID => portal address

  mapping(address => mapping(uint256 => address)) private Owners; // collection address => token ID => owner address
  mapping(address => mapping(address => BalanceRecord)) private OwnerBalances; // collection address => owner Address => count
  mapping(address => mapping(uint256 => uint256)) private DepositBlock; // collection address => token ID => block height
  mapping(address => mapping(uint256 => uint256)) private PingRequestBlock; // collection address => token ID => block height
  mapping(address => mapping(uint256 => address)) private Copilots; // collection address => token ID => copilot address
  mapping(address => mapping(address => bool)) private CopilotApprovals; // owner address => copilot address => is approved

  event Deposit(address indexed owner, address indexed tokenAddress, uint256 indexed tokenId);
  event Withdraw(address indexed owner, address indexed tokenAddress, uint256 indexed tokenId, uint256 duration);
  event Approval(address indexed owner, address indexed approved, address indexed tokenAddress, uint256 tokenId);
  event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
  event Lock(address indexed portalAddress, address indexed owner, address indexed tokenAddress, uint256 tokenId);
  event Unlock(address indexed portalAddress, address indexed owner, address indexed tokenAddress, uint256 tokenId);
  event ActionExecuted(address indexed tokenAddress, uint256 indexed tokenId, address target, bytes data);

  constructor (address documentationAddress) OwnableBase(documentationAddress) {}

  /* Deposit Tokens */

  /**
   * @dev Receive a token directly; transferred with the `safeTransferFrom` method of another ERC721 token.
   * @param operator the _msgSender of the transaction
   * @param from the address of the former owner of the incoming token
   * @param tokenId the ID of the incoming token
   * @param data additional metdata
   */
  function onERC721Received (
    address operator,
    address from,
    uint256 tokenId,
    bytes calldata data
  ) public override whenDepositNotPaused returns (bytes4) {

    Owners[msg.sender][tokenId] = from;
    unchecked {
      OwnerBalances[msg.sender][from].balance++;
      OwnerBalances[msg.sender][from].blockHeight = uint192(block.number);
    }
    DepositBlock[msg.sender][tokenId] = block.number;
    PingRequestBlock[msg.sender][tokenId] = 0;
    emit Deposit(from, msg.sender, tokenId);

    return IERC721Receiver.onERC721Received.selector;
  }

  /**
   * @dev Deposit an individual token from a specific collection.
   * To be successful, the JumpPort contract must be "Approved" to move this token on behalf
   * of the current owner, in the token's contract.
   */
  function deposit (address tokenAddress, uint256 tokenId) public whenDepositNotPaused {
    IERC721Transfers(tokenAddress).transferFrom(msg.sender, address(this), tokenId);
    Owners[tokenAddress][tokenId] = msg.sender;
    unchecked {
      OwnerBalances[tokenAddress][msg.sender].balance++;
      OwnerBalances[tokenAddress][msg.sender].blockHeight = uint192(block.number);
    }
    DepositBlock[tokenAddress][tokenId] = block.number;
    PingRequestBlock[tokenAddress][tokenId] = 0;
    emit Deposit(msg.sender, tokenAddress, tokenId);
  }

  /**
   * @dev Deposit multiple tokens from a single collection.
   * To be successful, the JumpPort contract must be "Approved" to move these tokens on behalf
   * of the current owner, in the token's contract.
   */
  function deposit (address tokenAddress, uint256[] calldata tokenIds) public {
    unchecked {
      for (uint256 i; i < tokenIds.length; i++) {
        deposit(tokenAddress, tokenIds[i]);
      }
    }
  }

  /**
   * @dev Deposit multiple tokens from multiple different collections.
   * To be successful, the JumpPort contract must be "Approved" to move these tokens on behalf
   * of the current owner, in the token's contract.
   */
  function deposit (address[] calldata tokenAddresses, uint256[] calldata tokenIds) public {
    require(tokenAddresses.length == tokenIds.length, "Mismatched inputs");
    unchecked {
      for (uint256 i; i < tokenIds.length; i++) {
        deposit(tokenAddresses[i], tokenIds[i]);
      }
    }
  }

  /* Withdraw Tokens */

  /**
   * @dev Internal helper function that clears out the tracked metadata for the token.
   * Does not do any permission checks, and does not do the actual transferring of the token.
   */
  function _withdraw (address tokenAddress, uint256 tokenId) internal {
    address currentOwner = Owners[tokenAddress][tokenId];
    emit Withdraw(
      currentOwner,
      tokenAddress,
      tokenId,
      block.number - DepositBlock[tokenAddress][tokenId]
    );
    unchecked {
      OwnerBalances[tokenAddress][currentOwner].balance--;
      OwnerBalances[tokenAddress][currentOwner].blockHeight = uint192(block.number);
    }
    Owners[tokenAddress][tokenId] = address(0);
    DepositBlock[tokenAddress][tokenId] = 0;
    Copilots[tokenAddress][tokenId] = address(0);
  }

  /**
   * @dev Withdraw a token, to the owner's address, using `safeTransferFrom`, with no additional data.
   */
  function safeWithdraw (address tokenAddress, uint256 tokenId)
    public
    isPilot(tokenAddress, tokenId)
    withdrawAllowed(tokenAddress, tokenId)
  {
    address ownerAddress = Owners[tokenAddress][tokenId];
    _withdraw(tokenAddress, tokenId);
    IERC721Transfers(tokenAddress).safeTransferFrom(address(this), ownerAddress, tokenId);
  }

  /**
   * @dev Withdraw a token, to the owner's address, using `safeTransferFrom`, with additional calldata.
   */
  function safeWithdraw (address tokenAddress, uint256 tokenId, bytes calldata data)
    public
    isPilot(tokenAddress, tokenId)
    withdrawAllowed(tokenAddress, tokenId)
  {
    address ownerAddress = Owners[tokenAddress][tokenId];
    _withdraw(tokenAddress, tokenId);
    IERC721Transfers(tokenAddress).safeTransferFrom(address(this), ownerAddress, tokenId, data);
  }

  /**
   * @dev Bulk withdraw multiple tokens, using `safeTransferFrom`, with no additional data.
   */
  function safeWithdraw (address[] calldata tokenAddresses, uint256[] calldata tokenIds) public {
    require(tokenAddresses.length == tokenIds.length, "Inputs mismatched");
    for(uint256 i = 0; i < tokenAddresses.length; i++) {
      safeWithdraw(tokenAddresses[i], tokenIds[i]);
    }
  }

  /**
   * @dev Bulk withdraw multiple tokens, using `safeTransferFrom`, with additional calldata.
   */
  function safeWithdraw (address[] calldata tokenAddresses, uint256[] calldata tokenIds, bytes[] calldata data) public {
    require(tokenAddresses.length == tokenIds.length, "Inputs mismatched");
    for(uint256 i = 0; i < tokenAddresses.length; i++) {
      safeWithdraw(tokenAddresses[i], tokenIds[i], data[i]);
    }
  }

  /**
   * @dev Withdraw a token, to the owner's address, using `transferFrom`.
   * USING `transferFrom` RATHER THAN `safeTransferFrom` COULD RESULT IN LOST TOKENS. USE `safeWithdraw` FUNCTIONS
   * WHERE POSSIBLE, OR DOUBLE-CHECK RECEIVING ADDRESSES CAN HOLD TOKENS IF USING THIS FUNCTION.
   */
  function withdraw (address tokenAddress, uint256 tokenId)
    public
    isPilot(tokenAddress, tokenId)
    withdrawAllowed(tokenAddress, tokenId)
  {
    address ownerAddress = Owners[tokenAddress][tokenId];
    _withdraw(tokenAddress, tokenId);
    IERC721Transfers(tokenAddress).transferFrom(address(this), ownerAddress, tokenId);
  }

  /**
   * @dev Bulk withdraw multiple tokens, to specific addresses, using `transferFrom`.
   * USING `transferFrom` RATHER THAN `safeTransferFrom` COULD RESULT IN LOST TOKENS. USE `safeWithdraw` FUNCTIONS
   * WHERE POSSIBLE, OR DOUBLE-CHECK RECEIVING ADDRESSES CAN HOLD TOKENS IF USING THIS FUNCTION.
   */
  function withdraw (address[] calldata tokenAddresses, uint256[] calldata tokenIds) public {
    require(tokenAddresses.length == tokenIds.length, "Inputs mismatched");
    for(uint256 i = 0; i < tokenAddresses.length; i++) {
      withdraw(tokenAddresses[i], tokenIds[i]);
    }
  }

  /**
   * @dev Designate another address that can act on behalf of this token.
   * This allows the Copliot address to withdraw the token from the JumpPort, and interact with any Portal
   * on behalf of this token.
   */
  function setCopilot (address copilot, address tokenAddress, uint256 tokenId) public {
    require(Owners[tokenAddress][tokenId] == msg.sender, "Not the owner of that token");
    require(msg.sender != copilot, "approve to caller");
    Copilots[tokenAddress][tokenId] = copilot;
    emit Approval(msg.sender, copilot, tokenAddress, tokenId);
  }

  /**
   * @dev Designate another address that can act on behalf of all tokens owned by the sender's address.
   * This allows the Copliot address to withdraw the token from the JumpPort, and interact with any Portal
   * on behalf of any token owned by the sender.
   */
  function setCopilotForAll (address copilot, bool approved) public {
    require(msg.sender != copilot, "approve to caller");
    CopilotApprovals[msg.sender][copilot] = approved;
    emit ApprovalForAll(msg.sender, copilot, approved);
  }

  /* Receive actions from Portals */

  /**
   * @dev Lock a token into the JumpPort.
   * Causes a token to not be able to be withdrawn by its Owner, until the same Portal contract calls the `unlockToken` function for it,
   * or the locks for that portal are all marked as invalid (either by JumpPort administrators, or the Portal itself).
   */
  function lockToken (address tokenAddress, uint256 tokenId) public tokenDeposited(tokenAddress, tokenId) onlyRole(PORTAL_ROLE) {
    if (portalLocks[tokenAddress][tokenId][msg.sender].isLocked) return; // Already locked; nothing to do

    // Check if this lock is already in the chain of "active" locks
    address checkPortal = currentLock[tokenAddress][tokenId];
    while (checkPortal != address(0)) {
      if (checkPortal == msg.sender) {
        // This portal is already in the chain of active locks
        portalLocks[tokenAddress][tokenId][msg.sender].isLocked = true;
        emit Lock(msg.sender, Owners[tokenAddress][tokenId], tokenAddress, tokenId);
        return;
      }
      checkPortal = portalLocks[tokenAddress][tokenId][checkPortal].parentLock;
    }

    // Looped through all active locks and didn't find this Portal. So, add it as the new head
    portalLocks[tokenAddress][tokenId][msg.sender] = LockRecord(currentLock[tokenAddress][tokenId], true);
    currentLock[tokenAddress][tokenId] = msg.sender;
    emit Lock(msg.sender, Owners[tokenAddress][tokenId], tokenAddress, tokenId);
  }

  /**
   * @dev Unlocks a token held in the JumpPort.
   * Does not withdraw the token from the JumpPort, but makes it available for withdraw whenever the Owner wishes to.
   */
  function unlockToken (address tokenAddress, uint256 tokenId) public tokenDeposited(tokenAddress, tokenId) onlyRole(PORTAL_ROLE) {
    portalLocks[tokenAddress][tokenId][msg.sender].isLocked = false;
    emit Unlock(msg.sender, Owners[tokenAddress][tokenId], tokenAddress, tokenId);
    if (!isLocked(tokenAddress, tokenId)) {
      currentLock[tokenAddress][tokenId] = address(0);
    }
  }

  /**
   * @dev Take an action as the JumpPort (the owner of the tokens within it), as directed by a Portal.
   * This is a powerful function and Portals that wish to use it NEEDS TO MAKE SURE its execution is guarded by
   * checks to ensure the address passed as `operator` to this function is the one authorizing the action
   * (in most cases, it should be the `msg.sender` communicating to the Portal), and that the `payload`
   * being passed in operates on the `tokenId` indicated, and no other tokens.
   *
   * Here on the JumpPort side, it verifies that the `operator` passed in is the current owner or a Copilot of the
   * token being operated upon, but has to trust the Portal that the passed-in `tokenId` matches what token
   * will get acted upon in the `payload`.
   */
  function executeAction (address operator, address tokenAddress, uint256 tokenId, address targetAddress, bytes calldata payload)
    public
    payable
    tokenDeposited(tokenAddress, tokenId)
    onlyRole(PORTAL_ROLE)
    returns(bytes memory result)
  {
    require(executionBlocked[msg.sender] == false, "Execution blocked for that Portal");

    // Check if operator is allowed to act for this token
    address owner = Owners[tokenAddress][tokenId];
    require(
      operator == owner || operator == Copilots[tokenAddress][tokenId] || CopilotApprovals[owner][operator] == true,
      "Not an operator of that token"
    );

    // Make the external call
    (bool success, bytes memory returnData) = targetAddress.call{ value: msg.value }(payload);
    if (success == false) {
      if (returnData.length == 0) {
        revert("Executing action on other contract failed");
      } else {
        assembly {
          revert(add(32, returnData), mload(returnData))
        }
      }
    } else {
      emit ActionExecuted(tokenAddress, tokenId, targetAddress, payload);
      return returnData;
    }
  }

  /**
   * @dev Unlocks all locks held by a Portal.
   * Intended to be called in the situation of a large failure of an individual Portal's operation,
   * as a way for the Portal itself to indicate it has failed, and all tokens that were previously
   * locked by it should be allowed to exit.
   *
   * This function only allows Portals to enable/disable the locks they created. The function `setAdminLockOverride`
   * is similar, but allows JumpPort administrators to set/clear the lock ability for any Portal contract.
   */
  function unlockAllTokens (bool isOverridden) public onlyRole(PORTAL_ROLE) {
    lockOverride[msg.sender] = isOverridden;
  }

  /**
   * @dev Prevent a Portal from executing calls to other contracts.
   * Intended to be called in the situation of a large failure of an individual Portal's operation,
   * as a way for the Portal itself to indicate it has failed, and arbitrary contract calls should not
   * be allowed to originate from it.
   *
   * This function only allows Portals to enable/disable their own execution right. The function `setAdminExecutionBlocked`
   * is similar, but allows JumpPort administrators to set/clear the execution block for any Portal contract.
   */
  function blockExecution (bool isBlocked) public onlyRole(PORTAL_ROLE) {
    executionBlocked[msg.sender] = isBlocked;
  }

  /* View functions */

  /**
   * @dev Is the specified token currently deposited in the JumpPort?
   */
  function isDeposited (address tokenAddress, uint256 tokenId) public view returns (bool) {
    return Owners[tokenAddress][tokenId] != address(0);
  }

  /**
   * @dev When was the specified token deposited in the JumpPort?
   */
  function depositedSince (address tokenAddress, uint256 tokenId) public view tokenDeposited(tokenAddress, tokenId) returns (uint256 blockNumber) {
    blockNumber = DepositBlock[tokenAddress][tokenId];
  }

  /**
   * @dev Is the specified token currently locked in the JumpPort?
   * If any Portal contract has a valid lock (the Portal has indicated the token should be locked,
   * and the Portal's locking rights haven't been overridden) on the token, this function will return true.
   */
  function isLocked (address tokenAddress, uint256 tokenId) public view tokenDeposited(tokenAddress, tokenId) returns (bool) {
    address checkPortal = currentLock[tokenAddress][tokenId];
    while (checkPortal != address(0)) {
      if (portalLocks[tokenAddress][tokenId][checkPortal].isLocked && lockOverride[checkPortal] == false) return true;
      checkPortal = portalLocks[tokenAddress][tokenId][checkPortal].parentLock;
    }
    return false;
  }

  /**
   * @dev Get a list of all Portal contract addresses that hold a valid lock (the Portal has indicated the token should be locked,
   * and the Portal's locking rights haven't been overridden) on the token.
   */
  function lockedBy (address tokenAddress, uint256 tokenId) public view returns (address[] memory) {
    address[] memory lockedRaw = new address[](500);
    uint256 index = 0;
    address checkPortal = currentLock[tokenAddress][tokenId];
    while (checkPortal != address(0)) {
      if (portalLocks[tokenAddress][tokenId][checkPortal].isLocked && lockOverride[checkPortal] == false) {
        lockedRaw[index] = checkPortal;
        index++;
      }
      checkPortal = portalLocks[tokenAddress][tokenId][checkPortal].parentLock;
    }

    address[] memory lockedFinal = new address[](index);
    unchecked {
      for (uint256 i = 0; i < index; i++) {
        lockedFinal[i] = lockedRaw[i];
      }
    }
    return lockedFinal;
  }

  /**
   * @dev Who is the owner of the specified token that is deposited in the JumpPort?
   * A core tenent of the JumpPort is that this value will not change while the token is deposited;
   * a token cannot change owners while in the JumpPort, though they can add/remove Copilots.
   */
  function ownerOf (address tokenAddress, uint256 tokenId) public view tokenDeposited(tokenAddress, tokenId) returns (address owner) {
    owner = Owners[tokenAddress][tokenId];
  }

  /**
   * @dev Who are the owners of a specified range of tokens in a collection?
   * Bulk query function, to be able to enumerate a whole token collection more easily on the client end
   */
  function ownersOf (address tokenAddress, uint256 tokenSearchStart, uint256 tokenSearchEnd) public view returns (address[] memory tokenOwners) {
    unchecked {
      require(tokenSearchEnd >= tokenSearchStart, "Search parameters out of order");
      tokenOwners = new address[](tokenSearchEnd - tokenSearchStart + 1);
      for (uint256 i = tokenSearchStart; i <= tokenSearchEnd; i++) {
        tokenOwners[i - tokenSearchStart] = Owners[tokenAddress][i];
      }
    }
  }

  /**
   * @dev For a specified owner address, what tokens in the specified range do they own?
   * Bulk query function, to be able to enumerate a specific address' collection more easily on the client end
   */
  function ownedTokens (address tokenAddress, address owner, uint256 tokenSearchStart, uint256 tokenSearchEnd) public view returns (uint256[] memory tokenIds) {
    unchecked {
      require(tokenSearchEnd >= tokenSearchStart, "Search parameters out of order");
      require(owner != address(0), "Balance query for the zero address");
      uint256[] memory ownedRaw = new uint256[](tokenSearchEnd - tokenSearchStart);
      uint256 index = 0;
      for (uint256 i = tokenSearchStart; i <= tokenSearchEnd; i++) {
        if (Owners[tokenAddress][i] == owner) {
          ownedRaw[index] = i;
          index++;
        }
      }
      uint256[] memory ownedFinal = new uint256[](index);
      for (uint256 i = 0; i < index; i++) {
        ownedFinal[i] = ownedRaw[i];
      }
      return ownedFinal;
    }
  }

  /**
   * @dev For a specific token collection, how many tokens in that collection does a specific owning address own in the JumpPort?
   */
  function balanceOf (address tokenAddress, address owner) public view returns (BalanceRecord memory) {
    require(owner != address(0), "Balance query for the zero address");
    return OwnerBalances[tokenAddress][owner];
  }

  /**
   * @dev For a specific set of token collections, how many tokens total does a specific owning address own in the JumpPort?
   * Bulk query function, to be able to enumerate a specific address' collection more easily on the client end
   */
  function balanceOf (address[] calldata tokenAddresses, address owner) public view returns (uint256) {
    require(owner != address(0), "Balance query for the zero address");
    uint256 totalBalance = 0;
    unchecked {
      for (uint256 i = 0; i < tokenAddresses.length; i++) {
        totalBalance += OwnerBalances[tokenAddresses[i]][owner].balance;
      }
    }
    return totalBalance;
  }

  /**
   * @dev For a specific token, which other address is approved to act as the owner of that token for actions pertaining to the JumpPort?
   */
  function getApproved (address tokenAddress, uint256 tokenId) public view tokenDeposited(tokenAddress, tokenId) returns (address copilot) {
    copilot = Copilots[tokenAddress][tokenId];
  }

  /**
   * @dev For a specific owner's address, is the specified operator address allowed to act as the owner for actions pertaining to the JumpPort?
   */
  function isApprovedForAll (address owner, address operator) public view returns (bool) {
    return CopilotApprovals[owner][operator];
  }

  /* Modifiers */

  /**
   * @dev Prevent execution if the specified token is not currently deposited in the JumpPort.
   */
  modifier tokenDeposited (address tokenAddress, uint256 tokenId) {
    require(Owners[tokenAddress][tokenId] != address(0), "Not currently deposited");
    _;
  }

  /**
   * @dev Prevent execution if deposits to the JumpPort overall are paused.
   */
  modifier whenDepositNotPaused () {
    require(depositPaused == false, "Paused");
    _;
  }

  /**
   * @dev Prevent execution if the specified token is locked by any Portal currently.
   */
  modifier withdrawAllowed (address tokenAddress, uint256 tokenId) {
    require(!isLocked(tokenAddress, tokenId), "Token is locked");
    _;
  }

  /**
   * @dev Prevent execution if the transaction sender is not the owner nor Copliot for the specified token.
   */
  modifier isPilot (address tokenAddress, uint256 tokenId) {
    address owner = Owners[tokenAddress][tokenId];
    require(
      msg.sender == owner || msg.sender == Copilots[tokenAddress][tokenId] || CopilotApprovals[owner][msg.sender] == true,
      "Not an operator of that token"
    );
    _;
  }

  /* Administration */

  /**
   * @dev Add or remove the "Portal" role to a specified address.
   */
  function setPortalValidation (address portalAddress, bool isValid) public onlyRole(ADMIN_ROLE) {
    roles[PORTAL_ROLE][portalAddress] = isValid;
    emit RoleChange(PORTAL_ROLE, portalAddress, isValid, msg.sender);
  }

  /**
   * @dev Prevent new tokens from being added to the JumpPort.
   */
  function setPaused (bool isDepositPaused)
    public
    onlyRole(ADMIN_ROLE)
  {
    depositPaused = isDepositPaused;
  }

  /**
   * @dev As an administrator of the JumpPort contract, set a Portal's locks to be valid or not.
   *
   * This function allows JumpPort administrators to set/clear the override for any Portal contract.
   * The `unlockAllTokens` function is similar (allowing Portal addresses to set/clear lock overrides as well)
   * but only for their own Portal address.
   */
  function setAdminLockOverride (address portal, bool isOverridden) public onlyRole(ADMIN_ROLE) {
    lockOverride[portal] = isOverridden;
  }

  /**
   * @dev As an administrator of the JumpPort contract, set a Portal to be able to execute other functions or not.
   *
   * This function allows JumpPort administrators to set/clear the execution block for any Portal contract.
   * The `blockExecution` function is similar (allowing Portal addresses to set/clear lock overrides as well)
   * but only for their own Portal address.
   */
  function setAdminExecutionBlocked (address portal, bool isBlocked) public onlyRole(ADMIN_ROLE) {
    executionBlocked[portal] = isBlocked;
  }

  /**
   * @dev Contract owner requesting the owner of a token check in.
   * This starts the process of the owner of the contract being able to remove any token, after a time delay.
   * If the current owner does not want the token removed, they have 2,400,000 blocks (about one year)
   * to trigger the `ownerPong` method, which will abort the withdraw
   */
  function adminWithdrawPing (address tokenAddress, uint256 tokenId)
    public
    onlyRole(ADMIN_ROLE)
  {
    require(Owners[tokenAddress][tokenId] != address(0), "Token not deposited");
    PingRequestBlock[tokenAddress][tokenId] = block.number;
  }

  /**
   * @dev As the owner of a token, abort an attempt to force-remove it.
   * The owner of the contract can remove any token from the JumpPort, if they trigger the `adminWithdrawPing` function
   * for that token, and the owner does not respond by calling this function within 2,400,000 blocks (about one year)
   */
  function ownerPong (address tokenAddress, uint256 tokenId) public isPilot(tokenAddress, tokenId) {
    PingRequestBlock[tokenAddress][tokenId] = 0;
  }

  /**
   * @dev As an Administrator, abort an attempt to force-remove a token.
   * This is a means for the Administration to change its mind about a force-withdraw, or to correct the actions of a rogue Administrator.
   */
  function adminPong (address tokenAddress, uint256 tokenId) public onlyRole(ADMIN_ROLE) {
    PingRequestBlock[tokenAddress][tokenId] = 0;
  }

  /**
   * @dev Check if a token has a ping from the contract Administration pending, and if so, what block it was requested at
   * Returns zero if there is no request pending.
   */
  function tokenPingRequestBlock (address tokenAddress, uint256 tokenId) public view returns (uint256 blockNumber) {
    return PingRequestBlock[tokenAddress][tokenId];
  }

  /**
   * @dev Check if a set of tokens have a ping from the contract Administration pending, and if so, what block it was requested at
   * Returns zero for a token if there is no request pending for that token.
   */
  function tokenPingRequestBlocks (address[] calldata tokenAddresses, uint256[] calldata tokenIds) public view returns(uint256[] memory blockNumbers) {
    require(tokenAddresses.length == tokenIds.length, "Inputs mismatched");
    unchecked {
      blockNumbers = new uint256[](tokenAddresses.length);
      for (uint256 i = 0; i < tokenAddresses.length; i++) {
        blockNumbers[i] = PingRequestBlock[tokenAddresses[i]][tokenIds[i]];
      }
    }
  }

  /**
   * @dev Rescue ERC721 assets sent directly to this contract.
   */
  function withdrawForeignERC721 (address tokenContract, uint256 tokenId)
    public
    override
    onlyRole(ADMIN_ROLE)
  {
    if (Owners[tokenContract][tokenId] == address(0)) {
      // This token got here without being properly recorded; allow withdraw immediately
      DepositBlock[tokenContract][tokenId] = 0;
      Copilots[tokenContract][tokenId] = address(0);
      IERC721(tokenContract).safeTransferFrom(
        address(this),
        msg.sender,
        tokenId
      );
      return;
    }

    // This token is deposited into the JumpPort in a valid manner.
    // Only allow contract-owner withdraw if owner does not respond to ping
    unchecked {
      require(PingRequestBlock[tokenContract][tokenId] > 0 && PingRequestBlock[tokenContract][tokenId] < block.number - 2_400_000, "Owner ping has not expired");
    }
    currentLock[tokenContract][tokenId] = address(0); // Remove all locks on this token
    _withdraw(tokenContract, tokenId);
    IERC721(tokenContract).safeTransferFrom(
      address(this),
      msg.sender,
      tokenId
    );
  }

}

File 2 of 3 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 3 of 3 : OwnableBase.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.9;

interface IReverseResolver {
  function claim (address owner) external returns (bytes32);
}

interface IERC20 {
  function balanceOf (address account) external view returns (uint256);
  function transfer (address recipient, uint256 amount) external returns (bool);
}

interface IERC721 {
  function safeTransferFrom (address from, address to, uint256 tokenId ) external;
}

interface IDocumentationRepository {
  function doc (address contractAddress) external view returns (string memory name, string memory description, string memory details);
}

error MissingRole(bytes32 role, address operator);

abstract contract OwnableBase {
  bytes32 public constant ADMIN_ROLE = 0x00;
  mapping(bytes32 => mapping(address => bool)) internal roles; // role => operator => hasRole
  mapping(bytes32 => uint256) internal validSignatures; // message hash => expiration block height
  IDocumentationRepository public DocumentationRepository;

  event RoleChange (bytes32 indexed role, address indexed account, bool indexed isGranted, address sender);

  constructor (address documentationAddress) {
    roles[ADMIN_ROLE][msg.sender] = true;
    DocumentationRepository = IDocumentationRepository(documentationAddress);
  }

  function doc () public view returns (string memory name, string memory description, string memory details) {
    return DocumentationRepository.doc(address(this));
  }

  /**
   * @dev See {ERC1271-isValidSignature}.
   */
  function isValidSignature(bytes32 hash, bytes memory)
    external
    view
    returns (bytes4 magicValue)
  {
    if (validSignatures[hash] >= block.number) {
      return 0x1626ba7e; // bytes4(keccak256("isValidSignature(bytes32,bytes)")
    } else {
      return 0xffffffff;
    }
  }

  /**
   * @dev Inspect whether a specific address has a specific role.
   */
  function hasRole (bytes32 role, address account) public view returns (bool) {
    return roles[role][account];
  }

  /* Modifiers */

  modifier onlyRole (bytes32 role) {
    if (roles[role][msg.sender] != true) revert MissingRole(role, msg.sender);
    _;
  }

  /* Administration */

  /**
   * @dev Allow current administrators to be able to grant/revoke admin role to other addresses.
   */
  function setAdmin (address account, bool isAdmin) public onlyRole(ADMIN_ROLE) {
    roles[ADMIN_ROLE][account] = isAdmin;
    emit RoleChange(ADMIN_ROLE, account, isAdmin, msg.sender);
  }

  /**
   * @dev Claim ENS reverse-resolver rights for this contract.
   * https://docs.ens.domains/contract-api-reference/reverseregistrar#claim-address
   */
  function setReverseResolver (address registrar) public onlyRole(ADMIN_ROLE) {
    IReverseResolver(registrar).claim(msg.sender);
  }

  /**
   * @dev Update address for on-chain documentation lookup.
   */
  function setDocumentationRepository (address documentationAddress) public onlyRole(ADMIN_ROLE) {
    DocumentationRepository = IDocumentationRepository(documentationAddress);
  }

  /**
   * @dev Set a message as valid, to be queried by ERC1271 clients.
   */
  function markMessageSigned (bytes32 hash, uint256 expirationLength) public onlyRole(ADMIN_ROLE) {
    validSignatures[hash] = block.number + expirationLength;
  }

  /**
   * @dev Rescue ERC20 assets sent directly to this contract.
   */
  function withdrawForeignERC20 (address tokenContract) public onlyRole(ADMIN_ROLE) {
    IERC20 token = IERC20(tokenContract);
    token.transfer(msg.sender, token.balanceOf(address(this)));
  }

  /**
   * @dev Rescue ERC721 assets sent directly to this contract.
   */
  function withdrawForeignERC721 (address tokenContract, uint256 tokenId)
    public
    virtual
    onlyRole(ADMIN_ROLE)
  {
    IERC721(tokenContract).safeTransferFrom(
      address(this),
      msg.sender,
      tokenId
    );
  }

  function withdrawEth () public onlyRole(ADMIN_ROLE) {
    payable(msg.sender).transfer(address(this).balance);
  }

}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"documentationAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"operator","type":"address"}],"name":"MissingRole","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ActionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"portalAddress","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Lock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bool","name":"isGranted","type":"bool"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"RoleChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"portalAddress","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DocumentationRepository","outputs":[{"internalType":"contract IDocumentationRepository","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PORTAL_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"adminPong","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"adminWithdrawPing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"components":[{"internalType":"uint64","name":"balance","type":"uint64"},{"internalType":"uint192","name":"blockHeight","type":"uint192"}],"internalType":"struct JumpPort.BalanceRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isBlocked","type":"bool"}],"name":"blockExecution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"depositedSince","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doc","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"details","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeAction","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"executionBlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"copilot","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isDeposited","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockOverride","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"lockToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"lockedBy","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint256","name":"expirationLength","type":"uint256"}],"name":"markMessageSigned","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenSearchStart","type":"uint256"},{"internalType":"uint256","name":"tokenSearchEnd","type":"uint256"}],"name":"ownedTokens","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerPong","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenSearchStart","type":"uint256"},{"internalType":"uint256","name":"tokenSearchEnd","type":"uint256"}],"name":"ownersOf","outputs":[{"internalType":"address[]","name":"tokenOwners","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"safeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"safeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isAdmin","type":"bool"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"portal","type":"address"},{"internalType":"bool","name":"isBlocked","type":"bool"}],"name":"setAdminExecutionBlocked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"portal","type":"address"},{"internalType":"bool","name":"isOverridden","type":"bool"}],"name":"setAdminLockOverride","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"copilot","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"setCopilot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"copilot","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setCopilotForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"documentationAddress","type":"address"}],"name":"setDocumentationRepository","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isDepositPaused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"portalAddress","type":"address"},{"internalType":"bool","name":"isValid","type":"bool"}],"name":"setPortalValidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registrar","type":"address"}],"name":"setReverseResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenPingRequestBlock","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"tokenPingRequestBlocks","outputs":[{"internalType":"uint256[]","name":"blockNumbers","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isOverridden","type":"bool"}],"name":"unlockAllTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unlockToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawForeignERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawForeignERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200404638038062004046833981016040819052620000349162000094565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560205260409020805460ff19166001179055600280546001600160a01b039092166001600160a01b0319909216919091179055620000c6565b600060208284031215620000a757600080fd5b81516001600160a01b0381168114620000bf57600080fd5b9392505050565b613f7080620000d66000396000f3fe60806040526004361061031a5760003560e01c80635c471995116101ab578063a71604e8116100f7578063e803c63f11610095578063f3fef3a31161006f578063f3fef3a314610a55578063f7888aec14610a75578063fc5472e114610ac2578063fe8c7b6914610ae257600080fd5b8063e803c63f146109bf578063e985e9c5146109ec578063efc908a114610a3557600080fd5b8063cb86d555116100d1578063cb86d5551461093f578063cf488ca71461095f578063da24cad51461097f578063de6d6d961461099f57600080fd5b8063a71604e8146108df578063a81158c7146108ff578063bf47146c1461091f57600080fd5b806391d148541161016457806399cca36c1161013e57806399cca36c146108475780639c27993f146108675780639ef76bd2146108aa578063a0ef91df146108ca57600080fd5b806391d14854146107b6578063935c04be146107fa5780639522b19d1461081a57600080fd5b80635c471995146106ed57806375b238fc1461070d57806378a90072146107225780637a0a3ac51461075257806389b6a48c146107765780638d0716cc1461079657600080fd5b806320285d2d1161026a5780633a02a533116102235780634b0bddd2116101fd5780634b0bddd21461066d5780634bdb2db91461068d57806350070b28146106ad5780635058c460146106cd57600080fd5b80633a02a5331461060b57806340db8f181461062b57806347e7ef241461064d57600080fd5b806320285d2d14610518578063216732741461053857806321b79a3d1461057d5780632a0ce756146105ab57806331e9e9c0146105cb57806337fd25c7146105eb57600080fd5b8063150b7a02116102d757806317be3fa5116102b157806317be3fa5146104885780631c8ff8c9146104a85780631e503ee4146104d85780631f29d2dc146104f857600080fd5b8063150b7a021461040f5780631626ba7e1461044857806316c38b3c1461046857600080fd5b806302befd241461031f578063098f2366146103555780630ce06b681461038d5780630ddfb6b2146103af5780630fdc7956146103cf57806310952088146103ef575b600080fd5b34801561032b57600080fd5b5060025461034090600160a01b900460ff1681565b60405190151581526020015b60405180910390f35b34801561036157600080fd5b506103756103703660046133d0565b610b02565b6040516001600160a01b03909116815260200161034c565b34801561039957600080fd5b506103ad6103a83660046133d0565b610b7e565b005b3480156103bb57600080fd5b50600254610375906001600160a01b031681565b3480156103db57600080fd5b506103ad6103ea36600461340b565b610da6565b3480156103fb57600080fd5b506103ad61040a36600461342f565b610e1d565b34801561041b57600080fd5b5061042f61042a3660046134ae565b610e8f565b6040516001600160e01b0319909116815260200161034c565b34801561045457600080fd5b5061042f610463366004613589565b610fab565b34801561047457600080fd5b506103ad61048336600461340b565b610fdf565b34801561049457600080fd5b506103ad6104a33660046133d0565b611044565b3480156104b457600080fd5b506103406104c3366004613612565b60036020526000908152604090205460ff1681565b3480156104e457600080fd5b506103ad6104f3366004613671565b611311565b34801561050457600080fd5b506103756105133660046133d0565b6113b4565b34801561052457600080fd5b506103ad610533366004613612565b611427565b34801561054457600080fd5b506103406105533660046133d0565b6001600160a01b039182166000908152600760209081526040808320938352929052205416151590565b34801561058957600080fd5b5061059d6105983660046133d0565b611490565b60405190815260200161034c565b3480156105b757600080fd5b506103ad6105c63660046133d0565b611502565b3480156105d757600080fd5b506103ad6105e63660046133d0565b6115d8565b3480156105f757600080fd5b5061059d61060636600461370a565b61173a565b34801561061757600080fd5b506103ad61062636600461342f565b6117e2565b34801561063757600080fd5b5061059d600080516020613edb83398151915281565b34801561065957600080fd5b506103ad6106683660046133d0565b611854565b34801561067957600080fd5b506103ad61068836600461342f565b6119c2565b34801561069957600080fd5b506103ad6106a836600461375d565b611a79565b3480156106b957600080fd5b506103ad6106c83660046137c8565b611afd565b3480156106d957600080fd5b506103ad6106e83660046133d0565b611c29565b3480156106f957600080fd5b506103ad610708366004613612565b611d99565b34801561071957600080fd5b5061059d600081565b34801561072e57600080fd5b5061034061073d366004613612565b60046020526000908152604090205460ff1681565b34801561075e57600080fd5b50610767611ee6565b60405161034c9392919061385c565b34801561078257600080fd5b506103ad61079136600461389f565b611f75565b3480156107a257600080fd5b506103ad6107b136600461342f565b611fdc565b3480156107c257600080fd5b506103406107d13660046138c1565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61080d6108083660046138ed565b612095565b60405161034c9190613959565b34801561082657600080fd5b5061083a6108353660046133d0565b61237d565b60405161034c919061396c565b34801561085357600080fd5b506103406108623660046133d0565b612558565b34801561087357600080fd5b5061059d6108823660046133d0565b6001600160a01b03919091166000908152600a60209081526040808320938352929052205490565b3480156108b657600080fd5b506103ad6108c536600461340b565b612687565b3480156108d657600080fd5b506103ad6126fe565b3480156108eb57600080fd5b506103ad6108fa3660046139b9565b612774565b34801561090b57600080fd5b506103ad61091a366004613612565b6127a9565b34801561092b57600080fd5b506103ad61093a3660046133d0565b612868565b34801561094b57600080fd5b5061083a61095a366004613a0b565b6128d7565b34801561096b57600080fd5b506103ad61097a36600461342f565b6129e1565b34801561098b57600080fd5b506103ad61099a3660046133d0565b612a9f565b3480156109ab57600080fd5b506103ad6109ba36600461375d565b612b76565b3480156109cb57600080fd5b506109df6109da36600461375d565b612bfa565b60405161034c9190613a3e565b3480156109f857600080fd5b50610340610a07366004613a76565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b348015610a4157600080fd5b506103ad610a5036600461375d565b612d04565b348015610a6157600080fd5b506103ad610a703660046133d0565b612d96565b348015610a8157600080fd5b50610a95610a90366004613a76565b612eca565b6040805182516001600160401b031681526020928301516001600160c01b0316928101929092520161034c565b348015610ace57600080fd5b506103ad610add366004613aa0565b612f59565b348015610aee57600080fd5b506109df610afd366004613aed565b6130cf565b6001600160a01b03808316600090815260076020908152604080832085845290915281205490918491849116610b535760405162461bcd60e51b8152600401610b4a90613b2f565b60405180910390fd5b5050506001600160a01b039182166000908152600b6020908152604080832093835292905220541690565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114610bc45780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b03838116600090815260076020908152604080832086845290915290205416610c90576001600160a01b03831660008181526009602090815260408083208684528252808320839055838352600b82528083208684529091529081902080546001600160a01b031916905551632142170760e11b81526342842e0e90610c5990309033908790600401613b7d565b600060405180830381600087803b158015610c7357600080fd5b505af1158015610c87573d6000803e3d6000fd5b50505050505050565b6001600160a01b0383166000908152600a6020908152604080832085845290915290205415801590610cea57506001600160a01b0383166000908152600a6020908152604080832085845290915290205462249eff194301115b610d365760405162461bcd60e51b815260206004820152601a60248201527f4f776e65722070696e6720686173206e6f7420657870697265640000000000006044820152606401610b4a565b6001600160a01b0383166000908152600660209081526040808320858452909152902080546001600160a01b0319169055610d718383613294565b604051632142170760e11b81526001600160a01b038416906342842e0e90610c5990309033908790600401613b7d565b505050565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff161515600114610dfc5780336040516301d4003760e61b8152600401610b4a929190613b66565b50336000908152600360205260409020805460ff1916911515919091179055565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114610e635780336040516301d4003760e61b8152600401610b4a929190613b66565b506001600160a01b03919091166000908152600360205260409020805460ff1916911515919091179055565b600254600090600160a01b900460ff1615610ed55760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610b4a565b336000818152600760209081526040808320888452825280832080546001600160a01b0319166001600160a01b038b1690811790915584845260088352818420818552835281842080546001600160401b0390811660010116600160401b436001600160c01b0381169190910291909117909155858552600984528285208a8652845282852055848452600a8352818420898552909252808320839055518793927f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6291a450630a85bd0160e11b95945050505050565b6000828152600160205260408120544311610fce5750630b135d3f60e11b610fd9565b506001600160e01b03195b92915050565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146110255780336040516301d4003760e61b8152600401610b4a929190613b66565b5060028054911515600160a01b0260ff60a01b19909216919091179055565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911661108a5760405162461bcd60e51b8152600401610b4a90613b2f565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146110e05780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b03851660009081526005602090815260408083208784528252808320338452909152902054600160a01b900460ff16156111205761130a565b6001600160a01b038086166000908152600660209081526040808320888452909152902054165b6001600160a01b0381161561122b576001600160a01b0381163314156111f4576001600160a01b0386811660008181526005602090815260408083208a8452825280832033808552908352818420805460ff60a01b1916600160a01b179055848452600783528184208b85528352928190205490518a8152939416927fd6aba49fa5adb7dbc18ab12d057e77c75e5d4b345cf473c7514afbbd6f5fc626910160405180910390a45061130a565b6001600160a01b03808716600090815260056020908152604080832089845282528083209484168352939052919091205416611147565b6040805180820182526001600160a01b038089166000818152600660209081528582208b835281528582208054851686526001828701908152848452600583528784208d85528352878420338086529084528885209751885492511515600160a01b026001600160a81b0319909316908816179190911790965580546001600160a01b03191686179055828252600781528582208b83529052849020549351909390911691907fd6aba49fa5adb7dbc18ab12d057e77c75e5d4b345cf473c7514afbbd6f5fc62690611300908a815260200190565b60405180910390a4505b5050505050565b8483146113305760405162461bcd60e51b8152600401610b4a90613ba1565b60005b85811015610c87576113a287878381811061135057611350613bcc565b90506020020160208101906113659190613612565b86868481811061137757611377613bcc565b9050602002013585858581811061139057611390613bcc565b9050602002810190610add9190613be2565b806113ac81613c3e565b915050611333565b6001600160a01b038083166000908152600760209081526040808320858452909152812054909184918491166113fc5760405162461bcd60e51b8152600401610b4a90613b2f565b5050506001600160a01b03918216600090815260076020908152604080832093835292905220541690565b336000908152600080516020613f1b833981519152602052604081205460ff16151560011461146d5780336040516301d4003760e61b8152600401610b4a929190613b66565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038083166000908152600760209081526040808320858452909152812054909184918491166114d85760405162461bcd60e51b8152600401610b4a90613b2f565b5050506001600160a01b039091166000908152600960209081526040808320938352929052205490565b6001600160a01b03808316600090815260076020908152604080832085845290915290205483918391163381148061155e57506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b8061159157506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b6115ad5760405162461bcd60e51b8152600401610b4a90613c59565b5050506001600160a01b039091166000908152600a6020908152604080832093835292905290812055565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911661161e5760405162461bcd60e51b8152600401610b4a90613b2f565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146116745780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b038581166000818152600560209081526040808320898452825280832033808552908352818420805460ff60a01b19169055848452600783528184208a8552835292819020549051898152939416927fd99169b5dcb595fb976fee14578e44584c0ebbbf50cf58d568b3100c59f2f4bb910160405180910390a46116ff8585612558565b61130a575050506001600160a01b039190911660009081526006602090815260408083209383529290522080546001600160a01b0319169055565b60006001600160a01b0382166117625760405162461bcd60e51b8152600401610b4a90613c90565b6000805b848110156117d9576008600087878481811061178457611784613bcc565b90506020020160208101906117999190613612565b6001600160a01b03908116825260208083019390935260409182016000908120918816815292529020546001600160401b03169190910190600101611766565b50949350505050565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146118285780336040516301d4003760e61b8152600401610b4a929190613b66565b506001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b600254600160a01b900460ff16156118975760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610b4a565b6040516323b872dd60e01b81526001600160a01b038316906323b872dd906118c790339030908690600401613b7d565b600060405180830381600087803b1580156118e157600080fd5b505af11580156118f5573d6000803e3d6000fd5b5050506001600160a01b0383166000818152600760209081526040808320868452825280832080546001600160a01b0319163390811790915584845260088352818420818552835281842080546001600160c01b0343908116600160401b026001600160401b039283166001019092169190911790915585855260098452828520888652845282852055848452600a83528184208785529092528083208390555185945090917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6291a45050565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114611a085780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b0383166000818152600080516020613f1b83398151915260209081526040808320805460ff19168715159081179091559051338152909392917fa10c5f794f33daa7ddb160c3de60a8a7a9ab14c911c8c4137c473029149ca5a291015b60405180910390a4505050565b828114611a985760405162461bcd60e51b8152600401610b4a90613ba1565b60005b8381101561130a57611aeb858583818110611ab857611ab8613bcc565b9050602002016020810190611acd9190613612565b848484818110611adf57611adf613bcc565b90506020020135611c29565b80611af581613c3e565b915050611a9b565b6001600160a01b038281166000908152600760209081526040808320858452909152902054163314611b715760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420746865206f776e6572206f66207468617420746f6b656e00000000006044820152606401610b4a565b336001600160a01b0384161415611bbe5760405162461bcd60e51b815260206004820152601160248201527030b8383937bb32903a379031b0b63632b960791b6044820152606401610b4a565b6001600160a01b038281166000818152600b6020908152604080832086845282529182902080546001600160a01b0319169488169485179055905184815291929133917fa0175360a15bca328baf7ea85c7b784d58b222a50d0ce760b10dba336d226a619101611a6c565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911633811480611c8557506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b80611cb857506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b611cd45760405162461bcd60e51b8152600401610b4a90613c59565b8484611ce08282612558565b15611cfd5760405162461bcd60e51b8152600401610b4a90613cd2565b6001600160a01b0380881660009081526007602090815260408083208a845290915290205416611d2d8888613294565b604051632142170760e11b81526001600160a01b038916906342842e0e90611d5d90309085908c90600401613b7d565b600060405180830381600087803b158015611d7757600080fd5b505af1158015611d8b573d6000803e3d6000fd5b505050505050505050505050565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114611ddf5780336040516301d4003760e61b8152600401610b4a929190613b66565b6040516370a0823160e01b815230600482015282906001600160a01b0382169063a9059cbb90339083906370a082319060240160206040518083038186803b158015611e2a57600080fd5b505afa158015611e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e629190613cfb565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611ea857600080fd5b505af1158015611ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613d14565b50505050565b600254604051630c5c275960e21b8152306004820152606091829182916001600160a01b0316906331709d649060240160006040518083038186803b158015611f2e57600080fd5b505afa158015611f42573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6a9190810190613d7e565b925092509250909192565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114611fbb5780336040516301d4003760e61b8152600401610b4a929190613b66565b611fc58243613e05565b600093845260016020526040909320929092555050565b336001600160a01b03831614156120295760405162461bcd60e51b815260206004820152601160248201527030b8383937bb32903a379031b0b63632b960791b6044820152606401610b4a565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6001600160a01b03808616600090815260076020908152604080832088845290915290205460609187918791166120de5760405162461bcd60e51b8152600401610b4a90613b2f565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146121345780336040516301d4003760e61b8152600401610b4a929190613b66565b3360009081526004602052604090205460ff161561219e5760405162461bcd60e51b815260206004820152602160248201527f457865637574696f6e20626c6f636b656420666f72207468617420506f7274616044820152601b60fa1b6064820152608401610b4a565b6001600160a01b03808a1660009081526007602090815260408083208c84529091529020548116908b168114806121fc57506001600160a01b03808b166000908152600b602090815260408083208d84529091529020548c82169116145b8061223157506001600160a01b038082166000908152600c60209081526040808320938f168352929052205460ff1615156001145b61224d5760405162461bcd60e51b8152600401610b4a90613c59565b600080896001600160a01b0316348a8a60405161226b929190613e1d565b60006040518083038185875af1925050503d80600081146122a8576040519150601f19603f3d011682016040523d82523d6000602084013e6122ad565b606091505b509092509050816123205780516123185760405162461bcd60e51b815260206004820152602960248201527f457865637574696e6720616374696f6e206f6e206f7468657220636f6e74726160448201526818dd0819985a5b195960ba1b6064820152608401610b4a565b805181602001fd5b8a8c6001600160a01b03167f38449c831d03fbd20b52e16dd07ad2d656d84665f18160ea515ae1acdd2634c48c8c8c60405161235e93929190613e56565b60405180910390a39550612370915050565b5050509695505050505050565b604080516101f4808252613ea082019092526060916000919060208201613e80803683375050506001600160a01b03858116600090815260066020908152604080832088845290915281205492935091165b6001600160a01b038116156124b0576001600160a01b038681166000908152600560209081526040808320898452825280832093851683529290522054600160a01b900460ff16801561243b57506001600160a01b03811660009081526003602052604090205460ff16155b15612479578083838151811061245357612453613bcc565b6001600160a01b03909216602092830291909101909101528161247581613c3e565b9250505b6001600160a01b038087166000908152600560209081526040808320898452825280832094841683529390529190912054166123cf565b6000826001600160401b038111156124ca576124ca61351c565b6040519080825280602002602001820160405280156124f3578160200160208202803683370190505b50905060005b8381101561254d5784818151811061251357612513613bcc565b602002602001015182828151811061252d5761252d613bcc565b6001600160a01b03909216602092830291909101909101526001016124f9565b509695505050505050565b6001600160a01b038083166000908152600760209081526040808320858452909152812054909184918491166125a05760405162461bcd60e51b8152600401610b4a90613b2f565b6001600160a01b038086166000908152600660209081526040808320888452909152902054165b6001600160a01b03811615612679576001600160a01b038681166000908152600560209081526040808320898452825280832093851683529290522054600160a01b900460ff16801561263357506001600160a01b03811660009081526003602052604090205460ff16155b1561264257600193505061267f565b6001600160a01b038087166000908152600560209081526040808320898452825280832094841683529390529190912054166125c7565b60009350505b505092915050565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146126dd5780336040516301d4003760e61b8152600401610b4a929190613b66565b50336000908152600460205260409020805460ff1916911515919091179055565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146127445780336040516301d4003760e61b8152600401610b4a929190613b66565b60405133904780156108fc02916000818181858888f19350505050158015612770573d6000803e3d6000fd5b5050565b60005b81811015611ee0576127a18484848481811061279557612795613bcc565b90506020020135611854565b600101612777565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146127ef5780336040516301d4003760e61b8152600401610b4a929190613b66565b604051630f41a04d60e11b81523360048201526001600160a01b03831690631e83409a90602401602060405180830381600087803b15801561283057600080fd5b505af1158015612844573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da19190613cfb565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146128ae5780336040516301d4003760e61b8152600401610b4a929190613b66565b506001600160a01b039091166000908152600a6020908152604080832093835292905290812055565b6060828210156129295760405162461bcd60e51b815260206004820152601e60248201527f53656172636820706172616d6574657273206f7574206f66206f7264657200006044820152606401610b4a565b8282036001016001600160401b038111156129465761294661351c565b60405190808252806020026020018201604052801561296f578160200160208202803683370190505b509050825b8281116129d9576001600160a01b038086166000908152600760209081526040808320858452909152902054835191169083908684039081106129b9576129b9613bcc565b6001600160a01b0390921660209283029190910190910152600101612974565b509392505050565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114612a275780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b0383166000818152600080516020613efb8339815191526020908152604091829020805460ff19168615159081179091559151338152919291600080516020613edb833981519152917fa10c5f794f33daa7ddb160c3de60a8a7a9ab14c911c8c4137c473029149ca5a29101611a6c565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114612ae55780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b03838116600090815260076020908152604080832086845290915290205416612b4d5760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd0819195c1bdcda5d1959606a1b6044820152606401610b4a565b506001600160a01b039091166000908152600a6020908152604080832093835292905220439055565b828114612b955760405162461bcd60e51b8152600401610b4a90613ba1565b60005b8381101561130a57612be8858583818110612bb557612bb5613bcc565b9050602002016020810190612bca9190613612565b848484818110612bdc57612bdc613bcc565b90506020020135612d96565b80612bf281613c3e565b915050612b98565b6060838214612c1b5760405162461bcd60e51b8152600401610b4a90613ba1565b836001600160401b03811115612c3357612c3361351c565b604051908082528060200260200182016040528015612c5c578160200160208202803683370190505b50905060005b848110156117d957600a6000878784818110612c8057612c80613bcc565b9050602002016020810190612c959190613612565b6001600160a01b03166001600160a01b031681526020019081526020016000206000858584818110612cc957612cc9613bcc565b90506020020135815260200190815260200160002054828281518110612cf157612cf1613bcc565b6020908102919091010152600101612c62565b828114612d475760405162461bcd60e51b81526020600482015260116024820152704d69736d61746368656420696e7075747360781b6044820152606401610b4a565b60005b8181101561130a57612d8e858583818110612d6757612d67613bcc565b9050602002016020810190612d7c9190613612565b84848481811061279557612795613bcc565b600101612d4a565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911633811480612df257506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b80612e2557506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b612e415760405162461bcd60e51b8152600401610b4a90613c59565b8484612e4d8282612558565b15612e6a5760405162461bcd60e51b8152600401610b4a90613cd2565b6001600160a01b0380881660009081526007602090815260408083208a845290915290205416612e9a8888613294565b6040516323b872dd60e01b81526001600160a01b038916906323b872dd90611d5d90309085908c90600401613b7d565b60408051808201909152600080825260208201526001600160a01b038216612f045760405162461bcd60e51b8152600401610b4a90613c90565b506001600160a01b0391821660009081526008602090815260408083209390941682529182528290208251808401909352546001600160401b0381168352600160401b90046001600160c01b03169082015290565b6001600160a01b038085166000908152600760209081526040808320878452909152902054859185911633811480612fb557506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b80612fe857506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b6130045760405162461bcd60e51b8152600401610b4a90613c59565b86866130108282612558565b1561302d5760405162461bcd60e51b8152600401610b4a90613cd2565b6001600160a01b03808a1660009081526007602090815260408083208c84529091529020541661305d8a8a613294565b604051635c46a7ef60e11b81526001600160a01b038b169063b88d4fde9061309190309085908e908e908e90600401613e84565b600060405180830381600087803b1580156130ab57600080fd5b505af11580156130bf573d6000803e3d6000fd5b5050505050505050505050505050565b6060828210156131215760405162461bcd60e51b815260206004820152601e60248201527f53656172636820706172616d6574657273206f7574206f66206f7264657200006044820152606401610b4a565b6001600160a01b0384166131475760405162461bcd60e51b8152600401610b4a90613c90565b60008383036001600160401b038111156131635761316361351c565b60405190808252806020026020018201604052801561318c578160200160208202803683370190505b5090506000845b8481116131f7576001600160a01b038881166000908152600760209081526040808320858452909152902054811690881614156131ef57808383815181106131dd576131dd613bcc565b60209081029190910101526001909101905b600101613193565b506000816001600160401b038111156132125761321261351c565b60405190808252806020026020018201604052801561323b578160200160208202803683370190505b50905060005b828110156132885783818151811061325b5761325b613bcc565b602002602001015182828151811061327557613275613bcc565b6020908102919091010152600101613241565b50979650505050505050565b6001600160a01b038083166000818152600760209081526040808320868452825280832054848452600983528184208785529092529091205492169183919083907ff341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567906133019043613ec3565b60405190815260200160405180910390a46001600160a01b03928316600081815260086020908152604080832094909616825292835284812080546001600160401b039081166000190116600160401b436001600160c01b03160217905581815260078352848120848252835284812080546001600160a01b0319908116909155828252600984528582208583528452858220829055918152600b83528481209381529290915291902080549091169055565b80356001600160a01b03811681146133cb57600080fd5b919050565b600080604083850312156133e357600080fd5b6133ec836133b4565b946020939093013593505050565b801515811461340857600080fd5b50565b60006020828403121561341d57600080fd5b8135613428816133fa565b9392505050565b6000806040838503121561344257600080fd5b61344b836133b4565b9150602083013561345b816133fa565b809150509250929050565b60008083601f84011261347857600080fd5b5081356001600160401b0381111561348f57600080fd5b6020830191508360208285010111156134a757600080fd5b9250929050565b6000806000806000608086880312156134c657600080fd5b6134cf866133b4565b94506134dd602087016133b4565b93506040860135925060608601356001600160401b038111156134ff57600080fd5b61350b88828901613466565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561355a5761355a61351c565b604052919050565b60006001600160401b0382111561357b5761357b61351c565b50601f01601f191660200190565b6000806040838503121561359c57600080fd5b8235915060208301356001600160401b038111156135b957600080fd5b8301601f810185136135ca57600080fd5b80356135dd6135d882613562565b613532565b8181528660208385010111156135f257600080fd5b816020840160208301376000602083830101528093505050509250929050565b60006020828403121561362457600080fd5b613428826133b4565b60008083601f84011261363f57600080fd5b5081356001600160401b0381111561365657600080fd5b6020830191508360208260051b85010111156134a757600080fd5b6000806000806000806060878903121561368a57600080fd5b86356001600160401b03808211156136a157600080fd5b6136ad8a838b0161362d565b909850965060208901359150808211156136c657600080fd5b6136d28a838b0161362d565b909650945060408901359150808211156136eb57600080fd5b506136f889828a0161362d565b979a9699509497509295939492505050565b60008060006040848603121561371f57600080fd5b83356001600160401b0381111561373557600080fd5b6137418682870161362d565b90945092506137549050602085016133b4565b90509250925092565b6000806000806040858703121561377357600080fd5b84356001600160401b038082111561378a57600080fd5b6137968883890161362d565b909650945060208701359150808211156137af57600080fd5b506137bc8782880161362d565b95989497509550505050565b6000806000606084860312156137dd57600080fd5b6137e6846133b4565b92506137f4602085016133b4565b9150604084013590509250925092565b60005b8381101561381f578181015183820152602001613807565b83811115611ee05750506000910152565b60008151808452613848816020860160208601613804565b601f01601f19169290920160200192915050565b60608152600061386f6060830186613830565b82810360208401526138818186613830565b905082810360408401526138958185613830565b9695505050505050565b600080604083850312156138b257600080fd5b50508035926020909101359150565b600080604083850312156138d457600080fd5b823591506138e4602084016133b4565b90509250929050565b60008060008060008060a0878903121561390657600080fd5b61390f876133b4565b955061391d602088016133b4565b945060408701359350613932606088016133b4565b925060808701356001600160401b0381111561394d57600080fd5b6136f889828a01613466565b6020815260006134286020830184613830565b6020808252825182820181905260009190848201906040850190845b818110156139ad5783516001600160a01b031683529284019291840191600101613988565b50909695505050505050565b6000806000604084860312156139ce57600080fd5b6139d7846133b4565b925060208401356001600160401b038111156139f257600080fd5b6139fe8682870161362d565b9497909650939450505050565b600080600060608486031215613a2057600080fd5b613a29846133b4565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b818110156139ad57835183529284019291840191600101613a5a565b60008060408385031215613a8957600080fd5b613a92836133b4565b91506138e4602084016133b4565b60008060008060608587031215613ab657600080fd5b613abf856133b4565b93506020850135925060408501356001600160401b03811115613ae157600080fd5b6137bc87828801613466565b60008060008060808587031215613b0357600080fd5b613b0c856133b4565b9350613b1a602086016133b4565b93969395505050506040820135916060013590565b60208082526017908201527f4e6f742063757272656e746c79206465706f7369746564000000000000000000604082015260600190565b9182526001600160a01b0316602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b602080825260119082015270125b9c1d5d1cc81b5a5cdb585d18da1959607a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112613bf957600080fd5b8301803591506001600160401b03821115613c1357600080fd5b6020019150368190038213156134a757600080fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415613c5257613c52613c28565b5060010190565b6020808252601d908201527f4e6f7420616e206f70657261746f72206f66207468617420746f6b656e000000604082015260600190565b60208082526022908201527f42616c616e636520717565727920666f7220746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252600f908201526e151bdad95b881a5cc81b1bd8dad959608a1b604082015260600190565b600060208284031215613d0d57600080fd5b5051919050565b600060208284031215613d2657600080fd5b8151613428816133fa565b600082601f830112613d4257600080fd5b8151613d506135d882613562565b818152846020838601011115613d6557600080fd5b613d76826020830160208701613804565b949350505050565b600080600060608486031215613d9357600080fd5b83516001600160401b0380821115613daa57600080fd5b613db687838801613d31565b94506020860151915080821115613dcc57600080fd5b613dd887838801613d31565b93506040860151915080821115613dee57600080fd5b50613dfb86828701613d31565b9150509250925092565b60008219821115613e1857613e18613c28565b500190565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0384168152604060208201819052600090613e7b9083018486613e2d565b95945050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090613eb89083018486613e2d565b979650505050505050565b600082821015613ed557613ed5613c28565b50039056fe9b9bd3cfbb9c232287cfb69ecbd1a9ff754a88300595ea98c0540a12dfb8d36a7e597e46eef5ff451a2574508b59e962880571a57d1f3d797fe78f7747ea7fe7ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5a26469706673582212202255f7cf85f07e62743ac8a162fa1f60d602dc428cb0d2cd272a1741b8f01df564736f6c634300080900330000000000000000000000000b78c64bce6d6d4447e58b09e53f3621f44a2a48

Deployed Bytecode

0x60806040526004361061031a5760003560e01c80635c471995116101ab578063a71604e8116100f7578063e803c63f11610095578063f3fef3a31161006f578063f3fef3a314610a55578063f7888aec14610a75578063fc5472e114610ac2578063fe8c7b6914610ae257600080fd5b8063e803c63f146109bf578063e985e9c5146109ec578063efc908a114610a3557600080fd5b8063cb86d555116100d1578063cb86d5551461093f578063cf488ca71461095f578063da24cad51461097f578063de6d6d961461099f57600080fd5b8063a71604e8146108df578063a81158c7146108ff578063bf47146c1461091f57600080fd5b806391d148541161016457806399cca36c1161013e57806399cca36c146108475780639c27993f146108675780639ef76bd2146108aa578063a0ef91df146108ca57600080fd5b806391d14854146107b6578063935c04be146107fa5780639522b19d1461081a57600080fd5b80635c471995146106ed57806375b238fc1461070d57806378a90072146107225780637a0a3ac51461075257806389b6a48c146107765780638d0716cc1461079657600080fd5b806320285d2d1161026a5780633a02a533116102235780634b0bddd2116101fd5780634b0bddd21461066d5780634bdb2db91461068d57806350070b28146106ad5780635058c460146106cd57600080fd5b80633a02a5331461060b57806340db8f181461062b57806347e7ef241461064d57600080fd5b806320285d2d14610518578063216732741461053857806321b79a3d1461057d5780632a0ce756146105ab57806331e9e9c0146105cb57806337fd25c7146105eb57600080fd5b8063150b7a02116102d757806317be3fa5116102b157806317be3fa5146104885780631c8ff8c9146104a85780631e503ee4146104d85780631f29d2dc146104f857600080fd5b8063150b7a021461040f5780631626ba7e1461044857806316c38b3c1461046857600080fd5b806302befd241461031f578063098f2366146103555780630ce06b681461038d5780630ddfb6b2146103af5780630fdc7956146103cf57806310952088146103ef575b600080fd5b34801561032b57600080fd5b5060025461034090600160a01b900460ff1681565b60405190151581526020015b60405180910390f35b34801561036157600080fd5b506103756103703660046133d0565b610b02565b6040516001600160a01b03909116815260200161034c565b34801561039957600080fd5b506103ad6103a83660046133d0565b610b7e565b005b3480156103bb57600080fd5b50600254610375906001600160a01b031681565b3480156103db57600080fd5b506103ad6103ea36600461340b565b610da6565b3480156103fb57600080fd5b506103ad61040a36600461342f565b610e1d565b34801561041b57600080fd5b5061042f61042a3660046134ae565b610e8f565b6040516001600160e01b0319909116815260200161034c565b34801561045457600080fd5b5061042f610463366004613589565b610fab565b34801561047457600080fd5b506103ad61048336600461340b565b610fdf565b34801561049457600080fd5b506103ad6104a33660046133d0565b611044565b3480156104b457600080fd5b506103406104c3366004613612565b60036020526000908152604090205460ff1681565b3480156104e457600080fd5b506103ad6104f3366004613671565b611311565b34801561050457600080fd5b506103756105133660046133d0565b6113b4565b34801561052457600080fd5b506103ad610533366004613612565b611427565b34801561054457600080fd5b506103406105533660046133d0565b6001600160a01b039182166000908152600760209081526040808320938352929052205416151590565b34801561058957600080fd5b5061059d6105983660046133d0565b611490565b60405190815260200161034c565b3480156105b757600080fd5b506103ad6105c63660046133d0565b611502565b3480156105d757600080fd5b506103ad6105e63660046133d0565b6115d8565b3480156105f757600080fd5b5061059d61060636600461370a565b61173a565b34801561061757600080fd5b506103ad61062636600461342f565b6117e2565b34801561063757600080fd5b5061059d600080516020613edb83398151915281565b34801561065957600080fd5b506103ad6106683660046133d0565b611854565b34801561067957600080fd5b506103ad61068836600461342f565b6119c2565b34801561069957600080fd5b506103ad6106a836600461375d565b611a79565b3480156106b957600080fd5b506103ad6106c83660046137c8565b611afd565b3480156106d957600080fd5b506103ad6106e83660046133d0565b611c29565b3480156106f957600080fd5b506103ad610708366004613612565b611d99565b34801561071957600080fd5b5061059d600081565b34801561072e57600080fd5b5061034061073d366004613612565b60046020526000908152604090205460ff1681565b34801561075e57600080fd5b50610767611ee6565b60405161034c9392919061385c565b34801561078257600080fd5b506103ad61079136600461389f565b611f75565b3480156107a257600080fd5b506103ad6107b136600461342f565b611fdc565b3480156107c257600080fd5b506103406107d13660046138c1565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61080d6108083660046138ed565b612095565b60405161034c9190613959565b34801561082657600080fd5b5061083a6108353660046133d0565b61237d565b60405161034c919061396c565b34801561085357600080fd5b506103406108623660046133d0565b612558565b34801561087357600080fd5b5061059d6108823660046133d0565b6001600160a01b03919091166000908152600a60209081526040808320938352929052205490565b3480156108b657600080fd5b506103ad6108c536600461340b565b612687565b3480156108d657600080fd5b506103ad6126fe565b3480156108eb57600080fd5b506103ad6108fa3660046139b9565b612774565b34801561090b57600080fd5b506103ad61091a366004613612565b6127a9565b34801561092b57600080fd5b506103ad61093a3660046133d0565b612868565b34801561094b57600080fd5b5061083a61095a366004613a0b565b6128d7565b34801561096b57600080fd5b506103ad61097a36600461342f565b6129e1565b34801561098b57600080fd5b506103ad61099a3660046133d0565b612a9f565b3480156109ab57600080fd5b506103ad6109ba36600461375d565b612b76565b3480156109cb57600080fd5b506109df6109da36600461375d565b612bfa565b60405161034c9190613a3e565b3480156109f857600080fd5b50610340610a07366004613a76565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b348015610a4157600080fd5b506103ad610a5036600461375d565b612d04565b348015610a6157600080fd5b506103ad610a703660046133d0565b612d96565b348015610a8157600080fd5b50610a95610a90366004613a76565b612eca565b6040805182516001600160401b031681526020928301516001600160c01b0316928101929092520161034c565b348015610ace57600080fd5b506103ad610add366004613aa0565b612f59565b348015610aee57600080fd5b506109df610afd366004613aed565b6130cf565b6001600160a01b03808316600090815260076020908152604080832085845290915281205490918491849116610b535760405162461bcd60e51b8152600401610b4a90613b2f565b60405180910390fd5b5050506001600160a01b039182166000908152600b6020908152604080832093835292905220541690565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114610bc45780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b03838116600090815260076020908152604080832086845290915290205416610c90576001600160a01b03831660008181526009602090815260408083208684528252808320839055838352600b82528083208684529091529081902080546001600160a01b031916905551632142170760e11b81526342842e0e90610c5990309033908790600401613b7d565b600060405180830381600087803b158015610c7357600080fd5b505af1158015610c87573d6000803e3d6000fd5b50505050505050565b6001600160a01b0383166000908152600a6020908152604080832085845290915290205415801590610cea57506001600160a01b0383166000908152600a6020908152604080832085845290915290205462249eff194301115b610d365760405162461bcd60e51b815260206004820152601a60248201527f4f776e65722070696e6720686173206e6f7420657870697265640000000000006044820152606401610b4a565b6001600160a01b0383166000908152600660209081526040808320858452909152902080546001600160a01b0319169055610d718383613294565b604051632142170760e11b81526001600160a01b038416906342842e0e90610c5990309033908790600401613b7d565b505050565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff161515600114610dfc5780336040516301d4003760e61b8152600401610b4a929190613b66565b50336000908152600360205260409020805460ff1916911515919091179055565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114610e635780336040516301d4003760e61b8152600401610b4a929190613b66565b506001600160a01b03919091166000908152600360205260409020805460ff1916911515919091179055565b600254600090600160a01b900460ff1615610ed55760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610b4a565b336000818152600760209081526040808320888452825280832080546001600160a01b0319166001600160a01b038b1690811790915584845260088352818420818552835281842080546001600160401b0390811660010116600160401b436001600160c01b0381169190910291909117909155858552600984528285208a8652845282852055848452600a8352818420898552909252808320839055518793927f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6291a450630a85bd0160e11b95945050505050565b6000828152600160205260408120544311610fce5750630b135d3f60e11b610fd9565b506001600160e01b03195b92915050565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146110255780336040516301d4003760e61b8152600401610b4a929190613b66565b5060028054911515600160a01b0260ff60a01b19909216919091179055565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911661108a5760405162461bcd60e51b8152600401610b4a90613b2f565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146110e05780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b03851660009081526005602090815260408083208784528252808320338452909152902054600160a01b900460ff16156111205761130a565b6001600160a01b038086166000908152600660209081526040808320888452909152902054165b6001600160a01b0381161561122b576001600160a01b0381163314156111f4576001600160a01b0386811660008181526005602090815260408083208a8452825280832033808552908352818420805460ff60a01b1916600160a01b179055848452600783528184208b85528352928190205490518a8152939416927fd6aba49fa5adb7dbc18ab12d057e77c75e5d4b345cf473c7514afbbd6f5fc626910160405180910390a45061130a565b6001600160a01b03808716600090815260056020908152604080832089845282528083209484168352939052919091205416611147565b6040805180820182526001600160a01b038089166000818152600660209081528582208b835281528582208054851686526001828701908152848452600583528784208d85528352878420338086529084528885209751885492511515600160a01b026001600160a81b0319909316908816179190911790965580546001600160a01b03191686179055828252600781528582208b83529052849020549351909390911691907fd6aba49fa5adb7dbc18ab12d057e77c75e5d4b345cf473c7514afbbd6f5fc62690611300908a815260200190565b60405180910390a4505b5050505050565b8483146113305760405162461bcd60e51b8152600401610b4a90613ba1565b60005b85811015610c87576113a287878381811061135057611350613bcc565b90506020020160208101906113659190613612565b86868481811061137757611377613bcc565b9050602002013585858581811061139057611390613bcc565b9050602002810190610add9190613be2565b806113ac81613c3e565b915050611333565b6001600160a01b038083166000908152600760209081526040808320858452909152812054909184918491166113fc5760405162461bcd60e51b8152600401610b4a90613b2f565b5050506001600160a01b03918216600090815260076020908152604080832093835292905220541690565b336000908152600080516020613f1b833981519152602052604081205460ff16151560011461146d5780336040516301d4003760e61b8152600401610b4a929190613b66565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038083166000908152600760209081526040808320858452909152812054909184918491166114d85760405162461bcd60e51b8152600401610b4a90613b2f565b5050506001600160a01b039091166000908152600960209081526040808320938352929052205490565b6001600160a01b03808316600090815260076020908152604080832085845290915290205483918391163381148061155e57506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b8061159157506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b6115ad5760405162461bcd60e51b8152600401610b4a90613c59565b5050506001600160a01b039091166000908152600a6020908152604080832093835292905290812055565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911661161e5760405162461bcd60e51b8152600401610b4a90613b2f565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146116745780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b038581166000818152600560209081526040808320898452825280832033808552908352818420805460ff60a01b19169055848452600783528184208a8552835292819020549051898152939416927fd99169b5dcb595fb976fee14578e44584c0ebbbf50cf58d568b3100c59f2f4bb910160405180910390a46116ff8585612558565b61130a575050506001600160a01b039190911660009081526006602090815260408083209383529290522080546001600160a01b0319169055565b60006001600160a01b0382166117625760405162461bcd60e51b8152600401610b4a90613c90565b6000805b848110156117d9576008600087878481811061178457611784613bcc565b90506020020160208101906117999190613612565b6001600160a01b03908116825260208083019390935260409182016000908120918816815292529020546001600160401b03169190910190600101611766565b50949350505050565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146118285780336040516301d4003760e61b8152600401610b4a929190613b66565b506001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b600254600160a01b900460ff16156118975760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610b4a565b6040516323b872dd60e01b81526001600160a01b038316906323b872dd906118c790339030908690600401613b7d565b600060405180830381600087803b1580156118e157600080fd5b505af11580156118f5573d6000803e3d6000fd5b5050506001600160a01b0383166000818152600760209081526040808320868452825280832080546001600160a01b0319163390811790915584845260088352818420818552835281842080546001600160c01b0343908116600160401b026001600160401b039283166001019092169190911790915585855260098452828520888652845282852055848452600a83528184208785529092528083208390555185945090917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6291a45050565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114611a085780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b0383166000818152600080516020613f1b83398151915260209081526040808320805460ff19168715159081179091559051338152909392917fa10c5f794f33daa7ddb160c3de60a8a7a9ab14c911c8c4137c473029149ca5a291015b60405180910390a4505050565b828114611a985760405162461bcd60e51b8152600401610b4a90613ba1565b60005b8381101561130a57611aeb858583818110611ab857611ab8613bcc565b9050602002016020810190611acd9190613612565b848484818110611adf57611adf613bcc565b90506020020135611c29565b80611af581613c3e565b915050611a9b565b6001600160a01b038281166000908152600760209081526040808320858452909152902054163314611b715760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420746865206f776e6572206f66207468617420746f6b656e00000000006044820152606401610b4a565b336001600160a01b0384161415611bbe5760405162461bcd60e51b815260206004820152601160248201527030b8383937bb32903a379031b0b63632b960791b6044820152606401610b4a565b6001600160a01b038281166000818152600b6020908152604080832086845282529182902080546001600160a01b0319169488169485179055905184815291929133917fa0175360a15bca328baf7ea85c7b784d58b222a50d0ce760b10dba336d226a619101611a6c565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911633811480611c8557506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b80611cb857506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b611cd45760405162461bcd60e51b8152600401610b4a90613c59565b8484611ce08282612558565b15611cfd5760405162461bcd60e51b8152600401610b4a90613cd2565b6001600160a01b0380881660009081526007602090815260408083208a845290915290205416611d2d8888613294565b604051632142170760e11b81526001600160a01b038916906342842e0e90611d5d90309085908c90600401613b7d565b600060405180830381600087803b158015611d7757600080fd5b505af1158015611d8b573d6000803e3d6000fd5b505050505050505050505050565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114611ddf5780336040516301d4003760e61b8152600401610b4a929190613b66565b6040516370a0823160e01b815230600482015282906001600160a01b0382169063a9059cbb90339083906370a082319060240160206040518083038186803b158015611e2a57600080fd5b505afa158015611e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e629190613cfb565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015611ea857600080fd5b505af1158015611ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613d14565b50505050565b600254604051630c5c275960e21b8152306004820152606091829182916001600160a01b0316906331709d649060240160006040518083038186803b158015611f2e57600080fd5b505afa158015611f42573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6a9190810190613d7e565b925092509250909192565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114611fbb5780336040516301d4003760e61b8152600401610b4a929190613b66565b611fc58243613e05565b600093845260016020526040909320929092555050565b336001600160a01b03831614156120295760405162461bcd60e51b815260206004820152601160248201527030b8383937bb32903a379031b0b63632b960791b6044820152606401610b4a565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6001600160a01b03808616600090815260076020908152604080832088845290915290205460609187918791166120de5760405162461bcd60e51b8152600401610b4a90613b2f565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146121345780336040516301d4003760e61b8152600401610b4a929190613b66565b3360009081526004602052604090205460ff161561219e5760405162461bcd60e51b815260206004820152602160248201527f457865637574696f6e20626c6f636b656420666f72207468617420506f7274616044820152601b60fa1b6064820152608401610b4a565b6001600160a01b03808a1660009081526007602090815260408083208c84529091529020548116908b168114806121fc57506001600160a01b03808b166000908152600b602090815260408083208d84529091529020548c82169116145b8061223157506001600160a01b038082166000908152600c60209081526040808320938f168352929052205460ff1615156001145b61224d5760405162461bcd60e51b8152600401610b4a90613c59565b600080896001600160a01b0316348a8a60405161226b929190613e1d565b60006040518083038185875af1925050503d80600081146122a8576040519150601f19603f3d011682016040523d82523d6000602084013e6122ad565b606091505b509092509050816123205780516123185760405162461bcd60e51b815260206004820152602960248201527f457865637574696e6720616374696f6e206f6e206f7468657220636f6e74726160448201526818dd0819985a5b195960ba1b6064820152608401610b4a565b805181602001fd5b8a8c6001600160a01b03167f38449c831d03fbd20b52e16dd07ad2d656d84665f18160ea515ae1acdd2634c48c8c8c60405161235e93929190613e56565b60405180910390a39550612370915050565b5050509695505050505050565b604080516101f4808252613ea082019092526060916000919060208201613e80803683375050506001600160a01b03858116600090815260066020908152604080832088845290915281205492935091165b6001600160a01b038116156124b0576001600160a01b038681166000908152600560209081526040808320898452825280832093851683529290522054600160a01b900460ff16801561243b57506001600160a01b03811660009081526003602052604090205460ff16155b15612479578083838151811061245357612453613bcc565b6001600160a01b03909216602092830291909101909101528161247581613c3e565b9250505b6001600160a01b038087166000908152600560209081526040808320898452825280832094841683529390529190912054166123cf565b6000826001600160401b038111156124ca576124ca61351c565b6040519080825280602002602001820160405280156124f3578160200160208202803683370190505b50905060005b8381101561254d5784818151811061251357612513613bcc565b602002602001015182828151811061252d5761252d613bcc565b6001600160a01b03909216602092830291909101909101526001016124f9565b509695505050505050565b6001600160a01b038083166000908152600760209081526040808320858452909152812054909184918491166125a05760405162461bcd60e51b8152600401610b4a90613b2f565b6001600160a01b038086166000908152600660209081526040808320888452909152902054165b6001600160a01b03811615612679576001600160a01b038681166000908152600560209081526040808320898452825280832093851683529290522054600160a01b900460ff16801561263357506001600160a01b03811660009081526003602052604090205460ff16155b1561264257600193505061267f565b6001600160a01b038087166000908152600560209081526040808320898452825280832094841683529390529190912054166125c7565b60009350505b505092915050565b336000908152600080516020613efb8339815191526020526040902054600080516020613edb8339815191529060ff1615156001146126dd5780336040516301d4003760e61b8152600401610b4a929190613b66565b50336000908152600460205260409020805460ff1916911515919091179055565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146127445780336040516301d4003760e61b8152600401610b4a929190613b66565b60405133904780156108fc02916000818181858888f19350505050158015612770573d6000803e3d6000fd5b5050565b60005b81811015611ee0576127a18484848481811061279557612795613bcc565b90506020020135611854565b600101612777565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146127ef5780336040516301d4003760e61b8152600401610b4a929190613b66565b604051630f41a04d60e11b81523360048201526001600160a01b03831690631e83409a90602401602060405180830381600087803b15801561283057600080fd5b505af1158015612844573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da19190613cfb565b336000908152600080516020613f1b833981519152602052604081205460ff1615156001146128ae5780336040516301d4003760e61b8152600401610b4a929190613b66565b506001600160a01b039091166000908152600a6020908152604080832093835292905290812055565b6060828210156129295760405162461bcd60e51b815260206004820152601e60248201527f53656172636820706172616d6574657273206f7574206f66206f7264657200006044820152606401610b4a565b8282036001016001600160401b038111156129465761294661351c565b60405190808252806020026020018201604052801561296f578160200160208202803683370190505b509050825b8281116129d9576001600160a01b038086166000908152600760209081526040808320858452909152902054835191169083908684039081106129b9576129b9613bcc565b6001600160a01b0390921660209283029190910190910152600101612974565b509392505050565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114612a275780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b0383166000818152600080516020613efb8339815191526020908152604091829020805460ff19168615159081179091559151338152919291600080516020613edb833981519152917fa10c5f794f33daa7ddb160c3de60a8a7a9ab14c911c8c4137c473029149ca5a29101611a6c565b336000908152600080516020613f1b833981519152602052604081205460ff161515600114612ae55780336040516301d4003760e61b8152600401610b4a929190613b66565b6001600160a01b03838116600090815260076020908152604080832086845290915290205416612b4d5760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881b9bdd0819195c1bdcda5d1959606a1b6044820152606401610b4a565b506001600160a01b039091166000908152600a6020908152604080832093835292905220439055565b828114612b955760405162461bcd60e51b8152600401610b4a90613ba1565b60005b8381101561130a57612be8858583818110612bb557612bb5613bcc565b9050602002016020810190612bca9190613612565b848484818110612bdc57612bdc613bcc565b90506020020135612d96565b80612bf281613c3e565b915050612b98565b6060838214612c1b5760405162461bcd60e51b8152600401610b4a90613ba1565b836001600160401b03811115612c3357612c3361351c565b604051908082528060200260200182016040528015612c5c578160200160208202803683370190505b50905060005b848110156117d957600a6000878784818110612c8057612c80613bcc565b9050602002016020810190612c959190613612565b6001600160a01b03166001600160a01b031681526020019081526020016000206000858584818110612cc957612cc9613bcc565b90506020020135815260200190815260200160002054828281518110612cf157612cf1613bcc565b6020908102919091010152600101612c62565b828114612d475760405162461bcd60e51b81526020600482015260116024820152704d69736d61746368656420696e7075747360781b6044820152606401610b4a565b60005b8181101561130a57612d8e858583818110612d6757612d67613bcc565b9050602002016020810190612d7c9190613612565b84848481811061279557612795613bcc565b600101612d4a565b6001600160a01b038083166000908152600760209081526040808320858452909152902054839183911633811480612df257506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b80612e2557506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b612e415760405162461bcd60e51b8152600401610b4a90613c59565b8484612e4d8282612558565b15612e6a5760405162461bcd60e51b8152600401610b4a90613cd2565b6001600160a01b0380881660009081526007602090815260408083208a845290915290205416612e9a8888613294565b6040516323b872dd60e01b81526001600160a01b038916906323b872dd90611d5d90309085908c90600401613b7d565b60408051808201909152600080825260208201526001600160a01b038216612f045760405162461bcd60e51b8152600401610b4a90613c90565b506001600160a01b0391821660009081526008602090815260408083209390941682529182528290208251808401909352546001600160401b0381168352600160401b90046001600160c01b03169082015290565b6001600160a01b038085166000908152600760209081526040808320878452909152902054859185911633811480612fb557506001600160a01b038381166000908152600b602090815260408083208684529091529020541633145b80612fe857506001600160a01b0381166000908152600c6020908152604080832033845290915290205460ff1615156001145b6130045760405162461bcd60e51b8152600401610b4a90613c59565b86866130108282612558565b1561302d5760405162461bcd60e51b8152600401610b4a90613cd2565b6001600160a01b03808a1660009081526007602090815260408083208c84529091529020541661305d8a8a613294565b604051635c46a7ef60e11b81526001600160a01b038b169063b88d4fde9061309190309085908e908e908e90600401613e84565b600060405180830381600087803b1580156130ab57600080fd5b505af11580156130bf573d6000803e3d6000fd5b5050505050505050505050505050565b6060828210156131215760405162461bcd60e51b815260206004820152601e60248201527f53656172636820706172616d6574657273206f7574206f66206f7264657200006044820152606401610b4a565b6001600160a01b0384166131475760405162461bcd60e51b8152600401610b4a90613c90565b60008383036001600160401b038111156131635761316361351c565b60405190808252806020026020018201604052801561318c578160200160208202803683370190505b5090506000845b8481116131f7576001600160a01b038881166000908152600760209081526040808320858452909152902054811690881614156131ef57808383815181106131dd576131dd613bcc565b60209081029190910101526001909101905b600101613193565b506000816001600160401b038111156132125761321261351c565b60405190808252806020026020018201604052801561323b578160200160208202803683370190505b50905060005b828110156132885783818151811061325b5761325b613bcc565b602002602001015182828151811061327557613275613bcc565b6020908102919091010152600101613241565b50979650505050505050565b6001600160a01b038083166000818152600760209081526040808320868452825280832054848452600983528184208785529092529091205492169183919083907ff341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567906133019043613ec3565b60405190815260200160405180910390a46001600160a01b03928316600081815260086020908152604080832094909616825292835284812080546001600160401b039081166000190116600160401b436001600160c01b03160217905581815260078352848120848252835284812080546001600160a01b0319908116909155828252600984528582208583528452858220829055918152600b83528481209381529290915291902080549091169055565b80356001600160a01b03811681146133cb57600080fd5b919050565b600080604083850312156133e357600080fd5b6133ec836133b4565b946020939093013593505050565b801515811461340857600080fd5b50565b60006020828403121561341d57600080fd5b8135613428816133fa565b9392505050565b6000806040838503121561344257600080fd5b61344b836133b4565b9150602083013561345b816133fa565b809150509250929050565b60008083601f84011261347857600080fd5b5081356001600160401b0381111561348f57600080fd5b6020830191508360208285010111156134a757600080fd5b9250929050565b6000806000806000608086880312156134c657600080fd5b6134cf866133b4565b94506134dd602087016133b4565b93506040860135925060608601356001600160401b038111156134ff57600080fd5b61350b88828901613466565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561355a5761355a61351c565b604052919050565b60006001600160401b0382111561357b5761357b61351c565b50601f01601f191660200190565b6000806040838503121561359c57600080fd5b8235915060208301356001600160401b038111156135b957600080fd5b8301601f810185136135ca57600080fd5b80356135dd6135d882613562565b613532565b8181528660208385010111156135f257600080fd5b816020840160208301376000602083830101528093505050509250929050565b60006020828403121561362457600080fd5b613428826133b4565b60008083601f84011261363f57600080fd5b5081356001600160401b0381111561365657600080fd5b6020830191508360208260051b85010111156134a757600080fd5b6000806000806000806060878903121561368a57600080fd5b86356001600160401b03808211156136a157600080fd5b6136ad8a838b0161362d565b909850965060208901359150808211156136c657600080fd5b6136d28a838b0161362d565b909650945060408901359150808211156136eb57600080fd5b506136f889828a0161362d565b979a9699509497509295939492505050565b60008060006040848603121561371f57600080fd5b83356001600160401b0381111561373557600080fd5b6137418682870161362d565b90945092506137549050602085016133b4565b90509250925092565b6000806000806040858703121561377357600080fd5b84356001600160401b038082111561378a57600080fd5b6137968883890161362d565b909650945060208701359150808211156137af57600080fd5b506137bc8782880161362d565b95989497509550505050565b6000806000606084860312156137dd57600080fd5b6137e6846133b4565b92506137f4602085016133b4565b9150604084013590509250925092565b60005b8381101561381f578181015183820152602001613807565b83811115611ee05750506000910152565b60008151808452613848816020860160208601613804565b601f01601f19169290920160200192915050565b60608152600061386f6060830186613830565b82810360208401526138818186613830565b905082810360408401526138958185613830565b9695505050505050565b600080604083850312156138b257600080fd5b50508035926020909101359150565b600080604083850312156138d457600080fd5b823591506138e4602084016133b4565b90509250929050565b60008060008060008060a0878903121561390657600080fd5b61390f876133b4565b955061391d602088016133b4565b945060408701359350613932606088016133b4565b925060808701356001600160401b0381111561394d57600080fd5b6136f889828a01613466565b6020815260006134286020830184613830565b6020808252825182820181905260009190848201906040850190845b818110156139ad5783516001600160a01b031683529284019291840191600101613988565b50909695505050505050565b6000806000604084860312156139ce57600080fd5b6139d7846133b4565b925060208401356001600160401b038111156139f257600080fd5b6139fe8682870161362d565b9497909650939450505050565b600080600060608486031215613a2057600080fd5b613a29846133b4565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b818110156139ad57835183529284019291840191600101613a5a565b60008060408385031215613a8957600080fd5b613a92836133b4565b91506138e4602084016133b4565b60008060008060608587031215613ab657600080fd5b613abf856133b4565b93506020850135925060408501356001600160401b03811115613ae157600080fd5b6137bc87828801613466565b60008060008060808587031215613b0357600080fd5b613b0c856133b4565b9350613b1a602086016133b4565b93969395505050506040820135916060013590565b60208082526017908201527f4e6f742063757272656e746c79206465706f7369746564000000000000000000604082015260600190565b9182526001600160a01b0316602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b602080825260119082015270125b9c1d5d1cc81b5a5cdb585d18da1959607a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112613bf957600080fd5b8301803591506001600160401b03821115613c1357600080fd5b6020019150368190038213156134a757600080fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415613c5257613c52613c28565b5060010190565b6020808252601d908201527f4e6f7420616e206f70657261746f72206f66207468617420746f6b656e000000604082015260600190565b60208082526022908201527f42616c616e636520717565727920666f7220746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252600f908201526e151bdad95b881a5cc81b1bd8dad959608a1b604082015260600190565b600060208284031215613d0d57600080fd5b5051919050565b600060208284031215613d2657600080fd5b8151613428816133fa565b600082601f830112613d4257600080fd5b8151613d506135d882613562565b818152846020838601011115613d6557600080fd5b613d76826020830160208701613804565b949350505050565b600080600060608486031215613d9357600080fd5b83516001600160401b0380821115613daa57600080fd5b613db687838801613d31565b94506020860151915080821115613dcc57600080fd5b613dd887838801613d31565b93506040860151915080821115613dee57600080fd5b50613dfb86828701613d31565b9150509250925092565b60008219821115613e1857613e18613c28565b500190565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0384168152604060208201819052600090613e7b9083018486613e2d565b95945050505050565b6001600160a01b0386811682528516602082015260408101849052608060608201819052600090613eb89083018486613e2d565b979650505050505050565b600082821015613ed557613ed5613c28565b50039056fe9b9bd3cfbb9c232287cfb69ecbd1a9ff754a88300595ea98c0540a12dfb8d36a7e597e46eef5ff451a2574508b59e962880571a57d1f3d797fe78f7747ea7fe7ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5a26469706673582212202255f7cf85f07e62743ac8a162fa1f60d602dc428cb0d2cd272a1741b8f01df564736f6c63430008090033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000b78c64bce6d6d4447e58b09e53f3621f44a2a48

-----Decoded View---------------
Arg [0] : documentationAddress (address): 0x0B78C64bCE6d6d4447e58b09E53F3621f44A2a48

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000b78c64bce6d6d4447e58b09e53f3621f44a2a48


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.