Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 2 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 16089567 | 1160 days ago | Contract Creation | 0 ETH | |||
| 0x60806040 | 15702622 | 1215 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Factory1155
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import './Factory721.sol';
import '../vaults/Vault1155.sol';
contract Factory1155 is Factory721 {
using Detector for address;
constructor(address market) Factory721(market) {}
function deployVault(
string memory _name,
string memory _symbol,
address _collection,
uint256 _minDuration,
uint256 _maxDuration,
uint256 _collectionOwnerFeeRatio,
uint256[] memory _minPrices, // wei
address[] memory _paymentTokens,
uint256[] calldata _allowedTokenIds
) external override {
require(_collection.is1155(), 'OnlyERC1155');
address _vault = address(
new Vault1155(
_name,
_symbol,
_collection,
msg.sender,
_market,
_minDuration * 1 days, // day -> sec
_maxDuration * 1 days, // day -> sec
_collectionOwnerFeeRatio, // bps: 1000 => 1%
_minPrices, // wei
_paymentTokens,
_allowedTokenIds
)
);
emit VaultDeployed(_vault, _collection);
}
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import './Vault721.sol';
import {IWrap1155} from '../interfaces/IWrap.sol';
import '../wraps/Wrap1155.sol';
contract Vault1155 is Vault721 {
constructor(
string memory _name,
string memory _symbol,
address _collection,
address _collectionOwner,
address _marketContract,
uint256 _minDuration,
uint256 _maxDuration,
uint256 _collectionOwnerFeeRatio,
uint256[] memory _minPrices,
address[] memory _paymentTokens, // 'Stack too deep' error because of too many args!
uint256[] memory _allowedTokenIds
)
Vault721(
_name,
_symbol,
_collection,
_collectionOwner,
_marketContract,
_minDuration,
_maxDuration,
_collectionOwnerFeeRatio,
_minPrices,
_paymentTokens,
_allowedTokenIds
)
{}
function _deployWrap() internal override {
wrapContract = address(
new Wrap1155(
string(abi.encodePacked('Wrapped ', originalName)),
string(abi.encodePacked('W', originalSymbol)),
marketContract
)
);
}
function _redeem(uint256 _lockId) internal override {
IMarket.Lend memory _lend = IMarket(marketContract).getLendRent(_lockId).lend;
// Send tokens back from Vault contract to the user's wallet
IERC1155(originalCollection).safeTransferFrom(
address(this),
ownerOf(_lockId),
_lend.tokenId,
_lend.amount,
''
);
_burn(_lockId);
}
function _mintWNft(
address _renter,
uint256 _lockId,
uint256 _tokenId,
uint256 _amount
) internal override {
IWrap1155(wrapContract).emitTransfer(address(this), _renter, _tokenId, _amount, _lockId);
}
function onERC1155Received(
address _operator,
address _from,
uint256 _tokenId,
uint256 _value,
bytes memory _data
) external pure returns (bytes4) {
_operator;
_from;
_tokenId;
_value;
_data;
return 0xf23a6e61;
}
// function onERC1155BatchReceived(
// address _operator,
// address _from,
// uint256[] memory _tokenIds,
// uint256[] memory _values,
// bytes memory _data
// ) external pure returns (bytes4) {
// _operator;
// _from;
// _tokenIds;
// _values;
// _data;
// return 0xbc197c81;
// }
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import '../vaults/Vault721.sol';
import '../interfaces/IMarket.sol';
import '../libraries/Detector.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
contract Factory721 is Ownable {
using Detector for address;
address internal _market;
event VaultDeployed(address indexed vault, address indexed collection);
constructor(address market) {
_market = market;
}
//@notice Create a vault by hitting this function from the frontend UI
//@access Can be executed by anyone, but must be the owner of the original NFT collection
function deployVault(
string memory _name,
string memory _symbol,
address _collection,
uint256 _minDuration, // default: 0, as non limited
uint256 _maxDuration, // default: 1000 years, as non limited
uint256 _collectionOwnerFeeRatio, //default: 0, (1000 = 1%)
uint256[] memory _minPrices, // default: 0, as a non limited
address[] memory _paymentTokens, // default: 0x00
uint256[] calldata _allowedTokenIds // default: [], it will be allow all tokens
) external virtual {
require(_collection.is721(), 'OnlyERC721');
address _vault = address(
new Vault721(
_name,
_symbol,
_collection,
msg.sender,
_market,
_minDuration * 1 days, // day -> sec
_maxDuration * 1 days, // day -> sec
_collectionOwnerFeeRatio, // bps: 1000 => 1%
_minPrices, // wei
_paymentTokens,
_allowedTokenIds
)
);
emit VaultDeployed(_vault, _collection);
}
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import '../wraps/Wrap721.sol';
import {IMarket, IMarketOwner} from '../interfaces/IMarket.sol';
import {IWrap721} from '../interfaces/IWrap.sol';
import '../libraries/RentaFiSVG.sol';
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/security/Pausable.sol';
//ERROR FUNCTIONS
error MustBeSameLength();
error InvalidTokens();
contract Vault721 is ERC721, Pausable {
address public wrapContract;
address public originalCollection;
address public marketContract;
address public collectionOwner;
uint256 public minDuration;
uint256 public maxDuration;
uint256 public collectionOwnerFeeRatio;
string public originalName;
string public originalSymbol;
mapping(uint256 => uint256) private tokenIdAllowed;
mapping(address => uint256) public minPrices;
address[] public paymentTokens;
uint256 public allTokenIdAllowed;
address public payoutAddress;
constructor(
string memory _name,
string memory _symbol,
address _collection,
address _collectionOwner,
address _marketContract,
uint256 _minDuration,
uint256 _maxDuration,
uint256 _collectionOwnerFeeRatio,
uint256[] memory _minPrices,
address[] memory _paymentTokens,
uint256[] memory _allowedTokenIds
)
ERC721(
string(abi.encodePacked('RentaFi Ownership NFT ', _name)),
string(abi.encodePacked('RentaFi-ON-', _symbol))
)
{
marketContract = _marketContract;
originalCollection = _collection;
collectionOwner = _collectionOwner; // Who deploys this Vault contract from Factory contract
originalName = _name;
originalSymbol = _symbol;
payoutAddress = _collectionOwner;
_setDuration(_minDuration, _maxDuration);
_setCollectionOwnerFeeRatio(_collectionOwnerFeeRatio);
_setMinPrices(_minPrices, _paymentTokens);
if (_allowedTokenIds.length > 0) {
unchecked {
for (uint256 i = 0; i < _allowedTokenIds.length; i++) {
tokenIdAllowed[_allowedTokenIds[i]] = 1;
}
}
} else {
allTokenIdAllowed = 1;
}
_deployWrap();
}
/**************
* MODIFIER *
**************/
modifier onlyProtocolAdmin() {
require(IMarketOwner(marketContract).owner() == msg.sender, 'onlyProtocolAdmin');
_;
}
modifier onlyCollectionOwner() {
require(msg.sender == collectionOwner, 'onlyCollectionOwner');
_;
}
modifier onlyMarket() {
require(msg.sender == marketContract, 'onlyMarket');
_;
}
modifier onlyONftOwner(uint256 _lockId) {
require(ownerOf(_lockId) == msg.sender, 'onlyONftOwner');
_;
}
/**********************
* EXTERNAL FUNCTIONS *
**********************/
function redeem(uint256 _lockId) external virtual onlyMarket whenNotPaused {
_redeem(_lockId);
}
function mintONft(uint256 _lockId) external onlyMarket whenNotPaused {
address _lender = IMarket(marketContract).getLendRent(_lockId).lend.lender;
_mint(_lender, _lockId);
}
function mintWNft(
address _renter,
uint256 _starts,
uint256 _expires,
uint256 _lockId,
uint256 _tokenId,
uint256 _amount
) public virtual onlyMarket {
_expires;
_amount;
// If it starts later, only book and return.
if (_starts > block.timestamp) return;
_mintWNft(_renter, _lockId, _tokenId, _amount);
}
function activate(
uint256 _rentId,
uint256 _lockId,
address _renter,
uint256 _amount
) external virtual onlyMarket whenNotPaused {
_amount;
uint256 _now = block.timestamp;
IMarket.Rent[] memory _rents = IMarket(marketContract).getLendRent(_lockId).rent;
IMarket.Rent memory _rent;
unchecked {
for (uint256 i = 0; i < _rents.length; i++) {
if (_rents[i].rentId == _rentId) {
_rent = _rents[i];
break;
}
}
}
require(_rent.rentId == _rentId, 'RentNotFound');
require(_rent.renterAddress == _renter, 'onlyRenter');
require(_rent.rentalStartTime < _now && _rent.rentalExpireTime > _now, 'OutsideTheTerm');
_mintWNft(_renter, _lockId, IMarket(marketContract).getLendRent(_lockId).lend.tokenId, _amount);
}
function onERC721Received(
address _operator,
address _from,
uint256 _tokenId,
bytes calldata _data
) external pure returns (bytes4) {
_operator;
_from;
_tokenId;
_data;
return 0x150b7a02;
}
/** GETTER FUNCTIONS */
function getPaymentTokens() external view returns (address[] memory) {
return paymentTokens;
}
function getTokenIdAllowed(uint256 _tokenId) external view returns (uint256) {
if (allTokenIdAllowed > 0) return 1;
return tokenIdAllowed[_tokenId];
}
function tokenURI(uint256 _lockId) public view override returns (string memory) {
require(_exists(_lockId), 'ERC721Metadata: URI query for nonexistent token');
// CHANGE STATE
IMarket.Lend memory _lend = IMarket(marketContract).getLendRent(_lockId).lend;
bytes memory json = RentaFiSVG.getOwnershipSVG(
_lockId,
_lend.tokenId,
_lend.amount,
_lend.lockStartTime,
_lend.lockExpireTime,
originalCollection,
IERC721Metadata(originalCollection).name()
);
string memory _tokenURI = string(
abi.encodePacked('data:application/json;base64,', Base64.encode(json))
);
return _tokenURI;
}
/** TX FUNCTIONS */
function transferCollectionOwner(address _newOwner) external onlyCollectionOwner {
collectionOwner = _newOwner;
}
function emergencyWithdraw(uint256 _lockId) external whenPaused onlyONftOwner(_lockId) {
_redeem(_lockId);
}
/** SETTER FUNCTIONS */
function setPayoutAddress(address _newAddress) external onlyCollectionOwner {
payoutAddress = _newAddress;
}
function setTokenIdAllowed(uint256[] calldata _tokenIds, uint256[] calldata _allowed)
external
onlyCollectionOwner
{
if (_tokenIds.length != _allowed.length) revert MustBeSameLength();
uint256 _allowedLength = _allowed.length;
unchecked {
for (uint256 i = 0; i < _allowedLength; i++) {
if (_allowed[i] > 0) {
tokenIdAllowed[_tokenIds[i]] = 1;
} else {
// Deleting a non-existent key does not result in an error.
delete tokenIdAllowed[_tokenIds[i]];
}
}
}
allTokenIdAllowed = 0;
}
function setAllTokenIdAllowed(uint256 _bool) external onlyCollectionOwner {
allTokenIdAllowed = _bool;
}
function setMinPrices(uint256[] memory _minPrices, address[] memory _paymentTokens)
external
onlyCollectionOwner
{
_setMinPrices(_minPrices, _paymentTokens);
}
function setCollectionOwnerFeeRatio(uint256 _collectionOwnerFeeRatio)
external
onlyCollectionOwner
{
_setCollectionOwnerFeeRatio(_collectionOwnerFeeRatio);
}
function setDuration(uint256 _minDuration, uint256 _maxDuration) external onlyCollectionOwner {
_setDuration(_minDuration, _maxDuration);
}
/** PROTOCOL ADMIN FUNCTIONS */
function pause() external onlyProtocolAdmin {
paused() ? _unpause() : _pause();
}
/*********************
* PRIVATE FUNCTIONS *
*********************/
function _setCollectionOwnerFeeRatio(uint256 _collectionOwnerFeeRatio) private {
require(_collectionOwnerFeeRatio <= 90 * 1000, 'FeeRatio>90%');
collectionOwnerFeeRatio = _collectionOwnerFeeRatio;
}
function _setDuration(uint256 _minDuration, uint256 _maxDuration) private {
require(minDuration <= maxDuration, 'minDur>maxDur');
minDuration = _minDuration;
maxDuration = _maxDuration;
}
// priceが0は非許可を意味する
function _setMinPrices(uint256[] memory _minPrices, address[] memory _paymentTokens) private {
require(_minPrices.length > 0, 'EmptyNotAllowed');
if (_minPrices.length != _paymentTokens.length) revert MustBeSameLength();
uint256 _paymentTokensLength = _paymentTokens.length;
unchecked {
for (uint256 i = 0; i < _paymentTokensLength; i++) {
if (IMarket(marketContract).paymentTokenWhiteList(_paymentTokens[i]) >= 1) {
minPrices[_paymentTokens[i]] = _minPrices[i];
} else revert InvalidTokens(); // 配列の中に1つでもinvalidなトークンが含まれていたらrevertする
}
}
paymentTokens = _paymentTokens;
}
/**********************
* INTERNAL FUNCTIONS *
**********************/
function _deployWrap() internal virtual {
wrapContract = address(
new Wrap721(
string(abi.encodePacked('Wrapped ', IERC721Metadata(originalCollection).name())),
string(abi.encodePacked('W', IERC721Metadata(originalCollection).symbol())),
marketContract
)
);
}
function _redeem(uint256 _lockId) internal virtual {
IMarket.Lend memory _lend = IMarket(marketContract).getLendRent(_lockId).lend;
// Send tokens back from Vault contract to the user's wallet
IERC721(originalCollection).transferFrom(address(this), ownerOf(_lockId), _lend.tokenId);
_burn(_lockId);
}
function _mintWNft(
address _renter,
uint256 _lockId,
uint256 _tokenId,
uint256 _amount
) internal virtual {
_amount;
IWrap721(wrapContract).emitTransfer(address(this), _renter, _tokenId, _lockId);
}
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
interface IWrap721 {
function emitTransfer(
address from,
address to,
uint256 id,
uint256 lockId
) external;
}
interface IWrap1155 {
function emitTransfer(
address from,
address to,
uint256 id,
uint256 amount,
uint256 lockId
) external;
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import '../interfaces/IMarket.sol';
import '../interfaces/IVault.sol';
import '@openzeppelin/contracts/token/ERC1155/ERC1155.sol';
import '@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
contract Wrap1155 is ERC1155 {
string public name;
string public symbol;
address private _vault;
address private _market;
uint256 initialized = 0;
/* tokenId => renter EOA address => lockId */
mapping(uint256 => mapping(address => uint256[])) private _userToLocks;
// tokenId => lockId[]
mapping(uint256 => uint256[]) private _tokenToLocks;
constructor(
string memory _name,
string memory _symbol,
address marketAddress
) ERC1155('') {
name = _name;
symbol = _symbol;
_vault = msg.sender;
_market = marketAddress;
}
function setURI(string memory _uri) public {
require(msg.sender == IVault(_vault).collectionOwner(), 'onlyCollectionOwner');
_setURI(_uri);
initialized = 1;
}
function balanceOf(address account, uint256 id) public view override returns (uint256) {
uint256 _now = block.timestamp;
uint256 _balance = 0;
for (uint256 x = 0; x < _userToLocks[id][account].length; x++) {
IMarket.Rent[] memory _rents = IMarket(_market)
.getLendRent(_userToLocks[id][account][x])
.rent;
for (uint256 i = 0; i < _rents.length; i++) {
if (
_rents[i].renterAddress == account &&
_rents[i].rentalStartTime <= _now &&
_now <= _rents[i].rentalExpireTime
) _balance += _rents[i].amount;
}
}
return _balance; // balanceOfBatch calls balanceOf internally, so no implementation required
}
function emitTransfer(
address from,
address to,
uint256 id,
uint256 amount,
uint256 lockId
) public {
require(msg.sender == _vault, 'onlyVault');
bool _exist = false;
//トークンIDごとに、ロックIDが複数つく場合があるので、今なんこLockIDが紐づいているか確認
for (uint256 i = 0; i < _tokenToLocks[id].length; i++)
// 今借りたNFTのlockIDがすでに借りられていた場合:つまり10個あるうち、自分が借りた分以外の数を誰かが先に借りていた場合
if (_tokenToLocks[id][i] == lockId) _exist = true; // 存在するフラグを立てる
if (!_exist) _tokenToLocks[id].push(lockId); // 存在していなかった場合には、lockIdを追加する
_exist = false; //フラグを戻す
for (
uint256 i = 0;
i < _userToLocks[id][to].length;
i++ //トークンIDごとにユーザーを複数紐づけているのでその長さをとる
) if (_userToLocks[id][to][i] == lockId) _exist = true; //自分が借りたトークンIDを別の貸板で借りていた場合 true
if (!_exist) _userToLocks[id][to].push(lockId); // そうでなかった場合は追加する
emit TransferSingle(_vault, from, to, id, amount); //transfer
}
function uri(uint256 _tokenId) public view virtual override returns (string memory) {
require(_exists(_tokenId), 'ERC1155Metadata: URI query for nonexistent token');
if (initialized == 0) {
address _originalNftAddress = IVault(_vault).originalCollection();
return IERC1155MetadataURI(_originalNftAddress).uri(_tokenId);
} else {
return string(abi.encodePacked(super.uri(_tokenId), Strings.toString(_tokenId)));
}
}
function _exists(uint256 _tokenId) internal view returns (bool) {
// Check Lend existence
if (_tokenToLocks[_tokenId].length == 0) return false;
// Check Rent existence
for (uint256 i = 0; i < _tokenToLocks[_tokenId].length; i++) {
IMarket.Rent[] memory _rents = IMarket(_market).getLendRent(_tokenToLocks[_tokenId][i]).rent;
for (uint256 j = 0; j < _rents.length; j++) {
if (_rents[j].rentalExpireTime > block.timestamp) return true;
}
}
return false;
}
modifier disabled() {
require(false, 'Disabled function');
_;
}
function setApprovalForAll(address operator, bool _approved) public override disabled {}
function isApprovedForAll(address owner, address operator)
public
view
override
disabled
returns (bool)
{}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
uint256 amount,
bytes calldata data
) public override disabled {}
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) public override disabled {}
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
interface IMarket {
event Listed(uint256 indexed lockId, address indexed lender, Lend lend);
event Rented(uint256 indexed rentId, address indexed renter, uint256 lockId, Rent rent);
event Canceled(uint256 indexed lockId);
event WhiteListed(address indexed collection, address indexed vault);
event Withdrawn(uint256 indexed lockId);
event Claimed(uint256 indexed lockId);
event ClaimedRoyalty(address indexed collection);
enum LockIdTarget {
Lender,
Renter,
Vault,
Token
}
enum PaymentMethod {
// 32bit
OneTime,
Loan,
BNPL,
Subscription
}
/*
* Market only returns data for listings
* Original NFT is in the Vault contract
*/
struct Lend {
uint64 minRentalDuration; // days
uint64 maxRentalDuration; // days
uint64 lockStartTime;
uint64 lockExpireTime;
uint256 dailyRentalPrice; // wei
uint256 tokenId;
uint256 amount; // for ERC1155
address vault; //160 bit
address paymentToken; // 160 bit
address lender; // 160 bit
address privateAddress;
PaymentMethod paymentMethod; // 32bit
}
struct Rent {
address renterAddress;
uint256 rentId;
uint256 rentalStartTime;
uint256 rentalExpireTime;
uint256 amount;
}
struct LendRent {
Lend lend;
Rent[] rent;
}
function getLendRent(uint256 _lockId) external view returns (LendRent memory);
function paymentTokenWhiteList(address _paymentToken) external view returns (uint256);
function protocolAdminFeeRatio() external view returns (uint256);
}
interface IMarketOwner {
function owner() external view returns (address);
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import '../interfaces/IMarket.sol';
import '../interfaces/IVault.sol';
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';
contract Wrap721 is ERC721 {
constructor(
string memory _name,
string memory _symbol,
address _marketAddress
) ERC721(_name, _symbol) {
_vault = msg.sender;
_market = _marketAddress;
}
address private _vault;
address private _market;
uint256[] private _tokens;
// tokenId => lockId
mapping(uint256 => uint256) private _tokenToLocks;
modifier onlyVault() {
require(msg.sender == _vault, 'onlyVault');
_;
}
function _exists(uint256 _tokenId) internal view override returns (bool) {
// Check Lend existence
uint256 _lockId = _tokenToLocks[_tokenId];
if (_lockId == 0) return false;
// Check Rent existence
IMarket.LendRent memory _lendRent = IMarket(_market).getLendRent(_lockId);
if (_lendRent.rent.length == 0) return false;
// Check Rent validity
uint256 _rentalExpireTime = _lendRent.rent[0].rentalExpireTime;
return _rentalExpireTime > block.timestamp;
}
function ownerOf(uint256 _tokenId) public view virtual override returns (address) {
uint256 _now = block.timestamp;
IMarket.Rent[] memory _rents = IMarket(_market).getLendRent(_tokenToLocks[_tokenId]).rent;
if (_rents.length == 0) return address(0);
if (_rents[0].rentalStartTime <= _now && _now <= _rents[0].rentalExpireTime) {
return _rents[0].renterAddress;
} else {
return address(0);
}
}
//ownerOfに依存する.ownerOfが正しければ、これも正しい
function balanceOf(address owner) public view override returns (uint256) {
uint256 _balance;
for (uint256 i = 0; i < _tokens.length; i++) {
if (ownerOf(_tokens[i]) == owner) _balance++;
}
return _balance;
}
function emitTransfer(
address _from,
address _to,
uint256 _tokenId,
uint256 _lockId
) public onlyVault {
_tokenToLocks[_tokenId] = _lockId;
_tokens.push(_tokenId);
emit Transfer(_from, _to, _tokenId);
}
function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
require(_exists(_tokenId), 'ERC721Metadata: URI query for nonexistent token');
return IERC721Metadata(IVault(_vault).originalCollection()).tokenURI(_tokenId);
}
modifier disabled() {
require(false, 'Disabled function');
_;
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public override disabled {}
function approve(address to, uint256 tokenId) public override disabled {}
function getApproved(uint256 tokenId) public view override disabled returns (address) {}
function setApprovalForAll(address operator, bool _approved) public override disabled {}
function isApprovedForAll(address owner, address operator)
public
view
override
disabled
returns (bool)
{}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public override disabled {}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) public override disabled {}
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
import '@openzeppelin/contracts/utils/Base64.sol';
library RentaFiSVG {
function weiToEther(uint256 num) public pure returns (string memory) {
if (num == 0) return '0.0';
bytes memory b = bytes(Strings.toString(num));
uint256 n = b.length;
if (n < 19) for (uint256 i = 0; i < 19 - n; i++) b = abi.encodePacked('0', b);
n = b.length;
uint256 k = 18;
for (uint256 i = n - 1; i > n - 18; i--) {
if (b[i] != '0') break;
k--;
}
uint256 m = n - 18 + k + 1;
bytes memory a = new bytes(m);
for (uint256 i = 0; i < k; i++) a[m - 1 - i] = b[n - 19 + k - i];
a[m - k - 1] = '.';
for (uint256 i = 0; i < n - 18; i++) a[m - k - 2 - i] = b[n - 19 - i];
return string(a);
}
function getYieldSVG(
uint256 _lockId,
uint256 _tokenId,
uint256 _amount,
uint256 _benefit,
uint256 _lockStartTime,
uint256 _lockExpireTime,
address _collection,
string memory _name,
string memory _tokenSymbol
) public pure returns (bytes memory) {
string memory parsed = weiToEther(_benefit);
string memory svg = string(
abi.encodePacked(
abi.encodePacked(
"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill='#fff' viewBox='0 0 486 300'><rect width='485.4' height='300' fill='#fff' rx='12'/><rect width='485.4' height='300' fill='url(#a)' rx='12'/><text fill='#5A6480' font-family='Poppins' font-size='10' font-weight='400'><tspan x='28' y='40'>Yield NFT - RentaFi</tspan></text><text fill='#5A6480' font-family='Poppins' font-size='10' font-weight='400' text-anchor='end'><tspan x='465' y='150'>",
_tokenSymbol,
"</tspan></text><text fill='#5A6480' font-family='Inter' font-size='24' font-weight='900'><tspan x='28' y='150'>Claimable Funds</tspan></text><text fill='#5A6480' font-family='Inter' font-size='36' font-weight='900'><tspan x='440' y='150' text-anchor='end'>",
parsed,
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400'><tspan x='28' y='270'>"
),
abi.encodePacked(
_name,
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400'><tspan x='28' y='283'>",
Strings.toHexString(uint256(uint160(_collection)), 20),
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400' text-anchor='end'><tspan x='463' y='270'>TokenID: ",
Strings.toString(_tokenId),
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400' text-anchor='end'><tspan x='463' y='283'>Amount: ",
Strings.toString(_amount),
"</tspan></text><defs><linearGradient id='a' x1='0' x2='379' y1='96' y2='353' gradientUnits='userSpaceOnUse'><stop stop-color='#7DBCFF' stop-opacity='.1'/><stop offset='1' stop-color='#FF7DC0' stop-opacity='.1'/></linearGradient></defs></svg>"
)
)
);
bytes memory json = abi.encodePacked(
abi.encodePacked(
'{"name": "yieldNFT #',
Strings.toString(_lockId),
' - RentaFi", "description": "YieldNFT represents Rental Fee deposited by Borrower in a RentaFi Escrow. The owner of this NFT can claim rental fee after lock-time expired by burn this.", "image": "data:image/svg+xml;base64,',
Base64.encode(bytes(svg)),
'", "attributes":[{"display_type": "date", "trait_type": "StartDate", "value":"'
),
abi.encodePacked(
Strings.toString(_lockStartTime),
'"},{"display_type": "date", "trait_type":"ExpireDate", "value":"',
Strings.toString(_lockExpireTime),
'"},{"trait_type":"FeeAmount", "value":"',
parsed,
'"},{"trait_type":"Collection", "value":"',
_name,
'"}]}'
)
);
return json;
}
function getOwnershipSVG(
uint256 _lockId,
uint256 _tokenId,
uint256 _amount,
uint256 _lockStartTime,
uint256 _lockExpireTime,
address _collection,
string memory _name
) public pure returns (bytes memory) {
string memory svg = string(
abi.encodePacked(
abi.encodePacked(
"<svg xmlns='http://www.w3.org/2000/svg' fill='#fff' viewBox='0 0 486 300'><rect width='485.4' height='300' fill='#fff' rx='12'/><rect width='485.4' height='300' fill='url(#a)' rx='12'/><text fill='#5A6480' font-family='Poppins' font-size='10' font-weight='400'><tspan x='28' y='40'>RentaFi Ownership NFT</tspan></text><text fill='#5A6480' font-family='Poppins' font-size='10' font-weight='400'><tspan x='280' y='270'>Until Unlock</tspan><tspan x='430' y='270'>Day</tspan></text><text fill='#5A6480' font-family='Inter' font-size='24' font-weight='900'><tspan x='28' y='150'>",
_name,
"</tspan></text><text fill='#5A6480' font-family='Inter' font-size='36' font-weight='900' text-anchor='end'><tspan x='425' y='270'>",
Strings.toString((_lockExpireTime - _lockStartTime) / 1 days)
),
abi.encodePacked(
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400'><tspan x='28' y='170'>",
Strings.toHexString(uint256(uint160(_collection)), 20),
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400'><tspan x='28' y='185'>TokenID: ",
Strings.toString(_tokenId),
"</tspan></text><text fill='#98AABE' font-family='Inter' font-size='10' font-weight='400'><tspan x='28' y='200'>Amount: ",
Strings.toString(_amount),
"</tspan></text><defs><linearGradient id='a' x1='0' x2='379' y1='96' y2='353' gradientUnits='userSpaceOnUse'><stop stop-color='#7DBCFF' stop-opacity='.1'/><stop offset='1' stop-color='#FF7DC0' stop-opacity='.1'/></linearGradient></defs></svg>"
)
)
);
bytes memory json = abi.encodePacked(
'{"name": "OwnershipNFT #',
Strings.toString(_lockId),
' - RentaFi", "description": "OwnershipNFT represents Original NFT locked in a RentaFi Escrow. The owner of this NFT can claim original NFT after lock-time expired by burn this.", "image": "data:image/svg+xml;base64,',
Base64.encode(bytes(svg)),
'", "attributes":[{"display_type": "date", "trait_type": "StartDate", "value":"',
Strings.toString(_lockStartTime),
'"},{"display_type": "date", "trait_type":"ExpireDate", "value":"',
Strings.toString(_lockExpireTime),
'"},{"trait_type": "Collection", "value":"',
_name,
'"}]}'
);
return json;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_safeTransfer(from, to, tokenId, data);
}
/**
* @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.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: 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);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (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`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: 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 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 the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
interface IVault {
function factoryContract() external view returns (address);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function approve(address _to, uint256 _tokenId) external;
function burn(uint256 _tokenId) external;
function mintONft(uint256 _lockId) external;
function mintWNft(
address _renter,
uint256 _starts,
uint256 _expires,
uint256 _lockId,
uint256 _tokenId,
uint256 _amount
) external;
function activate(
uint256 _rentId,
uint256 _lockId,
address _renter,
uint256 _amount
) external;
function originalCollection() external view returns (address);
function redeem(uint256 _tokenId) external;
function ownerOf(uint256 _tokenId) external view returns (address owner);
function collectionOwner() external view returns (address);
function payoutAddress() external view returns (address);
function collectionOwnerFeeRatio() external view returns (uint256);
function getTokenIdAllowed(uint256 _tokenId) external view returns (bool);
function getPaymentTokens() external view returns (address[] memory);
//function paymentTokenWhiteList(address _paymentToken) external view returns (uint256 _bool);
function setMinPrices(uint256[] memory _minPrices, address[] memory _paymentTokens) external;
//NOTE ホワリスの代わり
function minPrices(address _paymentToken) external view returns (uint256);
function minDuration() external view returns (uint256);
function maxDuration() external view returns (uint256);
function flashloan(
address _tokenAddress,
uint256 _tokenId,
address _receiver
) external payable;
function transferFrom(
address _from,
address _to,
uint256 _tokenId
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated 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 (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/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.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// 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
// 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.7.0) (utils/Base64.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides a set of functions to operate with Base64 strings.
*
* _Available since v4.5._
*/
library Base64 {
/**
* @dev Base64 Encoding/Decoding Table
*/
string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* @dev Converts a `bytes` to its Bytes64 `string` representation.
*/
function encode(bytes memory data) internal pure returns (string memory) {
/**
* Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
* https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
*/
if (data.length == 0) return "";
// Loads the table into memory
string memory table = _TABLE;
// Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
// and split into 4 numbers of 6 bits.
// The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
// - `data.length + 2` -> Round up
// - `/ 3` -> Number of 3-bytes chunks
// - `4 *` -> 4 characters for each chunk
string memory result = new string(4 * ((data.length + 2) / 3));
/// @solidity memory-safe-assembly
assembly {
// Prepare the lookup table (skip the first "length" byte)
let tablePtr := add(table, 1)
// Prepare result pointer, jump over length
let resultPtr := add(result, 32)
// Run over the input, 3 bytes at a time
for {
let dataPtr := data
let endPtr := add(data, mload(data))
} lt(dataPtr, endPtr) {
} {
// Advance 3 bytes
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
// To write each character, shift the 3 bytes (18 bits) chunk
// 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
// and apply logical AND with 0x3F which is the number of
// the previous character in the ASCII table prior to the Base64 Table
// The result is then added to the table to get the character to write,
// and finally write it in the result pointer but with a left shift
// of 256 (1 byte) - 8 (1 ASCII char) = 248 bits
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
}
// When data `bytes` is not exactly 3 bytes long
// it is padded with `=` characters at the end
switch mod(mload(data), 3)
case 1 {
mstore8(sub(resultPtr, 1), 0x3d)
mstore8(sub(resultPtr, 2), 0x3d)
}
case 2 {
mstore8(sub(resultPtr, 1), 0x3d)
}
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri_) {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `from`
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `ids` and `amounts` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
/**
* @dev Hook that is called after any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: None
pragma solidity =0.8.13;
import '../interfaces/IMarket.sol';
import '../ERC4907/IERC4907.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol';
library Detector {
function is721(address collection) public view returns (bool) {
return IERC165(collection).supportsInterface(type(IERC721).interfaceId);
}
function is1155(address collection) public view returns (bool) {
return IERC165(collection).supportsInterface(type(IERC1155).interfaceId);
}
function is4907(address collection) public view returns (bool) {
return IERC165(collection).supportsInterface(type(IERC4907).interfaceId);
}
function availability(
address _originalNftAddress,
IMarket.Rent[] calldata _rents,
IMarket.Lend calldata _lend,
uint256 _rentalStartTime,
uint256 _rentalExpireTime
) public view returns (uint256) {
uint256 _rentaled;
// ERC721 availability
if (is721(_originalNftAddress)) {
// Check for rental availability
unchecked {
for (uint256 i = 0; i < _rents.length; i++) {
// Periods A-B and C-D overlap only if A<=D && C<=B
if (
_rents[i].rentalStartTime <= _rentalExpireTime &&
_rentalStartTime <= _rents[i].rentalExpireTime
) _rentaled += _rents[i].amount;
}
// Check for rental availability
return _lend.amount - _rentaled;
}
}
// ERC1155 availability
if (is1155(_originalNftAddress)) {
// Confirmation of the number of tokens remaining available for rent
unchecked {
for (uint256 i = 0; i < _rents.length; i++) {
// Counting rent amount with overlapping periods
// Periods A-B and C-D overlap only if A<=D && C<=B
if (
_rents[i].rentalStartTime <= _rentalExpireTime &&
_rentalStartTime <= _rents[i].rentalExpireTime
) _rentaled += _rents[i].amount;
}
}
// Check for rental availability
return _lend.amount - _rentaled;
}
return 0;
}
}// 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: CC0-1.0
pragma solidity =0.8.13;
interface IERC4907 {
// Logged when the user of a token assigns a new user or updates expires
/// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed
/// The zero address for user indicates that there is no user address
event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);
/// @notice set the user and expires of a NFT
/// @dev The zero address indicates there is no user
/// Throws if `tokenId` is not valid NFT
/// @param user The new user of the NFT
/// @param expires UNIX timestamp, The new user could use the NFT before expires
function setUser(
uint256 tokenId,
address user,
uint64 expires
) external;
/// @notice Get the user address of an NFT
/// @dev The zero address indicates that there is no user or the user is expired
/// @param tokenId The NFT to get the user address for
/// @return The user address for this NFT
function userOf(uint256 tokenId) external view returns (address);
/// @notice Get the user expires of an NFT
/// @dev The zero value indicates that there is no user
/// @param tokenId The NFT to get the user expires for
/// @return The user expires for this NFT
function userExpires(uint256 tokenId) external view returns (uint256);
}{
"optimizer": {
"enabled": true,
"runs": 1
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {
"contracts/libraries/Detector.sol": {
"Detector": "0xea23e206842e9d6530b5efc3ba4e2ad226ec7258"
},
"contracts/libraries/RentaFiSVG.sol": {
"RentaFiSVG": "0x7597236ec607b2ecb96d8fe8970d7dc93cdccd43"
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"market","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"collection","type":"address"}],"name":"VaultDeployed","type":"event"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_minDuration","type":"uint256"},{"internalType":"uint256","name":"_maxDuration","type":"uint256"},{"internalType":"uint256","name":"_collectionOwnerFeeRatio","type":"uint256"},{"internalType":"uint256[]","name":"_minPrices","type":"uint256[]"},{"internalType":"address[]","name":"_paymentTokens","type":"address[]"},{"internalType":"uint256[]","name":"_allowedTokenIds","type":"uint256[]"}],"name":"deployVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5060405161609d38038061609d83398101604081905261002f916100af565b806100393361005f565b600180546001600160a01b0319166001600160a01b0392909216919091179055506100df565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100c157600080fd5b81516001600160a01b03811681146100d857600080fd5b9392505050565b615faf806100ee6000396000f3fe60806040523480156200001157600080fd5b5060043610620000525760003560e01c8063715018a614620000575780638da5cb5b1462000063578063babfaa231462000085578063f2fde38b146200009c575b600080fd5b62000061620000b3565b005b6200006d620000cb565b6040516200007c9190620003ac565b60405180910390f35b6200006162000096366004620005ee565b620000da565b62000061620000ad36600462000709565b6200026c565b620000bd620002eb565b620000c960006200034e565b565b6000546001600160a01b031690565b6040516302408fad60e11b815273ea23e206842e9d6530b5efc3ba4e2ad226ec7258906304811f5a906200011c906001600160a01b038c1690600401620003ac565b602060405180830381865af41580156200013a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016091906200072e565b620001a05760405162461bcd60e51b815260206004820152600b60248201526a4f6e6c794552433131353560a81b60448201526064015b60405180910390fd5b6001546000908b908b908b9033906001600160a01b0316620001c68d6201518062000752565b620001d58d6201518062000752565b8c8c8c8c8c604051620001e8906200039e565b620001ff9c9b9a999897969594939291906200087f565b604051809103906000f0801580156200021c573d6000803e3d6000fd5b509050886001600160a01b0316816001600160a01b03167f09d75e12e349f79020715b0ea7b2c707e8acf1889b6d6f1337fce7f4e1b9e5c760405160405180910390a35050505050505050505050565b62000276620002eb565b6001600160a01b038116620002dd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000197565b620002e8816200034e565b50565b33620002f6620000cb565b6001600160a01b031614620000c95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000197565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b615642806200093883390190565b6001600160a01b0391909116815260200190565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004015762000401620003c0565b604052919050565b600082601f8301126200041b57600080fd5b81356001600160401b03811115620004375762000437620003c0565b6200044c601f8201601f1916602001620003d6565b8181528460208386010111156200046257600080fd5b816020850160208301376000918101602001919091529392505050565b80356001600160a01b03811681146200049757600080fd5b919050565b60006001600160401b03821115620004b857620004b8620003c0565b5060051b60200190565b600082601f830112620004d457600080fd5b81356020620004ed620004e7836200049c565b620003d6565b82815260059290921b840181019181810190868411156200050d57600080fd5b8286015b848110156200052a578035835291830191830162000511565b509695505050505050565b600082601f8301126200054757600080fd5b813560206200055a620004e7836200049c565b82815260059290921b840181019181810190868411156200057a57600080fd5b8286015b848110156200052a5762000592816200047f565b83529183019183016200057e565b60008083601f840112620005b357600080fd5b5081356001600160401b03811115620005cb57600080fd5b6020830191508360208260051b8501011115620005e757600080fd5b9250929050565b6000806000806000806000806000806101208b8d0312156200060f57600080fd5b8a356001600160401b03808211156200062757600080fd5b620006358e838f0162000409565b9b5060208d01359150808211156200064c57600080fd5b6200065a8e838f0162000409565b9a506200066a60408e016200047f565b995060608d0135985060808d0135975060a08d0135965060c08d01359150808211156200069657600080fd5b620006a48e838f01620004c2565b955060e08d0135915080821115620006bb57600080fd5b620006c98e838f0162000535565b94506101008d0135915080821115620006e157600080fd5b50620006f08d828e01620005a0565b915080935050809150509295989b9194979a5092959850565b6000602082840312156200071c57600080fd5b62000727826200047f565b9392505050565b6000602082840312156200074157600080fd5b815180151581146200072757600080fd5b60008160001904831182151516156200077b57634e487b7160e01b600052601160045260246000fd5b500290565b6000815180845260005b81811015620007a8576020818501810151868301820152016200078a565b81811115620007bb576000602083870101525b50601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b838110156200080257815187529582019590820190600101620007e4565b509495945050505050565b600081518084526020808501945080840160005b83811015620008025781516001600160a01b03168752958201959082019060010162000821565b81835260006001600160fb1b038311156200086257600080fd5b8260051b8083602087013760009401602001938452509192915050565b610160815260006200089661016083018f62000780565b8281036020840152620008aa818f62000780565b6001600160a01b038e811660408601528d811660608601528c16608085015260a084018b905260c084018a905260e084018990528381036101008501529050620008f58188620007d0565b90508281036101208401526200090c81876200080d565b90508281036101408401526200092481858762000848565b9f9e50505050505050505050505050505056fe60806040523480156200001157600080fd5b506040516200564238038062005642833981016040819052620000349162000820565b8a8a8a8a8a8a8a8a8a8a8a8a60405160200162000052919062000974565b6040516020818303038152906040528a604051602001620000749190620009bb565b60408051601f1981840301815291905281516200009990600090602085019062000507565b508051620000af90600190602084019062000507565b50506006805460ff1916905550600880546001600160a01b03808a166001600160a01b031992831617909255600780548c841690831617905560098054928b16929091169190911790558a516200010e90600d9060208e019062000507565b5089516200012490600e9060208d019062000507565b50601380546001600160a01b0319166001600160a01b038a161790556200014c8686620001ea565b62000157846200023f565b62000163838362000288565b805115620001be5760005b8151811015620001b7576001600f6000848481518110620001935762000193620009f0565b6020908102919091018101518252810191909152604001600020556001016200016e565b50620001c4565b60016012555b620001ce6200044f565b5050505050505050505050505050505050505050505062000bab565b600b54600a541115620002345760405162461bcd60e51b815260206004820152600d60248201526c36b4b7223ab91f36b0bc223ab960991b60448201526064015b60405180910390fd5b600a91909155600b55565b62015f90811115620002835760405162461bcd60e51b815260206004820152600c60248201526b466565526174696f3e39302560a01b60448201526064016200022b565b600c55565b6000825111620002cd5760405162461bcd60e51b815260206004820152600f60248201526e115b5c1d1e539bdd105b1b1bddd959608a1b60448201526064016200022b565b8051825114620002f057604051635977c73960e01b815260040160405180910390fd5b805160005b81811015620004335760085483516001916001600160a01b031690630fcee7b0908690859081106200032b576200032b620009f0565b60200260200101516040518263ffffffff1660e01b81526004016200035f91906001600160a01b0391909116815260200190565b602060405180830381865afa1580156200037d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a3919062000a06565b106200041157838181518110620003be57620003be620009f0565b602002602001015160106000858481518110620003df57620003df620009f0565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055506200042a565b6040516333910aef60e11b815260040160405180910390fd5b600101620002f5565b5081516200044990601190602085019062000596565b50505050565b600d60405160200162000463919062000afd565b604051602081830303815290604052600e60405160200162000486919062000b23565b60408051601f198184030181529082905260085490916001600160a01b0390911690620004b390620005ee565b620004c19392919062000b69565b604051809103906000f080158015620004de573d6000803e3d6000fd5b50600660016101000a8154816001600160a01b0302191690836001600160a01b03160217905550565b828054620005159062000a20565b90600052602060002090601f01602090048101928262000539576000855562000584565b82601f106200055457805160ff191683800117855562000584565b8280016001018555821562000584579182015b828111156200058457825182559160200191906001019062000567565b5062000592929150620005fc565b5090565b82805482825590600052602060002090810192821562000584579160200282015b828111156200058457825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620005b7565b611b7a8062003ac883390190565b5b80821115620005925760008155600101620005fd565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000654576200065462000613565b604052919050565b60005b83811015620006795781810151838201526020016200065f565b83811115620004495750506000910152565b600082601f8301126200069d57600080fd5b81516001600160401b03811115620006b957620006b962000613565b620006ce601f8201601f191660200162000629565b818152846020838601011115620006e457600080fd5b620006f78260208301602087016200065c565b949350505050565b80516001600160a01b03811681146200071757600080fd5b919050565b60006001600160401b0382111562000738576200073862000613565b5060051b60200190565b600082601f8301126200075457600080fd5b815160206200076d62000767836200071c565b62000629565b82815260059290921b840181019181810190868411156200078d57600080fd5b8286015b84811015620007aa578051835291830191830162000791565b509695505050505050565b600082601f830112620007c757600080fd5b81516020620007da62000767836200071c565b82815260059290921b84018101918181019086841115620007fa57600080fd5b8286015b84811015620007aa576200081281620006ff565b8352918301918301620007fe565b60008060008060008060008060008060006101608c8e0312156200084357600080fd5b8b516001600160401b038111156200085a57600080fd5b620008688e828f016200068b565b60208e0151909c5090506001600160401b038111156200088757600080fd5b620008958e828f016200068b565b9a5050620008a660408d01620006ff565b9850620008b660608d01620006ff565b9750620008c660808d01620006ff565b965060a08c0151955060c08c0151945060e08c015193506101008c015160018060401b03811115620008f757600080fd5b620009058e828f0162000742565b6101208e015190945090506001600160401b038111156200092557600080fd5b620009338e828f01620007b5565b6101408e015190935090506001600160401b038111156200095357600080fd5b620009618e828f0162000742565b9150509295989b509295989b9093969950565b7f52656e74614669204f776e657273686970204e46542000000000000000000000815260008251620009ae8160168501602087016200065c565b9190910160160192915050565b6a52656e746146692d4f4e2d60a81b815260008251620009e381600b8501602087016200065c565b91909101600b0192915050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a1957600080fd5b5051919050565b600181811c9082168062000a3557607f821691505b60208210810362000a5657634e487b7160e01b600052602260045260246000fd5b50919050565b8054600090600181811c908083168062000a7757607f831692505b6020808410820362000a9957634e487b7160e01b600052602260045260246000fd5b81801562000ab0576001811462000ac25762000af1565b60ff1986168952848901965062000af1565b60008881526020902060005b8681101562000ae95781548b82015290850190830162000ace565b505084890196505b50505050505092915050565b6702bb930b83832b2160c51b8152600062000b1c600883018462000a5c565b9392505050565b605760f81b8152600062000b1c600183018462000a5c565b6000815180845262000b558160208601602086016200065c565b601f01601f19169290920160200192915050565b60608152600062000b7e606083018662000b3b565b828103602084015262000b92818662000b3b565b91505060018060a01b0383166040830152949350505050565b612f0d8062000bbb6000396000f3fe608060405234801561001057600080fd5b50600436106102045760003560e01c806301ffc9a71461020957806306fdde0314610231578063081812fc14610246578063095ea7b314610266578063139238da1461027b578063150b7a021461028e57806321024981146102c657806323b872dd146102dd578063280ec4c4146102f057806333a098411461030357806333ea51a81461030c57806334be77cd1461031f57806342842e0e146103275780635312ea8e1461033a578063567157611461034d5780635b8d02d7146103565780635c975abb146103695780635d77b8381461037457806361dd277e146103875780636352211e1461039a5780636db5c8fd146103ad57806370a08231146103b6578063710728a6146103c9578063833ea0ee146103dc5780638456cb59146103e45780638b8b1408146103ec57806395d89b41146103ff57806396201cc514610407578063a1794bcd14610427578063a22cb4651461043a578063b6bd2a941461044d578063b88d4fde14610460578063c87b56dd14610473578063c8f7243d14610486578063ca5e553e14610499578063cc1f4818146104ae578063cd7ea095146104c6578063cf6aaa05146104d9578063d6bca516146104ec578063db006a75146104ff578063de66084114610512578063df727d3b14610525578063e985e9c514610538578063f23a6e611461054b575b600080fd5b61021c610217366004612139565b61056a565b60405190151581526020015b60405180910390f35b6102396105bc565b60405161022891906121b5565b6102596102543660046121c8565b61064e565b60405161022891906121e1565b61027961027436600461220a565b610675565b005b610279610289366004612236565b61078f565b6102ad61029c366004612253565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610228565b6102cf600c5481565b604051908152602001610228565b6102796102eb3660046122f1565b6107db565b6102796102fe366004612332565b61080c565b6102cf60125481565b61027961031a366004612236565b610851565b61023961089d565b6102796103353660046122f1565b61092b565b6102796103483660046121c8565b610946565b6102cf600a5481565b601354610259906001600160a01b031681565b60065460ff1661021c565b6102796103823660046123c9565b6109ac565b600754610259906001600160a01b031681565b6102596103a83660046121c8565b610a9e565b6102cf600b5481565b6102cf6103c4366004612236565b610ad3565b6102796103d736600461257e565b610b59565b610239610b8d565b610279610b9a565b6102796103fa366004612636565b610c6d565b610239610f22565b6102cf610415366004612236565b60106020526000908152604090205481565b600854610259906001600160a01b031681565b610279610448366004612675565b610f31565b61027961045b3660046121c8565b610f3c565b61027961046e36600461272b565b610f72565b6102396104813660046121c8565b610faa565b6102cf6104943660046121c8565b6111f0565b6104a1611216565b6040516102289190612796565b6006546102599061010090046001600160a01b031681565b6102796104d43660046127e3565b611277565b6102796104e73660046121c8565b6112ab565b6102796104fa3660046121c8565b6112da565b61027961050d3660046121c8565b611390565b6102596105203660046121c8565b6113cb565b600954610259906001600160a01b031681565b61021c610546366004612805565b6113f5565b6102ad610559366004612833565b63f23a6e6160e01b95945050505050565b60006001600160e01b031982166380ac58cd60e01b148061059b57506001600160e01b03198216635b5e139f60e01b145b806105b657506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546105cb906128a8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f7906128a8565b80156106445780601f1061061957610100808354040283529160200191610644565b820191906000526020600020905b81548152906001019060200180831161062757829003601f168201915b5050505050905090565b600061065982611423565b506000908152600460205260409020546001600160a01b031690565b600061068082610a9e565b9050806001600160a01b0316836001600160a01b0316036106f25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061070e575061070e81336113f5565b6107805760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016106e9565b61078a8383611448565b505050565b6009546001600160a01b031633146107b95760405162461bcd60e51b81526004016106e9906128e2565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6107e533826114b6565b6108015760405162461bcd60e51b81526004016106e99061290f565b61078a838383611515565b6008546001600160a01b031633146108365760405162461bcd60e51b81526004016106e99061295d565b428511610849576108498684848461169f565b505050505050565b6009546001600160a01b0316331461087b5760405162461bcd60e51b81526004016106e9906128e2565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b600d80546108aa906128a8565b80601f01602080910402602001604051908101604052809291908181526020018280546108d6906128a8565b80156109235780601f106108f857610100808354040283529160200191610923565b820191906000526020600020905b81548152906001019060200180831161090657829003601f168201915b505050505081565b61078a83838360405180602001604052806000815250610f72565b61094e611725565b803361095982610a9e565b6001600160a01b03161461099f5760405162461bcd60e51b815260206004820152600d60248201526c37b7363ca7a7333a27bbb732b960991b60448201526064016106e9565b6109a88261176e565b5050565b6009546001600160a01b031633146109d65760405162461bcd60e51b81526004016106e9906128e2565b8281146109f657604051635977c73960e01b815260040160405180910390fd5b8060005b81811015610a91576000848483818110610a1657610a16612981565b905060200201351115610a59576001600f6000888885818110610a3b57610a3b612981565b90506020020135815260200190815260200160002081905550610a89565b600f6000878784818110610a6f57610a6f612981565b905060200201358152602001908152602001600020600090555b6001016109fa565b5050600060125550505050565b6000818152600260205260408120546001600160a01b0316806105b65760405162461bcd60e51b81526004016106e990612997565b60006001600160a01b038216610b3d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016106e9565b506001600160a01b031660009081526003602052604090205490565b6009546001600160a01b03163314610b835760405162461bcd60e51b81526004016106e9906128e2565b6109a8828261188e565b600e80546108aa906128a8565b60085460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610be3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0791906129d9565b6001600160a01b031614610c515760405162461bcd60e51b815260206004820152601160248201527037b7363ca83937ba37b1b7b620b236b4b760791b60448201526064016106e9565b60065460ff16610c6557610c63611a2a565b565b610c63611a7e565b6008546001600160a01b03163314610c975760405162461bcd60e51b81526004016106e99061295d565b610c9f611ab7565b60085460405163ed756fef60e01b81526004810185905242916000916001600160a01b039091169063ed756fef90602401600060405180830381865afa158015610ced573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d159190810190612acd565b602001519050610d566040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b60005b8251811015610daf5787838281518110610d7557610d75612981565b60200260200101516020015103610da757828181518110610d9857610d98612981565b60200260200101519150610daf565b600101610d59565b5086816020015114610df25760405162461bcd60e51b815260206004820152600c60248201526b14995b9d139bdd119bdd5b9960a21b60448201526064016106e9565b846001600160a01b031681600001516001600160a01b031614610e445760405162461bcd60e51b815260206004820152600a60248201526937b7363ca932b73a32b960b11b60448201526064016106e9565b828160400151108015610e5a5750828160600151115b610e975760405162461bcd60e51b815260206004820152600e60248201526d4f7574736964655468655465726d60901b60448201526064016106e9565b60085460405163ed756fef60e01b815260048101889052610f1991879189916001600160a01b03169063ed756fef90602401600060405180830381865afa158015610ee6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f0e9190810190612acd565b5160a001518761169f565b50505050505050565b6060600180546105cb906128a8565b6109a8338383611afd565b6009546001600160a01b03163314610f665760405162461bcd60e51b81526004016106e9906128e2565b610f6f81611bc7565b50565b610f7c33836114b6565b610f985760405162461bcd60e51b81526004016106e99061290f565b610fa484848484611c0e565b50505050565b6060610fb582611c41565b6110195760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106e9565b60085460405163ed756fef60e01b8152600481018490526000916001600160a01b03169063ed756fef90602401600060405180830381865afa158015611063573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261108b9190810190612acd565b6000015190506000737597236ec607b2ecb96d8fe8970d7dc93cdccd436304eb3355858460a001518560c0015186604001518760600151600760009054906101000a90046001600160a01b0316600760009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561112b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111539190810190612c43565b6040518863ffffffff1660e01b81526004016111759796959493929190612c8b565b600060405180830381865af4158015611192573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111ba9190810190612c43565b905060006111c782611c5e565b6040516020016111d79190612ce7565b60408051601f1981840301815291905295945050505050565b6012546000901561120357506001919050565b506000908152600f602052604090205490565b6060601180548060200260200160405190810160405280929190818152602001828054801561064457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611250575050505050905090565b6009546001600160a01b031633146112a15760405162461bcd60e51b81526004016106e9906128e2565b6109a88282611db0565b6009546001600160a01b031633146112d55760405162461bcd60e51b81526004016106e9906128e2565b601255565b6008546001600160a01b031633146113045760405162461bcd60e51b81526004016106e99061295d565b61130c611ab7565b60085460405163ed756fef60e01b8152600481018390526000916001600160a01b03169063ed756fef90602401600060405180830381865afa158015611356573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261137e9190810190612acd565b51610120015190506109a88183611dff565b6008546001600160a01b031633146113ba5760405162461bcd60e51b81526004016106e99061295d565b6113c2611ab7565b610f6f8161176e565b601181815481106113db57600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61142c81611c41565b610f6f5760405162461bcd60e51b81526004016106e990612997565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061147d82610a9e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806114c283610a9e565b9050806001600160a01b0316846001600160a01b031614806114e957506114e981856113f5565b8061150d5750836001600160a01b03166115028461064e565b6001600160a01b0316145b949350505050565b826001600160a01b031661152882610a9e565b6001600160a01b03161461158c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016106e9565b6001600160a01b0382166115ee5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016106e9565b6115f9600082611448565b6001600160a01b0383166000908152600360205260408120805460019290611622908490612d42565b90915550506001600160a01b0382166000908152600360205260408120805460019290611650908490612d59565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020612eb883398151915291a4505050565b60065460405163325ef54960e11b81523060048201526001600160a01b038681166024830152604482018590526064820184905260848201869052610100909204909116906364bdea929060a401600060405180830381600087803b15801561170757600080fd5b505af115801561171b573d6000803e3d6000fd5b5050505050505050565b60065460ff16610c635760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016106e9565b60085460405163ed756fef60e01b8152600481018390526000916001600160a01b03169063ed756fef90602401600060405180830381865afa1580156117b8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117e09190810190612acd565b516007549091506001600160a01b031663f242432a306117ff85610a9e565b60a08086015160c08701516040516001600160e01b031960e088901b1681526001600160a01b039586166004820152949093166024850152604484015260648301919091526084820152600060a482015260c401600060405180830381600087803b15801561186d57600080fd5b505af1158015611881573d6000803e3d6000fd5b505050506109a882611f1f565b60008251116118d15760405162461bcd60e51b815260206004820152600f60248201526e115b5c1d1e539bdd105b1b1bddd959608a1b60448201526064016106e9565b80518251146118f357604051635977c73960e01b815260040160405180910390fd5b805160005b81811015611a165760085483516001916001600160a01b031690630fcee7b09086908590811061192a5761192a612981565b60200260200101516040518263ffffffff1660e01b815260040161194e91906121e1565b602060405180830381865afa15801561196b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198f9190612d71565b106119f5578381815181106119a6576119a6612981565b6020026020010151601060008584815181106119c4576119c4612981565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550611a0e565b6040516333910aef60e11b815260040160405180910390fd5b6001016118f8565b508151610fa49060119060208501906120a9565b611a32611ab7565b6006805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a673390565b604051611a7491906121e1565b60405180910390a1565b611a86611725565b6006805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611a67565b60065460ff1615610c635760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016106e9565b816001600160a01b0316836001600160a01b031603611b5a5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b60448201526064016106e9565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b62015f90811115611c095760405162461bcd60e51b815260206004820152600c60248201526b466565526174696f3e39302560a01b60448201526064016106e9565b600c55565b611c19848484611515565b611c2584848484611fa8565b610fa45760405162461bcd60e51b81526004016106e990612d8a565b6000908152600260205260409020546001600160a01b0316151590565b60608151600003611c7d57505060408051602081019091526000815290565b6000604051806060016040528060408152602001612e786040913990506000600384516002611cac9190612d59565b611cb69190612ddc565b611cc1906004612dfe565b6001600160401b03811115611cd857611cd8612434565b6040519080825280601f01601f191660200182016040528015611d02576020820181803683370190505b509050600182016020820185865187015b80821015611d6e576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611d13565b5050600386510660018114611d8a5760028114611d9d57611da5565b603d6001830353603d6002830353611da5565b603d60018303535b509195945050505050565b600b54600a541115611df45760405162461bcd60e51b815260206004820152600d60248201526c36b4b7223ab91f36b0bc223ab960991b60448201526064016106e9565b600a91909155600b55565b6001600160a01b038216611e555760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016106e9565b611e5e81611c41565b15611eaa5760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60448201526064016106e9565b6001600160a01b0382166000908152600360205260408120805460019290611ed3908490612d59565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020612eb8833981519152908290a45050565b6000611f2a82610a9e565b9050611f37600083611448565b6001600160a01b0381166000908152600360205260408120805460019290611f60908490612d42565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020612eb8833981519152908390a45050565b60006001600160a01b0384163b1561209e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611fec903390899088908890600401612e1d565b6020604051808303816000875af1925050508015612027575060408051601f3d908101601f1916820190925261202491810190612e5a565b60015b612084573d808015612055576040519150601f19603f3d011682016040523d82523d6000602084013e61205a565b606091505b50805160000361207c5760405162461bcd60e51b81526004016106e990612d8a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061150d565b506001949350505050565b8280548282559060005260206000209081019282156120fe579160200282015b828111156120fe57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906120c9565b5061210a92915061210e565b5090565b5b8082111561210a576000815560010161210f565b6001600160e01b031981168114610f6f57600080fd5b60006020828403121561214b57600080fd5b813561215681612123565b9392505050565b60005b83811015612178578181015183820152602001612160565b83811115610fa45750506000910152565b600081518084526121a181602086016020860161215d565b601f01601f19169290920160200192915050565b6020815260006121566020830184612189565b6000602082840312156121da57600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114610f6f57600080fd5b6000806040838503121561221d57600080fd5b8235612228816121f5565b946020939093013593505050565b60006020828403121561224857600080fd5b8135612156816121f5565b60008060008060006080868803121561226b57600080fd5b8535612276816121f5565b94506020860135612286816121f5565b93506040860135925060608601356001600160401b03808211156122a957600080fd5b818801915088601f8301126122bd57600080fd5b8135818111156122cc57600080fd5b8960208285010111156122de57600080fd5b9699959850939650602001949392505050565b60008060006060848603121561230657600080fd5b8335612311816121f5565b92506020840135612321816121f5565b929592945050506040919091013590565b60008060008060008060c0878903121561234b57600080fd5b8635612356816121f5565b9860208801359850604088013597606081013597506080810135965060a00135945092505050565b60008083601f84011261239057600080fd5b5081356001600160401b038111156123a757600080fd5b6020830191508360208260051b85010111156123c257600080fd5b9250929050565b600080600080604085870312156123df57600080fd5b84356001600160401b03808211156123f657600080fd5b6124028883890161237e565b9096509450602087013591508082111561241b57600080fd5b506124288782880161237e565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171561246c5761246c612434565b60405290565b604080519081016001600160401b038111828210171561246c5761246c612434565b60405161018081016001600160401b038111828210171561246c5761246c612434565b604051601f8201601f191681016001600160401b03811182821017156124df576124df612434565b604052919050565b60006001600160401b0382111561250057612500612434565b5060051b60200190565b600082601f83011261251b57600080fd5b8135602061253061252b836124e7565b6124b7565b82815260059290921b8401810191818101908684111561254f57600080fd5b8286015b84811015612573578035612566816121f5565b8352918301918301612553565b509695505050505050565b6000806040838503121561259157600080fd5b82356001600160401b03808211156125a857600080fd5b818501915085601f8301126125bc57600080fd5b813560206125cc61252b836124e7565b82815260059290921b840181019181810190898411156125eb57600080fd5b948201945b83861015612609578535825294820194908201906125f0565b9650508601359250508082111561261f57600080fd5b5061262c8582860161250a565b9150509250929050565b6000806000806080858703121561264c57600080fd5b84359350602085013592506040850135612665816121f5565b9396929550929360600135925050565b6000806040838503121561268857600080fd5b8235612693816121f5565b9150602083013580151581146126a857600080fd5b809150509250929050565b60006001600160401b038211156126cc576126cc612434565b50601f01601f191660200190565b600082601f8301126126eb57600080fd5b81356126f961252b826126b3565b81815284602083860101111561270e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561274157600080fd5b843561274c816121f5565b9350602085013561275c816121f5565b92506040850135915060608501356001600160401b0381111561277e57600080fd5b61278a878288016126da565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156127d75783516001600160a01b0316835292840192918401916001016127b2565b50909695505050505050565b600080604083850312156127f657600080fd5b50508035926020909101359150565b6000806040838503121561281857600080fd5b8235612823816121f5565b915060208301356126a8816121f5565b600080600080600060a0868803121561284b57600080fd5b8535612856816121f5565b94506020860135612866816121f5565b9350604086013592506060860135915060808601356001600160401b0381111561288f57600080fd5b61289b888289016126da565b9150509295509295909350565b600181811c908216806128bc57607f821691505b6020821081036128dc57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526013908201527237b7363ca1b7b63632b1ba34b7b727bbb732b960691b604082015260600190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252600a90820152691bdb9b1e53585c9ad95d60b21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b602080825260189082015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604082015260600190565b80516129d4816121f5565b919050565b6000602082840312156129eb57600080fd5b8151612156816121f5565b80516001600160401b03811681146129d457600080fd5b8051600481106129d457600080fd5b600082601f830112612a2d57600080fd5b81516020612a3d61252b836124e7565b82815260a09283028501820192828201919087851115612a5c57600080fd5b8387015b85811015612ac05781818a031215612a785760008081fd5b612a8061244a565b8151612a8b816121f5565b815281860151868201526040808301519082015260608083015190820152608080830151908201528452928401928101612a60565b5090979650505050505050565b600060208284031215612adf57600080fd5b81516001600160401b0380821115612af657600080fd5b908301908185036101a0811215612b0c57600080fd5b612b14612472565b61018080831215612b2457600080fd5b612b2c612494565b9250612b37856129f6565b8352612b45602086016129f6565b6020840152612b56604086016129f6565b6040840152612b67606086016129f6565b60608401526080850151608084015260a085015160a084015260c085015160c0840152612b9660e086016129c9565b60e0840152610100612ba98187016129c9565b90840152610120612bbb8682016129c9565b90840152610140612bcd8682016129c9565b90840152610160612bdf868201612a0d565b90840152918152908301519082821115612bf857600080fd5b612c0487838601612a1c565b60208201529695505050505050565b6000612c2161252b846126b3565b9050828152838383011115612c3557600080fd5b61215683602083018461215d565b600060208284031215612c5557600080fd5b81516001600160401b03811115612c6b57600080fd5b8201601f81018413612c7c57600080fd5b61150d84825160208401612c13565b87815260208101879052604081018690526001600160401b038581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090612cda90830184612189565b9998505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251612d1f81601d85016020870161215d565b91909101601d0192915050565b634e487b7160e01b600052601160045260246000fd5b600082821015612d5457612d54612d2c565b500390565b60008219821115612d6c57612d6c612d2c565b500190565b600060208284031215612d8357600080fd5b5051919050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600082612df957634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612e1857612e18612d2c565b500290565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e5090830184612189565b9695505050505050565b600060208284031215612e6c57600080fd5b81516121568161212356fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220d3654f558b5bb47cb65b682816d4b772ec2f58709bf179af57ef9c4321f34d9e64736f6c634300080d0033608060405260006007553480156200001657600080fd5b5060405162001b7a38038062001b7a833981016040819052620000399162000243565b6040805160208101909152600081526200005381620000b7565b50825162000069906003906020860190620000d0565b5081516200007f906004906020850190620000d0565b5060058054336001600160a01b031991821617909155600680549091166001600160a01b0392909216919091179055506200030c9050565b8051620000cc906002906020840190620000d0565b5050565b828054620000de90620002d0565b90600052602060002090601f0160209004810192826200010257600085556200014d565b82601f106200011d57805160ff19168380011785556200014d565b828001600101855582156200014d579182015b828111156200014d57825182559160200191906001019062000130565b506200015b9291506200015f565b5090565b5b808211156200015b576000815560010162000160565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200019e57600080fd5b81516001600160401b0380821115620001bb57620001bb62000176565b604051601f8301601f19908116603f01168101908282118183101715620001e657620001e662000176565b816040528381526020925086838588010111156200020357600080fd5b600091505b8382101562000227578582018301518183018401529082019062000208565b83821115620002395760008385830101525b9695505050505050565b6000806000606084860312156200025957600080fd5b83516001600160401b03808211156200027157600080fd5b6200027f878388016200018c565b945060208601519150808211156200029657600080fd5b50620002a5868287016200018c565b604086015190935090506001600160a01b0381168114620002c557600080fd5b809150509250925092565b600181811c90821680620002e557607f821691505b6020821081036200030657634e487b7160e01b600052602260045260246000fd5b50919050565b61185e806200031c6000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8062fdd58e146100a857806301ffc9a7146100ce57806302fe5305146100f157806306fdde03146101065780630e89341c1461011b5780632eb2c2d61461012e5780634e1273f41461014157806364bdea921461016157806395d89b4114610174578063a22cb4651461017c578063e985e9c51461018a578063f242432a1461019d575b600080fd5b6100bb6100b6366004610dec565b6101ab565b6040519081526020015b60405180910390f35b6100e16100dc366004610e18565b610385565b60405190151581526020016100c5565b6101046100ff366004610f1c565b6103d7565b005b61010e6104ba565b6040516100c59190610fcb565b61010e610129366004610ffe565b610548565b61010461013c3660046110a3565b6106e5565b61015461014f3660046111ea565b6106fd565b6040516100c591906112ab565b61010461016f3660046112ef565b610826565b61010e610a15565b61010461013c366004611340565b6100e161019836600461137e565b610a26565b61010461013c3660046113ac565b60004281805b60008581526008602090815260408083206001600160a01b038a16845290915290205481101561037c5760065460008681526008602090815260408083206001600160a01b038b811685529252822080549293919091169163ed756fef91908590811061022057610220611427565b90600052602060002001546040518263ffffffff1660e01b815260040161024991815260200190565b600060405180830381865afa158015610266573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261028e919081019061151f565b60200151905060005b815181101561036757876001600160a01b03168282815181106102bc576102bc611427565b6020026020010151600001516001600160a01b03161480156102fb5750848282815181106102ec576102ec611427565b60200260200101516040015111155b8015610324575081818151811061031457610314611427565b6020026020010151606001518511155b156103555781818151811061033b5761033b611427565b60200260200101516080015184610352919061167b565b93505b8061035f81611693565b915050610297565b5050808061037490611693565b9150506101b1565b50949350505050565b60006001600160e01b03198216636cdb3d1360e11b14806103b657506001600160e01b031982166303a24d0760e21b145b806103d157506301ffc9a760e01b6001600160e01b03198316145b92915050565b600560009054906101000a90046001600160a01b03166001600160a01b031663df727d3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044e91906116ac565b6001600160a01b0316336001600160a01b0316146104a95760405162461bcd60e51b815260206004820152601360248201527237b7363ca1b7b63632b1ba34b7b727bbb732b960691b60448201526064015b60405180910390fd5b6104b281610a40565b506001600755565b600380546104c7906116c9565b80601f01602080910402602001604051908101604052809291908181526020018280546104f3906116c9565b80156105405780601f1061051557610100808354040283529160200191610540565b820191906000526020600020905b81548152906001019060200180831161052357829003601f168201915b505050505081565b606061055382610a53565b6105b85760405162461bcd60e51b815260206004820152603060248201527f455243313135354d657461646174613a2055524920717565727920666f72206e60448201526f37b732bc34b9ba32b73a103a37b5b2b760811b60648201526084016104a0565b6007546000036106a757600554604080516330ee93bf60e11b815290516000926001600160a01b0316916361dd277e9160048083019260209291908290030181865afa15801561060c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063091906116ac565b6040516303a24d0760e21b8152600481018590529091506001600160a01b03821690630e89341c90602401600060405180830381865afa158015610678573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106a09190810190611703565b9392505050565b6106b082610b9f565b6106b983610c33565b6040516020016106ca929190611779565b6040516020818303038152906040529050919050565b919050565b60405162461bcd60e51b81526004016104a0906117a8565b606081518351146107625760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016104a0565b600083516001600160401b0381111561077d5761077d610e42565b6040519080825280602002602001820160405280156107a6578160200160208202803683370190505b50905060005b845181101561081e576107f18582815181106107ca576107ca611427565b60200260200101518583815181106107e4576107e4611427565b60200260200101516101ab565b82828151811061080357610803611427565b602090810291909101015261081781611693565b90506107ac565b509392505050565b6005546001600160a01b0316331461086c5760405162461bcd60e51b81526020600482015260096024820152681bdb9b1e55985d5b1d60ba1b60448201526064016104a0565b6000805b6000858152600960205260409020548110156108d05760008581526009602052604090208054849190839081106108a9576108a9611427565b9060005260206000200154036108be57600191505b806108c881611693565b915050610870565b50806108f8576000848152600960209081526040822080546001810182559083529120018290555b506000805b60008581526008602090815260408083206001600160a01b038a1684529091529020548110156109855760008581526008602090815260408083206001600160a01b038a168452909152902080548491908390811061095e5761095e611427565b90600052602060002001540361097357600191505b8061097d81611693565b9150506108fd565b50806109be5760008481526008602090815260408083206001600160a01b03891684528252822080546001810182559083529120018290555b60055460408051868152602081018690526001600160a01b03888116938a8216939116917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050505050565b600480546104c7906116c9565b5050565b600060405162461bcd60e51b81526004016104a0906117a8565b8051610a22906002906020840190610d3b565b6000818152600960205260408120548103610a7057506000919050565b60005b600083815260096020526040902054811015610b96576006546000848152600960205260408120805491926001600160a01b03169163ed756fef919085908110610abf57610abf611427565b90600052602060002001546040518263ffffffff1660e01b8152600401610ae891815260200190565b600060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b2d919081019061151f565b60200151905060005b8151811015610b815742828281518110610b5257610b52611427565b6020026020010151606001511115610b6f57506001949350505050565b80610b7981611693565b915050610b36565b50508080610b8e90611693565b915050610a73565b50600092915050565b606060028054610bae906116c9565b80601f0160208091040260200160405190810160405280929190818152602001828054610bda906116c9565b8015610c275780601f10610bfc57610100808354040283529160200191610c27565b820191906000526020600020905b815481529060010190602001808311610c0a57829003601f168201915b50505050509050919050565b606081600003610c5a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610c845780610c6e81611693565b9150610c7d9050600a836117e9565b9150610c5e565b6000816001600160401b03811115610c9e57610c9e610e42565b6040519080825280601f01601f191660200182016040528015610cc8576020820181803683370190505b5090505b8415610d3357610cdd6001836117fd565b9150610cea600a86611814565b610cf590603061167b565b60f81b818381518110610d0a57610d0a611427565b60200101906001600160f81b031916908160001a905350610d2c600a866117e9565b9450610ccc565b949350505050565b828054610d47906116c9565b90600052602060002090601f016020900481019282610d695760008555610daf565b82601f10610d8257805160ff1916838001178555610daf565b82800160010185558215610daf579182015b82811115610daf578251825591602001919060010190610d94565b50610dbb929150610dbf565b5090565b5b80821115610dbb5760008155600101610dc0565b6001600160a01b0381168114610de957600080fd5b50565b60008060408385031215610dff57600080fd5b8235610e0a81610dd4565b946020939093013593505050565b600060208284031215610e2a57600080fd5b81356001600160e01b0319811681146106a057600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715610e7a57610e7a610e42565b60405290565b604080519081016001600160401b0381118282101715610e7a57610e7a610e42565b60405161018081016001600160401b0381118282101715610e7a57610e7a610e42565b604051601f8201601f191681016001600160401b0381118282101715610eed57610eed610e42565b604052919050565b60006001600160401b03821115610f0e57610f0e610e42565b50601f01601f191660200190565b600060208284031215610f2e57600080fd5b81356001600160401b03811115610f4457600080fd5b8201601f81018413610f5557600080fd5b8035610f68610f6382610ef5565b610ec5565b818152856020838501011115610f7d57600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b83811015610fb6578181015183820152602001610f9e565b83811115610fc5576000848401525b50505050565b6020815260008251806020840152610fea816040850160208701610f9b565b601f01601f19169190910160400192915050565b60006020828403121561101057600080fd5b5035919050565b60008083601f84011261102957600080fd5b5081356001600160401b0381111561104057600080fd5b6020830191508360208260051b850101111561105b57600080fd5b9250929050565b60008083601f84011261107457600080fd5b5081356001600160401b0381111561108b57600080fd5b60208301915083602082850101111561105b57600080fd5b60008060008060008060008060a0898b0312156110bf57600080fd5b88356110ca81610dd4565b975060208901356110da81610dd4565b965060408901356001600160401b03808211156110f657600080fd5b6111028c838d01611017565b909850965060608b013591508082111561111b57600080fd5b6111278c838d01611017565b909650945060808b013591508082111561114057600080fd5b5061114d8b828c01611062565b999c989b5096995094979396929594505050565b60006001600160401b0382111561117a5761117a610e42565b5060051b60200190565b600082601f83011261119557600080fd5b813560206111a5610f6383611161565b82815260059290921b840181019181810190868411156111c457600080fd5b8286015b848110156111df57803583529183019183016111c8565b509695505050505050565b600080604083850312156111fd57600080fd5b82356001600160401b038082111561121457600080fd5b818501915085601f83011261122857600080fd5b81356020611238610f6383611161565b82815260059290921b8401810191818101908984111561125757600080fd5b948201945b8386101561127e57853561126f81610dd4565b8252948201949082019061125c565b9650508601359250508082111561129457600080fd5b506112a185828601611184565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156112e3578351835292840192918401916001016112c7565b50909695505050505050565b600080600080600060a0868803121561130757600080fd5b853561131281610dd4565b9450602086013561132281610dd4565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561135357600080fd5b823561135e81610dd4565b91506020830135801515811461137357600080fd5b809150509250929050565b6000806040838503121561139157600080fd5b823561139c81610dd4565b9150602083013561137381610dd4565b60008060008060008060a087890312156113c557600080fd5b86356113d081610dd4565b955060208701356113e081610dd4565b9450604087013593506060870135925060808701356001600160401b0381111561140957600080fd5b61141589828a01611062565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b80516001600160401b03811681146106e057600080fd5b80516106e081610dd4565b8051600481106106e057600080fd5b600082601f83011261147f57600080fd5b8151602061148f610f6383611161565b82815260a092830285018201928282019190878511156114ae57600080fd5b8387015b858110156115125781818a0312156114ca5760008081fd5b6114d2610e58565b81516114dd81610dd4565b8152818601518682015260408083015190820152606080830151908201526080808301519082015284529284019281016114b2565b5090979650505050505050565b60006020828403121561153157600080fd5b81516001600160401b038082111561154857600080fd5b908301908185036101a081121561155e57600080fd5b611566610e80565b6101808083121561157657600080fd5b61157e610ea2565b92506115898561143d565b83526115976020860161143d565b60208401526115a86040860161143d565b60408401526115b96060860161143d565b60608401526080850151608084015260a085015160a084015260c085015160c08401526115e860e08601611454565b60e08401526101006115fb818701611454565b9084015261012061160d868201611454565b9084015261014061161f868201611454565b9084015261016061163186820161145f565b9084015291815290830151908282111561164a57600080fd5b6116568783860161146e565b60208201529695505050505050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561168e5761168e611665565b500190565b6000600182016116a5576116a5611665565b5060010190565b6000602082840312156116be57600080fd5b81516106a081610dd4565b600181811c908216806116dd57607f821691505b6020821081036116fd57634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561171557600080fd5b81516001600160401b0381111561172b57600080fd5b8201601f8101841361173c57600080fd5b805161174a610f6382610ef5565b81815285602083850101111561175f57600080fd5b611770826020830160208601610f9b565b95945050505050565b6000835161178b818460208801610f9b565b83519083019061179f818360208801610f9b565b01949350505050565b6020808252601190820152702234b9b0b13632b210333ab731ba34b7b760791b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b6000826117f8576117f86117d3565b500490565b60008282101561180f5761180f611665565b500390565b600082611823576118236117d3565b50069056fea2646970667358221220a3cb987179031f0100a20a33d49ba4e8c981e7272fe814d33bd59b58acfb1cd364736f6c634300080d0033a26469706673582212203918b8a3a016014db044f5e459b82d40aeb0eb424560b45de86c279bdb30004864736f6c634300080d0033000000000000000000000000651647ee8bc055e950241cf112fea964a0000827
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620000525760003560e01c8063715018a614620000575780638da5cb5b1462000063578063babfaa231462000085578063f2fde38b146200009c575b600080fd5b62000061620000b3565b005b6200006d620000cb565b6040516200007c9190620003ac565b60405180910390f35b6200006162000096366004620005ee565b620000da565b62000061620000ad36600462000709565b6200026c565b620000bd620002eb565b620000c960006200034e565b565b6000546001600160a01b031690565b6040516302408fad60e11b815273ea23e206842e9d6530b5efc3ba4e2ad226ec7258906304811f5a906200011c906001600160a01b038c1690600401620003ac565b602060405180830381865af41580156200013a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016091906200072e565b620001a05760405162461bcd60e51b815260206004820152600b60248201526a4f6e6c794552433131353560a81b60448201526064015b60405180910390fd5b6001546000908b908b908b9033906001600160a01b0316620001c68d6201518062000752565b620001d58d6201518062000752565b8c8c8c8c8c604051620001e8906200039e565b620001ff9c9b9a999897969594939291906200087f565b604051809103906000f0801580156200021c573d6000803e3d6000fd5b509050886001600160a01b0316816001600160a01b03167f09d75e12e349f79020715b0ea7b2c707e8acf1889b6d6f1337fce7f4e1b9e5c760405160405180910390a35050505050505050505050565b62000276620002eb565b6001600160a01b038116620002dd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000197565b620002e8816200034e565b50565b33620002f6620000cb565b6001600160a01b031614620000c95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000197565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b615642806200093883390190565b6001600160a01b0391909116815260200190565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004015762000401620003c0565b604052919050565b600082601f8301126200041b57600080fd5b81356001600160401b03811115620004375762000437620003c0565b6200044c601f8201601f1916602001620003d6565b8181528460208386010111156200046257600080fd5b816020850160208301376000918101602001919091529392505050565b80356001600160a01b03811681146200049757600080fd5b919050565b60006001600160401b03821115620004b857620004b8620003c0565b5060051b60200190565b600082601f830112620004d457600080fd5b81356020620004ed620004e7836200049c565b620003d6565b82815260059290921b840181019181810190868411156200050d57600080fd5b8286015b848110156200052a578035835291830191830162000511565b509695505050505050565b600082601f8301126200054757600080fd5b813560206200055a620004e7836200049c565b82815260059290921b840181019181810190868411156200057a57600080fd5b8286015b848110156200052a5762000592816200047f565b83529183019183016200057e565b60008083601f840112620005b357600080fd5b5081356001600160401b03811115620005cb57600080fd5b6020830191508360208260051b8501011115620005e757600080fd5b9250929050565b6000806000806000806000806000806101208b8d0312156200060f57600080fd5b8a356001600160401b03808211156200062757600080fd5b620006358e838f0162000409565b9b5060208d01359150808211156200064c57600080fd5b6200065a8e838f0162000409565b9a506200066a60408e016200047f565b995060608d0135985060808d0135975060a08d0135965060c08d01359150808211156200069657600080fd5b620006a48e838f01620004c2565b955060e08d0135915080821115620006bb57600080fd5b620006c98e838f0162000535565b94506101008d0135915080821115620006e157600080fd5b50620006f08d828e01620005a0565b915080935050809150509295989b9194979a5092959850565b6000602082840312156200071c57600080fd5b62000727826200047f565b9392505050565b6000602082840312156200074157600080fd5b815180151581146200072757600080fd5b60008160001904831182151516156200077b57634e487b7160e01b600052601160045260246000fd5b500290565b6000815180845260005b81811015620007a8576020818501810151868301820152016200078a565b81811115620007bb576000602083870101525b50601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b838110156200080257815187529582019590820190600101620007e4565b509495945050505050565b600081518084526020808501945080840160005b83811015620008025781516001600160a01b03168752958201959082019060010162000821565b81835260006001600160fb1b038311156200086257600080fd5b8260051b8083602087013760009401602001938452509192915050565b610160815260006200089661016083018f62000780565b8281036020840152620008aa818f62000780565b6001600160a01b038e811660408601528d811660608601528c16608085015260a084018b905260c084018a905260e084018990528381036101008501529050620008f58188620007d0565b90508281036101208401526200090c81876200080d565b90508281036101408401526200092481858762000848565b9f9e50505050505050505050505050505056fe60806040523480156200001157600080fd5b506040516200564238038062005642833981016040819052620000349162000820565b8a8a8a8a8a8a8a8a8a8a8a8a60405160200162000052919062000974565b6040516020818303038152906040528a604051602001620000749190620009bb565b60408051601f1981840301815291905281516200009990600090602085019062000507565b508051620000af90600190602084019062000507565b50506006805460ff1916905550600880546001600160a01b03808a166001600160a01b031992831617909255600780548c841690831617905560098054928b16929091169190911790558a516200010e90600d9060208e019062000507565b5089516200012490600e9060208d019062000507565b50601380546001600160a01b0319166001600160a01b038a161790556200014c8686620001ea565b62000157846200023f565b62000163838362000288565b805115620001be5760005b8151811015620001b7576001600f6000848481518110620001935762000193620009f0565b6020908102919091018101518252810191909152604001600020556001016200016e565b50620001c4565b60016012555b620001ce6200044f565b5050505050505050505050505050505050505050505062000bab565b600b54600a541115620002345760405162461bcd60e51b815260206004820152600d60248201526c36b4b7223ab91f36b0bc223ab960991b60448201526064015b60405180910390fd5b600a91909155600b55565b62015f90811115620002835760405162461bcd60e51b815260206004820152600c60248201526b466565526174696f3e39302560a01b60448201526064016200022b565b600c55565b6000825111620002cd5760405162461bcd60e51b815260206004820152600f60248201526e115b5c1d1e539bdd105b1b1bddd959608a1b60448201526064016200022b565b8051825114620002f057604051635977c73960e01b815260040160405180910390fd5b805160005b81811015620004335760085483516001916001600160a01b031690630fcee7b0908690859081106200032b576200032b620009f0565b60200260200101516040518263ffffffff1660e01b81526004016200035f91906001600160a01b0391909116815260200190565b602060405180830381865afa1580156200037d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a3919062000a06565b106200041157838181518110620003be57620003be620009f0565b602002602001015160106000858481518110620003df57620003df620009f0565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055506200042a565b6040516333910aef60e11b815260040160405180910390fd5b600101620002f5565b5081516200044990601190602085019062000596565b50505050565b600d60405160200162000463919062000afd565b604051602081830303815290604052600e60405160200162000486919062000b23565b60408051601f198184030181529082905260085490916001600160a01b0390911690620004b390620005ee565b620004c19392919062000b69565b604051809103906000f080158015620004de573d6000803e3d6000fd5b50600660016101000a8154816001600160a01b0302191690836001600160a01b03160217905550565b828054620005159062000a20565b90600052602060002090601f01602090048101928262000539576000855562000584565b82601f106200055457805160ff191683800117855562000584565b8280016001018555821562000584579182015b828111156200058457825182559160200191906001019062000567565b5062000592929150620005fc565b5090565b82805482825590600052602060002090810192821562000584579160200282015b828111156200058457825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620005b7565b611b7a8062003ac883390190565b5b80821115620005925760008155600101620005fd565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000654576200065462000613565b604052919050565b60005b83811015620006795781810151838201526020016200065f565b83811115620004495750506000910152565b600082601f8301126200069d57600080fd5b81516001600160401b03811115620006b957620006b962000613565b620006ce601f8201601f191660200162000629565b818152846020838601011115620006e457600080fd5b620006f78260208301602087016200065c565b949350505050565b80516001600160a01b03811681146200071757600080fd5b919050565b60006001600160401b0382111562000738576200073862000613565b5060051b60200190565b600082601f8301126200075457600080fd5b815160206200076d62000767836200071c565b62000629565b82815260059290921b840181019181810190868411156200078d57600080fd5b8286015b84811015620007aa578051835291830191830162000791565b509695505050505050565b600082601f830112620007c757600080fd5b81516020620007da62000767836200071c565b82815260059290921b84018101918181019086841115620007fa57600080fd5b8286015b84811015620007aa576200081281620006ff565b8352918301918301620007fe565b60008060008060008060008060008060006101608c8e0312156200084357600080fd5b8b516001600160401b038111156200085a57600080fd5b620008688e828f016200068b565b60208e0151909c5090506001600160401b038111156200088757600080fd5b620008958e828f016200068b565b9a5050620008a660408d01620006ff565b9850620008b660608d01620006ff565b9750620008c660808d01620006ff565b965060a08c0151955060c08c0151945060e08c015193506101008c015160018060401b03811115620008f757600080fd5b620009058e828f0162000742565b6101208e015190945090506001600160401b038111156200092557600080fd5b620009338e828f01620007b5565b6101408e015190935090506001600160401b038111156200095357600080fd5b620009618e828f0162000742565b9150509295989b509295989b9093969950565b7f52656e74614669204f776e657273686970204e46542000000000000000000000815260008251620009ae8160168501602087016200065c565b9190910160160192915050565b6a52656e746146692d4f4e2d60a81b815260008251620009e381600b8501602087016200065c565b91909101600b0192915050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a1957600080fd5b5051919050565b600181811c9082168062000a3557607f821691505b60208210810362000a5657634e487b7160e01b600052602260045260246000fd5b50919050565b8054600090600181811c908083168062000a7757607f831692505b6020808410820362000a9957634e487b7160e01b600052602260045260246000fd5b81801562000ab0576001811462000ac25762000af1565b60ff1986168952848901965062000af1565b60008881526020902060005b8681101562000ae95781548b82015290850190830162000ace565b505084890196505b50505050505092915050565b6702bb930b83832b2160c51b8152600062000b1c600883018462000a5c565b9392505050565b605760f81b8152600062000b1c600183018462000a5c565b6000815180845262000b558160208601602086016200065c565b601f01601f19169290920160200192915050565b60608152600062000b7e606083018662000b3b565b828103602084015262000b92818662000b3b565b91505060018060a01b0383166040830152949350505050565b612f0d8062000bbb6000396000f3fe608060405234801561001057600080fd5b50600436106102045760003560e01c806301ffc9a71461020957806306fdde0314610231578063081812fc14610246578063095ea7b314610266578063139238da1461027b578063150b7a021461028e57806321024981146102c657806323b872dd146102dd578063280ec4c4146102f057806333a098411461030357806333ea51a81461030c57806334be77cd1461031f57806342842e0e146103275780635312ea8e1461033a578063567157611461034d5780635b8d02d7146103565780635c975abb146103695780635d77b8381461037457806361dd277e146103875780636352211e1461039a5780636db5c8fd146103ad57806370a08231146103b6578063710728a6146103c9578063833ea0ee146103dc5780638456cb59146103e45780638b8b1408146103ec57806395d89b41146103ff57806396201cc514610407578063a1794bcd14610427578063a22cb4651461043a578063b6bd2a941461044d578063b88d4fde14610460578063c87b56dd14610473578063c8f7243d14610486578063ca5e553e14610499578063cc1f4818146104ae578063cd7ea095146104c6578063cf6aaa05146104d9578063d6bca516146104ec578063db006a75146104ff578063de66084114610512578063df727d3b14610525578063e985e9c514610538578063f23a6e611461054b575b600080fd5b61021c610217366004612139565b61056a565b60405190151581526020015b60405180910390f35b6102396105bc565b60405161022891906121b5565b6102596102543660046121c8565b61064e565b60405161022891906121e1565b61027961027436600461220a565b610675565b005b610279610289366004612236565b61078f565b6102ad61029c366004612253565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610228565b6102cf600c5481565b604051908152602001610228565b6102796102eb3660046122f1565b6107db565b6102796102fe366004612332565b61080c565b6102cf60125481565b61027961031a366004612236565b610851565b61023961089d565b6102796103353660046122f1565b61092b565b6102796103483660046121c8565b610946565b6102cf600a5481565b601354610259906001600160a01b031681565b60065460ff1661021c565b6102796103823660046123c9565b6109ac565b600754610259906001600160a01b031681565b6102596103a83660046121c8565b610a9e565b6102cf600b5481565b6102cf6103c4366004612236565b610ad3565b6102796103d736600461257e565b610b59565b610239610b8d565b610279610b9a565b6102796103fa366004612636565b610c6d565b610239610f22565b6102cf610415366004612236565b60106020526000908152604090205481565b600854610259906001600160a01b031681565b610279610448366004612675565b610f31565b61027961045b3660046121c8565b610f3c565b61027961046e36600461272b565b610f72565b6102396104813660046121c8565b610faa565b6102cf6104943660046121c8565b6111f0565b6104a1611216565b6040516102289190612796565b6006546102599061010090046001600160a01b031681565b6102796104d43660046127e3565b611277565b6102796104e73660046121c8565b6112ab565b6102796104fa3660046121c8565b6112da565b61027961050d3660046121c8565b611390565b6102596105203660046121c8565b6113cb565b600954610259906001600160a01b031681565b61021c610546366004612805565b6113f5565b6102ad610559366004612833565b63f23a6e6160e01b95945050505050565b60006001600160e01b031982166380ac58cd60e01b148061059b57506001600160e01b03198216635b5e139f60e01b145b806105b657506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546105cb906128a8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f7906128a8565b80156106445780601f1061061957610100808354040283529160200191610644565b820191906000526020600020905b81548152906001019060200180831161062757829003601f168201915b5050505050905090565b600061065982611423565b506000908152600460205260409020546001600160a01b031690565b600061068082610a9e565b9050806001600160a01b0316836001600160a01b0316036106f25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061070e575061070e81336113f5565b6107805760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016106e9565b61078a8383611448565b505050565b6009546001600160a01b031633146107b95760405162461bcd60e51b81526004016106e9906128e2565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6107e533826114b6565b6108015760405162461bcd60e51b81526004016106e99061290f565b61078a838383611515565b6008546001600160a01b031633146108365760405162461bcd60e51b81526004016106e99061295d565b428511610849576108498684848461169f565b505050505050565b6009546001600160a01b0316331461087b5760405162461bcd60e51b81526004016106e9906128e2565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b600d80546108aa906128a8565b80601f01602080910402602001604051908101604052809291908181526020018280546108d6906128a8565b80156109235780601f106108f857610100808354040283529160200191610923565b820191906000526020600020905b81548152906001019060200180831161090657829003601f168201915b505050505081565b61078a83838360405180602001604052806000815250610f72565b61094e611725565b803361095982610a9e565b6001600160a01b03161461099f5760405162461bcd60e51b815260206004820152600d60248201526c37b7363ca7a7333a27bbb732b960991b60448201526064016106e9565b6109a88261176e565b5050565b6009546001600160a01b031633146109d65760405162461bcd60e51b81526004016106e9906128e2565b8281146109f657604051635977c73960e01b815260040160405180910390fd5b8060005b81811015610a91576000848483818110610a1657610a16612981565b905060200201351115610a59576001600f6000888885818110610a3b57610a3b612981565b90506020020135815260200190815260200160002081905550610a89565b600f6000878784818110610a6f57610a6f612981565b905060200201358152602001908152602001600020600090555b6001016109fa565b5050600060125550505050565b6000818152600260205260408120546001600160a01b0316806105b65760405162461bcd60e51b81526004016106e990612997565b60006001600160a01b038216610b3d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016106e9565b506001600160a01b031660009081526003602052604090205490565b6009546001600160a01b03163314610b835760405162461bcd60e51b81526004016106e9906128e2565b6109a8828261188e565b600e80546108aa906128a8565b60085460408051638da5cb5b60e01b8152905133926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610be3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0791906129d9565b6001600160a01b031614610c515760405162461bcd60e51b815260206004820152601160248201527037b7363ca83937ba37b1b7b620b236b4b760791b60448201526064016106e9565b60065460ff16610c6557610c63611a2a565b565b610c63611a7e565b6008546001600160a01b03163314610c975760405162461bcd60e51b81526004016106e99061295d565b610c9f611ab7565b60085460405163ed756fef60e01b81526004810185905242916000916001600160a01b039091169063ed756fef90602401600060405180830381865afa158015610ced573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d159190810190612acd565b602001519050610d566040518060a0016040528060006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b60005b8251811015610daf5787838281518110610d7557610d75612981565b60200260200101516020015103610da757828181518110610d9857610d98612981565b60200260200101519150610daf565b600101610d59565b5086816020015114610df25760405162461bcd60e51b815260206004820152600c60248201526b14995b9d139bdd119bdd5b9960a21b60448201526064016106e9565b846001600160a01b031681600001516001600160a01b031614610e445760405162461bcd60e51b815260206004820152600a60248201526937b7363ca932b73a32b960b11b60448201526064016106e9565b828160400151108015610e5a5750828160600151115b610e975760405162461bcd60e51b815260206004820152600e60248201526d4f7574736964655468655465726d60901b60448201526064016106e9565b60085460405163ed756fef60e01b815260048101889052610f1991879189916001600160a01b03169063ed756fef90602401600060405180830381865afa158015610ee6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f0e9190810190612acd565b5160a001518761169f565b50505050505050565b6060600180546105cb906128a8565b6109a8338383611afd565b6009546001600160a01b03163314610f665760405162461bcd60e51b81526004016106e9906128e2565b610f6f81611bc7565b50565b610f7c33836114b6565b610f985760405162461bcd60e51b81526004016106e99061290f565b610fa484848484611c0e565b50505050565b6060610fb582611c41565b6110195760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106e9565b60085460405163ed756fef60e01b8152600481018490526000916001600160a01b03169063ed756fef90602401600060405180830381865afa158015611063573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261108b9190810190612acd565b6000015190506000737597236ec607b2ecb96d8fe8970d7dc93cdccd436304eb3355858460a001518560c0015186604001518760600151600760009054906101000a90046001600160a01b0316600760009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561112b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111539190810190612c43565b6040518863ffffffff1660e01b81526004016111759796959493929190612c8b565b600060405180830381865af4158015611192573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111ba9190810190612c43565b905060006111c782611c5e565b6040516020016111d79190612ce7565b60408051601f1981840301815291905295945050505050565b6012546000901561120357506001919050565b506000908152600f602052604090205490565b6060601180548060200260200160405190810160405280929190818152602001828054801561064457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611250575050505050905090565b6009546001600160a01b031633146112a15760405162461bcd60e51b81526004016106e9906128e2565b6109a88282611db0565b6009546001600160a01b031633146112d55760405162461bcd60e51b81526004016106e9906128e2565b601255565b6008546001600160a01b031633146113045760405162461bcd60e51b81526004016106e99061295d565b61130c611ab7565b60085460405163ed756fef60e01b8152600481018390526000916001600160a01b03169063ed756fef90602401600060405180830381865afa158015611356573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261137e9190810190612acd565b51610120015190506109a88183611dff565b6008546001600160a01b031633146113ba5760405162461bcd60e51b81526004016106e99061295d565b6113c2611ab7565b610f6f8161176e565b601181815481106113db57600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61142c81611c41565b610f6f5760405162461bcd60e51b81526004016106e990612997565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061147d82610a9e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806114c283610a9e565b9050806001600160a01b0316846001600160a01b031614806114e957506114e981856113f5565b8061150d5750836001600160a01b03166115028461064e565b6001600160a01b0316145b949350505050565b826001600160a01b031661152882610a9e565b6001600160a01b03161461158c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016106e9565b6001600160a01b0382166115ee5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016106e9565b6115f9600082611448565b6001600160a01b0383166000908152600360205260408120805460019290611622908490612d42565b90915550506001600160a01b0382166000908152600360205260408120805460019290611650908490612d59565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020612eb883398151915291a4505050565b60065460405163325ef54960e11b81523060048201526001600160a01b038681166024830152604482018590526064820184905260848201869052610100909204909116906364bdea929060a401600060405180830381600087803b15801561170757600080fd5b505af115801561171b573d6000803e3d6000fd5b5050505050505050565b60065460ff16610c635760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016106e9565b60085460405163ed756fef60e01b8152600481018390526000916001600160a01b03169063ed756fef90602401600060405180830381865afa1580156117b8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117e09190810190612acd565b516007549091506001600160a01b031663f242432a306117ff85610a9e565b60a08086015160c08701516040516001600160e01b031960e088901b1681526001600160a01b039586166004820152949093166024850152604484015260648301919091526084820152600060a482015260c401600060405180830381600087803b15801561186d57600080fd5b505af1158015611881573d6000803e3d6000fd5b505050506109a882611f1f565b60008251116118d15760405162461bcd60e51b815260206004820152600f60248201526e115b5c1d1e539bdd105b1b1bddd959608a1b60448201526064016106e9565b80518251146118f357604051635977c73960e01b815260040160405180910390fd5b805160005b81811015611a165760085483516001916001600160a01b031690630fcee7b09086908590811061192a5761192a612981565b60200260200101516040518263ffffffff1660e01b815260040161194e91906121e1565b602060405180830381865afa15801561196b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198f9190612d71565b106119f5578381815181106119a6576119a6612981565b6020026020010151601060008584815181106119c4576119c4612981565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550611a0e565b6040516333910aef60e11b815260040160405180910390fd5b6001016118f8565b508151610fa49060119060208501906120a9565b611a32611ab7565b6006805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a673390565b604051611a7491906121e1565b60405180910390a1565b611a86611725565b6006805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611a67565b60065460ff1615610c635760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016106e9565b816001600160a01b0316836001600160a01b031603611b5a5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b60448201526064016106e9565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b62015f90811115611c095760405162461bcd60e51b815260206004820152600c60248201526b466565526174696f3e39302560a01b60448201526064016106e9565b600c55565b611c19848484611515565b611c2584848484611fa8565b610fa45760405162461bcd60e51b81526004016106e990612d8a565b6000908152600260205260409020546001600160a01b0316151590565b60608151600003611c7d57505060408051602081019091526000815290565b6000604051806060016040528060408152602001612e786040913990506000600384516002611cac9190612d59565b611cb69190612ddc565b611cc1906004612dfe565b6001600160401b03811115611cd857611cd8612434565b6040519080825280601f01601f191660200182016040528015611d02576020820181803683370190505b509050600182016020820185865187015b80821015611d6e576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611d13565b5050600386510660018114611d8a5760028114611d9d57611da5565b603d6001830353603d6002830353611da5565b603d60018303535b509195945050505050565b600b54600a541115611df45760405162461bcd60e51b815260206004820152600d60248201526c36b4b7223ab91f36b0bc223ab960991b60448201526064016106e9565b600a91909155600b55565b6001600160a01b038216611e555760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016106e9565b611e5e81611c41565b15611eaa5760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60448201526064016106e9565b6001600160a01b0382166000908152600360205260408120805460019290611ed3908490612d59565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020612eb8833981519152908290a45050565b6000611f2a82610a9e565b9050611f37600083611448565b6001600160a01b0381166000908152600360205260408120805460019290611f60908490612d42565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020612eb8833981519152908390a45050565b60006001600160a01b0384163b1561209e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611fec903390899088908890600401612e1d565b6020604051808303816000875af1925050508015612027575060408051601f3d908101601f1916820190925261202491810190612e5a565b60015b612084573d808015612055576040519150601f19603f3d011682016040523d82523d6000602084013e61205a565b606091505b50805160000361207c5760405162461bcd60e51b81526004016106e990612d8a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061150d565b506001949350505050565b8280548282559060005260206000209081019282156120fe579160200282015b828111156120fe57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906120c9565b5061210a92915061210e565b5090565b5b8082111561210a576000815560010161210f565b6001600160e01b031981168114610f6f57600080fd5b60006020828403121561214b57600080fd5b813561215681612123565b9392505050565b60005b83811015612178578181015183820152602001612160565b83811115610fa45750506000910152565b600081518084526121a181602086016020860161215d565b601f01601f19169290920160200192915050565b6020815260006121566020830184612189565b6000602082840312156121da57600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114610f6f57600080fd5b6000806040838503121561221d57600080fd5b8235612228816121f5565b946020939093013593505050565b60006020828403121561224857600080fd5b8135612156816121f5565b60008060008060006080868803121561226b57600080fd5b8535612276816121f5565b94506020860135612286816121f5565b93506040860135925060608601356001600160401b03808211156122a957600080fd5b818801915088601f8301126122bd57600080fd5b8135818111156122cc57600080fd5b8960208285010111156122de57600080fd5b9699959850939650602001949392505050565b60008060006060848603121561230657600080fd5b8335612311816121f5565b92506020840135612321816121f5565b929592945050506040919091013590565b60008060008060008060c0878903121561234b57600080fd5b8635612356816121f5565b9860208801359850604088013597606081013597506080810135965060a00135945092505050565b60008083601f84011261239057600080fd5b5081356001600160401b038111156123a757600080fd5b6020830191508360208260051b85010111156123c257600080fd5b9250929050565b600080600080604085870312156123df57600080fd5b84356001600160401b03808211156123f657600080fd5b6124028883890161237e565b9096509450602087013591508082111561241b57600080fd5b506124288782880161237e565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171561246c5761246c612434565b60405290565b604080519081016001600160401b038111828210171561246c5761246c612434565b60405161018081016001600160401b038111828210171561246c5761246c612434565b604051601f8201601f191681016001600160401b03811182821017156124df576124df612434565b604052919050565b60006001600160401b0382111561250057612500612434565b5060051b60200190565b600082601f83011261251b57600080fd5b8135602061253061252b836124e7565b6124b7565b82815260059290921b8401810191818101908684111561254f57600080fd5b8286015b84811015612573578035612566816121f5565b8352918301918301612553565b509695505050505050565b6000806040838503121561259157600080fd5b82356001600160401b03808211156125a857600080fd5b818501915085601f8301126125bc57600080fd5b813560206125cc61252b836124e7565b82815260059290921b840181019181810190898411156125eb57600080fd5b948201945b83861015612609578535825294820194908201906125f0565b9650508601359250508082111561261f57600080fd5b5061262c8582860161250a565b9150509250929050565b6000806000806080858703121561264c57600080fd5b84359350602085013592506040850135612665816121f5565b9396929550929360600135925050565b6000806040838503121561268857600080fd5b8235612693816121f5565b9150602083013580151581146126a857600080fd5b809150509250929050565b60006001600160401b038211156126cc576126cc612434565b50601f01601f191660200190565b600082601f8301126126eb57600080fd5b81356126f961252b826126b3565b81815284602083860101111561270e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561274157600080fd5b843561274c816121f5565b9350602085013561275c816121f5565b92506040850135915060608501356001600160401b0381111561277e57600080fd5b61278a878288016126da565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156127d75783516001600160a01b0316835292840192918401916001016127b2565b50909695505050505050565b600080604083850312156127f657600080fd5b50508035926020909101359150565b6000806040838503121561281857600080fd5b8235612823816121f5565b915060208301356126a8816121f5565b600080600080600060a0868803121561284b57600080fd5b8535612856816121f5565b94506020860135612866816121f5565b9350604086013592506060860135915060808601356001600160401b0381111561288f57600080fd5b61289b888289016126da565b9150509295509295909350565b600181811c908216806128bc57607f821691505b6020821081036128dc57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526013908201527237b7363ca1b7b63632b1ba34b7b727bbb732b960691b604082015260600190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252600a90820152691bdb9b1e53585c9ad95d60b21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b602080825260189082015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604082015260600190565b80516129d4816121f5565b919050565b6000602082840312156129eb57600080fd5b8151612156816121f5565b80516001600160401b03811681146129d457600080fd5b8051600481106129d457600080fd5b600082601f830112612a2d57600080fd5b81516020612a3d61252b836124e7565b82815260a09283028501820192828201919087851115612a5c57600080fd5b8387015b85811015612ac05781818a031215612a785760008081fd5b612a8061244a565b8151612a8b816121f5565b815281860151868201526040808301519082015260608083015190820152608080830151908201528452928401928101612a60565b5090979650505050505050565b600060208284031215612adf57600080fd5b81516001600160401b0380821115612af657600080fd5b908301908185036101a0811215612b0c57600080fd5b612b14612472565b61018080831215612b2457600080fd5b612b2c612494565b9250612b37856129f6565b8352612b45602086016129f6565b6020840152612b56604086016129f6565b6040840152612b67606086016129f6565b60608401526080850151608084015260a085015160a084015260c085015160c0840152612b9660e086016129c9565b60e0840152610100612ba98187016129c9565b90840152610120612bbb8682016129c9565b90840152610140612bcd8682016129c9565b90840152610160612bdf868201612a0d565b90840152918152908301519082821115612bf857600080fd5b612c0487838601612a1c565b60208201529695505050505050565b6000612c2161252b846126b3565b9050828152838383011115612c3557600080fd5b61215683602083018461215d565b600060208284031215612c5557600080fd5b81516001600160401b03811115612c6b57600080fd5b8201601f81018413612c7c57600080fd5b61150d84825160208401612c13565b87815260208101879052604081018690526001600160401b038581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090612cda90830184612189565b9998505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251612d1f81601d85016020870161215d565b91909101601d0192915050565b634e487b7160e01b600052601160045260246000fd5b600082821015612d5457612d54612d2c565b500390565b60008219821115612d6c57612d6c612d2c565b500190565b600060208284031215612d8357600080fd5b5051919050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600082612df957634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612e1857612e18612d2c565b500290565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e5090830184612189565b9695505050505050565b600060208284031215612e6c57600080fd5b81516121568161212356fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220d3654f558b5bb47cb65b682816d4b772ec2f58709bf179af57ef9c4321f34d9e64736f6c634300080d0033608060405260006007553480156200001657600080fd5b5060405162001b7a38038062001b7a833981016040819052620000399162000243565b6040805160208101909152600081526200005381620000b7565b50825162000069906003906020860190620000d0565b5081516200007f906004906020850190620000d0565b5060058054336001600160a01b031991821617909155600680549091166001600160a01b0392909216919091179055506200030c9050565b8051620000cc906002906020840190620000d0565b5050565b828054620000de90620002d0565b90600052602060002090601f0160209004810192826200010257600085556200014d565b82601f106200011d57805160ff19168380011785556200014d565b828001600101855582156200014d579182015b828111156200014d57825182559160200191906001019062000130565b506200015b9291506200015f565b5090565b5b808211156200015b576000815560010162000160565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200019e57600080fd5b81516001600160401b0380821115620001bb57620001bb62000176565b604051601f8301601f19908116603f01168101908282118183101715620001e657620001e662000176565b816040528381526020925086838588010111156200020357600080fd5b600091505b8382101562000227578582018301518183018401529082019062000208565b83821115620002395760008385830101525b9695505050505050565b6000806000606084860312156200025957600080fd5b83516001600160401b03808211156200027157600080fd5b6200027f878388016200018c565b945060208601519150808211156200029657600080fd5b50620002a5868287016200018c565b604086015190935090506001600160a01b0381168114620002c557600080fd5b809150509250925092565b600181811c90821680620002e557607f821691505b6020821081036200030657634e487b7160e01b600052602260045260246000fd5b50919050565b61185e806200031c6000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8062fdd58e146100a857806301ffc9a7146100ce57806302fe5305146100f157806306fdde03146101065780630e89341c1461011b5780632eb2c2d61461012e5780634e1273f41461014157806364bdea921461016157806395d89b4114610174578063a22cb4651461017c578063e985e9c51461018a578063f242432a1461019d575b600080fd5b6100bb6100b6366004610dec565b6101ab565b6040519081526020015b60405180910390f35b6100e16100dc366004610e18565b610385565b60405190151581526020016100c5565b6101046100ff366004610f1c565b6103d7565b005b61010e6104ba565b6040516100c59190610fcb565b61010e610129366004610ffe565b610548565b61010461013c3660046110a3565b6106e5565b61015461014f3660046111ea565b6106fd565b6040516100c591906112ab565b61010461016f3660046112ef565b610826565b61010e610a15565b61010461013c366004611340565b6100e161019836600461137e565b610a26565b61010461013c3660046113ac565b60004281805b60008581526008602090815260408083206001600160a01b038a16845290915290205481101561037c5760065460008681526008602090815260408083206001600160a01b038b811685529252822080549293919091169163ed756fef91908590811061022057610220611427565b90600052602060002001546040518263ffffffff1660e01b815260040161024991815260200190565b600060405180830381865afa158015610266573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261028e919081019061151f565b60200151905060005b815181101561036757876001600160a01b03168282815181106102bc576102bc611427565b6020026020010151600001516001600160a01b03161480156102fb5750848282815181106102ec576102ec611427565b60200260200101516040015111155b8015610324575081818151811061031457610314611427565b6020026020010151606001518511155b156103555781818151811061033b5761033b611427565b60200260200101516080015184610352919061167b565b93505b8061035f81611693565b915050610297565b5050808061037490611693565b9150506101b1565b50949350505050565b60006001600160e01b03198216636cdb3d1360e11b14806103b657506001600160e01b031982166303a24d0760e21b145b806103d157506301ffc9a760e01b6001600160e01b03198316145b92915050565b600560009054906101000a90046001600160a01b03166001600160a01b031663df727d3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044e91906116ac565b6001600160a01b0316336001600160a01b0316146104a95760405162461bcd60e51b815260206004820152601360248201527237b7363ca1b7b63632b1ba34b7b727bbb732b960691b60448201526064015b60405180910390fd5b6104b281610a40565b506001600755565b600380546104c7906116c9565b80601f01602080910402602001604051908101604052809291908181526020018280546104f3906116c9565b80156105405780601f1061051557610100808354040283529160200191610540565b820191906000526020600020905b81548152906001019060200180831161052357829003601f168201915b505050505081565b606061055382610a53565b6105b85760405162461bcd60e51b815260206004820152603060248201527f455243313135354d657461646174613a2055524920717565727920666f72206e60448201526f37b732bc34b9ba32b73a103a37b5b2b760811b60648201526084016104a0565b6007546000036106a757600554604080516330ee93bf60e11b815290516000926001600160a01b0316916361dd277e9160048083019260209291908290030181865afa15801561060c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063091906116ac565b6040516303a24d0760e21b8152600481018590529091506001600160a01b03821690630e89341c90602401600060405180830381865afa158015610678573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106a09190810190611703565b9392505050565b6106b082610b9f565b6106b983610c33565b6040516020016106ca929190611779565b6040516020818303038152906040529050919050565b919050565b60405162461bcd60e51b81526004016104a0906117a8565b606081518351146107625760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016104a0565b600083516001600160401b0381111561077d5761077d610e42565b6040519080825280602002602001820160405280156107a6578160200160208202803683370190505b50905060005b845181101561081e576107f18582815181106107ca576107ca611427565b60200260200101518583815181106107e4576107e4611427565b60200260200101516101ab565b82828151811061080357610803611427565b602090810291909101015261081781611693565b90506107ac565b509392505050565b6005546001600160a01b0316331461086c5760405162461bcd60e51b81526020600482015260096024820152681bdb9b1e55985d5b1d60ba1b60448201526064016104a0565b6000805b6000858152600960205260409020548110156108d05760008581526009602052604090208054849190839081106108a9576108a9611427565b9060005260206000200154036108be57600191505b806108c881611693565b915050610870565b50806108f8576000848152600960209081526040822080546001810182559083529120018290555b506000805b60008581526008602090815260408083206001600160a01b038a1684529091529020548110156109855760008581526008602090815260408083206001600160a01b038a168452909152902080548491908390811061095e5761095e611427565b90600052602060002001540361097357600191505b8061097d81611693565b9150506108fd565b50806109be5760008481526008602090815260408083206001600160a01b03891684528252822080546001810182559083529120018290555b60055460408051868152602081018690526001600160a01b03888116938a8216939116917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050505050565b600480546104c7906116c9565b5050565b600060405162461bcd60e51b81526004016104a0906117a8565b8051610a22906002906020840190610d3b565b6000818152600960205260408120548103610a7057506000919050565b60005b600083815260096020526040902054811015610b96576006546000848152600960205260408120805491926001600160a01b03169163ed756fef919085908110610abf57610abf611427565b90600052602060002001546040518263ffffffff1660e01b8152600401610ae891815260200190565b600060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b2d919081019061151f565b60200151905060005b8151811015610b815742828281518110610b5257610b52611427565b6020026020010151606001511115610b6f57506001949350505050565b80610b7981611693565b915050610b36565b50508080610b8e90611693565b915050610a73565b50600092915050565b606060028054610bae906116c9565b80601f0160208091040260200160405190810160405280929190818152602001828054610bda906116c9565b8015610c275780601f10610bfc57610100808354040283529160200191610c27565b820191906000526020600020905b815481529060010190602001808311610c0a57829003601f168201915b50505050509050919050565b606081600003610c5a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610c845780610c6e81611693565b9150610c7d9050600a836117e9565b9150610c5e565b6000816001600160401b03811115610c9e57610c9e610e42565b6040519080825280601f01601f191660200182016040528015610cc8576020820181803683370190505b5090505b8415610d3357610cdd6001836117fd565b9150610cea600a86611814565b610cf590603061167b565b60f81b818381518110610d0a57610d0a611427565b60200101906001600160f81b031916908160001a905350610d2c600a866117e9565b9450610ccc565b949350505050565b828054610d47906116c9565b90600052602060002090601f016020900481019282610d695760008555610daf565b82601f10610d8257805160ff1916838001178555610daf565b82800160010185558215610daf579182015b82811115610daf578251825591602001919060010190610d94565b50610dbb929150610dbf565b5090565b5b80821115610dbb5760008155600101610dc0565b6001600160a01b0381168114610de957600080fd5b50565b60008060408385031215610dff57600080fd5b8235610e0a81610dd4565b946020939093013593505050565b600060208284031215610e2a57600080fd5b81356001600160e01b0319811681146106a057600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715610e7a57610e7a610e42565b60405290565b604080519081016001600160401b0381118282101715610e7a57610e7a610e42565b60405161018081016001600160401b0381118282101715610e7a57610e7a610e42565b604051601f8201601f191681016001600160401b0381118282101715610eed57610eed610e42565b604052919050565b60006001600160401b03821115610f0e57610f0e610e42565b50601f01601f191660200190565b600060208284031215610f2e57600080fd5b81356001600160401b03811115610f4457600080fd5b8201601f81018413610f5557600080fd5b8035610f68610f6382610ef5565b610ec5565b818152856020838501011115610f7d57600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b83811015610fb6578181015183820152602001610f9e565b83811115610fc5576000848401525b50505050565b6020815260008251806020840152610fea816040850160208701610f9b565b601f01601f19169190910160400192915050565b60006020828403121561101057600080fd5b5035919050565b60008083601f84011261102957600080fd5b5081356001600160401b0381111561104057600080fd5b6020830191508360208260051b850101111561105b57600080fd5b9250929050565b60008083601f84011261107457600080fd5b5081356001600160401b0381111561108b57600080fd5b60208301915083602082850101111561105b57600080fd5b60008060008060008060008060a0898b0312156110bf57600080fd5b88356110ca81610dd4565b975060208901356110da81610dd4565b965060408901356001600160401b03808211156110f657600080fd5b6111028c838d01611017565b909850965060608b013591508082111561111b57600080fd5b6111278c838d01611017565b909650945060808b013591508082111561114057600080fd5b5061114d8b828c01611062565b999c989b5096995094979396929594505050565b60006001600160401b0382111561117a5761117a610e42565b5060051b60200190565b600082601f83011261119557600080fd5b813560206111a5610f6383611161565b82815260059290921b840181019181810190868411156111c457600080fd5b8286015b848110156111df57803583529183019183016111c8565b509695505050505050565b600080604083850312156111fd57600080fd5b82356001600160401b038082111561121457600080fd5b818501915085601f83011261122857600080fd5b81356020611238610f6383611161565b82815260059290921b8401810191818101908984111561125757600080fd5b948201945b8386101561127e57853561126f81610dd4565b8252948201949082019061125c565b9650508601359250508082111561129457600080fd5b506112a185828601611184565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156112e3578351835292840192918401916001016112c7565b50909695505050505050565b600080600080600060a0868803121561130757600080fd5b853561131281610dd4565b9450602086013561132281610dd4565b94979496505050506040830135926060810135926080909101359150565b6000806040838503121561135357600080fd5b823561135e81610dd4565b91506020830135801515811461137357600080fd5b809150509250929050565b6000806040838503121561139157600080fd5b823561139c81610dd4565b9150602083013561137381610dd4565b60008060008060008060a087890312156113c557600080fd5b86356113d081610dd4565b955060208701356113e081610dd4565b9450604087013593506060870135925060808701356001600160401b0381111561140957600080fd5b61141589828a01611062565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b80516001600160401b03811681146106e057600080fd5b80516106e081610dd4565b8051600481106106e057600080fd5b600082601f83011261147f57600080fd5b8151602061148f610f6383611161565b82815260a092830285018201928282019190878511156114ae57600080fd5b8387015b858110156115125781818a0312156114ca5760008081fd5b6114d2610e58565b81516114dd81610dd4565b8152818601518682015260408083015190820152606080830151908201526080808301519082015284529284019281016114b2565b5090979650505050505050565b60006020828403121561153157600080fd5b81516001600160401b038082111561154857600080fd5b908301908185036101a081121561155e57600080fd5b611566610e80565b6101808083121561157657600080fd5b61157e610ea2565b92506115898561143d565b83526115976020860161143d565b60208401526115a86040860161143d565b60408401526115b96060860161143d565b60608401526080850151608084015260a085015160a084015260c085015160c08401526115e860e08601611454565b60e08401526101006115fb818701611454565b9084015261012061160d868201611454565b9084015261014061161f868201611454565b9084015261016061163186820161145f565b9084015291815290830151908282111561164a57600080fd5b6116568783860161146e565b60208201529695505050505050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561168e5761168e611665565b500190565b6000600182016116a5576116a5611665565b5060010190565b6000602082840312156116be57600080fd5b81516106a081610dd4565b600181811c908216806116dd57607f821691505b6020821081036116fd57634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561171557600080fd5b81516001600160401b0381111561172b57600080fd5b8201601f8101841361173c57600080fd5b805161174a610f6382610ef5565b81815285602083850101111561175f57600080fd5b611770826020830160208601610f9b565b95945050505050565b6000835161178b818460208801610f9b565b83519083019061179f818360208801610f9b565b01949350505050565b6020808252601190820152702234b9b0b13632b210333ab731ba34b7b760791b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b6000826117f8576117f86117d3565b500490565b60008282101561180f5761180f611665565b500390565b600082611823576118236117d3565b50069056fea2646970667358221220a3cb987179031f0100a20a33d49ba4e8c981e7272fe814d33bd59b58acfb1cd364736f6c634300080d0033a26469706673582212203918b8a3a016014db044f5e459b82d40aeb0eb424560b45de86c279bdb30004864736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000651647ee8bc055e950241cf112fea964a0000827
-----Decoded View---------------
Arg [0] : market (address): 0x651647Ee8bc055E950241cf112Fea964A0000827
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000651647ee8bc055e950241cf112fea964a0000827
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.