ETH Price: $2,530.07 (-0.10%)

Contract

0x1A1cA9C6484F88CECeD1304dfa558aa0115dE3A8
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Bulk Unstake164101052023-01-15 5:25:47592 days ago1673760347IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0022461217.08067239
Bulk Unstake163515312023-01-07 1:09:47600 days ago1673053787IN
0x1A1cA9C6...0115dE3A8
0 ETH0.001243815.37269971
Set Pause State163515292023-01-07 1:09:23600 days ago1673053763IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0004337315.04607715
Bulk Stake163514942023-01-07 1:02:23600 days ago1673053343IN
0x1A1cA9C6...0115dE3A8
0 ETH0.003153115.33169608
Stake Crystal160879582022-12-01 5:46:47637 days ago1669873607IN
0x1A1cA9C6...0115dE3A8
0 ETH0.001376111.52490467
Bulk Stake160879252022-12-01 5:40:11637 days ago1669873211IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0063465312.10069357
Bulk Stake155989822022-09-23 22:18:11706 days ago1663971491IN
0x1A1cA9C6...0115dE3A8
0 ETH0.00254227.4380233
Bulk Stake155016062022-09-09 7:59:32720 days ago1662710372IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0050998713.08522261
Bulk Stake155005882022-09-09 3:57:11720 days ago1662695831IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0017902610.4243848
Bulk Stake155005222022-09-09 3:42:38720 days ago1662694958IN
0x1A1cA9C6...0115dE3A8
0 ETH0.001921169.8366324
Bulk Stake155004392022-09-09 3:23:06720 days ago1662693786IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0082328312.27008624
Bulk Stake155003302022-09-09 2:52:15720 days ago1662691935IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0026772713.70802328
Bulk Stake155003252022-09-09 2:51:10720 days ago1662691870IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0026099613.3633837
Bulk Stake155002512022-09-09 2:33:35720 days ago1662690815IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0030813813.42047835
Bulk Stake155000052022-09-09 1:40:41720 days ago1662687641IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0038458919.6927478
Bulk Stake154998582022-09-09 1:06:39720 days ago1662685599IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0034894217.86637845
Bulk Stake154998382022-09-09 1:00:43720 days ago1662685243IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0022142911.33749837
Stake Crystal154997492022-09-09 0:37:43720 days ago1662683863IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0014319414.0589475
Bulk Stake154995082022-09-08 23:43:09720 days ago1662680589IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0048943214.31990625
Bulk Stake154995062022-09-08 23:42:17720 days ago1662680537IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0061004511.63149431
Bulk Stake154994632022-09-08 23:34:10720 days ago1662680050IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0139921614.57848315
Bulk Stake154994452022-09-08 23:31:34720 days ago1662679894IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0033501819.47592282
Bulk Stake154992562022-09-08 22:43:57721 days ago1662677037IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0044579822.82552318
Bulk Stake154990932022-09-08 22:08:43721 days ago1662674923IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0796791830.36149502
Bulk Stake154990232022-09-08 21:52:11721 days ago1662673931IN
0x1A1cA9C6...0115dE3A8
0 ETH0.0149346630.84158298
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CCVault

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 9 : CCVault.sol
// 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;
		}
	// **************************************
}

File 2 of 9 : IPausable.sol
// 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 );
		}
		_;
	}
}

File 3 of 9 : IOwnable.sol
// 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_ );
	}
}

File 4 of 9 : IERC1155Receiver.sol
// 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);
}

File 5 of 9 : IERC1155.sol
// 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 );
}

File 6 of 9 : IERC721Receiver.sol
// 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);
}

File 7 of 9 : IERC721.sol
// 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 );
}

File 8 of 9 : Context.sol
// 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;
    }
}

File 9 of 9 : IERC165.sol
// 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);
}

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

Contract Security Audit

Contract ABI

[{"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"}]

60806040523480156200001157600080fd5b506200003262000026620000b560201b60201c565b620000bd60201b60201c565b6703782dace9d90000600181905550662386f26fc1000060028190555067016345785d8a0000600381905550610fa06006600060018152602001908152602001600020819055506109c46006600060028152602001908152602001600020819055506107d060066000600381526020019081526020016000208190555062000100565b600033905090565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b615e2780620001106000396000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c8063afef974f11610182578063e78c6344116100e9578063f6c15160116100a2578063f97d04421161007c578063f97d0442146108b5578063fb6b2f55146108d1578063fcbc4cee146108ed578063fd457d4b14610909576102bb565b8063f6c1516014610861578063f74727f71461087d578063f7e3130c14610899576102bb565b8063e78c63441461077d578063ebfc5b95146107ad578063f1f0849e146107dd578063f23a6e61146107f9578063f248e74914610829578063f2fde38b14610845576102bb565b8063bb03e2971161013b578063bb03e29714610699578063bc197c81146106b5578063c4552791146106e5578063c92b84d014610715578063d2f6a68b14610745578063d6f4054314610761576102bb565b8063afef974f146105eb578063b081fd3014610609578063b0e6e11b14610625578063b13270d514610641578063b78ca4e21461065d578063ba4426fe1461067b576102bb565b806362d10e3f116102265780638511b50d116101df5780638511b50d146105225780638ae86dd41461053e5780638da5cb5b1461055c57806394eecb501461057a5780639a44f1fb146105b15780639c1c97d7146105cf576102bb565b806362d10e3f14610452578063630965091461046e578063643dcac61461048a578063694b04c8146104a657806370a08231146104c257806371ca00d1146104f2576102bb565b806335322f371161027857806335322f37146103a4578063372500ab146103ae578063413ec4a6146103b8578063555e25e8146103e8578063571bdbc81461040457806362875b8414610422576102bb565b806301ffc9a7146102c057806306793849146102f0578063150b7a021461030c578063248c6e4e1461033c5780632bcf161c14610358578063307e6edd14610388575b600080fd5b6102da60048036038101906102d59190615019565b61093a565b6040516102e79190615061565b60405180910390f35b61030a600480360381019061030591906150b2565b610a0c565b005b610326600480360381019061032191906151a2565b610aac565b6040516103339190615239565b60405180910390f35b61035660048036038101906103519190615254565b610ac1565b005b610372600480360381019061036d9190615254565b610b89565b60405161037f9190615290565b60405180910390f35b6103a2600480360381019061039d91906150b2565b610b9b565b005b6103ac610c3b565b005b6103b6610e17565b005b6103d260048036038101906103cd9190615254565b6110a5565b6040516103df9190615061565b60405180910390f35b61040260048036038101906103fd91906150b2565b6110c5565b005b61040c611165565b6040516104199190615290565b60405180910390f35b61043c60048036038101906104379190615254565b61116b565b60405161044991906153a7565b60405180910390f35b61046c60048036038101906104679190615254565b611269565b005b61048860048036038101906104839190615402565b611348565b005b6104a4600480360381019061049f91906150b2565b6113d8565b005b6104c060048036038101906104bb9190615641565b611466565b005b6104dc60048036038101906104d79190615254565b611840565b6040516104e99190615290565b60405180910390f35b61050c600480360381019061050791906150b2565b61188c565b6040516105199190615290565b60405180910390f35b61053c60048036038101906105379190615254565b6118a4565b005b610546611983565b6040516105539190615718565b60405180910390f35b6105646119a9565b6040516105719190615742565b60405180910390f35b610594600480360381019061058f9190615254565b6119d2565b6040516105a898979695949392919061575d565b60405180910390f35b6105b9611a1a565b6040516105c691906157ea565b60405180910390f35b6105e960048036038101906105e49190615805565b611a30565b005b6105f3611ea5565b6040516106009190615290565b60405180910390f35b610623600480360381019061061e9190615805565b611eab565b005b61063f600480360381019061063a9190615254565b6120c1565b005b61065b60048036038101906106569190615805565b6121a0565b005b6106656124d7565b6040516106729190615866565b60405180910390f35b6106836124fd565b6040516106909190615290565b60405180910390f35b6106b360048036038101906106ae9190615641565b612503565b005b6106cf60048036038101906106ca91906158d7565b612a69565b6040516106dc9190615239565b60405180910390f35b6106ff60048036038101906106fa9190615254565b612a81565b60405161070c9190615742565b60405180910390f35b61072f600480360381019061072a9190615254565b612a8b565b60405161073c9190615290565b60405180910390f35b61075f600480360381019061075a9190615254565b612c82565b005b61077b600480360381019061077691906150b2565b612d61565b005b61079760048036038101906107929190615254565b612e03565b6040516107a49190615061565b60405180910390f35b6107c760048036038101906107c29190615254565b612e23565b6040516107d49190615061565b60405180910390f35b6107f760048036038101906107f29190615254565b612e43565b005b610813600480360381019061080e91906159b3565b61341e565b6040516108209190615239565b60405180910390f35b610843600480360381019061083e9190615254565b613434565b005b61085f600480360381019061085a9190615254565b613513565b005b61087b60048036038101906108769190615254565b61365b565b005b610897600480360381019061089291906150b2565b61373a565b005b6108b360048036038101906108ae9190615a4d565b6137c8565b005b6108cf60048036038101906108ca91906150b2565b613a1b565b005b6108eb60048036038101906108e69190615a4d565b613aa9565b005b61090760048036038101906109029190615254565b613dd1565b005b610923600480360381019061091e9190615805565b613e99565b604051610931929190615a8d565b60405180910390f35b60007f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a0557507f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000610a16613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610a376119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610a8f57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610a869190615742565b60405180910390fd5b816006600060028152602001908152602001600020819055505050565b600063150b7a0260e01b905095945050505050565b6000610acb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610aec6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610b4457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610b3b9190615742565b60405180910390fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000610b9482613f02565b9050919050565b6000610ba5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610bc66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610c1e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610c159190615742565b60405180910390fd5b816006600060038152602001908152602001600020819055505050565b600160ff16600060149054906101000a900460ff1660ff1614610ca457600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401610c9b91906157ea565b60405180910390fd5b6000610cae613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610d3d57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610d349190615742565b60405180910390fd5b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115610da657808060019003915050610da18382613fef565b610d85565b600082600201541115610dc457610dc38360018460020154614474565b5b600082600301541115610de257610de18360028460030154614474565b5b600082600401541115610e0057610dff8360038460040154614474565b5b610e12836000806000806000806145ef565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401610e729190615742565b602060405180830381865afa158015610e8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb39190615ae2565b610f1657600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401610f0d9190615742565b60405180910390fd5b6000610f20613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610faf57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610fa69190615742565b60405180910390fd5b610fb8826146c3565b600081600701549050600081141561100757826040517f107024af000000000000000000000000000000000000000000000000000000008152600401610ffe9190615742565b60405180910390fd5b60008260070181905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084836040518363ffffffff1660e01b815260040161106e929190615a8d565b600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50505050505050565b600a6020528060005260406000206000915054906101000a900460ff1681565b60006110cf613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166110f06119a9565b73ffffffffffffffffffffffffffffffffffffffff161461114857806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161113f9190615742565b60405180910390fd5b816006600060018152602001908152602001600020819055505050565b60015481565b6060600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561125e57838290600052602060002090600202016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481525050815260200190600101906111cc565b505050509050919050565b6000611273613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166112946119a9565b73ffffffffffffffffffffffffffffffffffffffff16146112ec57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016112e39190615742565b60405180910390fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000611352613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166113736119a9565b73ffffffffffffffffffffffffffffffffffffffff16146113cb57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016113c29190615742565b60405180910390fd5b6113d482614730565b5050565b60006113e2613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166114036119a9565b73ffffffffffffffffffffffffffffffffffffffff161461145b57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016114529190615742565b60405180910390fd5b816003819055505050565b600082519050815181146114a6576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114b0613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b600088111561182557878060019003985050600960008b8a8151811061168657611685615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156116e85785806001019650506117e1565b600a60008b8a815181106116ff576116fe615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117615781806001019250506117e0565b600b60008b8a8151811061177857611777615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117da5780806001019150506117df565b61165d565b5b5b611820878b8a815181106117f8576117f7615b0f565b5b60200260200101518b8b8151811061181357611812615b0f565b5b6020026020010151614796565b61165d565b611834878787878787876145ef565b50505050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b60066020528060005260406000206000915090505481565b60006118ae613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166118cf6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461192757806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161191e9190615742565b60405180910390fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60076020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154905088565b60008060149054906101000a900460ff16905090565b600160ff16600060149054906101000a900460ff1660ff1614611a9957600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401611a9091906157ea565b60405180910390fd5b6000611aa3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611cf5576000861415611ce757886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611cde9190615742565b60405180910390fd5b858060019003965050611e80565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611d9b576000821415611d8d57886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611d849190615742565b60405180910390fd5b818060019003925050611e7f565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e41576000811415611e3357886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611e2a9190615742565b60405180910390fd5b808060019003915050611e7e565b886040517f71c52b1d000000000000000000000000000000000000000000000000000000008152600401611e759190615742565b60405180910390fd5b5b5b611e8b878a8a614a9e565b611e9a878787878787876145ef565b505050505050505050565b60035481565b6000611eb5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16611ed66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614611f2e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401611f259190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401611f899190615742565b602060405180830381865afa158015611fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fca9190615ae2565b61202d57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de0000000000000000000000000000000000000000000000000000000081526004016120249190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084846040518363ffffffff1660e01b815260040161208a929190615a8d565b600060405180830381600087803b1580156120a457600080fd5b505af11580156120b8573d6000803e3d6000fd5b50505050505050565b60006120cb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166120ec6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461214457806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161213b9190615742565b60405180910390fd5b6001600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60006121aa613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156123b55785806001019650506124b2565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124145781806001019250506124b1565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124735780806001019150506124b0565b886040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016124a79190615742565b60405180910390fd5b5b5b6124bd878a8a614796565b6124cc878787878787876145ef565b505050505050505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b600160ff16600060149054906101000a900460ff1660ff161461256c57600060149054906101000a900460ff166040517f81d1489b00000000000000000000000000000000000000000000000000000000815260040161256391906157ea565b60405180910390fd5b600082519050815181146125ac576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006125b6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b6000881115612a4e57878060019003985050600960008b8a8151811061278c5761278b615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561284f576000861415612841578988815181106127fd576127fc615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016128389190615742565b60405180910390fd5b858060019003965050612a0a565b600a60008b8a8151811061286657612865615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561292957600082141561291b578988815181106128d7576128d6615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129129190615742565b60405180910390fd5b818060019003925050612a09565b600b60008b8a815181106129405761293f615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a035760008114156129f5578988815181106129b1576129b0615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129ec9190615742565b60405180910390fd5b808060019003915050612a08565b612763565b5b5b612a49878b8a81518110612a2157612a20615b0f565b5b60200260200101518b8b81518110612a3c57612a3b615b0f565b5b6020026020010151614a9e565b612763565b612a5d878787878787876145ef565b50505050505050505050565b600063bc197c8160e01b905098975050505050505050565b6000309050919050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600201549050600082600301549050600083600401549050600080856001015490505b6000811115612c34578080600190039150506000851115612b6057620151806103e860066000600181526020019081526020016000205481612b3a57612b39615b3e565b5b046001540281612b4d57612b4c615b3e565b5b0482019150848060019003955050612c2f565b6000841115612bb957620151806103e860066000600281526020019081526020016000205481612b9357612b92615b3e565b5b046001540281612ba657612ba5615b3e565b5b0482019150838060019003945050612c2e565b6000831115612c1257620151806103e860066000600381526020019081526020016000205481612bec57612beb615b3e565b5b046001540281612bff57612bfe615b3e565b5b0482019150828060019003935050612c2d565b6201518060015481612c2757612c26615b3e565b5b04820191505b5b5b612af5565b6201518086600501546002540281612c4f57612c4e615b3e565b5b04820191506201518086600601546003540281612c6f57612c6e615b3e565b5b0482019150819650505050505050919050565b6000612c8c613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16612cad6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614612d0557806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401612cfc9190615742565b60405180910390fd5b6001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000612d6b613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612df557806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612dec9190615742565b60405180910390fd5b612dff8183614c74565b5050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b600160ff16600060149054906101000a900460ff1660ff1614612eac57600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401612ea391906157ea565b60405180910390fd5b6000612eb6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612f4057806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612f379190615742565b60405180910390fd5b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614156131935760008511156131565761315587600187614474565b5b600084111561316c5761316b87600286614474565b5b60008311156131825761318187600385614474565b5b600094506000935060009250613405565b600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156131ee57600095506132e3565b600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561324957600091506132e2565b600b60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156132a457600090506132e1565b876040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016132d89190615742565b60405180910390fd5b5b5b6000600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115613403578080600190039150508873ffffffffffffffffffffffffffffffffffffffff16600860008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106133a5576133a4615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133fe576133fd8882613fef565b5b61332b565b505b613414878787878787876145ef565b5050505050505050565b600063f23a6e6160e01b90509695505050505050565b600061343e613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661345f6119a9565b73ffffffffffffffffffffffffffffffffffffffff16146134b757806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016134ae9190615742565b60405180910390fd5b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600061351d613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661353e6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461359657806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161358d9190615742565b60405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000613665613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166136866119a9565b73ffffffffffffffffffffffffffffffffffffffff16146136de57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016136d59190615742565b60405180910390fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000613744613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166137656119a9565b73ffffffffffffffffffffffffffffffffffffffff16146137bd57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016137b49190615742565b60405180910390fd5b816001819055505050565b60006137d2613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060060154905060018914156139915787850194506139f6565b60028914156139a45787840193506139f5565b60038914156139b75787830192506139f4565b886040517ffb59b93f0000000000000000000000000000000000000000000000000000000081526004016139eb9190615290565b60405180910390fd5b5b5b613a01878a8a614d31565b613a10878787878787876145ef565b505050505050505050565b6000613a25613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613a466119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613a9e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613a959190615742565b60405180910390fd5b816002819055505050565b6000613ab3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490506001891415613cb95787851015613caf5788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613ca6929190615b6d565b60405180910390fd5b8785039450613dac565b6002891415613d135787841015613d095788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d00929190615b6d565b60405180910390fd5b8784039350613dab565b6003891415613d6d5787831015613d635788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d5a929190615b6d565b60405180910390fd5b8783039250613daa565b886040517ffb59b93f000000000000000000000000000000000000000000000000000000008152600401613da19190615290565b60405180910390fd5b5b5b613db7878a8a614474565b613dc6878787878787876145ef565b505050505050505050565b6000613ddb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613dfc6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613e5457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613e4b9190615742565b60405180910390fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60086020528160005260406000208181548110613eb557600080fd5b9060005260206000209060020201600091509150508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b600033905090565b6000806000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806101000160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152505090506000816000015114613fe5576000808260e0015193508260000151421115613fe25782600001514203915081613fd987612a8b565b02905080840193505b50505b8192505050919050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811061408957614088615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002084815481106141105761410f615b0f565b5b906000526020600020906002020160010154905060008290503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016141799190615290565b602060405180830381865afa158015614196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ba9190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146142145782826040517f1c6aa71e00000000000000000000000000000000000000000000000000000000815260040161420b929190615a8d565b60405180910390fd5b836001866142229190615c07565b1461436657600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001856142739190615c5d565b8154811061428457614283615b0f565b5b9060005260206000209060020201600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002086815481106142e3576142e2615b0f565b5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600182015481600101559050505b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806143b5576143b4615c91565b5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055505090558073ffffffffffffffffffffffffffffffffffffffff166323b872dd3088856040518463ffffffff1660e01b815260040161443a93929190615cc0565b600060405180830381600087803b15801561445457600080fd5b505af1158015614468573d6000803e3d6000fd5b50505050505050505050565b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e30856040518363ffffffff1660e01b81526004016144d1929190615a8d565b602060405180830381865afa1580156144ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145129190615d0c565b10156145575781816040517f403f7b3e00000000000000000000000000000000000000000000000000000000815260040161454e929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a308585856040518563ffffffff1660e01b81526004016145b89493929190615d70565b600060405180830381600087803b1580156145d257600080fd5b505af11580156145e6573d6000803e3d6000fd5b50505050505050565b6000600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905086816001015414614647578681600101819055505b8581600201541461465c578581600201819055505b84816003015414614671578481600301819055505b83816004015414614686578381600401819055505b8281600501541461469b578281600501819055505b818160060154146146b0578181600601819055505b6146b9886146c3565b5050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061470f82613f02565b81600701819055504281600001541461472c574281600001819055505b5050565b60008060149054906101000a900460ff16905081600060146101000a81548160ff021916908360ff1602179055508160ff168160ff167f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe460405160405180910390a35050565b60008290508073ffffffffffffffffffffffffffffffffffffffff1663e985e9c585306040518363ffffffff1660e01b81526004016147d6929190615dc8565b602060405180830381865afa1580156147f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148179190615ae2565b61485857826040517fd640e7de00000000000000000000000000000000000000000000000000000000815260040161484f9190615742565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016148a89190615290565b602060405180830381865afa1580156148c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e99190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146149435782826040517f8d4affb800000000000000000000000000000000000000000000000000000000815260040161493a929190615a8d565b60405180910390fd5b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052808573ffffffffffffffffffffffffffffffffffffffff16815260200184815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015550508073ffffffffffffffffffffffffffffffffffffffff166323b872dd8530856040518463ffffffff1660e01b8152600401614a6693929190615cc0565b600060405180830381600087803b158015614a8057600080fd5b505af1158015614a94573d6000803e3d6000fd5b5050505050505050565b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115614c30578080600190039150508273ffffffffffffffffffffffffffffffffffffffff16600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614b6057614b5f615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015614c16575081600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614c0257614c01615b0f565b5b906000526020600020906002020160010154145b15614c2b57614c258482613fef565b50614c6f565b614ae6565b82826040517f1c6aa71e000000000000000000000000000000000000000000000000000000008152600401614c66929190615a8d565b60405180910390fd5b505050565b6000614c7f83613f02565b905081811015614cc85781816040517f83015a83000000000000000000000000000000000000000000000000000000008152600401614cbf929190615b6d565b60405180910390fd5b6000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050828203816007018190555042816000015414614d2b574281600001819055505b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e985e9c584306040518363ffffffff1660e01b8152600401614d8e929190615dc8565b602060405180830381865afa158015614dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614dcf9190615ae2565b614e3257600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401614e299190615742565b60405180910390fd5b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e85856040518363ffffffff1660e01b8152600401614e8f929190615a8d565b602060405180830381865afa158015614eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ed09190615d0c565b1015614f155781816040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401614f0c929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a843085856040518563ffffffff1660e01b8152600401614f769493929190615d70565b600060405180830381600087803b158015614f9057600080fd5b505af1158015614fa4573d6000803e3d6000fd5b50505050505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614ff681614fc1565b811461500157600080fd5b50565b60008135905061501381614fed565b92915050565b60006020828403121561502f5761502e614fb7565b5b600061503d84828501615004565b91505092915050565b60008115159050919050565b61505b81615046565b82525050565b60006020820190506150766000830184615052565b92915050565b6000819050919050565b61508f8161507c565b811461509a57600080fd5b50565b6000813590506150ac81615086565b92915050565b6000602082840312156150c8576150c7614fb7565b5b60006150d68482850161509d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061510a826150df565b9050919050565b61511a816150ff565b811461512557600080fd5b50565b60008135905061513781615111565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126151625761516161513d565b5b8235905067ffffffffffffffff81111561517f5761517e615142565b5b60208301915083600182028301111561519b5761519a615147565b5b9250929050565b6000806000806000608086880312156151be576151bd614fb7565b5b60006151cc88828901615128565b95505060206151dd88828901615128565b94505060406151ee8882890161509d565b935050606086013567ffffffffffffffff81111561520f5761520e614fbc565b5b61521b8882890161514c565b92509250509295509295909350565b61523381614fc1565b82525050565b600060208201905061524e600083018461522a565b92915050565b60006020828403121561526a57615269614fb7565b5b600061527884828501615128565b91505092915050565b61528a8161507c565b82525050565b60006020820190506152a56000830184615281565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6152e0816150ff565b82525050565b6152ef8161507c565b82525050565b60408201600082015161530b60008501826152d7565b50602082015161531e60208501826152e6565b50505050565b600061533083836152f5565b60408301905092915050565b6000602082019050919050565b6000615354826152ab565b61535e81856152b6565b9350615369836152c7565b8060005b8381101561539a5781516153818882615324565b975061538c8361533c565b92505060018101905061536d565b5085935050505092915050565b600060208201905081810360008301526153c18184615349565b905092915050565b600060ff82169050919050565b6153df816153c9565b81146153ea57600080fd5b50565b6000813590506153fc816153d6565b92915050565b60006020828403121561541857615417614fb7565b5b6000615426848285016153ed565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6154788261542f565b810181811067ffffffffffffffff8211171561549757615496615440565b5b80604052505050565b60006154aa614fad565b90506154b6828261546f565b919050565b600067ffffffffffffffff8211156154d6576154d5615440565b5b602082029050602081019050919050565b60006154fa6154f5846154bb565b6154a0565b9050808382526020820190506020840283018581111561551d5761551c615147565b5b835b8181101561554657806155328882615128565b84526020840193505060208101905061551f565b5050509392505050565b600082601f8301126155655761556461513d565b5b81356155758482602086016154e7565b91505092915050565b600067ffffffffffffffff82111561559957615598615440565b5b602082029050602081019050919050565b60006155bd6155b88461557e565b6154a0565b905080838252602082019050602084028301858111156155e0576155df615147565b5b835b8181101561560957806155f5888261509d565b8452602084019350506020810190506155e2565b5050509392505050565b600082601f8301126156285761562761513d565b5b81356156388482602086016155aa565b91505092915050565b6000806040838503121561565857615657614fb7565b5b600083013567ffffffffffffffff81111561567657615675614fbc565b5b61568285828601615550565b925050602083013567ffffffffffffffff8111156156a3576156a2614fbc565b5b6156af85828601615613565b9150509250929050565b6000819050919050565b60006156de6156d96156d4846150df565b6156b9565b6150df565b9050919050565b60006156f0826156c3565b9050919050565b6000615702826156e5565b9050919050565b615712816156f7565b82525050565b600060208201905061572d6000830184615709565b92915050565b61573c816150ff565b82525050565b60006020820190506157576000830184615733565b92915050565b600061010082019050615773600083018b615281565b615780602083018a615281565b61578d6040830189615281565b61579a6060830188615281565b6157a76080830187615281565b6157b460a0830186615281565b6157c160c0830185615281565b6157ce60e0830184615281565b9998505050505050505050565b6157e4816153c9565b82525050565b60006020820190506157ff60008301846157db565b92915050565b6000806040838503121561581c5761581b614fb7565b5b600061582a85828601615128565b925050602061583b8582860161509d565b9150509250929050565b6000615850826156e5565b9050919050565b61586081615845565b82525050565b600060208201905061587b6000830184615857565b92915050565b60008083601f8401126158975761589661513d565b5b8235905067ffffffffffffffff8111156158b4576158b3615142565b5b6020830191508360208202830111156158d0576158cf615147565b5b9250929050565b60008060008060008060008060a0898b0312156158f7576158f6614fb7565b5b60006159058b828c01615128565b98505060206159168b828c01615128565b975050604089013567ffffffffffffffff81111561593757615936614fbc565b5b6159438b828c01615881565b9650965050606089013567ffffffffffffffff81111561596657615965614fbc565b5b6159728b828c01615881565b9450945050608089013567ffffffffffffffff81111561599557615994614fbc565b5b6159a18b828c0161514c565b92509250509295985092959890939650565b60008060008060008060a087890312156159d0576159cf614fb7565b5b60006159de89828a01615128565b96505060206159ef89828a01615128565b9550506040615a0089828a0161509d565b9450506060615a1189828a0161509d565b935050608087013567ffffffffffffffff811115615a3257615a31614fbc565b5b615a3e89828a0161514c565b92509250509295509295509295565b60008060408385031215615a6457615a63614fb7565b5b6000615a728582860161509d565b9250506020615a838582860161509d565b9150509250929050565b6000604082019050615aa26000830185615733565b615aaf6020830184615281565b9392505050565b615abf81615046565b8114615aca57600080fd5b50565b600081519050615adc81615ab6565b92915050565b600060208284031215615af857615af7614fb7565b5b6000615b0684828501615acd565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000604082019050615b826000830185615281565b615b8f6020830184615281565b9392505050565b600081519050615ba581615111565b92915050565b600060208284031215615bc157615bc0614fb7565b5b6000615bcf84828501615b96565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000615c128261507c565b9150615c1d8361507c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115615c5257615c51615bd8565b5b828201905092915050565b6000615c688261507c565b9150615c738361507c565b925082821015615c8657615c85615bd8565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000606082019050615cd56000830186615733565b615ce26020830185615733565b615cef6040830184615281565b949350505050565b600081519050615d0681615086565b92915050565b600060208284031215615d2257615d21614fb7565b5b6000615d3084828501615cf7565b91505092915050565b600082825260208201905092915050565b50565b6000615d5a600083615d39565b9150615d6582615d4a565b600082019050919050565b600060a082019050615d856000830187615733565b615d926020830186615733565b615d9f6040830185615281565b615dac6060830184615281565b8181036080830152615dbd81615d4d565b905095945050505050565b6000604082019050615ddd6000830185615733565b615dea6020830184615733565b939250505056fea2646970667358221220e7a2c839e9b2c717561968f8fe3cb67596764f6b032b2490f4369c5512b7a43a64736f6c634300080a0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c8063afef974f11610182578063e78c6344116100e9578063f6c15160116100a2578063f97d04421161007c578063f97d0442146108b5578063fb6b2f55146108d1578063fcbc4cee146108ed578063fd457d4b14610909576102bb565b8063f6c1516014610861578063f74727f71461087d578063f7e3130c14610899576102bb565b8063e78c63441461077d578063ebfc5b95146107ad578063f1f0849e146107dd578063f23a6e61146107f9578063f248e74914610829578063f2fde38b14610845576102bb565b8063bb03e2971161013b578063bb03e29714610699578063bc197c81146106b5578063c4552791146106e5578063c92b84d014610715578063d2f6a68b14610745578063d6f4054314610761576102bb565b8063afef974f146105eb578063b081fd3014610609578063b0e6e11b14610625578063b13270d514610641578063b78ca4e21461065d578063ba4426fe1461067b576102bb565b806362d10e3f116102265780638511b50d116101df5780638511b50d146105225780638ae86dd41461053e5780638da5cb5b1461055c57806394eecb501461057a5780639a44f1fb146105b15780639c1c97d7146105cf576102bb565b806362d10e3f14610452578063630965091461046e578063643dcac61461048a578063694b04c8146104a657806370a08231146104c257806371ca00d1146104f2576102bb565b806335322f371161027857806335322f37146103a4578063372500ab146103ae578063413ec4a6146103b8578063555e25e8146103e8578063571bdbc81461040457806362875b8414610422576102bb565b806301ffc9a7146102c057806306793849146102f0578063150b7a021461030c578063248c6e4e1461033c5780632bcf161c14610358578063307e6edd14610388575b600080fd5b6102da60048036038101906102d59190615019565b61093a565b6040516102e79190615061565b60405180910390f35b61030a600480360381019061030591906150b2565b610a0c565b005b610326600480360381019061032191906151a2565b610aac565b6040516103339190615239565b60405180910390f35b61035660048036038101906103519190615254565b610ac1565b005b610372600480360381019061036d9190615254565b610b89565b60405161037f9190615290565b60405180910390f35b6103a2600480360381019061039d91906150b2565b610b9b565b005b6103ac610c3b565b005b6103b6610e17565b005b6103d260048036038101906103cd9190615254565b6110a5565b6040516103df9190615061565b60405180910390f35b61040260048036038101906103fd91906150b2565b6110c5565b005b61040c611165565b6040516104199190615290565b60405180910390f35b61043c60048036038101906104379190615254565b61116b565b60405161044991906153a7565b60405180910390f35b61046c60048036038101906104679190615254565b611269565b005b61048860048036038101906104839190615402565b611348565b005b6104a4600480360381019061049f91906150b2565b6113d8565b005b6104c060048036038101906104bb9190615641565b611466565b005b6104dc60048036038101906104d79190615254565b611840565b6040516104e99190615290565b60405180910390f35b61050c600480360381019061050791906150b2565b61188c565b6040516105199190615290565b60405180910390f35b61053c60048036038101906105379190615254565b6118a4565b005b610546611983565b6040516105539190615718565b60405180910390f35b6105646119a9565b6040516105719190615742565b60405180910390f35b610594600480360381019061058f9190615254565b6119d2565b6040516105a898979695949392919061575d565b60405180910390f35b6105b9611a1a565b6040516105c691906157ea565b60405180910390f35b6105e960048036038101906105e49190615805565b611a30565b005b6105f3611ea5565b6040516106009190615290565b60405180910390f35b610623600480360381019061061e9190615805565b611eab565b005b61063f600480360381019061063a9190615254565b6120c1565b005b61065b60048036038101906106569190615805565b6121a0565b005b6106656124d7565b6040516106729190615866565b60405180910390f35b6106836124fd565b6040516106909190615290565b60405180910390f35b6106b360048036038101906106ae9190615641565b612503565b005b6106cf60048036038101906106ca91906158d7565b612a69565b6040516106dc9190615239565b60405180910390f35b6106ff60048036038101906106fa9190615254565b612a81565b60405161070c9190615742565b60405180910390f35b61072f600480360381019061072a9190615254565b612a8b565b60405161073c9190615290565b60405180910390f35b61075f600480360381019061075a9190615254565b612c82565b005b61077b600480360381019061077691906150b2565b612d61565b005b61079760048036038101906107929190615254565b612e03565b6040516107a49190615061565b60405180910390f35b6107c760048036038101906107c29190615254565b612e23565b6040516107d49190615061565b60405180910390f35b6107f760048036038101906107f29190615254565b612e43565b005b610813600480360381019061080e91906159b3565b61341e565b6040516108209190615239565b60405180910390f35b610843600480360381019061083e9190615254565b613434565b005b61085f600480360381019061085a9190615254565b613513565b005b61087b60048036038101906108769190615254565b61365b565b005b610897600480360381019061089291906150b2565b61373a565b005b6108b360048036038101906108ae9190615a4d565b6137c8565b005b6108cf60048036038101906108ca91906150b2565b613a1b565b005b6108eb60048036038101906108e69190615a4d565b613aa9565b005b61090760048036038101906109029190615254565b613dd1565b005b610923600480360381019061091e9190615805565b613e99565b604051610931929190615a8d565b60405180910390f35b60007f150b7a02000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a0557507f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000610a16613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610a376119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610a8f57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610a869190615742565b60405180910390fd5b816006600060028152602001908152602001600020819055505050565b600063150b7a0260e01b905095945050505050565b6000610acb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610aec6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610b4457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610b3b9190615742565b60405180910390fd5b81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000610b9482613f02565b9050919050565b6000610ba5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16610bc66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614610c1e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401610c159190615742565b60405180910390fd5b816006600060038152602001908152602001600020819055505050565b600160ff16600060149054906101000a900460ff1660ff1614610ca457600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401610c9b91906157ea565b60405180910390fd5b6000610cae613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610d3d57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610d349190615742565b60405180910390fd5b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115610da657808060019003915050610da18382613fef565b610d85565b600082600201541115610dc457610dc38360018460020154614474565b5b600082600301541115610de257610de18360028460030154614474565b5b600082600401541115610e0057610dff8360038460040154614474565b5b610e12836000806000806000806145ef565b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401610e729190615742565b602060405180830381865afa158015610e8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb39190615ae2565b610f1657600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401610f0d9190615742565b60405180910390fd5b6000610f20613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600001541415610faf57816040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401610fa69190615742565b60405180910390fd5b610fb8826146c3565b600081600701549050600081141561100757826040517f107024af000000000000000000000000000000000000000000000000000000008152600401610ffe9190615742565b60405180910390fd5b60008260070181905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084836040518363ffffffff1660e01b815260040161106e929190615a8d565b600060405180830381600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b50505050505050565b600a6020528060005260406000206000915054906101000a900460ff1681565b60006110cf613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166110f06119a9565b73ffffffffffffffffffffffffffffffffffffffff161461114857806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161113f9190615742565b60405180910390fd5b816006600060018152602001908152602001600020819055505050565b60015481565b6060600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561125e57838290600052602060002090600202016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481525050815260200190600101906111cc565b505050509050919050565b6000611273613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166112946119a9565b73ffffffffffffffffffffffffffffffffffffffff16146112ec57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016112e39190615742565b60405180910390fd5b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000611352613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166113736119a9565b73ffffffffffffffffffffffffffffffffffffffff16146113cb57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016113c29190615742565b60405180910390fd5b6113d482614730565b5050565b60006113e2613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166114036119a9565b73ffffffffffffffffffffffffffffffffffffffff161461145b57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016114529190615742565b60405180910390fd5b816003819055505050565b600082519050815181146114a6576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114b0613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b600088111561182557878060019003985050600960008b8a8151811061168657611685615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156116e85785806001019650506117e1565b600a60008b8a815181106116ff576116fe615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117615781806001019250506117e0565b600b60008b8a8151811061177857611777615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117da5780806001019150506117df565b61165d565b5b5b611820878b8a815181106117f8576117f7615b0f565b5b60200260200101518b8b8151811061181357611812615b0f565b5b6020026020010151614796565b61165d565b611834878787878787876145ef565b50505050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b60066020528060005260406000206000915090505481565b60006118ae613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166118cf6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461192757806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161191e9190615742565b60405180910390fd5b6001600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60076020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154905088565b60008060149054906101000a900460ff16905090565b600160ff16600060149054906101000a900460ff1660ff1614611a9957600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401611a9091906157ea565b60405180910390fd5b6000611aa3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611cf5576000861415611ce757886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611cde9190615742565b60405180910390fd5b858060019003965050611e80565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611d9b576000821415611d8d57886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611d849190615742565b60405180910390fd5b818060019003925050611e7f565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e41576000811415611e3357886040517f94ce624b000000000000000000000000000000000000000000000000000000008152600401611e2a9190615742565b60405180910390fd5b808060019003915050611e7e565b886040517f71c52b1d000000000000000000000000000000000000000000000000000000008152600401611e759190615742565b60405180910390fd5b5b5b611e8b878a8a614a9e565b611e9a878787878787876145ef565b505050505050505050565b60035481565b6000611eb5613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16611ed66119a9565b73ffffffffffffffffffffffffffffffffffffffff1614611f2e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401611f259190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166329710388306040518263ffffffff1660e01b8152600401611f899190615742565b602060405180830381865afa158015611fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fca9190615ae2565b61202d57600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de0000000000000000000000000000000000000000000000000000000081526004016120249190615742565b60405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631f471ad084846040518363ffffffff1660e01b815260040161208a929190615a8d565b600060405180830381600087803b1580156120a457600080fd5b505af11580156120b8573d6000803e3d6000fd5b50505050505050565b60006120cb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166120ec6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461214457806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161213b9190615742565b60405180910390fd5b6001600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60006121aa613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156123b55785806001019650506124b2565b600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124145781806001019250506124b1565b600b60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156124735780806001019150506124b0565b886040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016124a79190615742565b60405180910390fd5b5b5b6124bd878a8a614796565b6124cc878787878787876145ef565b505050505050505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b600160ff16600060149054906101000a900460ff1660ff161461256c57600060149054906101000a900460ff166040517f81d1489b00000000000000000000000000000000000000000000000000000000815260040161256391906157ea565b60405180910390fd5b600082519050815181146125ac576040517fd2d280ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006125b6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490505b6000881115612a4e57878060019003985050600960008b8a8151811061278c5761278b615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561284f576000861415612841578988815181106127fd576127fc615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016128389190615742565b60405180910390fd5b858060019003965050612a0a565b600a60008b8a8151811061286657612865615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561292957600082141561291b578988815181106128d7576128d6615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129129190615742565b60405180910390fd5b818060019003925050612a09565b600b60008b8a815181106129405761293f615b0f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a035760008114156129f5578988815181106129b1576129b0615b0f565b5b60200260200101516040517f94ce624b0000000000000000000000000000000000000000000000000000000081526004016129ec9190615742565b60405180910390fd5b808060019003915050612a08565b612763565b5b5b612a49878b8a81518110612a2157612a20615b0f565b5b60200260200101518b8b81518110612a3c57612a3b615b0f565b5b6020026020010151614a9e565b612763565b612a5d878787878787876145ef565b50505050505050505050565b600063bc197c8160e01b905098975050505050505050565b6000309050919050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600081600201549050600082600301549050600083600401549050600080856001015490505b6000811115612c34578080600190039150506000851115612b6057620151806103e860066000600181526020019081526020016000205481612b3a57612b39615b3e565b5b046001540281612b4d57612b4c615b3e565b5b0482019150848060019003955050612c2f565b6000841115612bb957620151806103e860066000600281526020019081526020016000205481612b9357612b92615b3e565b5b046001540281612ba657612ba5615b3e565b5b0482019150838060019003945050612c2e565b6000831115612c1257620151806103e860066000600381526020019081526020016000205481612bec57612beb615b3e565b5b046001540281612bff57612bfe615b3e565b5b0482019150828060019003935050612c2d565b6201518060015481612c2757612c26615b3e565b5b04820191505b5b5b612af5565b6201518086600501546002540281612c4f57612c4e615b3e565b5b04820191506201518086600601546003540281612c6f57612c6e615b3e565b5b0482019150819650505050505050919050565b6000612c8c613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16612cad6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614612d0557806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401612cfc9190615742565b60405180910390fd5b6001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000612d6b613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612df557806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612dec9190615742565b60405180910390fd5b612dff8183614c74565b5050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900460ff1681565b600160ff16600060149054906101000a900460ff1660ff1614612eac57600060149054906101000a900460ff166040517f81d1489b000000000000000000000000000000000000000000000000000000008152600401612ea391906157ea565b60405180910390fd5b6000612eb6613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001541415612f4057806040517fbc7696d3000000000000000000000000000000000000000000000000000000008152600401612f379190615742565b60405180910390fd5b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614156131935760008511156131565761315587600187614474565b5b600084111561316c5761316b87600286614474565b5b60008311156131825761318187600385614474565b5b600094506000935060009250613405565b600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156131ee57600095506132e3565b600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561324957600091506132e2565b600b60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156132a457600090506132e1565b876040517f71c52b1d0000000000000000000000000000000000000000000000000000000081526004016132d89190615742565b60405180910390fd5b5b5b6000600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115613403578080600190039150508873ffffffffffffffffffffffffffffffffffffffff16600860008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106133a5576133a4615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156133fe576133fd8882613fef565b5b61332b565b505b613414878787878787876145ef565b5050505050505050565b600063f23a6e6160e01b90509695505050505050565b600061343e613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661345f6119a9565b73ffffffffffffffffffffffffffffffffffffffff16146134b757806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016134ae9190615742565b60405180910390fd5b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600061351d613efa565b90508073ffffffffffffffffffffffffffffffffffffffff1661353e6119a9565b73ffffffffffffffffffffffffffffffffffffffff161461359657806040517fb4f195e600000000000000000000000000000000000000000000000000000000815260040161358d9190615742565b60405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6000613665613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166136866119a9565b73ffffffffffffffffffffffffffffffffffffffff16146136de57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016136d59190615742565b60405180910390fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000613744613efa565b90508073ffffffffffffffffffffffffffffffffffffffff166137656119a9565b73ffffffffffffffffffffffffffffffffffffffff16146137bd57806040517fb4f195e60000000000000000000000000000000000000000000000000000000081526004016137b49190615742565b60405180910390fd5b816001819055505050565b60006137d2613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060060154905060018914156139915787850194506139f6565b60028914156139a45787840193506139f5565b60038914156139b75787830192506139f4565b886040517ffb59b93f0000000000000000000000000000000000000000000000000000000081526004016139eb9190615290565b60405180910390fd5b5b5b613a01878a8a614d31565b613a10878787878787876145ef565b505050505050505050565b6000613a25613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613a466119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613a9e57806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613a959190615742565b60405180910390fd5b816002819055505050565b6000613ab3613efa565b90506000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490506000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015490506000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015490506000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490506000600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005015490506000600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006015490506001891415613cb95787851015613caf5788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613ca6929190615b6d565b60405180910390fd5b8785039450613dac565b6002891415613d135787841015613d095788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d00929190615b6d565b60405180910390fd5b8784039350613dab565b6003891415613d6d5787831015613d635788886040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401613d5a929190615b6d565b60405180910390fd5b8783039250613daa565b886040517ffb59b93f000000000000000000000000000000000000000000000000000000008152600401613da19190615290565b60405180910390fd5b5b5b613db7878a8a614474565b613dc6878787878787876145ef565b505050505050505050565b6000613ddb613efa565b90508073ffffffffffffffffffffffffffffffffffffffff16613dfc6119a9565b73ffffffffffffffffffffffffffffffffffffffff1614613e5457806040517fb4f195e6000000000000000000000000000000000000000000000000000000008152600401613e4b9190615742565b60405180910390fd5b81600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60086020528160005260406000208181548110613eb557600080fd5b9060005260206000209060020201600091509150508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b600033905090565b6000806000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806101000160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152505090506000816000015114613fe5576000808260e0015193508260000151421115613fe25782600001514203915081613fd987612a8b565b02905080840193505b50505b8192505050919050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811061408957614088615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002084815481106141105761410f615b0f565b5b906000526020600020906002020160010154905060008290503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016141799190615290565b602060405180830381865afa158015614196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ba9190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146142145782826040517f1c6aa71e00000000000000000000000000000000000000000000000000000000815260040161420b929190615a8d565b60405180910390fd5b836001866142229190615c07565b1461436657600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001856142739190615c5d565b8154811061428457614283615b0f565b5b9060005260206000209060020201600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002086815481106142e3576142e2615b0f565b5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600182015481600101559050505b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806143b5576143b4615c91565b5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160009055505090558073ffffffffffffffffffffffffffffffffffffffff166323b872dd3088856040518463ffffffff1660e01b815260040161443a93929190615cc0565b600060405180830381600087803b15801561445457600080fd5b505af1158015614468573d6000803e3d6000fd5b50505050505050505050565b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e30856040518363ffffffff1660e01b81526004016144d1929190615a8d565b602060405180830381865afa1580156144ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145129190615d0c565b10156145575781816040517f403f7b3e00000000000000000000000000000000000000000000000000000000815260040161454e929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a308585856040518563ffffffff1660e01b81526004016145b89493929190615d70565b600060405180830381600087803b1580156145d257600080fd5b505af11580156145e6573d6000803e3d6000fd5b50505050505050565b6000600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905086816001015414614647578681600101819055505b8581600201541461465c578581600201819055505b84816003015414614671578481600301819055505b83816004015414614686578381600401819055505b8281600501541461469b578281600501819055505b818160060154146146b0578181600601819055505b6146b9886146c3565b5050505050505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061470f82613f02565b81600701819055504281600001541461472c574281600001819055505b5050565b60008060149054906101000a900460ff16905081600060146101000a81548160ff021916908360ff1602179055508160ff168160ff167f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe460405160405180910390a35050565b60008290508073ffffffffffffffffffffffffffffffffffffffff1663e985e9c585306040518363ffffffff1660e01b81526004016147d6929190615dc8565b602060405180830381865afa1580156147f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148179190615ae2565b61485857826040517fd640e7de00000000000000000000000000000000000000000000000000000000815260040161484f9190615742565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016148a89190615290565b602060405180830381865afa1580156148c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e99190615bab565b73ffffffffffffffffffffffffffffffffffffffff16146149435782826040517f8d4affb800000000000000000000000000000000000000000000000000000000815260040161493a929190615a8d565b60405180910390fd5b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052808573ffffffffffffffffffffffffffffffffffffffff16815260200184815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015550508073ffffffffffffffffffffffffffffffffffffffff166323b872dd8530856040518463ffffffff1660e01b8152600401614a6693929190615cc0565b600060405180830381600087803b158015614a8057600080fd5b505af1158015614a94573d6000803e3d6000fd5b5050505050505050565b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090505b6000811115614c30578080600190039150508273ffffffffffffffffffffffffffffffffffffffff16600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614b6057614b5f615b0f565b5b906000526020600020906002020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148015614c16575081600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110614c0257614c01615b0f565b5b906000526020600020906002020160010154145b15614c2b57614c258482613fef565b50614c6f565b614ae6565b82826040517f1c6aa71e000000000000000000000000000000000000000000000000000000008152600401614c66929190615a8d565b60405180910390fd5b505050565b6000614c7f83613f02565b905081811015614cc85781816040517f83015a83000000000000000000000000000000000000000000000000000000008152600401614cbf929190615b6d565b60405180910390fd5b6000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050828203816007018190555042816000015414614d2b574281600001819055505b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e985e9c584306040518363ffffffff1660e01b8152600401614d8e929190615dc8565b602060405180830381865afa158015614dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614dcf9190615ae2565b614e3257600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fd640e7de000000000000000000000000000000000000000000000000000000008152600401614e299190615742565b60405180910390fd5b80600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1662fdd58e85856040518363ffffffff1660e01b8152600401614e8f929190615a8d565b602060405180830381865afa158015614eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ed09190615d0c565b1015614f155781816040517f403f7b3e000000000000000000000000000000000000000000000000000000008152600401614f0c929190615b6d565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f242432a843085856040518563ffffffff1660e01b8152600401614f769493929190615d70565b600060405180830381600087803b158015614f9057600080fd5b505af1158015614fa4573d6000803e3d6000fd5b50505050505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614ff681614fc1565b811461500157600080fd5b50565b60008135905061501381614fed565b92915050565b60006020828403121561502f5761502e614fb7565b5b600061503d84828501615004565b91505092915050565b60008115159050919050565b61505b81615046565b82525050565b60006020820190506150766000830184615052565b92915050565b6000819050919050565b61508f8161507c565b811461509a57600080fd5b50565b6000813590506150ac81615086565b92915050565b6000602082840312156150c8576150c7614fb7565b5b60006150d68482850161509d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061510a826150df565b9050919050565b61511a816150ff565b811461512557600080fd5b50565b60008135905061513781615111565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126151625761516161513d565b5b8235905067ffffffffffffffff81111561517f5761517e615142565b5b60208301915083600182028301111561519b5761519a615147565b5b9250929050565b6000806000806000608086880312156151be576151bd614fb7565b5b60006151cc88828901615128565b95505060206151dd88828901615128565b94505060406151ee8882890161509d565b935050606086013567ffffffffffffffff81111561520f5761520e614fbc565b5b61521b8882890161514c565b92509250509295509295909350565b61523381614fc1565b82525050565b600060208201905061524e600083018461522a565b92915050565b60006020828403121561526a57615269614fb7565b5b600061527884828501615128565b91505092915050565b61528a8161507c565b82525050565b60006020820190506152a56000830184615281565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6152e0816150ff565b82525050565b6152ef8161507c565b82525050565b60408201600082015161530b60008501826152d7565b50602082015161531e60208501826152e6565b50505050565b600061533083836152f5565b60408301905092915050565b6000602082019050919050565b6000615354826152ab565b61535e81856152b6565b9350615369836152c7565b8060005b8381101561539a5781516153818882615324565b975061538c8361533c565b92505060018101905061536d565b5085935050505092915050565b600060208201905081810360008301526153c18184615349565b905092915050565b600060ff82169050919050565b6153df816153c9565b81146153ea57600080fd5b50565b6000813590506153fc816153d6565b92915050565b60006020828403121561541857615417614fb7565b5b6000615426848285016153ed565b91505092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6154788261542f565b810181811067ffffffffffffffff8211171561549757615496615440565b5b80604052505050565b60006154aa614fad565b90506154b6828261546f565b919050565b600067ffffffffffffffff8211156154d6576154d5615440565b5b602082029050602081019050919050565b60006154fa6154f5846154bb565b6154a0565b9050808382526020820190506020840283018581111561551d5761551c615147565b5b835b8181101561554657806155328882615128565b84526020840193505060208101905061551f565b5050509392505050565b600082601f8301126155655761556461513d565b5b81356155758482602086016154e7565b91505092915050565b600067ffffffffffffffff82111561559957615598615440565b5b602082029050602081019050919050565b60006155bd6155b88461557e565b6154a0565b905080838252602082019050602084028301858111156155e0576155df615147565b5b835b8181101561560957806155f5888261509d565b8452602084019350506020810190506155e2565b5050509392505050565b600082601f8301126156285761562761513d565b5b81356156388482602086016155aa565b91505092915050565b6000806040838503121561565857615657614fb7565b5b600083013567ffffffffffffffff81111561567657615675614fbc565b5b61568285828601615550565b925050602083013567ffffffffffffffff8111156156a3576156a2614fbc565b5b6156af85828601615613565b9150509250929050565b6000819050919050565b60006156de6156d96156d4846150df565b6156b9565b6150df565b9050919050565b60006156f0826156c3565b9050919050565b6000615702826156e5565b9050919050565b615712816156f7565b82525050565b600060208201905061572d6000830184615709565b92915050565b61573c816150ff565b82525050565b60006020820190506157576000830184615733565b92915050565b600061010082019050615773600083018b615281565b615780602083018a615281565b61578d6040830189615281565b61579a6060830188615281565b6157a76080830187615281565b6157b460a0830186615281565b6157c160c0830185615281565b6157ce60e0830184615281565b9998505050505050505050565b6157e4816153c9565b82525050565b60006020820190506157ff60008301846157db565b92915050565b6000806040838503121561581c5761581b614fb7565b5b600061582a85828601615128565b925050602061583b8582860161509d565b9150509250929050565b6000615850826156e5565b9050919050565b61586081615845565b82525050565b600060208201905061587b6000830184615857565b92915050565b60008083601f8401126158975761589661513d565b5b8235905067ffffffffffffffff8111156158b4576158b3615142565b5b6020830191508360208202830111156158d0576158cf615147565b5b9250929050565b60008060008060008060008060a0898b0312156158f7576158f6614fb7565b5b60006159058b828c01615128565b98505060206159168b828c01615128565b975050604089013567ffffffffffffffff81111561593757615936614fbc565b5b6159438b828c01615881565b9650965050606089013567ffffffffffffffff81111561596657615965614fbc565b5b6159728b828c01615881565b9450945050608089013567ffffffffffffffff81111561599557615994614fbc565b5b6159a18b828c0161514c565b92509250509295985092959890939650565b60008060008060008060a087890312156159d0576159cf614fb7565b5b60006159de89828a01615128565b96505060206159ef89828a01615128565b9550506040615a0089828a0161509d565b9450506060615a1189828a0161509d565b935050608087013567ffffffffffffffff811115615a3257615a31614fbc565b5b615a3e89828a0161514c565b92509250509295509295509295565b60008060408385031215615a6457615a63614fb7565b5b6000615a728582860161509d565b9250506020615a838582860161509d565b9150509250929050565b6000604082019050615aa26000830185615733565b615aaf6020830184615281565b9392505050565b615abf81615046565b8114615aca57600080fd5b50565b600081519050615adc81615ab6565b92915050565b600060208284031215615af857615af7614fb7565b5b6000615b0684828501615acd565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000604082019050615b826000830185615281565b615b8f6020830184615281565b9392505050565b600081519050615ba581615111565b92915050565b600060208284031215615bc157615bc0614fb7565b5b6000615bcf84828501615b96565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000615c128261507c565b9150615c1d8361507c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115615c5257615c51615bd8565b5b828201905092915050565b6000615c688261507c565b9150615c738361507c565b925082821015615c8657615c85615bd8565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000606082019050615cd56000830186615733565b615ce26020830185615733565b615cef6040830184615281565b949350505050565b600081519050615d0681615086565b92915050565b600060208284031215615d2257615d21614fb7565b5b6000615d3084828501615cf7565b91505092915050565b600082825260208201905092915050565b50565b6000615d5a600083615d39565b9150615d6582615d4a565b600082019050919050565b600060a082019050615d856000830187615733565b615d926020830186615733565b615d9f6040830185615281565b615dac6060830184615281565b8181036080830152615dbd81615d4d565b905095945050505050565b6000604082019050615ddd6000830185615733565b615dea6020830184615733565b939250505056fea2646970667358221220e7a2c839e9b2c717561968f8fe3cb67596764f6b032b2490f4369c5512b7a43a64736f6c634300080a0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.