Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 218 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Base URI | 15408663 | 1250 days ago | IN | 0 ETH | 0.00036709 | ||||
| Mint | 15407693 | 1250 days ago | IN | 0 ETH | 0.00053004 | ||||
| Set Link | 15388449 | 1253 days ago | IN | 0 ETH | 0.00057311 | ||||
| Set Link | 15388449 | 1253 days ago | IN | 0 ETH | 0.00056969 | ||||
| Set Link | 15386751 | 1254 days ago | IN | 0 ETH | 0.00040687 | ||||
| Set Link | 15384899 | 1254 days ago | IN | 0 ETH | 0.00138082 | ||||
| Set Link | 15382859 | 1254 days ago | IN | 0 ETH | 0.00084052 | ||||
| Set Link | 15382859 | 1254 days ago | IN | 0 ETH | 0.0008402 | ||||
| Set Link | 15382859 | 1254 days ago | IN | 0 ETH | 0.00084045 | ||||
| Set Link | 15382859 | 1254 days ago | IN | 0 ETH | 0.00084029 | ||||
| Set Link | 15381260 | 1255 days ago | IN | 0 ETH | 0.00163351 | ||||
| Set Link | 15381181 | 1255 days ago | IN | 0 ETH | 0.00045488 | ||||
| Set Link | 15381099 | 1255 days ago | IN | 0 ETH | 0.00056688 | ||||
| Set Link | 15378158 | 1255 days ago | IN | 0 ETH | 0.00125398 | ||||
| Set Link | 15377517 | 1255 days ago | IN | 0 ETH | 0.00052168 | ||||
| Set Link | 15377404 | 1255 days ago | IN | 0 ETH | 0.00058811 | ||||
| Set Link | 15376139 | 1255 days ago | IN | 0 ETH | 0.00083675 | ||||
| Set Link | 15375439 | 1255 days ago | IN | 0 ETH | 0.00098119 | ||||
| Set Link | 15375436 | 1255 days ago | IN | 0 ETH | 0.00113079 | ||||
| Set Link | 15370597 | 1256 days ago | IN | 0 ETH | 0.00125331 | ||||
| Set Link | 15365489 | 1257 days ago | IN | 0 ETH | 0.00142212 | ||||
| Set Link | 15365484 | 1257 days ago | IN | 0 ETH | 0.00109676 | ||||
| Set Link | 15365300 | 1257 days ago | IN | 0 ETH | 0.00155517 | ||||
| Set Link | 15364863 | 1257 days ago | IN | 0 ETH | 0.00085297 | ||||
| Mint | 15356780 | 1258 days ago | IN | 0 ETH | 0.00073344 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Soulink
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import "./libraries/SoulinkLibrary.sol";
import "./standards/SoulBoundToken.sol";
import "./interfaces/ISoulink.sol";
contract Soulink is Ownable, SoulBoundToken, EIP712, ISoulink {
uint128 private _totalSupply;
uint128 private _burnCount;
// keccak256("RequestLink(address to,uint256 deadline)");
bytes32 private constant _REQUESTLINK_TYPEHASH = 0xc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc4;
mapping(address => bool) public isMinter;
mapping(uint256 => mapping(uint256 => bool)) internal _isLinked;
mapping(uint256 => uint256) internal _internalId;
mapping(bytes32 => bool) internal _notUsableSig;
string internal __baseURI;
constructor() SoulBoundToken("Soulink", "SL") EIP712("Soulink", "1") {
isMinter[msg.sender] = true;
__baseURI = "https://api.soul.ink/metadata/";
}
//ownership functions
function setBaseURI(string calldata baseURI_) external onlyOwner {
__baseURI = baseURI_;
emit SetBaseURI(baseURI_);
}
function setMinter(address target, bool _isMinter) external onlyOwner {
require(isMinter[target] != _isMinter, "UNCHANGED");
isMinter[target] = _isMinter;
emit SetMinter(target, _isMinter);
}
function updateSigNotUsable(bytes32 sigHash) external onlyOwner {
_notUsableSig[sigHash] = true;
}
//external view/pure functions
function DOMAIN_SEPARATOR() public view returns (bytes32) {
return _domainSeparatorV4();
}
function totalSupply() public view returns (uint256) {
return _totalSupply - _burnCount;
}
function getTokenId(address owner) public pure returns (uint256) {
return SoulinkLibrary._getTokenId(owner);
}
function isLinked(uint256 id0, uint256 id1) external view returns (bool) {
(uint256 iId0, uint256 iId1) = _getInternalIds(id0, id1);
return _isLinked[iId0][iId1];
}
function isUsableSig(bytes32 sigHash) external view returns (bool) {
return !_notUsableSig[sigHash];
}
//internal view/pure functions
function _baseURI() internal view override returns (string memory) {
return __baseURI;
}
function _requireUsable(bytes32 sig) internal view {
require(!_notUsableSig[sig], "USED_SIGNATURE");
}
function _getInternalIds(uint256 id0, uint256 id1) internal view returns (uint256 iId0, uint256 iId1) {
_requireMinted(id0);
_requireMinted(id1);
(iId0, iId1) = SoulinkLibrary._sort(_internalId[id0], _internalId[id1]);
}
//external functions
function mint(address to) external returns (uint256 tokenId) {
require(isMinter[msg.sender], "UNAUTHORIZED");
require(balanceOf(to) == 0, "ALREADY_MINTED");
tokenId = getTokenId(to);
_mint(to, tokenId);
_totalSupply++;
_internalId[tokenId] = _totalSupply; //_internalId starts from 1
}
function burn(uint256 tokenId) external {
require(getTokenId(msg.sender) == tokenId, "UNAUTHORIZED");
_burn(tokenId);
_burnCount++;
delete _internalId[tokenId];
emit ResetLink(tokenId);
}
/**
0: id of msg.sender
1: id of target
*/
function setLink(
uint256 targetId,
bytes[2] calldata sigs,
uint256[2] calldata deadlines
) external {
require(block.timestamp <= deadlines[0] && block.timestamp <= deadlines[1], "EXPIRED_DEADLINE");
uint256 myId = getTokenId(msg.sender);
bytes32 hash0 = _hashTypedDataV4(keccak256(abi.encode(_REQUESTLINK_TYPEHASH, targetId, deadlines[0])));
SignatureChecker.isValidSignatureNow(msg.sender, hash0, sigs[0]);
bytes32 sigHash = keccak256(sigs[0]);
_requireUsable(sigHash);
_notUsableSig[sigHash] = true;
bytes32 hash1 = _hashTypedDataV4(keccak256(abi.encode(_REQUESTLINK_TYPEHASH, myId, deadlines[1])));
SignatureChecker.isValidSignatureNow(address(uint160(targetId)), hash1, sigs[1]);
sigHash = keccak256(sigs[1]);
_requireUsable(sigHash);
_notUsableSig[sigHash] = true;
(uint256 iId0, uint256 iId1) = _getInternalIds(myId, targetId);
require(!_isLinked[iId0][iId1], "ALREADY_LINKED");
_isLinked[iId0][iId1] = true;
emit SetLink(myId, targetId);
}
function breakLink(uint256 targetId) external {
uint256 myId = getTokenId(msg.sender);
(uint256 iId0, uint256 iId1) = _getInternalIds(myId, targetId);
require(_isLinked[iId0][iId1], "NOT_LINKED");
delete _isLinked[iId0][iId1];
emit BreakLink(myId, targetId);
}
function cancelLinkSig(
uint256 targetId,
uint256 deadline,
bytes calldata sig
) external {
bytes32 hash = _hashTypedDataV4(keccak256(abi.encode(_REQUESTLINK_TYPEHASH, targetId, deadline)));
SignatureChecker.isValidSignatureNow(msg.sender, hash, sig);
bytes32 sigHash = keccak256(sig);
_requireUsable(sigHash);
_notUsableSig[sigHash] = true;
emit CancelLinkSig(msg.sender, targetId, deadline);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)
pragma solidity ^0.8.0;
import "./ECDSA.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _Available since v3.4._
*/
abstract contract EIP712 {
/* solhint-disable var-name-mixedcase */
// Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
// invalidate the cached domain separator if the chain id changes.
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
address private immutable _CACHED_THIS;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
bytes32 private immutable _TYPE_HASH;
/* solhint-enable var-name-mixedcase */
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
constructor(string memory name, string memory version) {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
bytes32 typeHash = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
_CACHED_THIS = address(this);
_TYPE_HASH = typeHash;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/SignatureChecker.sol)
pragma solidity ^0.8.0;
import "./ECDSA.sol";
import "../Address.sol";
import "../../interfaces/IERC1271.sol";
/**
* @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA
* signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like
* Argent and Gnosis Safe.
*
* _Available since v4.1._
*/
library SignatureChecker {
/**
* @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
* signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.
*
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
* change through time. It could return true at block N and false at block N+1 (or the opposite).
*/
function isValidSignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
if (error == ECDSA.RecoverError.NoError && recovered == signer) {
return true;
}
(bool success, bytes memory result) = signer.staticcall(
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
);
return (success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271.isValidSignature.selector);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
library SoulinkLibrary {
function _getTokenId(address owner) internal pure returns (uint256 id) {
assembly {
id := owner
}
}
function _sort(uint256 idA, uint256 idB) internal pure returns (uint256 id0, uint256 id1) {
require(idA != idB, "IDENTICAL_ADDRESSES");
(id0, id1) = idA < idB ? (idA, idB) : (idB, idA);
require(id0 != uint256(0), "ZERO_ADDRESS");
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "../interfaces/ISoulBoundToken.sol";
abstract contract SoulBoundToken is ERC165, ISoulBoundToken {
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual returns (uint256) {
require(owner != address(0), "SBT: address zero is not a valid owner");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "SBT: invalid token ID");
return owner;
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "SBT: invalid token ID");
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "SBT: mint to the zero address");
require(!_exists(tokenId), "SBT: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "./ISoulBoundToken.sol";
interface ISoulink is ISoulBoundToken {
event SetBaseURI(string uri);
event SetMinter(address indexed target, bool indexed isMinter);
event CancelLinkSig(address indexed caller, uint256 indexed targetId, uint256 deadline);
event ResetLink(uint256 indexed tokenId);
event SetLink(uint256 indexed id0, uint256 indexed id1);
event BreakLink(uint256 indexed id0, uint256 indexed id1);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function totalSupply() external view returns (uint256);
function isMinter(address target) external view returns (bool);
function getTokenId(address owner) external pure returns (uint256);
function cancelLinkSig(
uint256 targetId,
uint256 deadline,
bytes calldata sig
) external;
function mint(address to) external returns (uint256 id);
function burn(uint256 tokenId) external;
function isLinked(uint256 id0, uint256 id1) external view returns (bool);
function setLink(
uint256 targetId,
bytes[2] calldata sigs,
uint256[2] calldata deadlines
) external;
function breakLink(uint256 targetId) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../Strings.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
// Check the signature length
// - case 65: r,s,v signature (standard)
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "./IERC721Metadata.sol";
import "@openzeppelin/contracts/interfaces/IERC165.sol";
interface ISoulBoundToken is IERC165, IERC721Metadata {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
function balanceOf(address owner) external view returns (uint256);
function ownerOf(uint256 tokenId) external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
interface IERC721Metadata {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id0","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"id1","type":"uint256"}],"name":"BreakLink","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"uint256","name":"targetId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"CancelLinkSig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ResetLink","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"SetBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id0","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"id1","type":"uint256"}],"name":"SetLink","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"bool","name":"isMinter","type":"bool"}],"name":"SetMinter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"targetId","type":"uint256"}],"name":"breakLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"targetId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"cancelLinkSig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id0","type":"uint256"},{"internalType":"uint256","name":"id1","type":"uint256"}],"name":"isLinked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"sigHash","type":"bytes32"}],"name":"isUsableSig","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"targetId","type":"uint256"},{"internalType":"bytes[2]","name":"sigs","type":"bytes[2]"},{"internalType":"uint256[2]","name":"deadlines","type":"uint256[2]"}],"name":"setLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"_isMinter","type":"bool"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"sigHash","type":"bytes32"}],"name":"updateSigNotUsable","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101406040523480156200001257600080fd5b5060405180604001604052806007815260200166536f756c696e6b60c81b815250604051806040016040528060018152602001603160f81b81525060405180604001604052806007815260200166536f756c696e6b60c81b8152506040518060400160405280600281526020016114d360f21b815250620000a26200009c620001b860201b60201c565b620001bc565b6001620000b08382620002b1565b506002620000bf8282620002b1565b5050825160208085019190912083518483012060e08290526101008190524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81880181905281830187905260608201869052608082019490945230818401528151808203909301835260c0019052805194019390932091935091906080523060c05261012052505033600090815260066020908152604091829020805460ff191660011790558151808301909252601e82527f68747470733a2f2f6170692e736f756c2e696e6b2f6d657461646174612f000090820152600a9250620001b1915082620002b1565b506200037d565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200023757607f821691505b6020821081036200025857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ac57600081815260208120601f850160051c81016020861015620002875750805b601f850160051c820191505b81811015620002a85782815560010162000293565b5050505b505050565b81516001600160401b03811115620002cd57620002cd6200020c565b620002e581620002de845462000222565b846200025e565b602080601f8311600181146200031d5760008415620003045750858301515b600019600386901b1c1916600185901b178555620002a8565b600085815260208120601f198616915b828110156200034e578886015182559484019460019091019084016200032d565b50858210156200036d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516101005161012051611d9c620003cd6000396000610e7001526000610ebf01526000610e9a01526000610df301526000610e1d01526000610e470152611d9c6000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063b097b8571161007c578063b097b857146102c7578063c87b56dd146102da578063ca87dbab146102ed578063cf456ae714610300578063f153768614610313578063f2fde38b1461032657600080fd5b806370a082311461025d578063715018a6146102705780638da5cb5b14610278578063907a99241461028957806395d89b411461029c578063aa271e1a146102a457600080fd5b806342966c681161011557806342966c68146101d15780634b17fd74146101e65780634d96928c146101f957806355f804b31461020c5780636352211e1461021f5780636a6278421461024a57600080fd5b806301ffc9a71461015257806306fdde031461017a57806318160ddd1461018f57806326f65c9a146101a55780633644e515146101c9575b600080fd5b610165610160366004611770565b610339565b60405190151581526020015b60405180910390f35b610182610370565b60405161017191906117e9565b610197610402565b604051908152602001610171565b6101656101b33660046117fc565b60009081526009602052604090205460ff161590565b610197610432565b6101e46101df3660046117fc565b610441565b005b6101e46101f43660046117fc565b610513565b6101e4610207366004611857565b610536565b6101e461021a3660046118aa565b61065b565b61023261022d3660046117fc565b6106ae565b6040516001600160a01b039091168152602001610171565b610197610258366004611908565b61070b565b61019761026b366004611908565b610809565b6101e461088c565b6000546001600160a01b0316610232565b6101e46102973660046117fc565b6108a0565b610182610966565b6101656102b2366004611908565b60066020526000908152604090205460ff1681565b6101656102d5366004611923565b610975565b6101826102e83660046117fc565b6109aa565b6101e46102fb366004611956565b610a11565b6101e461030e3660046119ae565b610cad565b610197610321366004611908565b610d65565b6101e4610334366004611908565b610d6d565b60006001600160e01b03198216635b5e139f60e01b148061036a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606001805461037f906119ea565b80601f01602080910402602001604051908101604052809291908181526020018280546103ab906119ea565b80156103f85780601f106103cd576101008083540402835291602001916103f8565b820191906000526020600020905b8154815290600101906020018083116103db57829003601f168201915b5050505050905090565b600554600090610424906001600160801b03600160801b820481169116611a3a565b6001600160801b0316905090565b600061043c610de6565b905090565b8061044b33610d65565b1461048c5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b61049581610f0d565b60058054600160801b90046001600160801b03169060106104b583611a62565b82546001600160801b039182166101009390930a9283029190920219909116179055506000818152600860205260408082208290555182917fbb2f1e8df3cfe65fd278e99556fdd39c96443ba45224ad0f7a91e6c7293cee1491a250565b61051b610f9d565b6000908152600960205260409020805460ff19166001179055565b604080517fc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc4602082015290810185905260608101849052600090610593906080015b60405160208183030381529060405280519060200120610ff7565b90506105d6338285858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061104592505050565b50600083836040516105e9929190611a88565b604051809103902090506105fc81611191565b60008181526009602052604090819020805460ff1916600117905551869033907f8b7370199fbfd2601a62b6f0a0a38138093b301f0e5aa78d773cd352460b57a89061064b9089815260200190565b60405180910390a3505050505050565b610663610f9d565b600a610670828483611afc565b507f23c8c9488efebfd474e85a7956de6f39b17c7ab88502d42a623db2d8e382bbaa82826040516106a2929190611bbd565b60405180910390a15050565b6000818152600360205260408120546001600160a01b03168061036a5760405162461bcd60e51b815260206004820152601560248201527414d0950e881a5b9d985b1a59081d1bdad95b881251605a1b6044820152606401610483565b3360009081526006602052604081205460ff166107595760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610483565b61076282610809565b156107a05760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610483565b6107a982610d65565b90506107b582826111e1565b600580546001600160801b03169060006107ce83611a62565b82546101009290920a6001600160801b0381810219909316918316021790915560055460008481526008602052604090209116905550919050565b60006001600160a01b0382166108705760405162461bcd60e51b815260206004820152602660248201527f5342543a2061646472657373207a65726f206973206e6f7420612076616c69646044820152651037bbb732b960d11b6064820152608401610483565b506001600160a01b031660009081526004602052604090205490565b610894610f9d565b61089e6000611323565b565b60006108ab33610d65565b90506000806108ba8385611373565b6000828152600760209081526040808320848452909152902054919350915060ff166109155760405162461bcd60e51b815260206004820152600a6024820152691393d517d3125392d15160b21b6044820152606401610483565b6000828152600760209081526040808320848452909152808220805460ff1916905551859185917f390e010097209830b4344cddcbf54990936c4a09a414eb0a540d16dce17a985b9190a350505050565b60606002805461037f906119ea565b60008060006109848585611373565b600091825260076020908152604080842092845291905290205460ff1695945050505050565b60606109b5826113b3565b60006109bf61140f565b905060008151116109df5760405180602001604052806000815250610a0a565b806109e98461141e565b6040516020016109fa929190611bec565b6040516020818303038152906040525b9392505050565b80354211801590610a26575060208101354211155b610a655760405162461bcd60e51b815260206004820152601060248201526f455850495245445f444541444c494e4560801b6044820152606401610483565b6000610a7033610d65565b90506000610ac47fc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc48685845b6020020135604051602001610578939291909283526020830191909152604082015260600190565b9050610b1933828660005b602002810190610adf9190611c31565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061104592505050565b506000610b268580611c31565b604051610b34929190611a88565b60405180910390209050610b4781611191565b6000818152600960205260408120805460ff19166001908117909155610b92907fc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc49086908890610a9c565b9050610ba18782886001610acf565b50610baf6020870187611c31565b604051610bbd929190611a88565b60405180910390209150610bd082611191565b6000828152600960205260408120805460ff1916600117905580610bf4868a611373565b6000828152600760209081526040808320848452909152902054919350915060ff1615610c545760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3125392d15160921b6044820152606401610483565b6000828152600760209081526040808320848452909152808220805460ff19166001179055518a9188917ffd5159ca1bc2ff0066345aa67a248b5837ae92cd7b8c16e0034b12a075eb4a0b9190a3505050505050505050565b610cb5610f9d565b6001600160a01b03821660009081526006602052604090205481151560ff909116151503610d115760405162461bcd60e51b8152602060048201526009602482015268155390d2105391d15160ba1b6044820152606401610483565b6001600160a01b038216600081815260066020526040808220805460ff191685151590811790915590519092917f1f96bc657d385fd83da973a43f2ad969e6d96b6779b779571a7306db7ca1cd0091a35050565b60008161036a565b610d75610f9d565b6001600160a01b038116610dda5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610483565b610de381611323565b50565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015610e3f57507f000000000000000000000000000000000000000000000000000000000000000046145b15610e6957507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6000610f18826106ae565b90506001600160a01b0381166000908152600460205260408120805460019290610f43908490611c78565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000546001600160a01b0316331461089e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610483565b600061036a611004610de6565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000611054858561152c565b9092509050600081600481111561106d5761106d611c8f565b14801561108b5750856001600160a01b0316826001600160a01b0316145b1561109b57600192505050610a0a565b600080876001600160a01b0316631626ba7e60e01b88886040516024016110c3929190611ca5565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111019190611cbe565b600060405180830381855afa9150503d806000811461113c576040519150601f19603f3d011682016040523d82523d6000602084013e611141565b606091505b5091509150818015611154575080516020145b801561118557508051630b135d3f60e11b906111799083016020908101908401611cda565b6001600160e01b031916145b98975050505050505050565b60008181526009602052604090205460ff1615610de35760405162461bcd60e51b815260206004820152600e60248201526d555345445f5349474e415455524560901b6044820152606401610483565b6001600160a01b0382166112375760405162461bcd60e51b815260206004820152601d60248201527f5342543a206d696e7420746f20746865207a65726f20616464726573730000006044820152606401610483565b6000818152600360205260409020546001600160a01b03161561129c5760405162461bcd60e51b815260206004820152601960248201527f5342543a20746f6b656e20616c7265616479206d696e746564000000000000006044820152606401610483565b6001600160a01b03821660009081526004602052604081208054600192906112c5908490611cf7565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008061137f846113b3565b611388836113b3565b600084815260086020526040808220548583529120546113a8919061159a565b909590945092505050565b6000818152600360205260409020546001600160a01b0316610de35760405162461bcd60e51b815260206004820152601560248201527414d0950e881a5b9d985b1a59081d1bdad95b881251605a1b6044820152606401610483565b6060600a805461037f906119ea565b6060816000036114455750506040805180820190915260018152600360fc1b602082015290565b8160005b811561146f578061145981611d0f565b91506114689050600a83611d3e565b9150611449565b60008167ffffffffffffffff81111561148a5761148a611a98565b6040519080825280601f01601f1916602001820160405280156114b4576020820181803683370190505b5090505b841561151f576114c9600183611c78565b91506114d6600a86611d52565b6114e1906030611cf7565b60f81b8183815181106114f6576114f6611c1b565b60200101906001600160f81b031916908160001a905350611518600a86611d3e565b94506114b8565b949350505050565b505050565b60008082516041036115625760208301516040840151606085015160001a61155687828585611634565b94509450505050611593565b825160400361158b5760208301516040840151611580868383611721565b935093505050611593565b506000905060025b9250929050565b6000808284036115e25760405162461bcd60e51b81526020600482015260136024820152724944454e544943414c5f41444452455353455360681b6044820152606401610483565b8284106115f05782846115f3565b83835b9092509050816115935760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610483565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561166b5750600090506003611718565b8460ff16601b1415801561168357508460ff16601c14155b156116945750600090506004611718565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156116e8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661171157600060019250925050611718565b9150600090505b94509492505050565b6000806001600160ff1b0383168161173e60ff86901c601b611cf7565b905061174c87828885611634565b935093505050935093915050565b6001600160e01b031981168114610de357600080fd5b60006020828403121561178257600080fd5b8135610a0a8161175a565b60005b838110156117a8578181015183820152602001611790565b838111156117b7576000848401525b50505050565b600081518084526117d581602086016020860161178d565b601f01601f19169290920160200192915050565b602081526000610a0a60208301846117bd565b60006020828403121561180e57600080fd5b5035919050565b60008083601f84011261182757600080fd5b50813567ffffffffffffffff81111561183f57600080fd5b60208301915083602082850101111561159357600080fd5b6000806000806060858703121561186d57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561189257600080fd5b61189e87828801611815565b95989497509550505050565b600080602083850312156118bd57600080fd5b823567ffffffffffffffff8111156118d457600080fd5b6118e085828601611815565b90969095509350505050565b80356001600160a01b038116811461190357600080fd5b919050565b60006020828403121561191a57600080fd5b610a0a826118ec565b6000806040838503121561193657600080fd5b50508035926020909101359150565b806040810183101561036a57600080fd5b60008060006080848603121561196b57600080fd5b83359250602084013567ffffffffffffffff81111561198957600080fd5b61199586828701611945565b9250506119a58560408601611945565b90509250925092565b600080604083850312156119c157600080fd5b6119ca836118ec565b9150602083013580151581146119df57600080fd5b809150509250929050565b600181811c908216806119fe57607f821691505b602082108103611a1e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b0383811690831681811015611a5a57611a5a611a24565b039392505050565b60006001600160801b03808316818103611a7e57611a7e611a24565b6001019392505050565b8183823760009101908152919050565b634e487b7160e01b600052604160045260246000fd5b601f82111561152757600081815260208120601f850160051c81016020861015611ad55750805b601f850160051c820191505b81811015611af457828155600101611ae1565b505050505050565b67ffffffffffffffff831115611b1457611b14611a98565b611b2883611b2283546119ea565b83611aae565b6000601f841160018114611b5c5760008515611b445750838201355b600019600387901b1c1916600186901b178355611bb6565b600083815260209020601f19861690835b82811015611b8d5786850135825560209485019460019092019101611b6d565b5086821015611baa5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60008351611bfe81846020880161178d565b835190830190611c1281836020880161178d565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112611c4857600080fd5b83018035915067ffffffffffffffff821115611c6357600080fd5b60200191503681900382131561159357600080fd5b600082821015611c8a57611c8a611a24565b500390565b634e487b7160e01b600052602160045260246000fd5b82815260406020820152600061151f60408301846117bd565b60008251611cd081846020870161178d565b9190910192915050565b600060208284031215611cec57600080fd5b8151610a0a8161175a565b60008219821115611d0a57611d0a611a24565b500190565b600060018201611d2157611d21611a24565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611d4d57611d4d611d28565b500490565b600082611d6157611d61611d28565b50069056fea26469706673582212209c7ea08aed40d10d99b5f3f702632fda849fc3773ad18e6f6de4e9c3a313927e64736f6c634300080f0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063b097b8571161007c578063b097b857146102c7578063c87b56dd146102da578063ca87dbab146102ed578063cf456ae714610300578063f153768614610313578063f2fde38b1461032657600080fd5b806370a082311461025d578063715018a6146102705780638da5cb5b14610278578063907a99241461028957806395d89b411461029c578063aa271e1a146102a457600080fd5b806342966c681161011557806342966c68146101d15780634b17fd74146101e65780634d96928c146101f957806355f804b31461020c5780636352211e1461021f5780636a6278421461024a57600080fd5b806301ffc9a71461015257806306fdde031461017a57806318160ddd1461018f57806326f65c9a146101a55780633644e515146101c9575b600080fd5b610165610160366004611770565b610339565b60405190151581526020015b60405180910390f35b610182610370565b60405161017191906117e9565b610197610402565b604051908152602001610171565b6101656101b33660046117fc565b60009081526009602052604090205460ff161590565b610197610432565b6101e46101df3660046117fc565b610441565b005b6101e46101f43660046117fc565b610513565b6101e4610207366004611857565b610536565b6101e461021a3660046118aa565b61065b565b61023261022d3660046117fc565b6106ae565b6040516001600160a01b039091168152602001610171565b610197610258366004611908565b61070b565b61019761026b366004611908565b610809565b6101e461088c565b6000546001600160a01b0316610232565b6101e46102973660046117fc565b6108a0565b610182610966565b6101656102b2366004611908565b60066020526000908152604090205460ff1681565b6101656102d5366004611923565b610975565b6101826102e83660046117fc565b6109aa565b6101e46102fb366004611956565b610a11565b6101e461030e3660046119ae565b610cad565b610197610321366004611908565b610d65565b6101e4610334366004611908565b610d6d565b60006001600160e01b03198216635b5e139f60e01b148061036a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606001805461037f906119ea565b80601f01602080910402602001604051908101604052809291908181526020018280546103ab906119ea565b80156103f85780601f106103cd576101008083540402835291602001916103f8565b820191906000526020600020905b8154815290600101906020018083116103db57829003601f168201915b5050505050905090565b600554600090610424906001600160801b03600160801b820481169116611a3a565b6001600160801b0316905090565b600061043c610de6565b905090565b8061044b33610d65565b1461048c5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b61049581610f0d565b60058054600160801b90046001600160801b03169060106104b583611a62565b82546001600160801b039182166101009390930a9283029190920219909116179055506000818152600860205260408082208290555182917fbb2f1e8df3cfe65fd278e99556fdd39c96443ba45224ad0f7a91e6c7293cee1491a250565b61051b610f9d565b6000908152600960205260409020805460ff19166001179055565b604080517fc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc4602082015290810185905260608101849052600090610593906080015b60405160208183030381529060405280519060200120610ff7565b90506105d6338285858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061104592505050565b50600083836040516105e9929190611a88565b604051809103902090506105fc81611191565b60008181526009602052604090819020805460ff1916600117905551869033907f8b7370199fbfd2601a62b6f0a0a38138093b301f0e5aa78d773cd352460b57a89061064b9089815260200190565b60405180910390a3505050505050565b610663610f9d565b600a610670828483611afc565b507f23c8c9488efebfd474e85a7956de6f39b17c7ab88502d42a623db2d8e382bbaa82826040516106a2929190611bbd565b60405180910390a15050565b6000818152600360205260408120546001600160a01b03168061036a5760405162461bcd60e51b815260206004820152601560248201527414d0950e881a5b9d985b1a59081d1bdad95b881251605a1b6044820152606401610483565b3360009081526006602052604081205460ff166107595760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610483565b61076282610809565b156107a05760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610483565b6107a982610d65565b90506107b582826111e1565b600580546001600160801b03169060006107ce83611a62565b82546101009290920a6001600160801b0381810219909316918316021790915560055460008481526008602052604090209116905550919050565b60006001600160a01b0382166108705760405162461bcd60e51b815260206004820152602660248201527f5342543a2061646472657373207a65726f206973206e6f7420612076616c69646044820152651037bbb732b960d11b6064820152608401610483565b506001600160a01b031660009081526004602052604090205490565b610894610f9d565b61089e6000611323565b565b60006108ab33610d65565b90506000806108ba8385611373565b6000828152600760209081526040808320848452909152902054919350915060ff166109155760405162461bcd60e51b815260206004820152600a6024820152691393d517d3125392d15160b21b6044820152606401610483565b6000828152600760209081526040808320848452909152808220805460ff1916905551859185917f390e010097209830b4344cddcbf54990936c4a09a414eb0a540d16dce17a985b9190a350505050565b60606002805461037f906119ea565b60008060006109848585611373565b600091825260076020908152604080842092845291905290205460ff1695945050505050565b60606109b5826113b3565b60006109bf61140f565b905060008151116109df5760405180602001604052806000815250610a0a565b806109e98461141e565b6040516020016109fa929190611bec565b6040516020818303038152906040525b9392505050565b80354211801590610a26575060208101354211155b610a655760405162461bcd60e51b815260206004820152601060248201526f455850495245445f444541444c494e4560801b6044820152606401610483565b6000610a7033610d65565b90506000610ac47fc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc48685845b6020020135604051602001610578939291909283526020830191909152604082015260600190565b9050610b1933828660005b602002810190610adf9190611c31565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061104592505050565b506000610b268580611c31565b604051610b34929190611a88565b60405180910390209050610b4781611191565b6000818152600960205260408120805460ff19166001908117909155610b92907fc3b100a7bf35d534e6c9e325adabf47ef6ec87fd4874fe5d08986fbf0ad1efc49086908890610a9c565b9050610ba18782886001610acf565b50610baf6020870187611c31565b604051610bbd929190611a88565b60405180910390209150610bd082611191565b6000828152600960205260408120805460ff1916600117905580610bf4868a611373565b6000828152600760209081526040808320848452909152902054919350915060ff1615610c545760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3125392d15160921b6044820152606401610483565b6000828152600760209081526040808320848452909152808220805460ff19166001179055518a9188917ffd5159ca1bc2ff0066345aa67a248b5837ae92cd7b8c16e0034b12a075eb4a0b9190a3505050505050505050565b610cb5610f9d565b6001600160a01b03821660009081526006602052604090205481151560ff909116151503610d115760405162461bcd60e51b8152602060048201526009602482015268155390d2105391d15160ba1b6044820152606401610483565b6001600160a01b038216600081815260066020526040808220805460ff191685151590811790915590519092917f1f96bc657d385fd83da973a43f2ad969e6d96b6779b779571a7306db7ca1cd0091a35050565b60008161036a565b610d75610f9d565b6001600160a01b038116610dda5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610483565b610de381611323565b50565b6000306001600160a01b037f0000000000000000000000009f69c2a06c97fcaac1e586b30ea681c43975f05216148015610e3f57507f000000000000000000000000000000000000000000000000000000000000000146145b15610e6957507f76d67fc9dae18482396efd5bae120e6c726da99eb5da9f882e5972f259544cee90565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f8409e06fb9e7529eb69a160d67222f1a4e10add5b7aecc40d1cc5b4eff776282828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6000610f18826106ae565b90506001600160a01b0381166000908152600460205260408120805460019290610f43908490611c78565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000546001600160a01b0316331461089e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610483565b600061036a611004610de6565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000611054858561152c565b9092509050600081600481111561106d5761106d611c8f565b14801561108b5750856001600160a01b0316826001600160a01b0316145b1561109b57600192505050610a0a565b600080876001600160a01b0316631626ba7e60e01b88886040516024016110c3929190611ca5565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111019190611cbe565b600060405180830381855afa9150503d806000811461113c576040519150601f19603f3d011682016040523d82523d6000602084013e611141565b606091505b5091509150818015611154575080516020145b801561118557508051630b135d3f60e11b906111799083016020908101908401611cda565b6001600160e01b031916145b98975050505050505050565b60008181526009602052604090205460ff1615610de35760405162461bcd60e51b815260206004820152600e60248201526d555345445f5349474e415455524560901b6044820152606401610483565b6001600160a01b0382166112375760405162461bcd60e51b815260206004820152601d60248201527f5342543a206d696e7420746f20746865207a65726f20616464726573730000006044820152606401610483565b6000818152600360205260409020546001600160a01b03161561129c5760405162461bcd60e51b815260206004820152601960248201527f5342543a20746f6b656e20616c7265616479206d696e746564000000000000006044820152606401610483565b6001600160a01b03821660009081526004602052604081208054600192906112c5908490611cf7565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008061137f846113b3565b611388836113b3565b600084815260086020526040808220548583529120546113a8919061159a565b909590945092505050565b6000818152600360205260409020546001600160a01b0316610de35760405162461bcd60e51b815260206004820152601560248201527414d0950e881a5b9d985b1a59081d1bdad95b881251605a1b6044820152606401610483565b6060600a805461037f906119ea565b6060816000036114455750506040805180820190915260018152600360fc1b602082015290565b8160005b811561146f578061145981611d0f565b91506114689050600a83611d3e565b9150611449565b60008167ffffffffffffffff81111561148a5761148a611a98565b6040519080825280601f01601f1916602001820160405280156114b4576020820181803683370190505b5090505b841561151f576114c9600183611c78565b91506114d6600a86611d52565b6114e1906030611cf7565b60f81b8183815181106114f6576114f6611c1b565b60200101906001600160f81b031916908160001a905350611518600a86611d3e565b94506114b8565b949350505050565b505050565b60008082516041036115625760208301516040840151606085015160001a61155687828585611634565b94509450505050611593565b825160400361158b5760208301516040840151611580868383611721565b935093505050611593565b506000905060025b9250929050565b6000808284036115e25760405162461bcd60e51b81526020600482015260136024820152724944454e544943414c5f41444452455353455360681b6044820152606401610483565b8284106115f05782846115f3565b83835b9092509050816115935760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610483565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561166b5750600090506003611718565b8460ff16601b1415801561168357508460ff16601c14155b156116945750600090506004611718565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156116e8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661171157600060019250925050611718565b9150600090505b94509492505050565b6000806001600160ff1b0383168161173e60ff86901c601b611cf7565b905061174c87828885611634565b935093505050935093915050565b6001600160e01b031981168114610de357600080fd5b60006020828403121561178257600080fd5b8135610a0a8161175a565b60005b838110156117a8578181015183820152602001611790565b838111156117b7576000848401525b50505050565b600081518084526117d581602086016020860161178d565b601f01601f19169290920160200192915050565b602081526000610a0a60208301846117bd565b60006020828403121561180e57600080fd5b5035919050565b60008083601f84011261182757600080fd5b50813567ffffffffffffffff81111561183f57600080fd5b60208301915083602082850101111561159357600080fd5b6000806000806060858703121561186d57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561189257600080fd5b61189e87828801611815565b95989497509550505050565b600080602083850312156118bd57600080fd5b823567ffffffffffffffff8111156118d457600080fd5b6118e085828601611815565b90969095509350505050565b80356001600160a01b038116811461190357600080fd5b919050565b60006020828403121561191a57600080fd5b610a0a826118ec565b6000806040838503121561193657600080fd5b50508035926020909101359150565b806040810183101561036a57600080fd5b60008060006080848603121561196b57600080fd5b83359250602084013567ffffffffffffffff81111561198957600080fd5b61199586828701611945565b9250506119a58560408601611945565b90509250925092565b600080604083850312156119c157600080fd5b6119ca836118ec565b9150602083013580151581146119df57600080fd5b809150509250929050565b600181811c908216806119fe57607f821691505b602082108103611a1e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b0383811690831681811015611a5a57611a5a611a24565b039392505050565b60006001600160801b03808316818103611a7e57611a7e611a24565b6001019392505050565b8183823760009101908152919050565b634e487b7160e01b600052604160045260246000fd5b601f82111561152757600081815260208120601f850160051c81016020861015611ad55750805b601f850160051c820191505b81811015611af457828155600101611ae1565b505050505050565b67ffffffffffffffff831115611b1457611b14611a98565b611b2883611b2283546119ea565b83611aae565b6000601f841160018114611b5c5760008515611b445750838201355b600019600387901b1c1916600186901b178355611bb6565b600083815260209020601f19861690835b82811015611b8d5786850135825560209485019460019092019101611b6d565b5086821015611baa5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60008351611bfe81846020880161178d565b835190830190611c1281836020880161178d565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112611c4857600080fd5b83018035915067ffffffffffffffff821115611c6357600080fd5b60200191503681900382131561159357600080fd5b600082821015611c8a57611c8a611a24565b500390565b634e487b7160e01b600052602160045260246000fd5b82815260406020820152600061151f60408301846117bd565b60008251611cd081846020870161178d565b9190910192915050565b600060208284031215611cec57600080fd5b8151610a0a8161175a565b60008219821115611d0a57611d0a611a24565b500190565b600060018201611d2157611d21611a24565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611d4d57611d4d611d28565b500490565b600082611d6157611d61611d28565b50069056fea26469706673582212209c7ea08aed40d10d99b5f3f702632fda849fc3773ad18e6f6de4e9c3a313927e64736f6c634300080f0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.