More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 285 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Bulk Unstake | 16410105 | 592 days ago | IN | 0 ETH | 0.00224612 | ||||
Bulk Unstake | 16351531 | 600 days ago | IN | 0 ETH | 0.0012438 | ||||
Set Pause State | 16351529 | 600 days ago | IN | 0 ETH | 0.00043373 | ||||
Bulk Stake | 16351494 | 600 days ago | IN | 0 ETH | 0.0031531 | ||||
Stake Crystal | 16087958 | 637 days ago | IN | 0 ETH | 0.0013761 | ||||
Bulk Stake | 16087925 | 637 days ago | IN | 0 ETH | 0.00634653 | ||||
Bulk Stake | 15598982 | 706 days ago | IN | 0 ETH | 0.0025422 | ||||
Bulk Stake | 15501606 | 720 days ago | IN | 0 ETH | 0.00509987 | ||||
Bulk Stake | 15500588 | 720 days ago | IN | 0 ETH | 0.00179026 | ||||
Bulk Stake | 15500522 | 720 days ago | IN | 0 ETH | 0.00192116 | ||||
Bulk Stake | 15500439 | 720 days ago | IN | 0 ETH | 0.00823283 | ||||
Bulk Stake | 15500330 | 720 days ago | IN | 0 ETH | 0.00267727 | ||||
Bulk Stake | 15500325 | 720 days ago | IN | 0 ETH | 0.00260996 | ||||
Bulk Stake | 15500251 | 720 days ago | IN | 0 ETH | 0.00308138 | ||||
Bulk Stake | 15500005 | 720 days ago | IN | 0 ETH | 0.00384589 | ||||
Bulk Stake | 15499858 | 720 days ago | IN | 0 ETH | 0.00348942 | ||||
Bulk Stake | 15499838 | 720 days ago | IN | 0 ETH | 0.00221429 | ||||
Stake Crystal | 15499749 | 720 days ago | IN | 0 ETH | 0.00143194 | ||||
Bulk Stake | 15499508 | 720 days ago | IN | 0 ETH | 0.00489432 | ||||
Bulk Stake | 15499506 | 720 days ago | IN | 0 ETH | 0.00610045 | ||||
Bulk Stake | 15499463 | 720 days ago | IN | 0 ETH | 0.01399216 | ||||
Bulk Stake | 15499445 | 720 days ago | IN | 0 ETH | 0.00335018 | ||||
Bulk Stake | 15499256 | 721 days ago | IN | 0 ETH | 0.00445798 | ||||
Bulk Stake | 15499093 | 721 days ago | IN | 0 ETH | 0.07967918 | ||||
Bulk Stake | 15499023 | 721 days ago | IN | 0 ETH | 0.01493466 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CCVault
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "@openzeppelin/contracts/utils/Context.sol"; import "../EthereumContracts/contracts/interfaces/IERC721.sol"; import "../EthereumContracts/contracts/interfaces/IERC721Receiver.sol"; import "../EthereumContracts/contracts/interfaces/IERC1155.sol"; import "../EthereumContracts/contracts/interfaces/IERC1155Receiver.sol"; import "../EthereumContracts/contracts/utils/IOwnable.sol"; import "../EthereumContracts/contracts/utils/IPausable.sol"; contract CCCOIN { event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); function totalSupply() external view returns ( uint256 ) {} function balanceOf( address account ) external view returns ( uint256 ) {} function transfer( address recipient, uint256 amount ) external returns ( bool ) {} function allowance( address owner, address spender ) external view returns ( uint256 ) {} function approve( address spender, uint256 amount ) external returns ( bool ) {} function transferFrom( address sender, address recipient, uint256 amount ) external returns ( bool ) {} //proxy access functions: function isProxy( address checkProxy ) external view returns ( bool ) {} function proxyMint( address reciever, uint256 amount ) public {} function proxyBurn( address sender, uint256 amount ) public {} function proxyTransfer( address from, address to, uint256 amount ) public {} } // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@/ \@@@@/ \@@@@ @@@@@@@@@@ @@@@@@@@@@ \@@/ \@@ @@/ \@@@@@ \@@@@/ \@@ // @@@@@ /@@@@ @@@ /@@@@ @@@ @@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@ /@@@@ @@@@@ @@@@@@ /@@@@ @@@@ @@@@@ @@@ /@@@@ @@ // @@@@ @@@@@@@@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@@ @@@@@@ @@@@@@ @@@ @@@@/ @@@ @@@@@@@@@@ // @@@ @@@@@@@@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@@@@@ @@@@@@ @@@@@@ @@@ /@@@@\ \@@@@ // @@ @@@@@@@@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@@ @@@@@@ @@@@@@ @@@ @@@ @@@@@@@@@@@@@ @@@@ // @@ @@@@ @@@ @@@@ @@ @@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@ @@@@ @@@@@@@ @@@@ @@@ @@@@@ @@@@ @@@@/ @@@@@ // @@\ /@@@@\ /@@ @@ @@\ @@@@\ /@@@@ @@@@@@@@\ /@@@ @@@@@@ @@@@\ /@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@ @@@@@@@@ @@@@@@ @@ @@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ @@ @ @@@@@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@ @@ @@@@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ @@ @@@ @@@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@ @@@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@ @@@@@ @@@ @@@@@@ @@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@ @@ @@ @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ contract CCVault is Context, IOwnable, IERC721Receiver, IERC1155Receiver, IPausable { error CCVault_ARRAY_LENGTH_MISMATCH(); error CCVault_INVALID_CONTRACT( address contractAddress ); error CCVault_INSUFFICIENT_CRYSTAL_BALANCE( uint256 seriesId, uint256 amountRequested ); error CCVault_INSUFFICIENT_BALANCE( address contractAddress ); error CCVault_INSUFFICIENT_REWARDS( uint256 amountRequested, uint256 amountAvailable ); error CCVault_NONEXISTANT_CRYSTAL( uint256 seriesId ); error CCVault_NO_PROXY_ACCESS( address contractAddress ); error CCVault_NO_REWARDS_EARNED( address tokenOwner ); error CCVault_TOKEN_ALREADY_STAKED( uint256 tokenId ); error CCVault_TOKEN_NOT_OWNED( address contractAddress, uint256 tokenId ); error CCVault_TOKEN_NOT_STAKED( address contractAddress, uint256 tokenId ); error CCVault_EMPTY( address tokenOwner ); struct StakingInfo { uint256 lastUpdate; uint256 key; uint256 tier1; uint256 tier2; uint256 tier3; uint256 degen; uint256 partner; uint256 rewardsEarned; } struct stakedNFT { address contractAddress; uint256 tokenId; } uint constant DAY = 86400; // Staking rewards in tokens per second uint256 public KEY_REWARD; uint256 public DEGEN_REWARD; uint256 public PARTNER_REWARD; CCCOIN public COIN_CONTRACT; IERC1155 public CRYSTAL_CONTRACT; // Multipliers, expressed in percentage, with base 1000: // one crystal can only be applied to one key at a time, // and one key can only be applied one crystal at a time mapping( uint256 => uint256 ) public CRYSTAL_MULTIPLIER; // Wallet address mapped to staking info mapping ( address => StakingInfo ) public stakingInfo; // Wallet address mapped to a dynamic array of staked tokens mapping ( address => stakedNFT[] ) public stakeNFTWallets; // Mappings to verify stakable contracts. mapping ( address => bool ) public keyContracts; mapping ( address => bool ) public degenContracts; mapping ( address => bool ) public partnerContracts; constructor() { _initIOwnable( _msgSender() ); KEY_REWARD = 250 * ( 10 ** 15 ); DEGEN_REWARD = 10 * ( 10 ** 15 ); PARTNER_REWARD = 100 * ( 10 ** 15 ); CRYSTAL_MULTIPLIER[ 1 ] = 4000; CRYSTAL_MULTIPLIER[ 2 ] = 2500; CRYSTAL_MULTIPLIER[ 3 ] = 2000; } // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Internal function executing the staking of an NFT. * * @param tokenOwner_ ~ type = address : the owner of the NFT * @param contractAddress_ ~ type = address : the contract that manages the NFT * @param tokenId_ ~ type = uint256 : the NFT's token ID */ function _stakeNFT( address tokenOwner_, address contractAddress_, uint256 tokenId_ ) private { IERC721 NFTcontract = IERC721( contractAddress_ ); if ( ! NFTcontract.isApprovedForAll( tokenOwner_, address( this ) ) ) { revert CCVault_NO_PROXY_ACCESS( contractAddress_ ); } if ( NFTcontract.ownerOf( tokenId_ ) != tokenOwner_ ) { revert CCVault_TOKEN_NOT_OWNED( contractAddress_, tokenId_ ); } stakeNFTWallets[ tokenOwner_ ].push( stakedNFT( contractAddress_, tokenId_ ) ); NFTcontract.transferFrom( tokenOwner_, address( this ), tokenId_ ); } /** * @dev Internal function to unstake a specific NFT. * * @param tokenOwner_ ~ type = address : the owner of the NFT * @param contractAddress_ ~ type = address : the contract that manages the NFT * @param tokenId_ ~ type = uint256 : the NFT's token ID */ function _unstakeNFT( address tokenOwner_, address contractAddress_, uint256 tokenId_ ) private { uint256 _index_ = stakeNFTWallets[ tokenOwner_ ].length; while ( _index_ > 0 ) { unchecked { _index_ --; } if ( stakeNFTWallets[ tokenOwner_ ][ _index_ ].contractAddress == contractAddress_ && stakeNFTWallets[ tokenOwner_ ][ _index_ ].tokenId == tokenId_ ) { _unstakeNFTatIndex( tokenOwner_, _index_ ); return; } } revert CCVault_TOKEN_NOT_STAKED( contractAddress_, tokenId_ ); } /** * @dev Internal function executing the unstaking of an NFT. * * @param tokenOwner_ ~ type = address : the owner of the NFT * @param index_ ~ type = uint256 : the index of the NFT */ function _unstakeNFTatIndex( address tokenOwner_, uint256 index_ ) private { uint256 _totalStaked_ = stakeNFTWallets[ tokenOwner_ ].length; address _contractAddress_ = stakeNFTWallets[ tokenOwner_ ][ index_ ].contractAddress; uint256 _tokenId_ = stakeNFTWallets[ tokenOwner_ ][ index_ ].tokenId; IERC721 NFTcontract = IERC721( _contractAddress_ ); if ( NFTcontract.ownerOf( _tokenId_ ) != address( this ) ) { revert CCVault_TOKEN_NOT_STAKED( _contractAddress_, _tokenId_ ); } if ( index_ + 1 != _totalStaked_ ) { stakeNFTWallets[ tokenOwner_ ][ index_ ] = stakeNFTWallets[ tokenOwner_ ][ _totalStaked_ - 1 ]; } stakeNFTWallets[ tokenOwner_ ].pop(); NFTcontract.transferFrom( address( this ), tokenOwner_, _tokenId_ ); } /** * @dev Internal function executing the staking of a crystal. * * @param tokenOwner_ ~ type = address : the owner of the NFT * @param tier_ ~ type = uint256 : the crystal series * @param amount_ ~ type = uint256 : the amount of crystals to be staked */ function _stakeCrystal( address tokenOwner_, uint256 tier_, uint256 amount_ ) private { if ( ! CRYSTAL_CONTRACT.isApprovedForAll( tokenOwner_, address( this ) ) ) { revert CCVault_NO_PROXY_ACCESS( address( CRYSTAL_CONTRACT ) ); } if ( CRYSTAL_CONTRACT.balanceOf( tokenOwner_, tier_ ) < amount_ ) { revert CCVault_INSUFFICIENT_CRYSTAL_BALANCE( tier_, amount_ ); } CRYSTAL_CONTRACT.safeTransferFrom( tokenOwner_, address( this ), tier_, amount_, "" ); } /** * @dev Internal function executing the staking of a crystal. * * @param tokenOwner_ ~ type = address : the owner of the NFT * @param tier_ ~ type = uint256 : the crystal series * @param amount_ ~ type = uint256 : the amount of crystals to be unstaked */ function _unstakeCrystal( address tokenOwner_, uint256 tier_, uint256 amount_ ) private { if ( CRYSTAL_CONTRACT.balanceOf( address( this ), tier_ ) < amount_ ) { revert CCVault_INSUFFICIENT_CRYSTAL_BALANCE( tier_, amount_ ); } CRYSTAL_CONTRACT.safeTransferFrom( address( this ), tokenOwner_, tier_, amount_, "" ); } /** * @dev Internal function that updates the staking info for the given user. * * @param tokenOwner_ ~ type = address : the owner of the NFTs * @param key_ ~ type = uint256 : the number of keys staked, regardless of their contract * @param tier1_ ~ type = uint256 : the amount of tier1 crystals staked * @param tier2_ ~ type = uint256 : the amount of tier2 crystals staked * @param tier3_ ~ type = uint256 : the amount of tier3 crystals staked * @param degen_ ~ type = uint256 : the number of degen tokens staked, regardless of their contract * @param partner_ ~ type = uint256 : the number of partner tokens staked, regardless of their contract */ function _updateStakingInfo( address tokenOwner_, uint256 key_, uint256 tier1_, uint256 tier2_, uint256 tier3_, uint256 degen_, uint256 partner_ ) private { StakingInfo storage _stakingInfo_ = stakingInfo[ tokenOwner_ ]; if ( _stakingInfo_.key != key_ ) { _stakingInfo_.key = key_; } if ( _stakingInfo_.tier1 != tier1_ ) { _stakingInfo_.tier1 = tier1_; } if ( _stakingInfo_.tier2 != tier2_ ) { _stakingInfo_.tier2 = tier2_; } if ( _stakingInfo_.tier3 != tier3_ ) { _stakingInfo_.tier3 = tier3_; } if ( _stakingInfo_.degen != degen_ ) { _stakingInfo_.degen = degen_; } if ( _stakingInfo_.partner != partner_ ) { _stakingInfo_.partner = partner_; } _updateRewards( tokenOwner_ ); } /** * @dev Internal function that updates the rewards and timestamp for a given account. * * @param tokenOwner_ ~ type = address : the owner of the NFTs */ function _updateRewards( address tokenOwner_ ) private { StakingInfo storage _stakingInfo_ = stakingInfo[ tokenOwner_ ]; _stakingInfo_.rewardsEarned = _totalRewards( tokenOwner_ ); if ( _stakingInfo_.lastUpdate != block.timestamp ) { _stakingInfo_.lastUpdate = block.timestamp; } } /** * @dev Internal function that spends rewards for a given account. * * @param tokenOwner_ ~ type = address : the owner of the NFTs * @param amountSpent_ ~ type = uint256 : the amount of rewards spent */ function _spendRewards( address tokenOwner_, uint256 amountSpent_ ) private { uint256 _totalRewards_ = _totalRewards( tokenOwner_ ); if ( _totalRewards_ < amountSpent_ ) { revert CCVault_INSUFFICIENT_REWARDS( amountSpent_, _totalRewards_ ); } StakingInfo storage _stakingInfo_ = stakingInfo[ tokenOwner_ ]; unchecked { _stakingInfo_.rewardsEarned = _totalRewards_ - amountSpent_; } if ( _stakingInfo_.lastUpdate != block.timestamp ) { _stakingInfo_.lastUpdate = block.timestamp; } } /** * @dev Internal function that calculates and returns the amount of rewards earned by `tokenOwner_` so far. * * @param tokenOwner_ ~ type = address : the owner of the NFTs */ function _totalRewards( address tokenOwner_ ) private view returns ( uint256 ) { uint256 _totalRewards_; StakingInfo memory _stakingInfo_ = stakingInfo[ tokenOwner_ ]; if ( _stakingInfo_.lastUpdate != 0 ) { uint256 _timeDiff_; uint256 _unclaimedRewards_; _totalRewards_ = _stakingInfo_.rewardsEarned; if ( block.timestamp > _stakingInfo_.lastUpdate ) { unchecked { _timeDiff_ = block.timestamp - _stakingInfo_.lastUpdate; _unclaimedRewards_ = rewardsPerSecond( tokenOwner_ ) * _timeDiff_; _totalRewards_ += _unclaimedRewards_; } } } return _totalRewards_; } // ************************************** // ************************************** // ***** PUBLIC ***** // ************************************** /** * @dev Stake several token types for the caller * * @param contractAddresses_ ~ type = address[] : an array of contract addresses * @param tokenIds_ ~ type = uint256[] : an array of token IDs */ function bulkStake( address[] memory contractAddresses_, uint256[] memory tokenIds_ ) public { uint256 _index_ = contractAddresses_.length; if ( _index_ != tokenIds_.length ) { revert CCVault_ARRAY_LENGTH_MISMATCH(); } address _tokenOwner_ = _msgSender(); uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; while ( _index_ > 0 ) { unchecked { _index_ --; } if ( keyContracts[ contractAddresses_[ _index_ ] ] ) { unchecked { _key_ ++; } } else if ( degenContracts[ contractAddresses_[ _index_ ] ] ) { unchecked { _degen_ ++; } } else if ( partnerContracts[ contractAddresses_[ _index_ ] ] ) { unchecked { _partner_ ++; } } else { // Skip if contract is invalid continue; } _stakeNFT( _tokenOwner_, contractAddresses_[ _index_ ], tokenIds_[ _index_ ] ); } _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Stake an ERC721 token for the caller. * * @param contractAddress_ ~ type = address : the contract that manages the NFT * @param tokenId_ ~ type = uint256 : the NFT's token ID */ function stakeNFT( address contractAddress_, uint256 tokenId_ ) public { address _tokenOwner_ = _msgSender(); uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; if ( keyContracts[ contractAddress_ ] ) { unchecked { _key_ ++; } } else if ( degenContracts[ contractAddress_ ] ) { unchecked { _degen_ ++; } } else if ( partnerContracts[ contractAddress_ ] ) { unchecked { _partner_ ++; } } else { revert CCVault_INVALID_CONTRACT( contractAddress_ ); } _stakeNFT( _tokenOwner_, contractAddress_, tokenId_ ); _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Stake `amount_` crystals of series `tier_` for the caller. * * @param tier_ ~ type = uint256 : the crystal series * @param amount_ ~ type = uint256 : the amount of crystals to be staked */ function stakeCrystal( uint256 tier_, uint256 amount_ ) public { address _tokenOwner_ = _msgSender(); uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; if ( tier_ == 1 ) { unchecked { _tier1_ += amount_; } } else if ( tier_ == 2 ) { unchecked { _tier2_ += amount_; } } else if ( tier_ == 3 ) { unchecked { _tier3_ += amount_; } } else { revert CCVault_NONEXISTANT_CRYSTAL( tier_ ); } _stakeCrystal( _tokenOwner_, tier_, amount_ ); _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Unstake several token types for the caller * * @param contractAddresses_ ~ type = address[] : an array of contract addresses * @param tokenIds_ ~ type = uint256[] : an array of token IDs * * Requirements: * - Contract state is OPEN */ function bulkUnstake( address[] memory contractAddresses_, uint256[] memory tokenIds_ ) public isOpen { uint256 _index_ = contractAddresses_.length; if ( _index_ != tokenIds_.length ) { revert CCVault_ARRAY_LENGTH_MISMATCH(); } address _tokenOwner_ = _msgSender(); uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; while ( _index_ > 0 ) { unchecked { _index_ --; } if ( keyContracts[ contractAddresses_[ _index_ ] ] ) { if ( _key_ == 0 ) { revert CCVault_INSUFFICIENT_BALANCE( contractAddresses_[ _index_ ] ); } unchecked { _key_ --; } } else if ( degenContracts[ contractAddresses_[ _index_ ] ] ) { if ( _degen_ == 0 ) { revert CCVault_INSUFFICIENT_BALANCE( contractAddresses_[ _index_ ] ); } unchecked { _degen_ --; } } else if ( partnerContracts[ contractAddresses_[ _index_ ] ] ) { if ( _partner_ == 0 ) { revert CCVault_INSUFFICIENT_BALANCE( contractAddresses_[ _index_ ] ); } unchecked { _partner_ --; } } else { // Skip if contract is invalid continue; } _unstakeNFT( _tokenOwner_, contractAddresses_[ _index_ ], tokenIds_[ _index_ ] ); } _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Unstake all tokens staked by the caller * * Requirements: * - Contract state is OPEN */ function unstakeAll() public isOpen { address _tokenOwner_ = _msgSender(); StakingInfo storage _stakingInfo_ = stakingInfo[ _tokenOwner_ ]; if ( _stakingInfo_.lastUpdate == 0 ) { revert CCVault_EMPTY( _tokenOwner_ ); } uint256 _totalStaked_ = stakeNFTWallets[ _tokenOwner_ ].length; while ( _totalStaked_ > 0 ) { unchecked { _totalStaked_ --; } _unstakeNFTatIndex( _tokenOwner_, _totalStaked_ ); } if ( _stakingInfo_.tier1 > 0 ) { _unstakeCrystal( _tokenOwner_, 1, _stakingInfo_.tier1 ); } if ( _stakingInfo_.tier2 > 0 ) { _unstakeCrystal( _tokenOwner_, 2, _stakingInfo_.tier2 ); } if ( _stakingInfo_.tier3 > 0 ) { _unstakeCrystal( _tokenOwner_, 3, _stakingInfo_.tier3 ); } _updateStakingInfo( _tokenOwner_, 0, 0, 0, 0, 0, 0 ); } /** * @dev Unstake all tokens managed by `contractAddress_` staked by the caller * * @param contractAddress_ ~ type = address : the contract that manages the tokens * * Requirements: * - Contract state is OPEN */ function unstakeCollection( address contractAddress_ ) public isOpen { address _tokenOwner_ = _msgSender(); if ( stakingInfo[ _tokenOwner_ ].lastUpdate == 0 ) { revert CCVault_EMPTY( _tokenOwner_ ); } uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; if ( contractAddress_ == address( CRYSTAL_CONTRACT ) ) { if ( _tier1_ > 0 ) { _unstakeCrystal( _tokenOwner_, 1, _tier1_ ); } if ( _tier2_ > 0 ) { _unstakeCrystal( _tokenOwner_, 2, _tier2_ ); } if ( _tier3_ > 0 ) { _unstakeCrystal( _tokenOwner_, 3, _tier3_ ); } _tier1_ = 0; _tier2_ = 0; _tier3_ = 0; } else { if ( keyContracts[ contractAddress_ ] ) { _key_ = 0; } else if ( degenContracts[ contractAddress_ ] ) { _degen_ = 0; } else if ( partnerContracts[ contractAddress_ ] ) { _partner_ = 0; } else { revert CCVault_INVALID_CONTRACT( contractAddress_ ); } uint256 _totalStaked_ = stakeNFTWallets[ _tokenOwner_ ].length; while ( _totalStaked_ > 0 ) { unchecked { _totalStaked_ --; } if ( stakeNFTWallets[ _tokenOwner_ ][ _totalStaked_ ].contractAddress == contractAddress_ ) { _unstakeNFTatIndex( _tokenOwner_, _totalStaked_ ); } } } _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Unstake an ERC721 token for the caller. * * @param contractAddress_ ~ type = address : the contract that manages the NFT * @param tokenId_ ~ type = uint256 : the NFT's token ID * * Requirements: * - Contract state is OPEN */ function unstakeNFT( address contractAddress_, uint256 tokenId_ ) public isOpen { address _tokenOwner_ = _msgSender(); uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; if ( keyContracts[ contractAddress_ ] ) { if ( _key_ == 0 ) { revert CCVault_INSUFFICIENT_BALANCE( contractAddress_ ); } unchecked { _key_ --; } } else if ( degenContracts[ contractAddress_ ] ) { if ( _degen_ == 0 ) { revert CCVault_INSUFFICIENT_BALANCE( contractAddress_ ); } unchecked { _degen_ --; } } else if ( partnerContracts[ contractAddress_ ] ) { if ( _partner_ == 0 ) { revert CCVault_INSUFFICIENT_BALANCE( contractAddress_ ); } unchecked { _partner_ --; } } else { revert CCVault_INVALID_CONTRACT( contractAddress_ ); } _unstakeNFT( _tokenOwner_, contractAddress_, tokenId_ ); _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Unstake `amount_` crystals of series `tier_` for the caller. * * @param tier_ ~ type = uint256 : the crystal series * @param amount_ ~ type = uint256 : the amount of crystals to be staked */ function unstakeCrystal( uint256 tier_, uint256 amount_ ) public { address _tokenOwner_ = _msgSender(); uint256 _key_ = stakingInfo[ _tokenOwner_ ].key; uint256 _tier1_ = stakingInfo[ _tokenOwner_ ].tier1; uint256 _tier2_ = stakingInfo[ _tokenOwner_ ].tier2; uint256 _tier3_ = stakingInfo[ _tokenOwner_ ].tier3; uint256 _degen_ = stakingInfo[ _tokenOwner_ ].degen; uint256 _partner_ = stakingInfo[ _tokenOwner_ ].partner; if ( tier_ == 1 ) { if ( _tier1_ < amount_ ) { revert CCVault_INSUFFICIENT_CRYSTAL_BALANCE( tier_, amount_ ); } unchecked { _tier1_ -= amount_; } } else if ( tier_ == 2 ) { if ( _tier2_ < amount_ ) { revert CCVault_INSUFFICIENT_CRYSTAL_BALANCE( tier_, amount_ ); } unchecked { _tier2_ -= amount_; } } else if ( tier_ == 3 ) { if ( _tier3_ < amount_ ) { revert CCVault_INSUFFICIENT_CRYSTAL_BALANCE( tier_, amount_ ); } unchecked { _tier3_ -= amount_; } } else { revert CCVault_NONEXISTANT_CRYSTAL( tier_ ); } _unstakeCrystal( _tokenOwner_, tier_, amount_ ); _updateStakingInfo( _tokenOwner_, _key_, _tier1_, _tier2_, _tier3_, _degen_, _partner_ ); } /** * @dev Spend `amountSpent_` amount of rewards for the caller. * * @param amountSpent_ ~ type = uint256 : the amount of rewards spent */ function spendRewards( uint256 amountSpent_ ) public { address _tokenOwner_ = _msgSender(); if ( stakingInfo[ _tokenOwner_ ].lastUpdate == 0 ) { revert CCVault_EMPTY( _tokenOwner_ ); } _spendRewards( _tokenOwner_, amountSpent_ ); } /** * @dev Claim all rewards earned by the caller. */ function claimRewards() public { if ( ! COIN_CONTRACT.isProxy( address( this ) ) ) { revert CCVault_NO_PROXY_ACCESS( address( COIN_CONTRACT ) ); } address _tokenOwner_ = _msgSender(); StakingInfo storage _stakingInfo_ = stakingInfo[ _tokenOwner_ ]; if ( _stakingInfo_.lastUpdate == 0 ) { revert CCVault_EMPTY( _tokenOwner_ ); } _updateRewards( _tokenOwner_ ); uint256 _rewardsEarned_ = _stakingInfo_.rewardsEarned; if ( _rewardsEarned_ == 0 ) { revert CCVault_NO_REWARDS_EARNED( _tokenOwner_ ); } _stakingInfo_.rewardsEarned = 0; COIN_CONTRACT.proxyMint( _tokenOwner_, _rewardsEarned_ ); } // ************************************** // ************************************** // ***** CONTRACT_OWNER ***** // ************************************** /** * @dev Airdrops `amount_` coins to `recipient_`. * * @param recipient_ ~ type = address : the address that will receive the coins * @param amount_ ~ type = uint256 : the amount of coin the address will receive */ function airdropCoin( address recipient_, uint256 amount_ ) public onlyOwner { if ( ! COIN_CONTRACT.isProxy( address( this ) ) ) { revert CCVault_NO_PROXY_ACCESS( address( COIN_CONTRACT ) ); } COIN_CONTRACT.proxyMint( recipient_, amount_ ); } /** * @dev Register `contractAddress` as a key collection manager. * * @param contractAddress_ ~ type = address : the contract to register */ function addKeyContract( address contractAddress_ ) public onlyOwner { keyContracts[ contractAddress_ ] = true; } /** * @dev Register `contractAddress` as a degen collection manager. * * @param contractAddress_ ~ type = address : the contract to register */ function addDegenContract( address contractAddress_ ) public onlyOwner { degenContracts[ contractAddress_ ] = true; } /** * @dev Register `contractAddress` as a partner collection manager. * * @param contractAddress_ ~ type = address : the contract to register */ function addPartnerContract( address contractAddress_ ) public onlyOwner { partnerContracts[ contractAddress_ ] = true; } /** * @dev Remove `contractAddress` from the key collection managers. * * @param contractAddress_ ~ type = address : the contract to register */ function removeKeyContract( address contractAddress_ ) public onlyOwner { keyContracts[ contractAddress_ ] = false; } /** * @dev Remove `contractAddress` from the degen collection managers. * * @param contractAddress_ ~ type = address : the contract to register */ function removeDegenContract( address contractAddress_ ) public onlyOwner { degenContracts[ contractAddress_ ] = false; } /** * @dev Remove `contractAddress` from the partner collection managers. * * @param contractAddress_ ~ type = address : the contract to register */ function removePartnerContract( address contractAddress_ ) public onlyOwner { partnerContracts[ contractAddress_ ] = false; } /** * @dev Sets `contractAddress_` as the coin manager. * * @param contractAddress_ ~ type = address : the contract to register */ function setCoinContract( address contractAddress_ ) public onlyOwner { COIN_CONTRACT = CCCOIN( contractAddress_ ); } /** * @dev Sets `contractAddress_` as the crystal manager. * * @param contractAddress_ ~ type = address : the contract to register */ function setCrystalContract( address contractAddress_ ) public onlyOwner { CRYSTAL_CONTRACT = IERC1155( contractAddress_ ); } /** * @dev Updates the daily rewards for staking a key. * * @param rewards_ ~ type = uint256 : the new daily rewards for staking a key */ function setKeyRewards( uint256 rewards_ ) public onlyOwner { KEY_REWARD = rewards_; } /** * @dev Updates the daily rewards for staking a degen drop. * * @param rewards_ ~ type = uint256 : the new daily rewards for staking a degen drop */ function setDegenRewards( uint256 rewards_ ) public onlyOwner { DEGEN_REWARD = rewards_; } /** * @dev Updates the daily rewards for staking a partner drop. * * @param rewards_ ~ type = uint256 : the new daily rewards for staking a partner drop */ function setPartnerRewards( uint256 rewards_ ) public onlyOwner { PARTNER_REWARD = rewards_; } /** * @dev Activates or deactivates unstaking, to activate unstaking, set the state to {IPausable.OPEN}. * * @param newState_ : the new state of the contract * * Requirements: * * - Caller must be the contract owner. */ function setPauseState( uint8 newState_ ) external onlyOwner { _setPauseState( newState_ ); } /** * @dev Updates the daily reward multiplier for staking a tier 1 crystal. * * @param multiplier_ ~ type = uint256 : the new daily rewards for staking a tier 1 crystal */ function setTier1Multiplier( uint256 multiplier_ ) public onlyOwner { CRYSTAL_MULTIPLIER[ 1 ] = multiplier_; } /** * @dev Updates the daily reward multiplier for staking a tier 2 crystal. * * @param multiplier_ ~ type = uint256 : the new daily rewards for staking a tier 2 crystal */ function setTier2Multiplier( uint256 multiplier_ ) public onlyOwner { CRYSTAL_MULTIPLIER[ 2 ] = multiplier_; } /** * @dev Updates the daily reward multiplier for staking a tier 3 crystal. * * @param multiplier_ ~ type = uint256 : the new daily rewards for staking a tier 3 crystal */ function setTier3Multiplier( uint256 multiplier_ ) public onlyOwner { CRYSTAL_MULTIPLIER[ 3 ] = multiplier_; } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the number of keys staked by `tokenOwner_`. * * Note: We add this function here so that collab.land can grant roles to keyholders who stake their keys. */ function balanceOf( address tokenOwner_ ) public view returns ( uint256 ) { return stakingInfo[ tokenOwner_ ].key; } /** * @dev Returns the list of nfts staked by `tokenOwner_`. * * @param tokenOwner_ ~ type = address : the owner of the NFT */ function nftsOfOwner( address tokenOwner_ ) public view returns ( stakedNFT[] memory ) { return stakeNFTWallets[ tokenOwner_ ]; } /** * @dev Returns the rewards that `tokenOwner_` earns per second. * * @param tokenOwner_ ~ type = address : the owner of the NFT */ function rewardsPerSecond( address tokenOwner_ ) public view returns ( uint256 ) { StakingInfo storage _stakingInfo_ = stakingInfo[ tokenOwner_ ]; uint256 _tier1_ = _stakingInfo_.tier1; uint256 _tier2_ = _stakingInfo_.tier2; uint256 _tier3_ = _stakingInfo_.tier3; uint256 _reward_; uint256 _index_ = _stakingInfo_.key; while ( _index_ > 0 ) { unchecked { _index_ --; } if ( _tier1_ > 0 ) { unchecked { _reward_ += KEY_REWARD * ( CRYSTAL_MULTIPLIER[ 1 ] / 1000 ) / DAY; _tier1_ --; } } else if ( _tier2_ > 0 ) { unchecked { _reward_ += KEY_REWARD * ( CRYSTAL_MULTIPLIER[ 2 ] / 1000 ) / DAY; _tier2_ --; } } else if ( _tier3_ > 0 ) { unchecked { _reward_ += KEY_REWARD * ( CRYSTAL_MULTIPLIER[ 3 ] / 1000 ) / DAY; _tier3_ --; } } else { unchecked { _reward_ += KEY_REWARD / DAY; } } } unchecked { _reward_ += DEGEN_REWARD * _stakingInfo_.degen / DAY; _reward_ += PARTNER_REWARD * _stakingInfo_.partner / DAY; } return _reward_; } /** * @dev Returns the amount of rewards earned by `tokenOwner_` so far. * * @param tokenOwner_ ~ type = address : the owner of the NFT */ function getTotalRewards( address tokenOwner_ ) public view returns ( uint256 ) { return _totalRewards( tokenOwner_ ); } /** * @dev Allows the contract to manage tokens on behalf of token holders. * This function is called as part of the {IERC721.isApprovedForAll}. */ function proxies( address ) public view returns ( address ) { return address( this ); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId_ ) public view virtual returns ( bool ) { return interfaceId_ == type( IERC721Receiver ).interfaceId || interfaceId_ == type( IERC1155Receiver ).interfaceId; } // ************************************** // ************************************** // ***** PURE ***** // ************************************** /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes calldata ) external pure returns ( bytes4 ) { return IERC721Receiver.onERC721Received.selector; } /** * @notice Handle the receipt of a single ERC1155 token type. * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated. * This function MAY throw to revert and reject the transfer. * Return of other amount than the magic value MUST result in the transaction being reverted. * Note: The token contract address is always the message sender. */ function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external pure returns ( bytes4 ) { return IERC1155Receiver.onERC1155Received.selector; } /** * @notice Handle the receipt of multiple ERC1155 token types. * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated. * This function MAY throw to revert and reject the transfer. * Return of other amount than the magic value WILL result in the transaction being reverted. * Note: The token contract address is always the message sender. */ function onERC1155BatchReceived( address, address, uint256[] calldata, uint256[] calldata, bytes calldata ) external pure returns ( bytes4 ) { return IERC1155Receiver.onERC1155BatchReceived.selector; } // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.10; abstract contract IPausable { // Enum to represent the sale state, defaults to ``CLOSED``. uint8 constant CLOSED = 0; uint8 constant OPEN = 1; // Errors error IPausable_INCORRECT_STATE( uint8 currentState ); error IPausable_INVALID_STATE( uint8 newState ); // The current state of the contract uint8 private _contractState; /** * @dev Emitted when the sale state changes */ event ContractStateChanged( uint8 indexed previousState, uint8 indexed newState ); /** * @dev Internal function setting the contract state to `newState_`. * * Note: Contract state can have one of 2 values by default, ``CLOSED`` or ``OPEN``. * To maintain extendability, the 2 available states are kept as uint8 instead of enum. * As a result, it is possible to set the state to an incorrect value. * To avoid issues, `newState_` should be validated before calling this function */ function _setPauseState( uint8 newState_ ) internal virtual { uint8 _previousState_ = _contractState; _contractState = newState_; emit ContractStateChanged( _previousState_, newState_ ); } /** * @dev Internal function returning the contract state. */ function getPauseState() public virtual view returns ( uint8 ) { return _contractState; } /** * @dev Throws if sale state is not ``CLOSED``. */ modifier isClosed { if ( _contractState != CLOSED ) { revert IPausable_INCORRECT_STATE( _contractState ); } _; } /** * @dev Throws if sale state is ``CLOSED``. */ modifier isNotClosed { if ( _contractState == CLOSED ) { revert IPausable_INCORRECT_STATE( _contractState ); } _; } /** * @dev Throws if sale state is not ``OPEN``. */ modifier isOpen { if ( _contractState != OPEN ) { revert IPausable_INCORRECT_STATE( _contractState ); } _; } /** * @dev Throws if sale state is ``OPEN``. */ modifier isNotOpen { if ( _contractState == OPEN ) { revert IPausable_INCORRECT_STATE( _contractState ); } _; } }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.10; import "@openzeppelin/contracts/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 IOwnable is Context { // Errors error IOwnable_NOT_OWNER( address operator ); // The owner of the contract address private _owner; /** * @dev Emitted when contract ownership changes. */ event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function _initIOwnable( address owner_ ) internal { _owner = owner_; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns ( address ) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { address _sender_ = _msgSender(); if ( owner() != _sender_ ) { revert IOwnable_NOT_OWNER( _sender_ ); } _; } /** * @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 { address _oldOwner_ = _owner; _owner = newOwner_; emit OwnershipTransferred( _oldOwner_, newOwner_ ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol) pragma solidity 0.8.10; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver { /** @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. 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. 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: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol) pragma solidity 0.8.10; import "./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 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; /** * @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 be 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 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 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 Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll( address account, address operator ) external view returns ( bool ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol) pragma solidity 0.8.10; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity 0.8.10; import "./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 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 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 tokenI_d ) external; /** * @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 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 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 Returns the number of tokens in `tokenOwner_`'s account. */ function balanceOf( address tokenOwner_ ) external view returns ( uint256 balance ); /** * @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 `tokenOwner_`. * * See {setApprovalForAll} */ function isApprovedForAll( address tokenOwner_, address operator_ ) external view returns ( bool ); /** * @dev Returns the owner of the `tokenId_` token. * * Requirements: * * - `tokenId_` must exist. */ function ownerOf( uint256 tokenId_ ) external view returns ( address owner ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity 0.8.10; /** * @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); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CCVault_ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"}],"name":"CCVault_EMPTY","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"CCVault_INSUFFICIENT_BALANCE","type":"error"},{"inputs":[{"internalType":"uint256","name":"seriesId","type":"uint256"},{"internalType":"uint256","name":"amountRequested","type":"uint256"}],"name":"CCVault_INSUFFICIENT_CRYSTAL_BALANCE","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountRequested","type":"uint256"},{"internalType":"uint256","name":"amountAvailable","type":"uint256"}],"name":"CCVault_INSUFFICIENT_REWARDS","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"CCVault_INVALID_CONTRACT","type":"error"},{"inputs":[{"internalType":"uint256","name":"seriesId","type":"uint256"}],"name":"CCVault_NONEXISTANT_CRYSTAL","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"CCVault_NO_PROXY_ACCESS","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"}],"name":"CCVault_NO_REWARDS_EARNED","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"CCVault_TOKEN_ALREADY_STAKED","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"CCVault_TOKEN_NOT_OWNED","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"CCVault_TOKEN_NOT_STAKED","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IOwnable_NOT_OWNER","type":"error"},{"inputs":[{"internalType":"uint8","name":"currentState","type":"uint8"}],"name":"IPausable_INCORRECT_STATE","type":"error"},{"inputs":[{"internalType":"uint8","name":"newState","type":"uint8"}],"name":"IPausable_INVALID_STATE","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"previousState","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"newState","type":"uint8"}],"name":"ContractStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"COIN_CONTRACT","outputs":[{"internalType":"contract CCCOIN","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CRYSTAL_CONTRACT","outputs":[{"internalType":"contract IERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"CRYSTAL_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEGEN_REWARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KEY_REWARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PARTNER_REWARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"addDegenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"addKeyContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"addPartnerContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"airdropCoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"contractAddresses_","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"}],"name":"bulkStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contractAddresses_","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"}],"name":"bulkUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"degenContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseState","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"getTotalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"keyContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"nftsOfOwner","outputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct CCVault.stakedNFT[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"partnerContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"proxies","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"removeDegenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"removeKeyContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"removePartnerContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"rewardsPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"setCoinContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"setCrystalContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rewards_","type":"uint256"}],"name":"setDegenRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rewards_","type":"uint256"}],"name":"setKeyRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rewards_","type":"uint256"}],"name":"setPartnerRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newState_","type":"uint8"}],"name":"setPauseState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"multiplier_","type":"uint256"}],"name":"setTier1Multiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"multiplier_","type":"uint256"}],"name":"setTier2Multiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"multiplier_","type":"uint256"}],"name":"setTier3Multiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountSpent_","type":"uint256"}],"name":"spendRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"stakeCrystal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"stakeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakeNFTWallets","outputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingInfo","outputs":[{"internalType":"uint256","name":"lastUpdate","type":"uint256"},{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"tier1","type":"uint256"},{"internalType":"uint256","name":"tier2","type":"uint256"},{"internalType":"uint256","name":"tier3","type":"uint256"},{"internalType":"uint256","name":"degen","type":"uint256"},{"internalType":"uint256","name":"partner","type":"uint256"},{"internalType":"uint256","name":"rewardsEarned","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId_","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"}],"name":"unstakeCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"unstakeCrystal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"unstakeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200003262000026620000b560201b60201c565b620000bd60201b60201c565b6703782dace9d90000600181905550662386f26fc1000060028190555067016345785d8a0000600381905550610fa06006600060018152602001908152602001600020819055506109c46006600060028152602001908152602001600020819055506107d060066000600381526020019081526020016000208190555062000100565b600033905090565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b615e2780620001106000396000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c8063afef974f11610182578063e78c6344116100e9578063f6c15160116100a2578063f97d04421161007c578063f97d0442146108b5578063fb6b2f55146108d1578063fcbc4cee146108ed578063fd457d4b14610909576102bb565b8063f6c1516014610861578063f74727f71461087d578063f7e3130c14610899576102bb565b8063e78c63441461077d578063ebfc5b95146107ad578063f1f0849e146107dd578063f23a6e61146107f9578063f248e74914610829578063f2fde38b14610845576102bb565b8063bb03e2971161013b578063bb03e29714610699578063bc197c81146106b5578063c4552791146106e5578063c92b84d014610715578063d2f6a68b14610745578063d6f4054314610761576102bb565b8063afef974f146105eb578063b081fd3014610609578063b0e6e11b14610625578063b13270d514610641578063b78ca4e21461065d578063ba4426fe1461067b576102bb565b806362d10e3f116102265780638511b50d116101df5780638511b50d146105225780638ae86dd41461053e5780638da5cb5b1461055c57806394eecb501461057a5780639a44f1fb146105b15780639c1c97d7146105cf576102bb565b806362d10e3f14610452578063630965091461046e578063643dcac61461048a578063694b04c8146104a657806370a08231146104c257806371ca00d1146104f2576102bb565b806335322f371161027857806335322f37146103a4578063372500ab146103ae578063413ec4a6146103b8578063555e25e8146103e8578063571bdbc81461040457806362875b8414610422576102bb565b806301ffc9a7146102c057806306793849146102f0578063150b7a021461030c578063248c6e4e1461033c5780632bcf161c14610358578063307e6edd14610388575b600080fd5b6102da60048036038101906102d59190615019565b61093a565b6040516102e79190615061565b60405180910390f35b61030a600480360381019061030591906150b2565b610a0c565b005b610326600480360381019061032191906151a2565b610aac565b6040516103339190615239565b60405180910390f35b61035660048036038101906103519190615254565b610ac1565b005b610372600480360381019061036d9190615254565b610b89565b60405161037f9190615290565b60405180910390f35b6103a2600480360381019061039d91906150b2565b610b9b565b005b6103ac610c3b565b005b6103b6610e17565b005b6103d260048036038101906103cd9190615254565b6110a5565b6040516103df9190615061565b60405180910390f35b61040260048036038101906103fd91906150b2565b6110c5565b005b61040c611165565b6040516104199190615290565b60405180910390f35b61043c60048036038101906104379190615254565b61116b565b60405161044991906153a7565b60405180910390f35b61046c60048036038101906104679190615254565b611269565b005b61048860048036038101906104839190615402565b611348565b005b6104a4600480360381019061049f91906150b2565b6113d8565b005b6104c060048036038101906104bb9190615641565b611466565b005b6104dc60048036038101906104d79190615254565b611840565b6040516104e99190615290565b60405180910390f35b61050c600480360381019061050791906150b2565b61188c565b6040516105199190615290565b60405180910390f35b61053c60048036038101906105379190615254565b6118a4565b005b610546611983565b6040516105539190615718565b60405180910390f35b6105646119a9565b6040516105719190615742565b60405180910390f35b610594600480360381019061058f9190615254565b6119d2565b6040516105a898979695949392919061575d565b60405180910390f35b6105b9611a1a565b6040516105c691906157ea565b60405180910390f35b6105e960048036038101906105e49190615805565b611a30565b005b6105f3611ea5565b6040516106009190615290565b60405180910390f35b610623600480360381019061061e9190615805565b611eab565b005b61063f600480360381019061063a9190615254565b6120c1565b005b61065b60048036038101906106569190615805565b6121a0565b005b6106656124d7565b6040516106729190615866565b60405180910390f35b6106836124fd565b6040516106909190615290565b60405180910390f35b6106b360048036038101906106ae9190615641565b612503565b005b6106cf60048036038101906106ca91906158d7565b612a69565b6040516106dc9190615239565b60405180910390f35b6106ff60048036038101906106fa9190615254565b612a81565b60405161070c9190615742565b60405180910390f35b61072f600480360381019061072a9190615254565b612a8b565b60405161073c9190615290565b60405180910390f35b61075f600480360381019061075a9190615254565b612c82565b005b61077b600480360381019061077691906150b2565b612d61565b005b61079760048036038101906107929190615254565b612e03565b6040516107a49190615061565b60405180910390f35b6107c760048036038101906107c29190615254565b612e23565b6040516107d49190615061565b60405180910390f35b6107f760048036038101906107f29190615254565b612e43565b005b610813600480360381019061080e91906159b3565b61341e565b6040516108209190615239565b60405180910390f35b610843600480360381019061083e9190615254565b613434565b005b61085f600480360381019061085a9190615254565b613513565b005b61087b60048036038101906108769190615254565b61365b565b005b610897600480360381019061089291906150b2565b61373a565b005b6108b360048036038101906108ae9190615a4d565b6137c8565b005b6108cf60048036038101906108ca91906150b2565b613a1b565b005b6108eb60048036038101906108e69190615a4d565b613aa9565b005b61090760048036038101906109029190615254565b613dd1565b005b610923600480360381019061091e9190615805565b613e99565b604051610931929190615a8d565b60405180910390f35b60007f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a0557507f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000610a16613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610a376119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610a8f57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610a869190615742565b60405180910390fd5b816006600060028152602001908152602001600020819055505050565b600063150b7a0260e01b905095945050505050565b6000610acb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610aec6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610b4457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610b3b9190615742565b60405180910390fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000610b9482613f02565b9050919050565b6000610ba5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610bc66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610c1e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610c159190615742565b60405180910390fd5b816006600060038152602001908152602001600020819055505050565b600160ff16600060149054906101000a900460ff1660ff1614610ca457600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401610c9b91906157ea565b60405180910390fd5b6000610cae613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610d3d57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610d349190615742565b60405180910390fd5b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115610da657808060019003915050610da18382613fef565b610d85565b600082600201541115610dc457610dc38360018460020154614474565b5b600082600301541115610de257610de18360028460030154614474565b5b600082600401541115610e0057610dff8360038460040154614474565b5b610e12836000806000806000806145ef565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401610e729190615742565b602060405180830381865afa158015610e8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb39190615ae2565b610f1657600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401610f0d9190615742565b60405180910390fd5b6000610f20613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610faf57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610fa69190615742565b60405180910390fd5b610fb8826146c3565b600081600701549050600081141561100757826040517f107024af000000000000000000000000000000000000000000000000000000008152600401610ffe9190615742565b60405180910390fd5b60008260070181905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084836040518363ffffffff1660e01b815260040161106e929190615a8d565b600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50505050505050565b600a6020528060005260406000206000915054906101000a900460ff1681565b60006110cf613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166110f06119a9565b73ffffffffffffffffffffffffffffffffffffffff161461114857806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161113f9190615742565b60405180910390fd5b816006600060018152602001908152602001600020819055505050565b60015481565b6060600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561125e57838290600052602060002090600202016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481525050815260200190600101906111cc565b505050509050919050565b6000611273613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166112946119a9565b73ffffffffffffffffffffffffffffffffffffffff16146112ec57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016112e39190615742565b60405180910390fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000611352613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166113736119a9565b73ffffffffffffffffffffffffffffffffffffffff16146113cb57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016113c29190615742565b60405180910390fd5b6113d482614730565b5050565b60006113e2613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166114036119a9565b73ffffffffffffffffffffffffffffffffffffffff161461145b57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016114529190615742565b60405180910390fd5b816003819055505050565b600082519050815181146114a6576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114b0613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b600088111561182557878060019003985050600960008b8a8151811061168657611685615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156116e85785806001019650506117e1565b600a60008b8a815181106116ff576116fe615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117615781806001019250506117e0565b600b60008b8a8151811061177857611777615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117da5780806001019150506117df565b61165d565b5b5b611820878b8a815181106117f8576117f7615b0f565b5b60200260200101518b8b8151811061181357611812615b0f565b5b6020026020010151614796565b61165d565b611834878787878787876145ef565b50505050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b60066020528060005260406000206000915090505481565b60006118ae613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166118cf6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461192757806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161191e9190615742565b60405180910390fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60076020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154905088565b60008060149054906101000a900460ff16905090565b600160ff16600060149054906101000a900460ff1660ff1614611a9957600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401611a9091906157ea565b60405180910390fd5b6000611aa3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611cf5576000861415611ce757886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611cde9190615742565b60405180910390fd5b858060019003965050611e80565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611d9b576000821415611d8d57886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611d849190615742565b60405180910390fd5b818060019003925050611e7f565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e41576000811415611e3357886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611e2a9190615742565b60405180910390fd5b808060019003915050611e7e565b886040517f71c52b1d000000000000000000000000000000000000000000000000000000008152600401611e759190615742565b60405180910390fd5b5b5b611e8b878a8a614a9e565b611e9a878787878787876145ef565b505050505050505050565b60035481565b6000611eb5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16611ed66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614611f2e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401611f259190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401611f899190615742565b602060405180830381865afa158015611fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fca9190615ae2565b61202d57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de0000000000000000000000000000000000000000000000000000000081526004016120249190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084846040518363ffffffff1660e01b815260040161208a929190615a8d565b600060405180830381600087803b1580156120a457600080fd5b505af11580156120b8573d6000803e3d6000fd5b50505050505050565b60006120cb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166120ec6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461214457806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161213b9190615742565b60405180910390fd5b6001600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60006121aa613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156123b55785806001019650506124b2565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124145781806001019250506124b1565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124735780806001019150506124b0565b886040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016124a79190615742565b60405180910390fd5b5b5b6124bd878a8a614796565b6124cc878787878787876145ef565b505050505050505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b600160ff16600060149054906101000a900460ff1660ff161461256c57600060149054906101000a900460ff166040517f81d1489b00000000000000000000000000000000000000000000000000000000815260040161256391906157ea565b60405180910390fd5b600082519050815181146125ac576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006125b6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b6000881115612a4e57878060019003985050600960008b8a8151811061278c5761278b615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561284f576000861415612841578988815181106127fd576127fc615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016128389190615742565b60405180910390fd5b858060019003965050612a0a565b600a60008b8a8151811061286657612865615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561292957600082141561291b578988815181106128d7576128d6615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129129190615742565b60405180910390fd5b818060019003925050612a09565b600b60008b8a815181106129405761293f615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a035760008114156129f5578988815181106129b1576129b0615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129ec9190615742565b60405180910390fd5b808060019003915050612a08565b612763565b5b5b612a49878b8a81518110612a2157612a20615b0f565b5b60200260200101518b8b81518110612a3c57612a3b615b0f565b5b6020026020010151614a9e565b612763565b612a5d878787878787876145ef565b50505050505050505050565b600063bc197c8160e01b905098975050505050505050565b6000309050919050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600201549050600082600301549050600083600401549050600080856001015490505b6000811115612c34578080600190039150506000851115612b6057620151806103e860066000600181526020019081526020016000205481612b3a57612b39615b3e565b5b046001540281612b4d57612b4c615b3e565b5b0482019150848060019003955050612c2f565b6000841115612bb957620151806103e860066000600281526020019081526020016000205481612b9357612b92615b3e565b5b046001540281612ba657612ba5615b3e565b5b0482019150838060019003945050612c2e565b6000831115612c1257620151806103e860066000600381526020019081526020016000205481612bec57612beb615b3e565b5b046001540281612bff57612bfe615b3e565b5b0482019150828060019003935050612c2d565b6201518060015481612c2757612c26615b3e565b5b04820191505b5b5b612af5565b6201518086600501546002540281612c4f57612c4e615b3e565b5b04820191506201518086600601546003540281612c6f57612c6e615b3e565b5b0482019150819650505050505050919050565b6000612c8c613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16612cad6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614612d0557806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401612cfc9190615742565b60405180910390fd5b6001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000612d6b613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612df557806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612dec9190615742565b60405180910390fd5b612dff8183614c74565b5050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b600160ff16600060149054906101000a900460ff1660ff1614612eac57600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401612ea391906157ea565b60405180910390fd5b6000612eb6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612f4057806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612f379190615742565b60405180910390fd5b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614156131935760008511156131565761315587600187614474565b5b600084111561316c5761316b87600286614474565b5b60008311156131825761318187600385614474565b5b600094506000935060009250613405565b600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156131ee57600095506132e3565b600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561324957600091506132e2565b600b60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156132a457600090506132e1565b876040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016132d89190615742565b60405180910390fd5b5b5b6000600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115613403578080600190039150508873ffffffffffffffffffffffffffffffffffffffff16600860008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106133a5576133a4615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133fe576133fd8882613fef565b5b61332b565b505b613414878787878787876145ef565b5050505050505050565b600063f23a6e6160e01b90509695505050505050565b600061343e613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661345f6119a9565b73ffffffffffffffffffffffffffffffffffffffff16146134b757806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016134ae9190615742565b60405180910390fd5b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600061351d613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661353e6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461359657806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161358d9190615742565b60405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000613665613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166136866119a9565b73ffffffffffffffffffffffffffffffffffffffff16146136de57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016136d59190615742565b60405180910390fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000613744613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166137656119a9565b73ffffffffffffffffffffffffffffffffffffffff16146137bd57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016137b49190615742565b60405180910390fd5b816001819055505050565b60006137d2613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060060154905060018914156139915787850194506139f6565b60028914156139a45787840193506139f5565b60038914156139b75787830192506139f4565b886040517ffb59b93f0000000000000000000000000000000000000000000000000000000081526004016139eb9190615290565b60405180910390fd5b5b5b613a01878a8a614d31565b613a10878787878787876145ef565b505050505050505050565b6000613a25613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613a466119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613a9e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613a959190615742565b60405180910390fd5b816002819055505050565b6000613ab3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490506001891415613cb95787851015613caf5788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613ca6929190615b6d565b60405180910390fd5b8785039450613dac565b6002891415613d135787841015613d095788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d00929190615b6d565b60405180910390fd5b8784039350613dab565b6003891415613d6d5787831015613d635788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d5a929190615b6d565b60405180910390fd5b8783039250613daa565b886040517ffb59b93f000000000000000000000000000000000000000000000000000000008152600401613da19190615290565b60405180910390fd5b5b5b613db7878a8a614474565b613dc6878787878787876145ef565b505050505050505050565b6000613ddb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613dfc6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613e5457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613e4b9190615742565b60405180910390fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60086020528160005260406000208181548110613eb557600080fd5b9060005260206000209060020201600091509150508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b600033905090565b6000806000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806101000160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152505090506000816000015114613fe5576000808260e0015193508260000151421115613fe25782600001514203915081613fd987612a8b565b02905080840193505b50505b8192505050919050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811061408957614088615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002084815481106141105761410f615b0f565b5b906000526020600020906002020160010154905060008290503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016141799190615290565b602060405180830381865afa158015614196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ba9190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146142145782826040517f1c6aa71e00000000000000000000000000000000000000000000000000000000815260040161420b929190615a8d565b60405180910390fd5b836001866142229190615c07565b1461436657600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001856142739190615c5d565b8154811061428457614283615b0f565b5b9060005260206000209060020201600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002086815481106142e3576142e2615b0f565b5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600182015481600101559050505b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806143b5576143b4615c91565b5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055505090558073ffffffffffffffffffffffffffffffffffffffff166323b872dd3088856040518463ffffffff1660e01b815260040161443a93929190615cc0565b600060405180830381600087803b15801561445457600080fd5b505af1158015614468573d6000803e3d6000fd5b50505050505050505050565b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e30856040518363ffffffff1660e01b81526004016144d1929190615a8d565b602060405180830381865afa1580156144ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145129190615d0c565b10156145575781816040517f403f7b3e00000000000000000000000000000000000000000000000000000000815260040161454e929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a308585856040518563ffffffff1660e01b81526004016145b89493929190615d70565b600060405180830381600087803b1580156145d257600080fd5b505af11580156145e6573d6000803e3d6000fd5b50505050505050565b6000600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905086816001015414614647578681600101819055505b8581600201541461465c578581600201819055505b84816003015414614671578481600301819055505b83816004015414614686578381600401819055505b8281600501541461469b578281600501819055505b818160060154146146b0578181600601819055505b6146b9886146c3565b5050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061470f82613f02565b81600701819055504281600001541461472c574281600001819055505b5050565b60008060149054906101000a900460ff16905081600060146101000a81548160ff021916908360ff1602179055508160ff168160ff167f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe460405160405180910390a35050565b60008290508073ffffffffffffffffffffffffffffffffffffffff1663e985e9c585306040518363ffffffff1660e01b81526004016147d6929190615dc8565b602060405180830381865afa1580156147f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148179190615ae2565b61485857826040517fd640e7de00000000000000000000000000000000000000000000000000000000815260040161484f9190615742565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016148a89190615290565b602060405180830381865afa1580156148c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e99190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146149435782826040517f8d4affb800000000000000000000000000000000000000000000000000000000815260040161493a929190615a8d565b60405180910390fd5b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052808573ffffffffffffffffffffffffffffffffffffffff16815260200184815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015550508073ffffffffffffffffffffffffffffffffffffffff166323b872dd8530856040518463ffffffff1660e01b8152600401614a6693929190615cc0565b600060405180830381600087803b158015614a8057600080fd5b505af1158015614a94573d6000803e3d6000fd5b5050505050505050565b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115614c30578080600190039150508273ffffffffffffffffffffffffffffffffffffffff16600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614b6057614b5f615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015614c16575081600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614c0257614c01615b0f565b5b906000526020600020906002020160010154145b15614c2b57614c258482613fef565b50614c6f565b614ae6565b82826040517f1c6aa71e000000000000000000000000000000000000000000000000000000008152600401614c66929190615a8d565b60405180910390fd5b505050565b6000614c7f83613f02565b905081811015614cc85781816040517f83015a83000000000000000000000000000000000000000000000000000000008152600401614cbf929190615b6d565b60405180910390fd5b6000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050828203816007018190555042816000015414614d2b574281600001819055505b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e985e9c584306040518363ffffffff1660e01b8152600401614d8e929190615dc8565b602060405180830381865afa158015614dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614dcf9190615ae2565b614e3257600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401614e299190615742565b60405180910390fd5b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e85856040518363ffffffff1660e01b8152600401614e8f929190615a8d565b602060405180830381865afa158015614eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ed09190615d0c565b1015614f155781816040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401614f0c929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a843085856040518563ffffffff1660e01b8152600401614f769493929190615d70565b600060405180830381600087803b158015614f9057600080fd5b505af1158015614fa4573d6000803e3d6000fd5b50505050505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614ff681614fc1565b811461500157600080fd5b50565b60008135905061501381614fed565b92915050565b60006020828403121561502f5761502e614fb7565b5b600061503d84828501615004565b91505092915050565b60008115159050919050565b61505b81615046565b82525050565b60006020820190506150766000830184615052565b92915050565b6000819050919050565b61508f8161507c565b811461509a57600080fd5b50565b6000813590506150ac81615086565b92915050565b6000602082840312156150c8576150c7614fb7565b5b60006150d68482850161509d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061510a826150df565b9050919050565b61511a816150ff565b811461512557600080fd5b50565b60008135905061513781615111565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126151625761516161513d565b5b8235905067ffffffffffffffff81111561517f5761517e615142565b5b60208301915083600182028301111561519b5761519a615147565b5b9250929050565b6000806000806000608086880312156151be576151bd614fb7565b5b60006151cc88828901615128565b95505060206151dd88828901615128565b94505060406151ee8882890161509d565b935050606086013567ffffffffffffffff81111561520f5761520e614fbc565b5b61521b8882890161514c565b92509250509295509295909350565b61523381614fc1565b82525050565b600060208201905061524e600083018461522a565b92915050565b60006020828403121561526a57615269614fb7565b5b600061527884828501615128565b91505092915050565b61528a8161507c565b82525050565b60006020820190506152a56000830184615281565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6152e0816150ff565b82525050565b6152ef8161507c565b82525050565b60408201600082015161530b60008501826152d7565b50602082015161531e60208501826152e6565b50505050565b600061533083836152f5565b60408301905092915050565b6000602082019050919050565b6000615354826152ab565b61535e81856152b6565b9350615369836152c7565b8060005b8381101561539a5781516153818882615324565b975061538c8361533c565b92505060018101905061536d565b5085935050505092915050565b600060208201905081810360008301526153c18184615349565b905092915050565b600060ff82169050919050565b6153df816153c9565b81146153ea57600080fd5b50565b6000813590506153fc816153d6565b92915050565b60006020828403121561541857615417614fb7565b5b6000615426848285016153ed565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6154788261542f565b810181811067ffffffffffffffff8211171561549757615496615440565b5b80604052505050565b60006154aa614fad565b90506154b6828261546f565b919050565b600067ffffffffffffffff8211156154d6576154d5615440565b5b602082029050602081019050919050565b60006154fa6154f5846154bb565b6154a0565b9050808382526020820190506020840283018581111561551d5761551c615147565b5b835b8181101561554657806155328882615128565b84526020840193505060208101905061551f565b5050509392505050565b600082601f8301126155655761556461513d565b5b81356155758482602086016154e7565b91505092915050565b600067ffffffffffffffff82111561559957615598615440565b5b602082029050602081019050919050565b60006155bd6155b88461557e565b6154a0565b905080838252602082019050602084028301858111156155e0576155df615147565b5b835b8181101561560957806155f5888261509d565b8452602084019350506020810190506155e2565b5050509392505050565b600082601f8301126156285761562761513d565b5b81356156388482602086016155aa565b91505092915050565b6000806040838503121561565857615657614fb7565b5b600083013567ffffffffffffffff81111561567657615675614fbc565b5b61568285828601615550565b925050602083013567ffffffffffffffff8111156156a3576156a2614fbc565b5b6156af85828601615613565b9150509250929050565b6000819050919050565b60006156de6156d96156d4846150df565b6156b9565b6150df565b9050919050565b60006156f0826156c3565b9050919050565b6000615702826156e5565b9050919050565b615712816156f7565b82525050565b600060208201905061572d6000830184615709565b92915050565b61573c816150ff565b82525050565b60006020820190506157576000830184615733565b92915050565b600061010082019050615773600083018b615281565b615780602083018a615281565b61578d6040830189615281565b61579a6060830188615281565b6157a76080830187615281565b6157b460a0830186615281565b6157c160c0830185615281565b6157ce60e0830184615281565b9998505050505050505050565b6157e4816153c9565b82525050565b60006020820190506157ff60008301846157db565b92915050565b6000806040838503121561581c5761581b614fb7565b5b600061582a85828601615128565b925050602061583b8582860161509d565b9150509250929050565b6000615850826156e5565b9050919050565b61586081615845565b82525050565b600060208201905061587b6000830184615857565b92915050565b60008083601f8401126158975761589661513d565b5b8235905067ffffffffffffffff8111156158b4576158b3615142565b5b6020830191508360208202830111156158d0576158cf615147565b5b9250929050565b60008060008060008060008060a0898b0312156158f7576158f6614fb7565b5b60006159058b828c01615128565b98505060206159168b828c01615128565b975050604089013567ffffffffffffffff81111561593757615936614fbc565b5b6159438b828c01615881565b9650965050606089013567ffffffffffffffff81111561596657615965614fbc565b5b6159728b828c01615881565b9450945050608089013567ffffffffffffffff81111561599557615994614fbc565b5b6159a18b828c0161514c565b92509250509295985092959890939650565b60008060008060008060a087890312156159d0576159cf614fb7565b5b60006159de89828a01615128565b96505060206159ef89828a01615128565b9550506040615a0089828a0161509d565b9450506060615a1189828a0161509d565b935050608087013567ffffffffffffffff811115615a3257615a31614fbc565b5b615a3e89828a0161514c565b92509250509295509295509295565b60008060408385031215615a6457615a63614fb7565b5b6000615a728582860161509d565b9250506020615a838582860161509d565b9150509250929050565b6000604082019050615aa26000830185615733565b615aaf6020830184615281565b9392505050565b615abf81615046565b8114615aca57600080fd5b50565b600081519050615adc81615ab6565b92915050565b600060208284031215615af857615af7614fb7565b5b6000615b0684828501615acd565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000604082019050615b826000830185615281565b615b8f6020830184615281565b9392505050565b600081519050615ba581615111565b92915050565b600060208284031215615bc157615bc0614fb7565b5b6000615bcf84828501615b96565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000615c128261507c565b9150615c1d8361507c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115615c5257615c51615bd8565b5b828201905092915050565b6000615c688261507c565b9150615c738361507c565b925082821015615c8657615c85615bd8565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000606082019050615cd56000830186615733565b615ce26020830185615733565b615cef6040830184615281565b949350505050565b600081519050615d0681615086565b92915050565b600060208284031215615d2257615d21614fb7565b5b6000615d3084828501615cf7565b91505092915050565b600082825260208201905092915050565b50565b6000615d5a600083615d39565b9150615d6582615d4a565b600082019050919050565b600060a082019050615d856000830187615733565b615d926020830186615733565b615d9f6040830185615281565b615dac6060830184615281565b8181036080830152615dbd81615d4d565b905095945050505050565b6000604082019050615ddd6000830185615733565b615dea6020830184615733565b939250505056fea2646970667358221220e7a2c839e9b2c717561968f8fe3cb67596764f6b032b2490f4369c5512b7a43a64736f6c634300080a0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c8063afef974f11610182578063e78c6344116100e9578063f6c15160116100a2578063f97d04421161007c578063f97d0442146108b5578063fb6b2f55146108d1578063fcbc4cee146108ed578063fd457d4b14610909576102bb565b8063f6c1516014610861578063f74727f71461087d578063f7e3130c14610899576102bb565b8063e78c63441461077d578063ebfc5b95146107ad578063f1f0849e146107dd578063f23a6e61146107f9578063f248e74914610829578063f2fde38b14610845576102bb565b8063bb03e2971161013b578063bb03e29714610699578063bc197c81146106b5578063c4552791146106e5578063c92b84d014610715578063d2f6a68b14610745578063d6f4054314610761576102bb565b8063afef974f146105eb578063b081fd3014610609578063b0e6e11b14610625578063b13270d514610641578063b78ca4e21461065d578063ba4426fe1461067b576102bb565b806362d10e3f116102265780638511b50d116101df5780638511b50d146105225780638ae86dd41461053e5780638da5cb5b1461055c57806394eecb501461057a5780639a44f1fb146105b15780639c1c97d7146105cf576102bb565b806362d10e3f14610452578063630965091461046e578063643dcac61461048a578063694b04c8146104a657806370a08231146104c257806371ca00d1146104f2576102bb565b806335322f371161027857806335322f37146103a4578063372500ab146103ae578063413ec4a6146103b8578063555e25e8146103e8578063571bdbc81461040457806362875b8414610422576102bb565b806301ffc9a7146102c057806306793849146102f0578063150b7a021461030c578063248c6e4e1461033c5780632bcf161c14610358578063307e6edd14610388575b600080fd5b6102da60048036038101906102d59190615019565b61093a565b6040516102e79190615061565b60405180910390f35b61030a600480360381019061030591906150b2565b610a0c565b005b610326600480360381019061032191906151a2565b610aac565b6040516103339190615239565b60405180910390f35b61035660048036038101906103519190615254565b610ac1565b005b610372600480360381019061036d9190615254565b610b89565b60405161037f9190615290565b60405180910390f35b6103a2600480360381019061039d91906150b2565b610b9b565b005b6103ac610c3b565b005b6103b6610e17565b005b6103d260048036038101906103cd9190615254565b6110a5565b6040516103df9190615061565b60405180910390f35b61040260048036038101906103fd91906150b2565b6110c5565b005b61040c611165565b6040516104199190615290565b60405180910390f35b61043c60048036038101906104379190615254565b61116b565b60405161044991906153a7565b60405180910390f35b61046c60048036038101906104679190615254565b611269565b005b61048860048036038101906104839190615402565b611348565b005b6104a4600480360381019061049f91906150b2565b6113d8565b005b6104c060048036038101906104bb9190615641565b611466565b005b6104dc60048036038101906104d79190615254565b611840565b6040516104e99190615290565b60405180910390f35b61050c600480360381019061050791906150b2565b61188c565b6040516105199190615290565b60405180910390f35b61053c60048036038101906105379190615254565b6118a4565b005b610546611983565b6040516105539190615718565b60405180910390f35b6105646119a9565b6040516105719190615742565b60405180910390f35b610594600480360381019061058f9190615254565b6119d2565b6040516105a898979695949392919061575d565b60405180910390f35b6105b9611a1a565b6040516105c691906157ea565b60405180910390f35b6105e960048036038101906105e49190615805565b611a30565b005b6105f3611ea5565b6040516106009190615290565b60405180910390f35b610623600480360381019061061e9190615805565b611eab565b005b61063f600480360381019061063a9190615254565b6120c1565b005b61065b60048036038101906106569190615805565b6121a0565b005b6106656124d7565b6040516106729190615866565b60405180910390f35b6106836124fd565b6040516106909190615290565b60405180910390f35b6106b360048036038101906106ae9190615641565b612503565b005b6106cf60048036038101906106ca91906158d7565b612a69565b6040516106dc9190615239565b60405180910390f35b6106ff60048036038101906106fa9190615254565b612a81565b60405161070c9190615742565b60405180910390f35b61072f600480360381019061072a9190615254565b612a8b565b60405161073c9190615290565b60405180910390f35b61075f600480360381019061075a9190615254565b612c82565b005b61077b600480360381019061077691906150b2565b612d61565b005b61079760048036038101906107929190615254565b612e03565b6040516107a49190615061565b60405180910390f35b6107c760048036038101906107c29190615254565b612e23565b6040516107d49190615061565b60405180910390f35b6107f760048036038101906107f29190615254565b612e43565b005b610813600480360381019061080e91906159b3565b61341e565b6040516108209190615239565b60405180910390f35b610843600480360381019061083e9190615254565b613434565b005b61085f600480360381019061085a9190615254565b613513565b005b61087b60048036038101906108769190615254565b61365b565b005b610897600480360381019061089291906150b2565b61373a565b005b6108b360048036038101906108ae9190615a4d565b6137c8565b005b6108cf60048036038101906108ca91906150b2565b613a1b565b005b6108eb60048036038101906108e69190615a4d565b613aa9565b005b61090760048036038101906109029190615254565b613dd1565b005b610923600480360381019061091e9190615805565b613e99565b604051610931929190615a8d565b60405180910390f35b60007f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a0557507f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000610a16613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610a376119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610a8f57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610a869190615742565b60405180910390fd5b816006600060028152602001908152602001600020819055505050565b600063150b7a0260e01b905095945050505050565b6000610acb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610aec6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610b4457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610b3b9190615742565b60405180910390fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000610b9482613f02565b9050919050565b6000610ba5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610bc66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610c1e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610c159190615742565b60405180910390fd5b816006600060038152602001908152602001600020819055505050565b600160ff16600060149054906101000a900460ff1660ff1614610ca457600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401610c9b91906157ea565b60405180910390fd5b6000610cae613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610d3d57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610d349190615742565b60405180910390fd5b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115610da657808060019003915050610da18382613fef565b610d85565b600082600201541115610dc457610dc38360018460020154614474565b5b600082600301541115610de257610de18360028460030154614474565b5b600082600401541115610e0057610dff8360038460040154614474565b5b610e12836000806000806000806145ef565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401610e729190615742565b602060405180830381865afa158015610e8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb39190615ae2565b610f1657600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401610f0d9190615742565b60405180910390fd5b6000610f20613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610faf57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610fa69190615742565b60405180910390fd5b610fb8826146c3565b600081600701549050600081141561100757826040517f107024af000000000000000000000000000000000000000000000000000000008152600401610ffe9190615742565b60405180910390fd5b60008260070181905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084836040518363ffffffff1660e01b815260040161106e929190615a8d565b600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50505050505050565b600a6020528060005260406000206000915054906101000a900460ff1681565b60006110cf613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166110f06119a9565b73ffffffffffffffffffffffffffffffffffffffff161461114857806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161113f9190615742565b60405180910390fd5b816006600060018152602001908152602001600020819055505050565b60015481565b6060600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561125e57838290600052602060002090600202016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481525050815260200190600101906111cc565b505050509050919050565b6000611273613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166112946119a9565b73ffffffffffffffffffffffffffffffffffffffff16146112ec57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016112e39190615742565b60405180910390fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000611352613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166113736119a9565b73ffffffffffffffffffffffffffffffffffffffff16146113cb57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016113c29190615742565b60405180910390fd5b6113d482614730565b5050565b60006113e2613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166114036119a9565b73ffffffffffffffffffffffffffffffffffffffff161461145b57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016114529190615742565b60405180910390fd5b816003819055505050565b600082519050815181146114a6576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114b0613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b600088111561182557878060019003985050600960008b8a8151811061168657611685615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156116e85785806001019650506117e1565b600a60008b8a815181106116ff576116fe615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117615781806001019250506117e0565b600b60008b8a8151811061177857611777615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117da5780806001019150506117df565b61165d565b5b5b611820878b8a815181106117f8576117f7615b0f565b5b60200260200101518b8b8151811061181357611812615b0f565b5b6020026020010151614796565b61165d565b611834878787878787876145ef565b50505050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b60066020528060005260406000206000915090505481565b60006118ae613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166118cf6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461192757806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161191e9190615742565b60405180910390fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60076020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154905088565b60008060149054906101000a900460ff16905090565b600160ff16600060149054906101000a900460ff1660ff1614611a9957600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401611a9091906157ea565b60405180910390fd5b6000611aa3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611cf5576000861415611ce757886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611cde9190615742565b60405180910390fd5b858060019003965050611e80565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611d9b576000821415611d8d57886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611d849190615742565b60405180910390fd5b818060019003925050611e7f565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e41576000811415611e3357886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611e2a9190615742565b60405180910390fd5b808060019003915050611e7e565b886040517f71c52b1d000000000000000000000000000000000000000000000000000000008152600401611e759190615742565b60405180910390fd5b5b5b611e8b878a8a614a9e565b611e9a878787878787876145ef565b505050505050505050565b60035481565b6000611eb5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16611ed66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614611f2e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401611f259190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401611f899190615742565b602060405180830381865afa158015611fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fca9190615ae2565b61202d57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de0000000000000000000000000000000000000000000000000000000081526004016120249190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084846040518363ffffffff1660e01b815260040161208a929190615a8d565b600060405180830381600087803b1580156120a457600080fd5b505af11580156120b8573d6000803e3d6000fd5b50505050505050565b60006120cb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166120ec6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461214457806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161213b9190615742565b60405180910390fd5b6001600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60006121aa613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156123b55785806001019650506124b2565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124145781806001019250506124b1565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124735780806001019150506124b0565b886040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016124a79190615742565b60405180910390fd5b5b5b6124bd878a8a614796565b6124cc878787878787876145ef565b505050505050505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b600160ff16600060149054906101000a900460ff1660ff161461256c57600060149054906101000a900460ff166040517f81d1489b00000000000000000000000000000000000000000000000000000000815260040161256391906157ea565b60405180910390fd5b600082519050815181146125ac576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006125b6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b6000881115612a4e57878060019003985050600960008b8a8151811061278c5761278b615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561284f576000861415612841578988815181106127fd576127fc615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016128389190615742565b60405180910390fd5b858060019003965050612a0a565b600a60008b8a8151811061286657612865615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561292957600082141561291b578988815181106128d7576128d6615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129129190615742565b60405180910390fd5b818060019003925050612a09565b600b60008b8a815181106129405761293f615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a035760008114156129f5578988815181106129b1576129b0615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129ec9190615742565b60405180910390fd5b808060019003915050612a08565b612763565b5b5b612a49878b8a81518110612a2157612a20615b0f565b5b60200260200101518b8b81518110612a3c57612a3b615b0f565b5b6020026020010151614a9e565b612763565b612a5d878787878787876145ef565b50505050505050505050565b600063bc197c8160e01b905098975050505050505050565b6000309050919050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600201549050600082600301549050600083600401549050600080856001015490505b6000811115612c34578080600190039150506000851115612b6057620151806103e860066000600181526020019081526020016000205481612b3a57612b39615b3e565b5b046001540281612b4d57612b4c615b3e565b5b0482019150848060019003955050612c2f565b6000841115612bb957620151806103e860066000600281526020019081526020016000205481612b9357612b92615b3e565b5b046001540281612ba657612ba5615b3e565b5b0482019150838060019003945050612c2e565b6000831115612c1257620151806103e860066000600381526020019081526020016000205481612bec57612beb615b3e565b5b046001540281612bff57612bfe615b3e565b5b0482019150828060019003935050612c2d565b6201518060015481612c2757612c26615b3e565b5b04820191505b5b5b612af5565b6201518086600501546002540281612c4f57612c4e615b3e565b5b04820191506201518086600601546003540281612c6f57612c6e615b3e565b5b0482019150819650505050505050919050565b6000612c8c613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16612cad6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614612d0557806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401612cfc9190615742565b60405180910390fd5b6001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000612d6b613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612df557806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612dec9190615742565b60405180910390fd5b612dff8183614c74565b5050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b600160ff16600060149054906101000a900460ff1660ff1614612eac57600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401612ea391906157ea565b60405180910390fd5b6000612eb6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612f4057806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612f379190615742565b60405180910390fd5b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614156131935760008511156131565761315587600187614474565b5b600084111561316c5761316b87600286614474565b5b60008311156131825761318187600385614474565b5b600094506000935060009250613405565b600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156131ee57600095506132e3565b600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561324957600091506132e2565b600b60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156132a457600090506132e1565b876040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016132d89190615742565b60405180910390fd5b5b5b6000600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115613403578080600190039150508873ffffffffffffffffffffffffffffffffffffffff16600860008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106133a5576133a4615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133fe576133fd8882613fef565b5b61332b565b505b613414878787878787876145ef565b5050505050505050565b600063f23a6e6160e01b90509695505050505050565b600061343e613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661345f6119a9565b73ffffffffffffffffffffffffffffffffffffffff16146134b757806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016134ae9190615742565b60405180910390fd5b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600061351d613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661353e6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461359657806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161358d9190615742565b60405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000613665613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166136866119a9565b73ffffffffffffffffffffffffffffffffffffffff16146136de57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016136d59190615742565b60405180910390fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000613744613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166137656119a9565b73ffffffffffffffffffffffffffffffffffffffff16146137bd57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016137b49190615742565b60405180910390fd5b816001819055505050565b60006137d2613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060060154905060018914156139915787850194506139f6565b60028914156139a45787840193506139f5565b60038914156139b75787830192506139f4565b886040517ffb59b93f0000000000000000000000000000000000000000000000000000000081526004016139eb9190615290565b60405180910390fd5b5b5b613a01878a8a614d31565b613a10878787878787876145ef565b505050505050505050565b6000613a25613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613a466119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613a9e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613a959190615742565b60405180910390fd5b816002819055505050565b6000613ab3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490506001891415613cb95787851015613caf5788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613ca6929190615b6d565b60405180910390fd5b8785039450613dac565b6002891415613d135787841015613d095788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d00929190615b6d565b60405180910390fd5b8784039350613dab565b6003891415613d6d5787831015613d635788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d5a929190615b6d565b60405180910390fd5b8783039250613daa565b886040517ffb59b93f000000000000000000000000000000000000000000000000000000008152600401613da19190615290565b60405180910390fd5b5b5b613db7878a8a614474565b613dc6878787878787876145ef565b505050505050505050565b6000613ddb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613dfc6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613e5457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613e4b9190615742565b60405180910390fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60086020528160005260406000208181548110613eb557600080fd5b9060005260206000209060020201600091509150508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b600033905090565b6000806000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806101000160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152505090506000816000015114613fe5576000808260e0015193508260000151421115613fe25782600001514203915081613fd987612a8b565b02905080840193505b50505b8192505050919050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811061408957614088615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002084815481106141105761410f615b0f565b5b906000526020600020906002020160010154905060008290503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016141799190615290565b602060405180830381865afa158015614196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ba9190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146142145782826040517f1c6aa71e00000000000000000000000000000000000000000000000000000000815260040161420b929190615a8d565b60405180910390fd5b836001866142229190615c07565b1461436657600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001856142739190615c5d565b8154811061428457614283615b0f565b5b9060005260206000209060020201600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002086815481106142e3576142e2615b0f565b5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600182015481600101559050505b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806143b5576143b4615c91565b5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055505090558073ffffffffffffffffffffffffffffffffffffffff166323b872dd3088856040518463ffffffff1660e01b815260040161443a93929190615cc0565b600060405180830381600087803b15801561445457600080fd5b505af1158015614468573d6000803e3d6000fd5b50505050505050505050565b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e30856040518363ffffffff1660e01b81526004016144d1929190615a8d565b602060405180830381865afa1580156144ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145129190615d0c565b10156145575781816040517f403f7b3e00000000000000000000000000000000000000000000000000000000815260040161454e929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a308585856040518563ffffffff1660e01b81526004016145b89493929190615d70565b600060405180830381600087803b1580156145d257600080fd5b505af11580156145e6573d6000803e3d6000fd5b50505050505050565b6000600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905086816001015414614647578681600101819055505b8581600201541461465c578581600201819055505b84816003015414614671578481600301819055505b83816004015414614686578381600401819055505b8281600501541461469b578281600501819055505b818160060154146146b0578181600601819055505b6146b9886146c3565b5050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061470f82613f02565b81600701819055504281600001541461472c574281600001819055505b5050565b60008060149054906101000a900460ff16905081600060146101000a81548160ff021916908360ff1602179055508160ff168160ff167f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe460405160405180910390a35050565b60008290508073ffffffffffffffffffffffffffffffffffffffff1663e985e9c585306040518363ffffffff1660e01b81526004016147d6929190615dc8565b602060405180830381865afa1580156147f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148179190615ae2565b61485857826040517fd640e7de00000000000000000000000000000000000000000000000000000000815260040161484f9190615742565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016148a89190615290565b602060405180830381865afa1580156148c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e99190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146149435782826040517f8d4affb800000000000000000000000000000000000000000000000000000000815260040161493a929190615a8d565b60405180910390fd5b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052808573ffffffffffffffffffffffffffffffffffffffff16815260200184815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015550508073ffffffffffffffffffffffffffffffffffffffff166323b872dd8530856040518463ffffffff1660e01b8152600401614a6693929190615cc0565b600060405180830381600087803b158015614a8057600080fd5b505af1158015614a94573d6000803e3d6000fd5b5050505050505050565b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115614c30578080600190039150508273ffffffffffffffffffffffffffffffffffffffff16600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614b6057614b5f615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015614c16575081600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614c0257614c01615b0f565b5b906000526020600020906002020160010154145b15614c2b57614c258482613fef565b50614c6f565b614ae6565b82826040517f1c6aa71e000000000000000000000000000000000000000000000000000000008152600401614c66929190615a8d565b60405180910390fd5b505050565b6000614c7f83613f02565b905081811015614cc85781816040517f83015a83000000000000000000000000000000000000000000000000000000008152600401614cbf929190615b6d565b60405180910390fd5b6000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050828203816007018190555042816000015414614d2b574281600001819055505b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e985e9c584306040518363ffffffff1660e01b8152600401614d8e929190615dc8565b602060405180830381865afa158015614dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614dcf9190615ae2565b614e3257600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401614e299190615742565b60405180910390fd5b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e85856040518363ffffffff1660e01b8152600401614e8f929190615a8d565b602060405180830381865afa158015614eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ed09190615d0c565b1015614f155781816040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401614f0c929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a843085856040518563ffffffff1660e01b8152600401614f769493929190615d70565b600060405180830381600087803b158015614f9057600080fd5b505af1158015614fa4573d6000803e3d6000fd5b50505050505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614ff681614fc1565b811461500157600080fd5b50565b60008135905061501381614fed565b92915050565b60006020828403121561502f5761502e614fb7565b5b600061503d84828501615004565b91505092915050565b60008115159050919050565b61505b81615046565b82525050565b60006020820190506150766000830184615052565b92915050565b6000819050919050565b61508f8161507c565b811461509a57600080fd5b50565b6000813590506150ac81615086565b92915050565b6000602082840312156150c8576150c7614fb7565b5b60006150d68482850161509d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061510a826150df565b9050919050565b61511a816150ff565b811461512557600080fd5b50565b60008135905061513781615111565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126151625761516161513d565b5b8235905067ffffffffffffffff81111561517f5761517e615142565b5b60208301915083600182028301111561519b5761519a615147565b5b9250929050565b6000806000806000608086880312156151be576151bd614fb7565b5b60006151cc88828901615128565b95505060206151dd88828901615128565b94505060406151ee8882890161509d565b935050606086013567ffffffffffffffff81111561520f5761520e614fbc565b5b61521b8882890161514c565b92509250509295509295909350565b61523381614fc1565b82525050565b600060208201905061524e600083018461522a565b92915050565b60006020828403121561526a57615269614fb7565b5b600061527884828501615128565b91505092915050565b61528a8161507c565b82525050565b60006020820190506152a56000830184615281565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6152e0816150ff565b82525050565b6152ef8161507c565b82525050565b60408201600082015161530b60008501826152d7565b50602082015161531e60208501826152e6565b50505050565b600061533083836152f5565b60408301905092915050565b6000602082019050919050565b6000615354826152ab565b61535e81856152b6565b9350615369836152c7565b8060005b8381101561539a5781516153818882615324565b975061538c8361533c565b92505060018101905061536d565b5085935050505092915050565b600060208201905081810360008301526153c18184615349565b905092915050565b600060ff82169050919050565b6153df816153c9565b81146153ea57600080fd5b50565b6000813590506153fc816153d6565b92915050565b60006020828403121561541857615417614fb7565b5b6000615426848285016153ed565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6154788261542f565b810181811067ffffffffffffffff8211171561549757615496615440565b5b80604052505050565b60006154aa614fad565b90506154b6828261546f565b919050565b600067ffffffffffffffff8211156154d6576154d5615440565b5b602082029050602081019050919050565b60006154fa6154f5846154bb565b6154a0565b9050808382526020820190506020840283018581111561551d5761551c615147565b5b835b8181101561554657806155328882615128565b84526020840193505060208101905061551f565b5050509392505050565b600082601f8301126155655761556461513d565b5b81356155758482602086016154e7565b91505092915050565b600067ffffffffffffffff82111561559957615598615440565b5b602082029050602081019050919050565b60006155bd6155b88461557e565b6154a0565b905080838252602082019050602084028301858111156155e0576155df615147565b5b835b8181101561560957806155f5888261509d565b8452602084019350506020810190506155e2565b5050509392505050565b600082601f8301126156285761562761513d565b5b81356156388482602086016155aa565b91505092915050565b6000806040838503121561565857615657614fb7565b5b600083013567ffffffffffffffff81111561567657615675614fbc565b5b61568285828601615550565b925050602083013567ffffffffffffffff8111156156a3576156a2614fbc565b5b6156af85828601615613565b9150509250929050565b6000819050919050565b60006156de6156d96156d4846150df565b6156b9565b6150df565b9050919050565b60006156f0826156c3565b9050919050565b6000615702826156e5565b9050919050565b615712816156f7565b82525050565b600060208201905061572d6000830184615709565b92915050565b61573c816150ff565b82525050565b60006020820190506157576000830184615733565b92915050565b600061010082019050615773600083018b615281565b615780602083018a615281565b61578d6040830189615281565b61579a6060830188615281565b6157a76080830187615281565b6157b460a0830186615281565b6157c160c0830185615281565b6157ce60e0830184615281565b9998505050505050505050565b6157e4816153c9565b82525050565b60006020820190506157ff60008301846157db565b92915050565b6000806040838503121561581c5761581b614fb7565b5b600061582a85828601615128565b925050602061583b8582860161509d565b9150509250929050565b6000615850826156e5565b9050919050565b61586081615845565b82525050565b600060208201905061587b6000830184615857565b92915050565b60008083601f8401126158975761589661513d565b5b8235905067ffffffffffffffff8111156158b4576158b3615142565b5b6020830191508360208202830111156158d0576158cf615147565b5b9250929050565b60008060008060008060008060a0898b0312156158f7576158f6614fb7565b5b60006159058b828c01615128565b98505060206159168b828c01615128565b975050604089013567ffffffffffffffff81111561593757615936614fbc565b5b6159438b828c01615881565b9650965050606089013567ffffffffffffffff81111561596657615965614fbc565b5b6159728b828c01615881565b9450945050608089013567ffffffffffffffff81111561599557615994614fbc565b5b6159a18b828c0161514c565b92509250509295985092959890939650565b60008060008060008060a087890312156159d0576159cf614fb7565b5b60006159de89828a01615128565b96505060206159ef89828a01615128565b9550506040615a0089828a0161509d565b9450506060615a1189828a0161509d565b935050608087013567ffffffffffffffff811115615a3257615a31614fbc565b5b615a3e89828a0161514c565b92509250509295509295509295565b60008060408385031215615a6457615a63614fb7565b5b6000615a728582860161509d565b9250506020615a838582860161509d565b9150509250929050565b6000604082019050615aa26000830185615733565b615aaf6020830184615281565b9392505050565b615abf81615046565b8114615aca57600080fd5b50565b600081519050615adc81615ab6565b92915050565b600060208284031215615af857615af7614fb7565b5b6000615b0684828501615acd565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000604082019050615b826000830185615281565b615b8f6020830184615281565b9392505050565b600081519050615ba581615111565b92915050565b600060208284031215615bc157615bc0614fb7565b5b6000615bcf84828501615b96565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000615c128261507c565b9150615c1d8361507c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115615c5257615c51615bd8565b5b828201905092915050565b6000615c688261507c565b9150615c738361507c565b925082821015615c8657615c85615bd8565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000606082019050615cd56000830186615733565b615ce26020830185615733565b615cef6040830184615281565b949350505050565b600081519050615d0681615086565b92915050565b600060208284031215615d2257615d21614fb7565b5b6000615d3084828501615cf7565b91505092915050565b600082825260208201905092915050565b50565b6000615d5a600083615d39565b9150615d6582615d4a565b600082019050919050565b600060a082019050615d856000830187615733565b615d926020830186615733565b615d9f6040830185615281565b615dac6060830184615281565b8181036080830152615dbd81615d4d565b905095945050505050565b6000604082019050615ddd6000830185615733565b615dea6020830184615733565b939250505056fea2646970667358221220e7a2c839e9b2c717561968f8fe3cb67596764f6b032b2490f4369c5512b7a43a64736f6c634300080a0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.