Contract
0xbcb09cdb2011fea0591b52e52085bb102e4a082a
11
Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
CampfireMarket
Compiler Version
v0.8.1+commit.df193b15
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.1; import "./IERC721Royalties.sol"; import "./CampfireStaking.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract CampfireMarket is Ownable, ReentrancyGuard { using ECDSA for bytes32; mapping (bytes32 => bool) private _saltUsed; mapping (bytes32 => bool) private _saltCancelled; address private _stakingContractAddress; address private _wavaxAddress; bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; bool private _active; // kind = 1 for PurchaseListed // kind = 2 for AcceptOffer event Sale( address indexed buyer, address indexed seller, address indexed nftContractAddress, uint256 nftTokenId, uint256 price, uint kind, bytes32 salt ); // kind = 1 for Listing // kind = 2 for Offer event Cancel( address indexed creator, address indexed nftContractAddress, uint256 nftTokenId, uint256 price, uint kind, bytes32 salt ); constructor() { _active = true; } function purchase(address _seller, address _contractAddress, uint256 _tokenId, uint256 _price, uint256 _expiration, bytes32 _salt, bytes memory _signature) public nonReentrant payable { require(_active, "Campfire Market: Contract is not active."); require(!_saltUsed[_salt], "Campfire Market: Salt has already been used."); require(!_saltCancelled[_salt], "Campfire Market: Listing has been cancelled."); require(block.timestamp <= _expiration, "Campfire Market: This listing has expired."); require(!CampfireStaking(payable(_stakingContractAddress)).isStaked(_contractAddress, _tokenId), "Campfire Market: Cannot sell staked NFTs."); IERC721Royalties nft = IERC721Royalties(_contractAddress); address currentNFTOwner = nft.ownerOf(_tokenId); bytes32 hash = keccak256(abi.encodePacked(_seller, _contractAddress, _tokenId, _price, _expiration, _salt)); address signer = hash.toEthSignedMessageHash().recover(_signature); require(signer == currentNFTOwner && currentNFTOwner == _seller, "Campfire Market: Signature does not match."); require(msg.value >= _price, "Campfire Market: Not enough AVAX sent."); _saltUsed[_salt] = true; nft.safeTransferFrom(currentNFTOwner, msg.sender, _tokenId); if (nft.supportsInterface(_INTERFACE_ID_ERC2981)) { (address receiver, uint256 royaltyAmount) = nft.royaltyInfo(_tokenId, _price); payable(receiver).transfer(royaltyAmount); payable(owner()).transfer(msg.value / 100); payable(_stakingContractAddress).transfer(msg.value / 100); uint256 remainder = msg.value - (royaltyAmount + ((msg.value * 2) / 100)); payable(currentNFTOwner).transfer(remainder); } else { payable(currentNFTOwner).transfer((msg.value * 98) / 100); payable(owner()).transfer(msg.value / 100); payable(_stakingContractAddress).transfer(msg.value / 100); } emit Sale(msg.sender, signer, _contractAddress, _tokenId, _price, 1, _salt); } function acceptOffer(address _buyer, address _contractAddress, uint256 _tokenId, uint256 _price, uint256 _expiration, bytes32 _salt, bytes memory _signature) public nonReentrant { require(_active, "Campfire Market: Contract is not active."); require(!_saltUsed[_salt], "Campfire Market: Salt has already been used."); require(!_saltCancelled[_salt], "Campfire Market: Offer has been cancelled."); require(block.timestamp <= _expiration, "Campfire Market: This offer has expired."); require(!CampfireStaking(payable(_stakingContractAddress)).isStaked(_contractAddress, _tokenId), "Campfire Market: Cannot sell staked NFTs."); bytes32 hash = keccak256(abi.encodePacked(_buyer, _contractAddress, _tokenId, _price, _expiration, _salt)); address signer = hash.toEthSignedMessageHash().recover(_signature); require(signer == _buyer, "Campfire Market: Signature does not match."); IERC20 wavax = IERC20(_wavaxAddress); require(wavax.balanceOf(_buyer) >= _price, "Campfire Market: Buyer doesn't have enough WAVAX."); IERC721Royalties nft = IERC721Royalties(_contractAddress); _saltUsed[_salt] = true; nft.safeTransferFrom(msg.sender, _buyer, _tokenId); if (nft.supportsInterface(_INTERFACE_ID_ERC2981)) { (address receiver, uint256 royaltyAmount) = nft.royaltyInfo(_tokenId, _price); wavax.transferFrom(_buyer, receiver, royaltyAmount); wavax.transferFrom(_buyer, owner(), (_price / 100)); wavax.transferFrom(_buyer, _stakingContractAddress, (_price / 100)); uint256 remainder = _price - (royaltyAmount + ((_price * 2) / 100)); wavax.transferFrom(_buyer, msg.sender, remainder); } else { wavax.transferFrom(_buyer, msg.sender, ((_price * 98) / 100)); wavax.transferFrom(_buyer, owner(), (_price / 100)); wavax.transferFrom(_buyer, _stakingContractAddress, (_price / 100)); } emit Sale(signer, msg.sender, _contractAddress, _tokenId, _price, 2, _salt); } function cancelListing(address _seller, address _contractAddress, uint256 _tokenId, uint256 _price, uint256 _expiration, bytes32 _salt, bytes memory _signature) public nonReentrant { bytes32 hash = keccak256(abi.encodePacked(_seller, _contractAddress, _tokenId, _price, _expiration, _salt)); address signer = hash.toEthSignedMessageHash().recover(_signature); require(msg.sender == signer && signer == _seller, "Campfire Market: You didn't create that listing."); _saltCancelled[_salt] = true; emit Cancel(signer, _contractAddress, _tokenId, _price, 1, _salt); } function cancelOffer(address _buyer, address _contractAddress, uint256 _tokenId, uint256 _price, uint256 _expiration, bytes32 _salt, bytes memory _signature) public nonReentrant { bytes32 hash = keccak256(abi.encodePacked(_buyer, _contractAddress, _tokenId, _price, _expiration, _salt)); address signer = hash.toEthSignedMessageHash().recover(_signature); require((msg.sender == signer) && (signer == _buyer), "Campfire Market: You didn't create that offer."); _saltCancelled[_salt] = true; emit Cancel(signer, _contractAddress, _tokenId, _price, 2, _salt); } function saltUsed(bytes32 salt) public view returns (bool) { return _saltUsed[salt]; } function hasBeenCancelled(bytes32 salt) public view returns (bool) { return _saltCancelled[salt]; } function setStakingContract(address stakingContractAddress_) public onlyOwner { _stakingContractAddress = stakingContractAddress_; } function setWAVAX(address wavaxAddress_) public onlyOwner { _wavaxAddress = wavaxAddress_; } function setActive(bool active_) public onlyOwner { _active = active_; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; interface IERC721Royalties is IERC721 { function royaltyInfo( uint256 _tokenId, uint256 _salePrice ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.1; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract CampfireStaking is Ownable, ReentrancyGuard { uint256 private _totalNftsStaked; uint256 private _totalBlockEntries; address private _wavaxAddress; address private _keeperAddress; uint256 private _maxStake; mapping (address => uint256) private _totalNftsStakedForAccount; mapping (address => bool) private _partners; mapping (address => bool) private _managers; mapping (address => uint256) private _blockEntries; mapping (address => mapping (uint256 => bool)) _staked; mapping (address => mapping (uint256 => address)) private _stakers; // mapping (address => StakedNFT[]) private _stakedNFTs; mapping (address => mapping (address => bool)) private _approvals; mapping (bytes32 => StakedNFT) private _stakedNFTs; mapping (address => bytes32[]) private _stakedNFTHashes; struct StakedNFT { address contractAddress; uint256 tokenId; } constructor() { _managers[msg.sender] = true; _maxStake = 250; } modifier onlyManager() { require(_managers[msg.sender], "Campfire Staking: Caller is not the manager"); _; } function addManager(address _newManager) public onlyManager { _managers[_newManager] = true; } function removeManager(address _manager) public onlyManager { _managers[_manager] = false; } function addPartner(address _contractAddress) public onlyManager { _partners[_contractAddress] = true; } function isPartner(address _contractAddress) public view returns (bool) { if (_contractAddress == 0x5e4504663AB2a8060715A1D1f162873F39DF9abf) { // OUTLAWS return true; } else { return _partners[_contractAddress]; } } function stakeSet(address _contractAddress, uint256[] memory _tokenIds) public nonReentrant { require(_tokenIds.length <= 15, "Campfire Staking: You can't stake more than 15 at a time."); // IMPORTANT: Rely on real value here, not cached! uint256 accountNftsStaked = getNumberStaked(msg.sender); for (uint256 index = 0; index < _tokenIds.length; index++) { uint256 _tokenId = _tokenIds[index]; _stake(_contractAddress, _tokenId, (accountNftsStaked + index)); } } function stake(address _contractAddress, uint256 _tokenId) public nonReentrant { // IMPORTANT: Rely on real value here, not cached! uint256 accountNftsStaked = getNumberStaked(msg.sender); _stake(_contractAddress, _tokenId, accountNftsStaked); } function _stake(address _contractAddress, uint256 _tokenId, uint256 accountNftsStaked) private { require(isPartner(_contractAddress), "Campfire Staking: This project is not a parter."); IERC721 nft = IERC721(_contractAddress); require(nft.ownerOf(_tokenId) == msg.sender, "Campfire Staking: You don't own that NFT."); if (isStaked(_contractAddress, _tokenId)) { if (_stakers[_contractAddress][_tokenId] == msg.sender) { require(false, "Campfire Staking: You cannot stake an NFT more than once."); } else { address originalOwner = _stakers[_contractAddress][_tokenId]; uint256 currentForOriginal = getNumberStaked(originalOwner); resetTotalsFor(originalOwner, currentForOriginal); _stakers[_contractAddress][_tokenId] = msg.sender; } } if (_totalNftsStakedForAccount[msg.sender] > 0 && block.number < _blockEntries[msg.sender]) { if (_totalNftsStakedForAccount[msg.sender] > accountNftsStaked) { resetTotalsFor(msg.sender, accountNftsStaked); } uint256 avaxRewards = _availableAVAXRewards(msg.sender, accountNftsStaked); uint256 wavaxRewards = _availableWAVAXRewards(msg.sender, accountNftsStaked); _totalBlockEntries -= _blockEntries[msg.sender] * _totalNftsStakedForAccount[msg.sender]; if (wavaxRewards > 0) { IERC20 wavax = IERC20(_wavaxAddress); wavax.transfer(msg.sender, wavaxRewards); } if (avaxRewards > 0) { payable(msg.sender).transfer(avaxRewards); } } else if (_totalNftsStakedForAccount[msg.sender] > 0) { _totalBlockEntries -= _blockEntries[msg.sender] * _totalNftsStakedForAccount[msg.sender]; } _totalNftsStaked += 1; _totalNftsStakedForAccount[msg.sender] += 1; _blockEntries[msg.sender] = block.number; _totalBlockEntries += block.number * _totalNftsStakedForAccount[msg.sender]; bytes32 nftHash = keccak256(abi.encodePacked(msg.sender, _contractAddress, _tokenId)); _stakedNFTs[nftHash] = StakedNFT(_contractAddress, _tokenId); _stakedNFTHashes[msg.sender].push(nftHash); _stakers[_contractAddress][_tokenId] = msg.sender; require(_totalNftsStakedForAccount[msg.sender] <= _maxStake, "Campfire Staking: You have hit the max staked limit."); _staked[_contractAddress][_tokenId] = true; } function isStaked(address _contractAddress, uint256 _tokenId) public view returns (bool) { return _staked[_contractAddress][_tokenId]; } function totalStaked() public view returns (uint256) { return _totalNftsStaked; } function totalStakedFor(address staker) public view returns (uint256) { return _totalNftsStakedForAccount[staker]; } function totalBlockEntries() public view returns (uint256) { return _totalBlockEntries; } function blockEntriesFor(address staker) public view returns (uint256) { return _blockEntries[staker]; } function unstake(address _contractAddress, uint256 _tokenId) public nonReentrant { IERC721 nft = IERC721(_contractAddress); address nftOwner = nft.ownerOf(_tokenId); require(msg.sender == nftOwner, "Campfire Staking: You don't own that NFT."); require(isStaked(_contractAddress, _tokenId), "Campfire Staking: That NFT is not currently staked."); // IMPORTANT: Rely on real value here, not cached! uint256 accountNftsStaked = getNumberStaked(msg.sender); if (_totalNftsStakedForAccount[msg.sender] > accountNftsStaked) { resetTotalsFor(msg.sender, accountNftsStaked); } uint256 avaxRewards = _availableAVAXRewards(msg.sender, accountNftsStaked); uint256 wavaxRewards = _availableWAVAXRewards(msg.sender, accountNftsStaked); _totalBlockEntries -= _blockEntries[msg.sender] * _totalNftsStakedForAccount[msg.sender]; _totalNftsStaked -= 1; _totalNftsStakedForAccount[msg.sender] -= 1; _blockEntries[msg.sender] = block.number; _totalBlockEntries += block.number * _totalNftsStakedForAccount[msg.sender]; _staked[_contractAddress][_tokenId] = false; IERC20 wavax = IERC20(_wavaxAddress); if (wavaxRewards > 0) { wavax.transfer(msg.sender, wavaxRewards); } if (avaxRewards > 0) { payable(msg.sender).transfer(avaxRewards); } } function unclaimedBlocks() public view returns (uint256) { uint256 totalUnclaimedBlocks = (block.number * _totalNftsStaked) - _totalBlockEntries; return totalUnclaimedBlocks; } function claim() public nonReentrant { _claim(msg.sender); } function claimFor(address account) public { require(msg.sender == _keeperAddress || _approvals[account][msg.sender], "Campfire Staking: You don't have permission to do that."); _claim(account); } function _claim(address account) private { require(_totalNftsStakedForAccount[account] > 0, "Campfire Staking: You are not staked."); // IMPORTANT: Rely on real value here, not cached! uint256 accountNftsStaked = getNumberStaked(account); if (_totalNftsStakedForAccount[account] > accountNftsStaked) { resetTotalsFor(account, accountNftsStaked); } uint256 avaxRewards = _availableAVAXRewards(account, accountNftsStaked); uint256 wavaxRewards = _availableWAVAXRewards(account, accountNftsStaked); _totalBlockEntries -= _blockEntries[account] * _totalNftsStakedForAccount[account]; _blockEntries[account] = block.number; _totalBlockEntries += block.number * _totalNftsStakedForAccount[account]; IERC20 wavax = IERC20(_wavaxAddress); if (wavaxRewards > 0) { wavax.transfer(account, wavaxRewards); } if (avaxRewards > 0) { payable(account).transfer(avaxRewards); } } function resetTotalsFor(address account, uint256 accountNftsStaked) private { _totalBlockEntries -= (_blockEntries[account] * _totalNftsStakedForAccount[account]); _totalNftsStaked -= _totalNftsStakedForAccount[account]; _totalNftsStakedForAccount[account] = accountNftsStaked; _totalBlockEntries += (_blockEntries[account] * _totalNftsStakedForAccount[account]); _totalNftsStaked += _totalNftsStakedForAccount[account]; } // NOTE: The next two methods are convenience methods for the UI --> not to be used internally function availableAVAXRewards(address account) public view returns (uint256) { uint256 accountNftsStaked = getNumberStaked(account); uint256 available = address(this).balance; return _rewardsCalc(account, available, accountNftsStaked); } function availableWAVAXRewards(address account) public view returns (uint256) { uint256 accountNftsStaked = getNumberStaked(account); IERC20 wavax = IERC20(_wavaxAddress); uint256 available = wavax.balanceOf(address(this)); return _rewardsCalc(account, available, accountNftsStaked); } function _availableAVAXRewards(address account, uint256 accountNftsStaked) private view returns (uint256) { uint256 available = address(this).balance; return _rewardsCalc(account, available, accountNftsStaked); } function _availableWAVAXRewards(address account, uint256 accountNftsStaked) private view returns (uint256) { IERC20 wavax = IERC20(_wavaxAddress); uint256 available = wavax.balanceOf(address(this)); return _rewardsCalc(account, available, accountNftsStaked); } function _rewardsCalc(address account, uint256 available, uint256 accountNftsStaked) private view returns (uint256) { uint256 totalUnclaimedBlocks = (block.number * _totalNftsStaked) - _totalBlockEntries; if (totalUnclaimedBlocks > 0) { uint256 accountUnclaimedBlocks = (block.number * accountNftsStaked) - (_blockEntries[account] * accountNftsStaked); uint256 reward = (available * accountUnclaimedBlocks) / totalUnclaimedBlocks; return reward; } else { return 0; } } function getNumberStaked(address staker) public view returns (uint256) { uint256 numberStaked = 0; for (uint256 index = 0; index < _stakedNFTHashes[staker].length; index++) { bytes32 nftHash = _stakedNFTHashes[staker][index]; StakedNFT memory stakedNFT = _stakedNFTs[nftHash]; if (isStaked(stakedNFT.contractAddress, stakedNFT.tokenId)) { IERC721 nft = IERC721(stakedNFT.contractAddress); if (nft.ownerOf(stakedNFT.tokenId) == staker) { numberStaked += 1; } } } return numberStaked; } function setWAVAX(address wavaxAddress_) public onlyOwner { _wavaxAddress = wavaxAddress_; } function setKeeper(address keeperAddress_) public onlyOwner { _keeperAddress = keeperAddress_; } function setMaxStake(uint256 maxStake_) public onlyOwner { _maxStake = maxStake_; } function approve(address manager, bool approved) public { _approvals[msg.sender][manager] = approved; } receive() external payable {} }
// 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 // OpenZeppelin Contracts (last updated v4.5.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. 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. 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 v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// 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 v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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); } }
{ "remappings": [], "optimizer": { "enabled": false, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"kind","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"Cancel","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":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"kind","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"Sale","type":"event"},{"inputs":[{"internalType":"address","name":"_buyer","type":"address"},{"internalType":"address","name":"_contractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_expiration","type":"uint256"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"acceptOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_seller","type":"address"},{"internalType":"address","name":"_contractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_expiration","type":"uint256"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"cancelListing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_buyer","type":"address"},{"internalType":"address","name":"_contractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_expiration","type":"uint256"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"cancelOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"hasBeenCancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_seller","type":"address"},{"internalType":"address","name":"_contractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_expiration","type":"uint256"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"purchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"saltUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"active_","type":"bool"}],"name":"setActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingContractAddress_","type":"address"}],"name":"setStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wavaxAddress_","type":"address"}],"name":"setWAVAX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5062000032620000266200005a60201b60201c565b6200006260201b60201c565b600180819055506001600560146101000a81548160ff02191690831515021790555062000126565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613a4f80620001366000396000f3fe6080604052600436106100a75760003560e01c80637e95f4c1116100645780637e95f4c1146101ab57806384d3cf38146101d45780638da5cb5b146101fd5780639dd373b914610228578063acec338a14610251578063f2fde38b1461027a576100a7565b8063168ae9b6146100ac5780632088c0d1146100d5578063422551bb146100fe578063444a3e881461013b578063715018a61461017857806371f4f5aa1461018f575b600080fd5b3480156100b857600080fd5b506100d360048036038101906100ce91906126db565b6102a3565b005b3480156100e157600080fd5b506100fc60048036038101906100f7919061272d565b610363565b005b34801561010a57600080fd5b5061012560048036038101906101209190612871565b610ec9565b6040516101329190612d4d565b60405180910390f35b34801561014757600080fd5b50610162600480360381019061015d9190612871565b610ef3565b60405161016f9190612d4d565b60405180910390f35b34801561018457600080fd5b5061018d610f1d565b005b6101a960048036038101906101a4919061272d565b610fa5565b005b3480156101b757600080fd5b506101d260048036038101906101cd919061272d565b611921565b005b3480156101e057600080fd5b506101fb60048036038101906101f6919061272d565b611b12565b005b34801561020957600080fd5b50610212611d03565b60405161021f9190612cd2565b60405180910390f35b34801561023457600080fd5b5061024f600480360381019061024a91906126db565b611d2c565b005b34801561025d57600080fd5b506102786004803603810190610273919061281f565b611dec565b005b34801561028657600080fd5b506102a1600480360381019061029c91906126db565b611e85565b005b6102ab611f7d565b73ffffffffffffffffffffffffffffffffffffffff166102c9611d03565b73ffffffffffffffffffffffffffffffffffffffff161461031f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161031690612f28565b60405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260015414156103a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a090612fc8565b60405180910390fd5b6002600181905550600560149054906101000a900460ff16610400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f790612f68565b60405180910390fd5b6002600083815260200190815260200160002060009054906101000a900460ff1615610461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045890613008565b60405180910390fd5b6003600083815260200190815260200160002060009054906101000a900460ff16156104c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b990612ee8565b60405180910390fd5b82421115610505576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104fc90612e88565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635451da1b87876040518363ffffffff1660e01b8152600401610562929190612d24565b60206040518083038186803b15801561057a57600080fd5b505afa15801561058e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b29190612848565b156105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990612e68565b60405180910390fd5b600087878787878760405160200161060f96959493929190612c3c565b60405160208183030381529060405280519060200120905060006106448361063684611f85565b611fb590919063ffffffff16565b90508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ab90612e28565b60405180910390fd5b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050868173ffffffffffffffffffffffffffffffffffffffff166370a082318c6040518263ffffffff1660e01b81526004016107159190612cd2565b60206040518083038186803b15801561072d57600080fd5b505afa158015610741573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610765919061289a565b10156107a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079d90612fa8565b60405180910390fd5b600089905060016002600088815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff166342842e0e338d8c6040518463ffffffff1660e01b815260040161081493929190612ced565b600060405180830381600087803b15801561082e57600080fd5b505af1158015610842573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7632a55205a60e01b6040518263ffffffff1660e01b81526004016108869190612dad565b60206040518083038186803b15801561089e57600080fd5b505afa1580156108b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d69190612848565b15610c28576000808273ffffffffffffffffffffffffffffffffffffffff16632a55205a8c8c6040518363ffffffff1660e01b8152600401610919929190613043565b604080518083038186803b15801561093057600080fd5b505afa158015610944573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096891906127e3565b915091508373ffffffffffffffffffffffffffffffffffffffff166323b872dd8e84846040518463ffffffff1660e01b81526004016109a993929190612ced565b602060405180830381600087803b1580156109c357600080fd5b505af11580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb9190612848565b508373ffffffffffffffffffffffffffffffffffffffff166323b872dd8e610a21611d03565b60648e610a2e91906131be565b6040518463ffffffff1660e01b8152600401610a4c93929190612ced565b602060405180830381600087803b158015610a6657600080fd5b505af1158015610a7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9e9190612848565b508373ffffffffffffffffffffffffffffffffffffffff166323b872dd8e600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660648e610aec91906131be565b6040518463ffffffff1660e01b8152600401610b0a93929190612ced565b602060405180830381600087803b158015610b2457600080fd5b505af1158015610b38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5c9190612848565b506000606460028c610b6e91906131ef565b610b7891906131be565b82610b839190613168565b8b610b8e9190613249565b90508473ffffffffffffffffffffffffffffffffffffffff166323b872dd8f33846040518463ffffffff1660e01b8152600401610bcd93929190612ced565b602060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1f9190612848565b50505050610e32565b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd8c33606460628d610c5591906131ef565b610c5f91906131be565b6040518463ffffffff1660e01b8152600401610c7d93929190612ced565b602060405180830381600087803b158015610c9757600080fd5b505af1158015610cab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190612848565b508173ffffffffffffffffffffffffffffffffffffffff166323b872dd8c610cf5611d03565b60648c610d0291906131be565b6040518463ffffffff1660e01b8152600401610d2093929190612ced565b602060405180830381600087803b158015610d3a57600080fd5b505af1158015610d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d729190612848565b508173ffffffffffffffffffffffffffffffffffffffff166323b872dd8c600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660648c610dc091906131be565b6040518463ffffffff1660e01b8152600401610dde93929190612ced565b602060405180830381600087803b158015610df857600080fd5b505af1158015610e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e309190612848565b505b8973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fe6ecf98f5a7ebe851dea0eddf8843ebdef2143373ad1548c6b88feeab636df7a8c8c60028c604051610ead94939291906130b1565b60405180910390a4505050506001808190555050505050505050565b60006002600083815260200190815260200160002060009054906101000a900460ff169050919050565b60006003600083815260200190815260200160002060009054906101000a900460ff169050919050565b610f25611f7d565b73ffffffffffffffffffffffffffffffffffffffff16610f43611d03565b73ffffffffffffffffffffffffffffffffffffffff1614610f99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9090612f28565b60405180910390fd5b610fa36000611fdc565b565b60026001541415610feb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe290612fc8565b60405180910390fd5b6002600181905550600560149054906101000a900460ff16611042576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103990612f68565b60405180910390fd5b6002600083815260200190815260200160002060009054906101000a900460ff16156110a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109a90613008565b60405180910390fd5b6003600083815260200190815260200160002060009054906101000a900460ff1615611104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fb90612f48565b60405180910390fd5b82421115611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113e90612f08565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635451da1b87876040518363ffffffff1660e01b81526004016111a4929190612d24565b60206040518083038186803b1580156111bc57600080fd5b505afa1580156111d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f49190612848565b15611234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122b90612e68565b60405180910390fd5b600086905060008173ffffffffffffffffffffffffffffffffffffffff16636352211e886040518263ffffffff1660e01b81526004016112749190613028565b60206040518083038186803b15801561128c57600080fd5b505afa1580156112a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c49190612704565b905060008989898989896040516020016112e396959493929190612c3c565b60405160208183030381529060405280519060200120905060006113188561130a84611f85565b611fb590919063ffffffff16565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614801561138057508a73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b6113bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b690612e28565b60405180910390fd5b87341015611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f990612ea8565b60405180910390fd5b60016002600088815260200190815260200160002060006101000a81548160ff0219169083151502179055508373ffffffffffffffffffffffffffffffffffffffff166342842e0e84338c6040518463ffffffff1660e01b815260040161146b93929190612ced565b600060405180830381600087803b15801561148557600080fd5b505af1158015611499573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff166301ffc9a7632a55205a60e01b6040518263ffffffff1660e01b81526004016114dd9190612dad565b60206040518083038186803b1580156114f557600080fd5b505afa158015611509573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152d9190612848565b1561175b576000808573ffffffffffffffffffffffffffffffffffffffff16632a55205a8c8c6040518363ffffffff1660e01b8152600401611570929190613043565b604080518083038186803b15801561158757600080fd5b505afa15801561159b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bf91906127e3565b915091508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611609573d6000803e3d6000fd5b50611612611d03565b73ffffffffffffffffffffffffffffffffffffffff166108fc60643461163891906131be565b9081150290604051600060405180830381858888f19350505050158015611663573d6000803e3d6000fd5b50600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc6064346116ad91906131be565b9081150290604051600060405180830381858888f193505050501580156116d8573d6000803e3d6000fd5b50600060646002346116ea91906131ef565b6116f491906131be565b826116ff9190613168565b3461170a9190613249565b90508573ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611752573d6000803e3d6000fd5b5050505061188a565b8273ffffffffffffffffffffffffffffffffffffffff166108fc606460623461178491906131ef565b61178e91906131be565b9081150290604051600060405180830381858888f193505050501580156117b9573d6000803e3d6000fd5b506117c2611d03565b73ffffffffffffffffffffffffffffffffffffffff166108fc6064346117e891906131be565b9081150290604051600060405180830381858888f19350505050158015611813573d6000803e3d6000fd5b50600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc60643461185d91906131be565b9081150290604051600060405180830381858888f19350505050158015611888573d6000803e3d6000fd5b505b8973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe6ecf98f5a7ebe851dea0eddf8843ebdef2143373ad1548c6b88feeab636df7a8c8c60018c604051611905949392919061306c565b60405180910390a4505050506001808190555050505050505050565b60026001541415611967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195e90612fc8565b60405180910390fd5b6002600181905550600087878787878760405160200161198c96959493929190612c3c565b60405160208183030381529060405280519060200120905060006119c1836119b384611f85565b611fb590919063ffffffff16565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148015611a2957508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611a68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5f90612fe8565b60405180910390fd5b60016003600086815260200190815260200160002060006101000a81548160ff0219169083151502179055508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8cb9362bf174a12ae5c3e9c96c6085bd72b0784ee5e1078759bcbf4013a532fb8989600289604051611af894939291906130b1565b60405180910390a350506001808190555050505050505050565b60026001541415611b58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4f90612fc8565b60405180910390fd5b60026001819055506000878787878787604051602001611b7d96959493929190612c3c565b6040516020818303038152906040528051906020012090506000611bb283611ba484611f85565b611fb590919063ffffffff16565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148015611c1a57508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611c59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5090612f88565b60405180910390fd5b60016003600086815260200190815260200160002060006101000a81548160ff0219169083151502179055508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8cb9362bf174a12ae5c3e9c96c6085bd72b0784ee5e1078759bcbf4013a532fb8989600189604051611ce9949392919061306c565b60405180910390a350506001808190555050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611d34611f7d565b73ffffffffffffffffffffffffffffffffffffffff16611d52611d03565b73ffffffffffffffffffffffffffffffffffffffff1614611da8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9f90612f28565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611df4611f7d565b73ffffffffffffffffffffffffffffffffffffffff16611e12611d03565b73ffffffffffffffffffffffffffffffffffffffff1614611e68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5f90612f28565b60405180910390fd5b80600560146101000a81548160ff02191690831515021790555050565b611e8d611f7d565b73ffffffffffffffffffffffffffffffffffffffff16611eab611d03565b73ffffffffffffffffffffffffffffffffffffffff1614611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890612f28565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6890612e08565b60405180910390fd5b611f7a81611fdc565b50565b600033905090565b600081604051602001611f989190612cac565b604051602081830303815290604052805190602001209050919050565b6000806000611fc485856120a0565b91509150611fd181612123565b819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000806041835114156120e25760008060006020860151925060408601519150606086015160001a90506120d687828585612474565b9450945050505061211c565b604083511415612113576000806020850151915060408501519050612108868383612581565b93509350505061211c565b60006002915091505b9250929050565b6000600481111561215d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612196577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156121a157612471565b600160048111156121db577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612214577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224c90612dc8565b60405180910390fd5b6002600481111561228f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8160048111156122c8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230090612de8565b60405180910390fd5b60036004811115612343577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81600481111561237c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156123bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b490612e48565b60405180910390fd5b6004808111156123f6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81600481111561242f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612470576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246790612ec8565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c11156124af576000600391509150612578565b601b8560ff16141580156124c75750601c8560ff1614155b156124d9576000600491509150612578565b6000600187878787604051600081526020016040526040516124fe9493929190612d68565b6020604051602081039080840390855afa158015612520573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561256f57600060019250925050612578565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c6125c49190613168565b90506125d287828885612474565b935093505050935093915050565b60006125f36125ee8461311b565b6130f6565b90508281526020810184848401111561260b57600080fd5b61261684828561332c565b509392505050565b60008135905061262d816139bd565b92915050565b600081519050612642816139bd565b92915050565b600081359050612657816139d4565b92915050565b60008151905061266c816139d4565b92915050565b600081359050612681816139eb565b92915050565b600082601f83011261269857600080fd5b81356126a88482602086016125e0565b91505092915050565b6000813590506126c081613a02565b92915050565b6000815190506126d581613a02565b92915050565b6000602082840312156126ed57600080fd5b60006126fb8482850161261e565b91505092915050565b60006020828403121561271657600080fd5b600061272484828501612633565b91505092915050565b600080600080600080600060e0888a03121561274857600080fd5b60006127568a828b0161261e565b97505060206127678a828b0161261e565b96505060406127788a828b016126b1565b95505060606127898a828b016126b1565b945050608061279a8a828b016126b1565b93505060a06127ab8a828b01612672565b92505060c088013567ffffffffffffffff8111156127c857600080fd5b6127d48a828b01612687565b91505092959891949750929550565b600080604083850312156127f657600080fd5b600061280485828601612633565b9250506020612815858286016126c6565b9150509250929050565b60006020828403121561283157600080fd5b600061283f84828501612648565b91505092915050565b60006020828403121561285a57600080fd5b60006128688482850161265d565b91505092915050565b60006020828403121561288357600080fd5b600061289184828501612672565b91505092915050565b6000602082840312156128ac57600080fd5b60006128ba848285016126c6565b91505092915050565b6128cc8161327d565b82525050565b6128e36128de8261327d565b61336c565b82525050565b6128f28161328f565b82525050565b6129018161329b565b82525050565b6129186129138261329b565b61337e565b82525050565b612927816132a5565b82525050565b61293681613308565b82525050565b6129458161331a565b82525050565b600061295860188361314c565b91506129638261344f565b602082019050919050565b600061297b601f8361314c565b915061298682613478565b602082019050919050565b600061299e601c8361315d565b91506129a9826134a1565b601c82019050919050565b60006129c160268361314c565b91506129cc826134ca565b604082019050919050565b60006129e4602a8361314c565b91506129ef82613519565b604082019050919050565b6000612a0760228361314c565b9150612a1282613568565b604082019050919050565b6000612a2a60298361314c565b9150612a35826135b7565b604082019050919050565b6000612a4d60288361314c565b9150612a5882613606565b604082019050919050565b6000612a7060268361314c565b9150612a7b82613655565b604082019050919050565b6000612a9360228361314c565b9150612a9e826136a4565b604082019050919050565b6000612ab6602a8361314c565b9150612ac1826136f3565b604082019050919050565b6000612ad9602a8361314c565b9150612ae482613742565b604082019050919050565b6000612afc60208361314c565b9150612b0782613791565b602082019050919050565b6000612b1f602c8361314c565b9150612b2a826137ba565b604082019050919050565b6000612b4260288361314c565b9150612b4d82613809565b604082019050919050565b6000612b6560308361314c565b9150612b7082613858565b604082019050919050565b6000612b8860318361314c565b9150612b93826138a7565b604082019050919050565b6000612bab601f8361314c565b9150612bb6826138f6565b602082019050919050565b6000612bce602e8361314c565b9150612bd98261391f565b604082019050919050565b6000612bf1602c8361314c565b9150612bfc8261396e565b604082019050919050565b612c10816132f1565b82525050565b612c27612c22826132f1565b61339a565b82525050565b612c36816132fb565b82525050565b6000612c4882896128d2565b601482019150612c5882886128d2565b601482019150612c688287612c16565b602082019150612c788286612c16565b602082019150612c888285612c16565b602082019150612c988284612907565b602082019150819050979650505050505050565b6000612cb782612991565b9150612cc38284612907565b60208201915081905092915050565b6000602082019050612ce760008301846128c3565b92915050565b6000606082019050612d0260008301866128c3565b612d0f60208301856128c3565b612d1c6040830184612c07565b949350505050565b6000604082019050612d3960008301856128c3565b612d466020830184612c07565b9392505050565b6000602082019050612d6260008301846128e9565b92915050565b6000608082019050612d7d60008301876128f8565b612d8a6020830186612c2d565b612d9760408301856128f8565b612da460608301846128f8565b95945050505050565b6000602082019050612dc2600083018461291e565b92915050565b60006020820190508181036000830152612de18161294b565b9050919050565b60006020820190508181036000830152612e018161296e565b9050919050565b60006020820190508181036000830152612e21816129b4565b9050919050565b60006020820190508181036000830152612e41816129d7565b9050919050565b60006020820190508181036000830152612e61816129fa565b9050919050565b60006020820190508181036000830152612e8181612a1d565b9050919050565b60006020820190508181036000830152612ea181612a40565b9050919050565b60006020820190508181036000830152612ec181612a63565b9050919050565b60006020820190508181036000830152612ee181612a86565b9050919050565b60006020820190508181036000830152612f0181612aa9565b9050919050565b60006020820190508181036000830152612f2181612acc565b9050919050565b60006020820190508181036000830152612f4181612aef565b9050919050565b60006020820190508181036000830152612f6181612b12565b9050919050565b60006020820190508181036000830152612f8181612b35565b9050919050565b60006020820190508181036000830152612fa181612b58565b9050919050565b60006020820190508181036000830152612fc181612b7b565b9050919050565b60006020820190508181036000830152612fe181612b9e565b9050919050565b6000602082019050818103600083015261300181612bc1565b9050919050565b6000602082019050818103600083015261302181612be4565b9050919050565b600060208201905061303d6000830184612c07565b92915050565b60006040820190506130586000830185612c07565b6130656020830184612c07565b9392505050565b60006080820190506130816000830187612c07565b61308e6020830186612c07565b61309b604083018561292d565b6130a860608301846128f8565b95945050505050565b60006080820190506130c66000830187612c07565b6130d36020830186612c07565b6130e0604083018561293c565b6130ed60608301846128f8565b95945050505050565b6000613100613111565b905061310c828261333b565b919050565b6000604051905090565b600067ffffffffffffffff82111561313657613135613402565b5b61313f82613431565b9050602081019050919050565b600082825260208201905092915050565b600081905092915050565b6000613173826132f1565b915061317e836132f1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156131b3576131b26133a4565b5b828201905092915050565b60006131c9826132f1565b91506131d4836132f1565b9250826131e4576131e36133d3565b5b828204905092915050565b60006131fa826132f1565b9150613205836132f1565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561323e5761323d6133a4565b5b828202905092915050565b6000613254826132f1565b915061325f836132f1565b925082821015613272576132716133a4565b5b828203905092915050565b6000613288826132d1565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000613313826132f1565b9050919050565b6000613325826132f1565b9050919050565b82818337600083830152505050565b61334482613431565b810181811067ffffffffffffffff8211171561336357613362613402565b5b80604052505050565b600061337782613388565b9050919050565b6000819050919050565b600061339382613442565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a205369676e617475726520646f65732060008201527f6e6f74206d617463682e00000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a2043616e6e6f742073656c6c2073746160008201527f6b6564204e4654732e0000000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a2054686973206f66666572206861732060008201527f657870697265642e000000000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a204e6f7420656e6f756768204156415860008201527f2073656e742e0000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a204f6666657220686173206265656e2060008201527f63616e63656c6c65642e00000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a2054686973206c697374696e6720686160008201527f7320657870697265642e00000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f43616d7066697265204d61726b65743a204c697374696e67206861732062656560008201527f6e2063616e63656c6c65642e0000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a20436f6e7472616374206973206e6f7460008201527f206163746976652e000000000000000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a20596f75206469646e2774206372656160008201527f74652074686174206c697374696e672e00000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a20427579657220646f65736e2774206860008201527f61766520656e6f7567682057415641582e000000000000000000000000000000602082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f43616d7066697265204d61726b65743a20596f75206469646e2774206372656160008201527f74652074686174206f666665722e000000000000000000000000000000000000602082015250565b7f43616d7066697265204d61726b65743a2053616c742068617320616c7265616460008201527f79206265656e20757365642e0000000000000000000000000000000000000000602082015250565b6139c68161327d565b81146139d157600080fd5b50565b6139dd8161328f565b81146139e857600080fd5b50565b6139f48161329b565b81146139ff57600080fd5b50565b613a0b816132f1565b8114613a1657600080fd5b5056fea26469706673582212207be45f9250989e8a5ed87bfa0ba7a08a9806b9acd6c8ef4400e97963ce4f639764736f6c63430008010033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.