More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 18,138 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake Llama | 21269610 | 24 hrs ago | IN | 0 ETH | 0.00059594 | ||||
Unstake Gold Boo... | 21244994 | 4 days ago | IN | 0 ETH | 0.00138163 | ||||
Unstake Llama | 21244980 | 4 days ago | IN | 0 ETH | 0.00108063 | ||||
Unstake Llama | 21244975 | 4 days ago | IN | 0 ETH | 0.00142234 | ||||
Unstake Llama | 21244970 | 4 days ago | IN | 0 ETH | 0.00150213 | ||||
Unstake Llama | 21244962 | 4 days ago | IN | 0 ETH | 0.00139917 | ||||
Unstake Pixlet C... | 21243919 | 4 days ago | IN | 0 ETH | 0.00152865 | ||||
Unstake Boosts | 21243626 | 4 days ago | IN | 0 ETH | 0.00196475 | ||||
Unstake Llama | 21243609 | 4 days ago | IN | 0 ETH | 0.00224415 | ||||
Unstake Llama | 21205349 | 9 days ago | IN | 0 ETH | 0.00087235 | ||||
Unstake Silver B... | 21203170 | 10 days ago | IN | 0 ETH | 0.00100226 | ||||
Unstake Llama | 21203163 | 10 days ago | IN | 0 ETH | 0.00109065 | ||||
Unstake Llama | 21189989 | 12 days ago | IN | 0 ETH | 0.00145902 | ||||
Unstake Llama | 21170883 | 14 days ago | IN | 0 ETH | 0.00436749 | ||||
Unstake Llama | 21129875 | 20 days ago | IN | 0 ETH | 0.00183413 | ||||
Unstake Llama | 21107803 | 23 days ago | IN | 0 ETH | 0.00084206 | ||||
Unstake Llama | 21084574 | 26 days ago | IN | 0 ETH | 0.00073926 | ||||
Unstake Llama | 21075718 | 28 days ago | IN | 0 ETH | 0.00106466 | ||||
Unstake Llama | 21075713 | 28 days ago | IN | 0 ETH | 0.00129565 | ||||
Unstake Llama | 21075708 | 28 days ago | IN | 0 ETH | 0.0016763 | ||||
Unstake Llama | 21075698 | 28 days ago | IN | 0 ETH | 0.00173749 | ||||
Unstake Llama | 20999096 | 38 days ago | IN | 0 ETH | 0.00070644 | ||||
Unstake Llama | 20999092 | 38 days ago | IN | 0 ETH | 0.0009743 | ||||
Unstake Llama | 20997792 | 38 days ago | IN | 0 ETH | 0.00095867 | ||||
Unstake Llama | 20997725 | 38 days ago | IN | 0 ETH | 0.00024359 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
LlamaZoo
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import "./ERC1155.sol"; import "./SpitToken.sol"; import "./ERC721.sol"; import "./FxBaseRootTunnel.sol"; import "./Ownable.sol"; /** __ _ / /| | __ _ _ __ ___ __ _/\ /\___ _ __ ___ ___ / / | |/ _` | '_ ` _ \ / _` \ \ / / _ \ '__/ __|/ _ \ / /__| | (_| | | | | | | (_| |\ V / __/ | \__ \ __/ \____/_|\__,_|_| |_| |_|\__,_| \_/ \___|_| |___/\___| **/ /// @title Llama Zoo /// @author delta devs (https://twitter.com/deltadevelopers) contract LlamaZoo is FxBaseRootTunnel, Ownable { /*/////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ /// @notice ERC721 instance of the PixelatedLlama contract. ERC721 public pixellatedLlamaContract; /// @notice ERC721 instance of the LlamaDraws contract. ERC721 public llamaDrawsContract; /// @notice ERC1155 instance of the StakingBoost contract. ERC1155 public boostContract; /// @notice ERC1155 instance of the Pixlet contract. ERC1155 public pixletContract; struct Staker { uint256[] stakedLlamas; uint256 stakedPixletCanvas; uint256 stakedLlamaDraws; uint128 stakedSilverBoosts; uint128 stakedGoldBoosts; } mapping(address => Staker) public userInfo; bool public stakingPaused; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( address checkpointManager, address fxRoot, address _pixellatedLlamaContract, address _llamaDrawsContract, address _boostContract, address _pixletContract ) FxBaseRootTunnel(checkpointManager, fxRoot) { pixellatedLlamaContract = ERC721(_pixellatedLlamaContract); llamaDrawsContract = ERC721(_llamaDrawsContract); boostContract = ERC1155(_boostContract); pixletContract = ERC1155(_pixletContract); } /*/////////////////////////////////////////////////////////////// CONTRACT SETTERS //////////////////////////////////////////////////////////////*/ /// @notice Set the contract addresses for all contract instances. /// @param _pixellatedLlamaContract The contract address of PixellatedLlama. /// @param _llamaDrawsContract The contract address of LlamaDraws. /// @param _boostContract The contract address of RewardBooster. /// @param _pixletContract The contract address of the Pixlet contract. function setContractAddresses( address _pixellatedLlamaContract, address _llamaDrawsContract, address _boostContract, address _pixletContract ) public onlyOwner { pixellatedLlamaContract = ERC721(_pixellatedLlamaContract); llamaDrawsContract = ERC721(_llamaDrawsContract); boostContract = ERC1155(_boostContract); pixletContract = ERC1155(_pixletContract); } /// @notice Pauses staking and unstaking, for emergency purposes /// @dev If we have to migrate because of Polygon instability or state sync issues, this will save us function setStakingPaused(bool paused) public onlyOwner { stakingPaused = paused; } /// @notice For collab.land to give a role based on staking status function balanceOf(address owner) public view returns (uint256) { uint[] memory llamas = userInfo[owner].stakedLlamas; if(llamas.length == 0) return 0; for (uint256 i = 0; i < llamas.length; i++) { if(llamas[i] < 500) return 1; } return 2; } /// @dev Using the mapping directly wasn't returning the array, so we made this helper fuction. function getStakedTokens(address user) public view returns ( uint256[] memory llamas, uint256 pixletCanvas, uint256 llamaDraws, uint128 silverBoosts, uint128 goldBoosts ) { Staker memory staker = userInfo[user]; return ( staker.stakedLlamas, staker.stakedPixletCanvas, staker.stakedLlamaDraws, staker.stakedSilverBoosts, staker.stakedGoldBoosts ); } /*/////////////////////////////////////////////////////////////// UTILITY STAKING LOGIC //////////////////////////////////////////////////////////////*/ function bulkStake( uint256[] memory llamas, uint128 silverBoosts, uint128 goldBoosts, uint256 pixletStudio, uint256 llamaDraws ) public { if (llamas.length > 0) stakeMultipleLlamas(llamas); stakeBoosts(silverBoosts, goldBoosts); if (pixletStudio != 0) stakePixletCanvas(pixletStudio); if (llamaDraws != 0) stakeLlamaDraws(llamaDraws); } function bulkUnstake( uint256[] memory llamas, uint128 silverBoosts, uint128 goldBoosts, bool pixletStudio, bool llamaDraws ) public { if (llamas.length > 0) unstakeMultipleLlamas(llamas); unstakeBoosts(silverBoosts, goldBoosts); if (pixletStudio) unstakePixletCanvas(); if (llamaDraws) unstakeLlamaDraws(); } function stakeMultipleLlamas(uint256[] memory tokenIds) public { require(!stakingPaused, "Staking is currently paused."); uint256 animatedCount = 0; Staker storage staker = userInfo[msg.sender]; for (uint256 i = 0; i < tokenIds.length; i++) { if (tokenIds[i] < 500) ++animatedCount; staker.stakedLlamas.push(tokenIds[i]); pixellatedLlamaContract.transferFrom( msg.sender, address(this), tokenIds[i] ); } if (animatedCount > 0) { _sendMessageToChild( abi.encode( msg.sender, uint256(TokenType.AnimatedLlama), animatedCount, true ) ); } if ((tokenIds.length - animatedCount) > 0) { _sendMessageToChild( abi.encode( msg.sender, uint256(TokenType.StaticLlama), tokenIds.length - animatedCount, true ) ); } } function unstakeMultipleLlamas(uint256[] memory tokenIds) public { require(!stakingPaused, "Staking is currently paused."); uint256 animatedCount = 0; Staker storage staker = userInfo[msg.sender]; for (uint256 i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; require(containsElement(staker.stakedLlamas, tokenId), "You do not own this llama."); if (tokenId < 500) ++animatedCount; pixellatedLlamaContract.transferFrom( address(this), msg.sender, tokenId ); uint256[] memory stakedLlamas = staker.stakedLlamas; uint256 index; for (uint256 j; j < stakedLlamas.length; j++) { if (stakedLlamas[j] == tokenId) index = j; } if (stakedLlamas[index] == tokenId) { staker.stakedLlamas[index] = stakedLlamas[ staker.stakedLlamas.length - 1 ]; staker.stakedLlamas.pop(); } } if (animatedCount > 0) { _sendMessageToChild( abi.encode( msg.sender, uint256(TokenType.AnimatedLlama), animatedCount, false ) ); } if ((tokenIds.length - animatedCount) > 0) { _sendMessageToChild( abi.encode( msg.sender, uint256(TokenType.StaticLlama), tokenIds.length - animatedCount, false ) ); } } /// @notice Stake a LlamaVerse llama. /// @param tokenId The tokenId of the llama to stake function stakeLlama(uint256 tokenId) external { require(!stakingPaused, "Staking is currently paused."); bool animated = tokenId < 500; Staker storage staker = userInfo[msg.sender]; staker.stakedLlamas.push(tokenId); pixellatedLlamaContract.transferFrom( msg.sender, address(this), tokenId ); _sendMessageToChild( abi.encode( msg.sender, uint256( animated ? TokenType.AnimatedLlama : TokenType.StaticLlama ), 1, true ) ); } /// @notice Unstake a LlamaVerse llama. /// @param tokenId The tokenId of the llama to unstake function unstakeLlama(uint256 tokenId) external { require(!stakingPaused, "Staking is currently paused."); bool animated = tokenId < 500; Staker storage staker = userInfo[msg.sender]; require(containsElement(staker.stakedLlamas, tokenId), "You do not own this llama."); pixellatedLlamaContract.transferFrom( address(this), msg.sender, tokenId ); uint256[] memory stakedLlamas = staker.stakedLlamas; uint256 index; for (uint256 i; i < stakedLlamas.length; i++) { if (stakedLlamas[i] == tokenId) index = i; } if (stakedLlamas[index] == tokenId) { _sendMessageToChild( abi.encode( msg.sender, uint256( animated ? TokenType.AnimatedLlama : TokenType.StaticLlama ), 1, false ) ); staker.stakedLlamas[index] = stakedLlamas[ staker.stakedLlamas.length - 1 ]; staker.stakedLlamas.pop(); } } /// @notice Stake silver boosts. /// @param amount The amount of boosts to stake. function stakeSilverBoosts(uint128 amount) public { require(!stakingPaused, "Staking is currently paused."); require(amount != 0, "Staking 0 is not allowed."); userInfo[msg.sender].stakedSilverBoosts += amount; boostContract.safeTransferFrom( msg.sender, address(this), 2, amount, "" ); _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.SilverBoost), amount, true) ); } /// @notice Unstake silver boosts. /// @param amount The amount of boosts to unstake. function unstakeSilverBoosts(uint128 amount) public { require(!stakingPaused, "Staking is currently paused."); require(amount != 0, "Unstaking 0 is not allowed."); userInfo[msg.sender].stakedSilverBoosts -= amount; boostContract.safeTransferFrom( address(this), msg.sender, 2, amount, "" ); _sendMessageToChild( abi.encode( msg.sender, uint256(TokenType.SilverBoost), amount, false ) ); } /// @notice Stake gold boosts with the requested tokenID. /// @param amount The amount of boosts to stake. function stakeGoldBoosts(uint128 amount) public { require(!stakingPaused, "Staking is currently paused."); require(amount != 0, "Staking 0 is not allowed."); userInfo[msg.sender].stakedGoldBoosts += amount; boostContract.safeTransferFrom( msg.sender, address(this), 1, amount, "" ); _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.GoldBoost), amount, true) ); } /// @notice Unstake gold boosts with the requested tokenID. /// @param amount The amount of boosts to stake. function unstakeGoldBoosts(uint128 amount) public { require(!stakingPaused, "Staking is currently paused."); require(amount != 0, "Unstaking 0 is not allowed."); userInfo[msg.sender].stakedGoldBoosts -= amount; boostContract.safeTransferFrom( address(this), msg.sender, 1, amount, "" ); _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.GoldBoost), amount, false) ); } function stakeBoosts(uint128 silverAmount, uint128 goldAmount) public { if (silverAmount != 0) stakeSilverBoosts(silverAmount); if (goldAmount != 0) stakeGoldBoosts(goldAmount); } function unstakeBoosts(uint128 silverAmount, uint128 goldAmount) public { if (silverAmount != 0) unstakeSilverBoosts(silverAmount); if (goldAmount != 0) unstakeGoldBoosts(goldAmount); } /// @notice Stake a Pixlet Canvas with the requested tokenID. /// @param tokenId The token ID of the pixlet canvas to stake. function stakePixletCanvas(uint256 tokenId) public { require(!stakingPaused, "Staking is currently paused."); require( userInfo[msg.sender].stakedPixletCanvas == 0, "You already have a pixlet canvas staked." ); userInfo[msg.sender].stakedPixletCanvas = tokenId; pixletContract.safeTransferFrom( msg.sender, address(this), tokenId, 1, "" ); _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.PixletCanvas), 1, true) ); } /// @notice Unstake your Pixlet Canvas. function unstakePixletCanvas() public { require(!stakingPaused, "Staking is currently paused."); require( userInfo[msg.sender].stakedPixletCanvas != 0, "You do not have a pixlet canvas staked." ); pixletContract.safeTransferFrom( address(this), msg.sender, userInfo[msg.sender].stakedPixletCanvas, 1, "" ); userInfo[msg.sender].stakedPixletCanvas = 0; _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.PixletCanvas), 1, false) ); } /// @notice Stake a Llamadraws. /// @param tokenId The token ID of the llamadraws to stake. function stakeLlamaDraws(uint256 tokenId) public { require(!stakingPaused, "Staking is currently paused."); require( userInfo[msg.sender].stakedLlamaDraws == 0, "You already have a llamadraws staked." ); userInfo[msg.sender].stakedLlamaDraws = tokenId; llamaDrawsContract.transferFrom(msg.sender, address(this), tokenId); _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.LlamaDraws), 1, true) ); } /// @notice Unstake your Llamadraws. function unstakeLlamaDraws() public { require(!stakingPaused, "Staking is currently paused."); require( userInfo[msg.sender].stakedLlamaDraws != 0, "You do not have a llamadraws staked." ); llamaDrawsContract.transferFrom( address(this), msg.sender, userInfo[msg.sender].stakedLlamaDraws ); userInfo[msg.sender].stakedLlamaDraws = 0; _sendMessageToChild( abi.encode(msg.sender, uint256(TokenType.LlamaDraws), 1, false) ); } function _processMessageFromChild(bytes memory message) internal override { // We don't need a message from child } function containsElement(uint[] memory elements, uint tokenId) internal returns (bool) { for (uint256 i = 0; i < elements.length; i++) { if(elements[i] == tokenId) return true; } return false; } /*/////////////////////////////////////////////////////////////// ERC ON RECEIVED LOGIC //////////////////////////////////////////////////////////////*/ /** * @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 id, bytes calldata data ) external returns (bytes4) { return ERC721TokenReceiver.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. * @param operator The address which called the `safeTransferFrom` function. * @param from The address which previously owned the token. * @param id The id of the token being transferred. * @param amount The amount of tokens being transferred. * @param data Additional data with no specified format. * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`. */ function onERC1155Received( address operator, address from, uint256 id, uint256 amount, bytes calldata data ) external returns (bytes4) { return ERC1155TokenReceiver.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. * @param operator The address which called the `safeBatchTransferFrom` function. * @param from The address which previously owned the token. * @param ids An array containing ids of each token being transferred. * @param amounts An array containing amounts of each token being transferred. * @param data Additional data with no specified format. * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`. */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external returns (bytes4) { return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*/////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*/////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*/////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); for (uint256 i = 0; i < idsLength; ) { uint256 id = ids[i]; uint256 amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { i++; } } emit TransferBatch(msg.sender, from, to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function balanceOfBatch(address[] memory owners, uint256[] memory ids) public view virtual returns (uint256[] memory balances) { uint256 ownersLength = owners.length; // Saves MLOADs. require(ownersLength == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < ownersLength; i++) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*/////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { i++; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { i++; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) interface ERC1155TokenReceiver { function onERC1155Received( address operator, address from, uint256 id, uint256 amount, bytes calldata data ) external returns (bytes4); function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*/////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*/////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*/////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*/////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) /// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC. abstract contract ERC721 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*/////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*/////////////////////////////////////////////////////////////// ERC721 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => uint256) public balanceOf; mapping(uint256 => address) public ownerOf; mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*/////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { balanceOf[from]--; balanceOf[to]++; } ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes memory data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*/////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { balanceOf[to]++; } ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = ownerOf[id]; require(ownerOf[id] != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { balanceOf[owner]--; } delete ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*/////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) interface ERC721TokenReceiver { function onERC721Received( address operator, address from, uint256 id, bytes calldata data ) external returns (bytes4); }
pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library ExitPayloadReader { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; uint8 constant WORD_SIZE = 32; struct ExitPayload { RLPReader.RLPItem[] data; } struct Receipt { RLPReader.RLPItem[] data; bytes raw; uint256 logIndex; } struct Log { RLPReader.RLPItem data; RLPReader.RLPItem[] list; } struct LogTopics { RLPReader.RLPItem[] data; } // copy paste of private copy() from RLPReader to avoid changing of existing contracts function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) { RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList(); return ExitPayload(payloadData); } function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[0].toUint(); } function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[1].toBytes(); } function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[2].toUint(); } function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[3].toUint(); } function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) { return bytes32(payload.data[4].toUint()); } function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) { return bytes32(payload.data[5].toUint()); } function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) { receipt.raw = payload.data[6].toBytes(); RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem(); if (receiptItem.isList()) { // legacy tx receipt.data = receiptItem.toList(); } else { // pop first byte before parsting receipt bytes memory typedBytes = receipt.raw; bytes memory result = new bytes(typedBytes.length - 1); uint256 srcPtr; uint256 destPtr; assembly { srcPtr := add(33, typedBytes) destPtr := add(0x20, result) } copy(srcPtr, destPtr, result.length); receipt.data = result.toRlpItem().toList(); } receipt.logIndex = getReceiptLogIndex(payload); return receipt; } function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[7].toBytes(); } function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) { return payload.data[8].toBytes(); } function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[8].toUint(); } function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) { return payload.data[9].toUint(); } // Receipt methods function toBytes(Receipt memory receipt) internal pure returns (bytes memory) { return receipt.raw; } function getLog(Receipt memory receipt) internal pure returns (Log memory) { RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex]; return Log(logData, logData.toList()); } // Log methods function getEmitter(Log memory log) internal pure returns (address) { return RLPReader.toAddress(log.list[0]); } function getTopics(Log memory log) internal pure returns (LogTopics memory) { return LogTopics(log.list[1].toList()); } function getData(Log memory log) internal pure returns (bytes memory) { return log.list[2].toBytes(); } function toRlpBytes(Log memory log) internal pure returns (bytes memory) { return log.data.toRlpBytes(); } // LogTopics methods function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) { return topics.data[index]; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // IFxMessageProcessor represents interface to process message interface IFxMessageProcessor { function processMessageFromRoot( uint256 stateId, address rootMessageSender, bytes calldata data ) external; } /** * @notice Mock child tunnel contract to receive and send message from L2 */ abstract contract FxBaseChildTunnel is IFxMessageProcessor { // MessageTunnel on L1 will get data from this event event MessageSent(bytes message); // fx child address public fxChild; // fx root tunnel address public fxRootTunnel; constructor(address _fxChild) { fxChild = _fxChild; } // Sender must be fxRootTunnel in case of ERC20 tunnel modifier validateSender(address sender) { require(sender == fxRootTunnel, "FxBaseChildTunnel: INVALID_SENDER_FROM_ROOT"); _; } // set fxRootTunnel if not set already function setFxRootTunnel(address _fxRootTunnel) external { require(fxRootTunnel == address(0x0), "FxBaseChildTunnel: ROOT_TUNNEL_ALREADY_SET"); fxRootTunnel = _fxRootTunnel; } function processMessageFromRoot( uint256 stateId, address rootMessageSender, bytes calldata data ) external override { require(msg.sender == fxChild, "FxBaseChildTunnel: INVALID_SENDER"); _processMessageFromRoot(stateId, rootMessageSender, data); } /** * @notice Emit message that can be received on Root Tunnel * @dev Call the internal function when need to emit message * @param message bytes message that will be sent to Root Tunnel * some message examples - * abi.encode(tokenId); * abi.encode(tokenId, tokenMetadata); * abi.encode(messageType, messageData); */ function _sendMessageToRoot(bytes memory message) internal { emit MessageSent(message); } /** * @notice Process message received from Root Tunnel * @dev function needs to be implemented to handle message as per requirement * This is called by onStateReceive function. * Since it is called via a system call, any event will not be emitted during its execution. * @param stateId unique state id * @param sender root message sender * @param message bytes message that was sent from Root Tunnel */ function _processMessageFromRoot( uint256 stateId, address sender, bytes memory message ) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; import {MerklePatriciaProof} from "./MerklePatriciaProof.sol"; import {Merkle} from "./Merkle.sol"; import "./ExitPayloadReader.sol"; interface IFxStateSender { function sendMessageToChild(address _receiver, bytes calldata _data) external; } contract ICheckpointManager { struct HeaderBlock { bytes32 root; uint256 start; uint256 end; uint256 createdAt; address proposer; } /** * @notice mapping of checkpoint header numbers to block details * @dev These checkpoints are submited by plasma contracts */ mapping(uint256 => HeaderBlock) public headerBlocks; } abstract contract FxBaseRootTunnel { using RLPReader for RLPReader.RLPItem; using Merkle for bytes32; using ExitPayloadReader for bytes; using ExitPayloadReader for ExitPayloadReader.ExitPayload; using ExitPayloadReader for ExitPayloadReader.Log; using ExitPayloadReader for ExitPayloadReader.LogTopics; using ExitPayloadReader for ExitPayloadReader.Receipt; // keccak256(MessageSent(bytes)) bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036; // state sender contract IFxStateSender public fxRoot; // root chain manager ICheckpointManager public checkpointManager; // child tunnel contract which receives and sends messages address public fxChildTunnel; // storage to avoid duplicate exits mapping(bytes32 => bool) public processedExits; constructor(address _checkpointManager, address _fxRoot) { checkpointManager = ICheckpointManager(_checkpointManager); fxRoot = IFxStateSender(_fxRoot); } // set fxChildTunnel if not set already function setFxChildTunnel(address _fxChildTunnel) public { require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET"); fxChildTunnel = _fxChildTunnel; } /** * @notice Send bytes message to Child Tunnel * @param message bytes message that will be sent to Child Tunnel * some message examples - * abi.encode(tokenId); * abi.encode(tokenId, tokenMetadata); * abi.encode(messageType, messageData); */ function _sendMessageToChild(bytes memory message) internal { fxRoot.sendMessageToChild(fxChildTunnel, message); } function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) { ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload(); bytes memory branchMaskBytes = payload.getBranchMaskAsBytes(); uint256 blockNumber = payload.getBlockNumber(); // checking if exit has already been processed // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex) bytes32 exitHash = keccak256( abi.encodePacked( blockNumber, // first 2 nibbles are dropped while generating nibble array // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only) // so converting to nibble array and then hashing it MerklePatriciaProof._getNibbleArray(branchMaskBytes), payload.getReceiptLogIndex() ) ); require(processedExits[exitHash] == false, "FxRootTunnel: EXIT_ALREADY_PROCESSED"); processedExits[exitHash] = true; ExitPayloadReader.Receipt memory receipt = payload.getReceipt(); ExitPayloadReader.Log memory log = receipt.getLog(); // check child tunnel require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL"); bytes32 receiptRoot = payload.getReceiptRoot(); // verify receipt inclusion require( MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot), "FxRootTunnel: INVALID_RECEIPT_PROOF" ); // verify checkpoint inclusion _checkBlockMembershipInCheckpoint( blockNumber, payload.getBlockTime(), payload.getTxRoot(), receiptRoot, payload.getHeaderNumber(), payload.getBlockProof() ); ExitPayloadReader.LogTopics memory topics = log.getTopics(); require( bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig "FxRootTunnel: INVALID_SIGNATURE" ); // received message data bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message return message; } function _checkBlockMembershipInCheckpoint( uint256 blockNumber, uint256 blockTime, bytes32 txRoot, bytes32 receiptRoot, uint256 headerNumber, bytes memory blockProof ) private view returns (uint256) { (bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber); require( keccak256(abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)).checkMembership( blockNumber - startBlock, headerRoot, blockProof ), "FxRootTunnel: INVALID_HEADER" ); return createdAt; } /** * @notice receive message from L2 to L1, validated by proof * @dev This function verifies if the transaction actually happened on child chain * * @param inputData RLP encoded data of the reference tx containing following list of fields * 0 - headerNumber - Checkpoint header block number containing the reference tx * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root * 2 - blockNumber - Block number containing the reference tx on child chain * 3 - blockTime - Reference tx block time * 4 - txRoot - Transactions root of block * 5 - receiptRoot - Receipts root of block * 6 - receipt - Receipt of the reference transaction * 7 - receiptProof - Merkle proof of the reference receipt * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree * 9 - receiptLogIndex - Log Index to read from the receipt */ function receiveMessage(bytes memory inputData) public virtual { bytes memory message = _validateAndExtractMessage(inputData); _processMessageFromChild(message); } /** * @notice Process message received from Child Tunnel * @dev function needs to be implemented to handle message as per requirement * This is called by onStateReceive function. * Since it is called via a system call, any event will not be emitted during its execution. * @param message bytes message that was sent from Child Tunnel */ function _processMessageFromChild(bytes memory message) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Merkle { function checkMembership( bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof ) internal pure returns (bool) { require(proof.length % 32 == 0, "Invalid proof length"); uint256 proofHeight = proof.length / 32; // Proof of size n means, height of the tree is n+1. // In a tree of height n+1, max #leafs possible is 2 ^ n require(index < 2**proofHeight, "Leaf index is too big"); bytes32 proofElement; bytes32 computedHash = leaf; for (uint256 i = 32; i <= proof.length; i += 32) { assembly { proofElement := mload(add(proof, i)) } if (index % 2 == 0) { computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } index = index / 2; } return computedHash == rootHash; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {RLPReader} from "./RLPReader.sol"; library MerklePatriciaProof { /* * @dev Verifies a merkle patricia proof. * @param value The terminating value in the trie. * @param encodedPath The path in the trie leading to value. * @param rlpParentNodes The rlp encoded stack of nodes. * @param root The root hash of the trie. * @return The boolean validity of the proof. */ function verify( bytes memory value, bytes memory encodedPath, bytes memory rlpParentNodes, bytes32 root ) internal pure returns (bool) { RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes); RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item); bytes memory currentNode; RLPReader.RLPItem[] memory currentNodeList; bytes32 nodeKey = root; uint256 pathPtr = 0; bytes memory path = _getNibbleArray(encodedPath); if (path.length == 0) { return false; } for (uint256 i = 0; i < parentNodes.length; i++) { if (pathPtr > path.length) { return false; } currentNode = RLPReader.toRlpBytes(parentNodes[i]); if (nodeKey != keccak256(currentNode)) { return false; } currentNodeList = RLPReader.toList(parentNodes[i]); if (currentNodeList.length == 17) { if (pathPtr == path.length) { if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) { return true; } else { return false; } } uint8 nextPathNibble = uint8(path[pathPtr]); if (nextPathNibble > 16) { return false; } nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble])); pathPtr += 1; } else if (currentNodeList.length == 2) { uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr); if (pathPtr + traversed == path.length) { //leaf node if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) { return true; } else { return false; } } //extension node if (traversed == 0) { return false; } pathPtr += traversed; nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1])); } else { return false; } } } function _nibblesToTraverse( bytes memory encodedPartialPath, bytes memory path, uint256 pathPtr ) private pure returns (uint256) { uint256 len = 0; // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath // and slicedPath have elements that are each one hex character (1 nibble) bytes memory partialPath = _getNibbleArray(encodedPartialPath); bytes memory slicedPath = new bytes(partialPath.length); // pathPtr counts nibbles in path // partialPath.length is a number of nibbles for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) { bytes1 pathNibble = path[i]; slicedPath[i - pathPtr] = pathNibble; } if (keccak256(partialPath) == keccak256(slicedPath)) { len = partialPath.length; } else { len = 0; } return len; } // bytes b must be hp encoded function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) { bytes memory nibbles = ""; if (b.length > 0) { uint8 offset; uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b)); if (hpNibble == 1 || hpNibble == 3) { nibbles = new bytes(b.length * 2 - 1); bytes1 oddNibble = _getNthNibbleOfBytes(1, b); nibbles[0] = oddNibble; offset = 1; } else { nibbles = new bytes(b.length * 2 - 2); offset = 0; } for (uint256 i = offset; i < nibbles.length; i++) { nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b); } } return nibbles; } function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) { return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.10; error NotOwner(); // https://github.com/m1guelpf/erc721-drop/blob/main/src/LilOwnable.sol abstract contract Ownable { address internal _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); modifier onlyOwner() { require(_owner == msg.sender); _; } constructor() { _owner = msg.sender; } function owner() external view returns (address) { return _owner; } function transferOwnership(address _newOwner) external { if (msg.sender != _owner) revert NotOwner(); _owner = _newOwner; } function renounceOwnership() public { if (msg.sender != _owner) revert NotOwner(); _owner = address(0); } function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == 0x7f5828d0; // ERC165 Interface ID for ERC173 } }
/* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity ^0.8.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param item RLP encoded bytes */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param item RLP encoded bytes */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { return item.len - _payloadOffset(item.memPtr); } /* * @param item RLP encoded list in bytes */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint256 memPtr, uint256 len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } return result == 0 ? false : true; } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; uint256 result; uint256 memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; // data length bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len == 0) return; // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import "./ERC20.sol"; import "./FXBaseChildTunnel.sol"; import "./Ownable.sol"; /** __ _ / /| | __ _ _ __ ___ __ _/\ /\___ _ __ ___ ___ / / | |/ _` | '_ ` _ \ / _` \ \ / / _ \ '__/ __|/ _ \ / /__| | (_| | | | | | | (_| |\ V / __/ | \__ \ __/ \____/_|\__,_|_| |_| |_|\__,_| \_/ \___|_| |___/\___| **/ /// @title $SPIT Token /// @author delta devs (https://twitter.com/deltadevelopers) enum TokenType { StaticLlama, AnimatedLlama, SilverBoost, GoldBoost, PixletCanvas, LlamaDraws } contract SpitToken is ERC20, FxBaseChildTunnel, Ownable { /*/////////////////////////////////////////////////////////////// STORAGE /////////////////////////////////////////////////////////////*/ struct Rewards { uint256 staticLlama; uint256 animatedLlama; uint256 silverEnergy; uint256 goldEnergy; uint256 pixletCanvas; uint256 llamaDraws; } /// @notice The current reward rates per token type. Rewards public rewards; /// @notice Keeps track of the staking balances (how much is being staked) of each token type for all holders. mapping(address => mapping(uint256 => uint256)) public balances; /// @notice Keeps track of the timestamp of when a holder last withdrew their rewards. mapping(address => uint256) public lastUpdated; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _fxChild) FxBaseChildTunnel(_fxChild) ERC20("Spit Token", "SPIT", 18) { rewards.staticLlama = (uint256(10) * 1e18) / 1 days; rewards.animatedLlama = (uint256(30) * 1e18) / 1 days; rewards.silverEnergy = (uint256(4) * 1e18) / 1 days; rewards.goldEnergy = (uint256(12) * 1e18) / 1 days; rewards.llamaDraws = (uint256(1) * 1e18) / 1 days; rewards.pixletCanvas = (uint256(1) * 1e18) / 1 days; _mint(address(this), 100_000_000 * 1e18); uint256 allocation = (30_000_000 + 5_000_000 + 5_000_000 + 2_500_000) * 1e18; balanceOf[address(this)] -= allocation; unchecked { balanceOf[ 0xcc5cDaB325689Bcd654aB8611c528e60CC8CBe6A ] += (30_000_000 * 1e18); balanceOf[ 0x58B96f5C8ef1CdD7e12a9b71Bbbe575E7B26b142 ] += (5_000_000 * 1e18); balanceOf[ 0x58caDf06fcC222f573F81B08B6Cc156e420D35d7 ] += (5_000_000 * 1e18); balanceOf[ 0x5D31E4A33470e1a15e54aAdD1d913b613fd0E9ED ] += (2_500_000 * 1e18); } emit Transfer( address(this), 0xcc5cDaB325689Bcd654aB8611c528e60CC8CBe6A, 30_000_000 * 1e18 ); emit Transfer( address(this), 0x58B96f5C8ef1CdD7e12a9b71Bbbe575E7B26b142, 5_000_000 * 1e18 ); emit Transfer( address(this), 0x58caDf06fcC222f573F81B08B6Cc156e420D35d7, 5_000_000 * 1e18 ); emit Transfer( address(this), 0x5D31E4A33470e1a15e54aAdD1d913b613fd0E9ED, 2_500_000 * 1e18 ); } /*/////////////////////////////////////////////////////////////// STAKING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Called when withdrawing rewards. $SPIT is transferred to the address, and the lastUpdated field is updated. /// @param account The address to mint to. modifier updateReward(address account) { uint256 amount = earned(account); balanceOf[address(this)] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[account] += amount; } lastUpdated[account] = block.timestamp; emit Transfer(address(this), account, amount); _; } /// @notice Internal call to stake an amount of a specific token type. /// @param account The address which will be staking. /// @param tokenType The token type to stake. /// @param amount The amount to stake. function processStake( address account, TokenType tokenType, uint256 amount ) internal updateReward(account) { balances[account][uint256(tokenType)] += amount; } /// @notice Internal call to unstake an amount of a specific token type. /// @param account The address which will be unstaking. /// @param tokenType The token type to unstake. /// @param amount The amount to unstake. function processUnstake( address account, TokenType tokenType, uint256 amount ) internal updateReward(account) { balances[account][uint256(tokenType)] -= amount; } /** * @notice Process message received from FxChild * @param stateId unique state id * @param sender root message sender * @param message bytes message that was sent from Root Tunnel */ function _processMessageFromRoot( uint256 stateId, address sender, bytes memory message ) internal override validateSender(sender) { (address from, uint256 token, uint256 count, bool action) = abi.decode( message, (address, uint256, uint256, bool) ); action ? processStake(from, TokenType(token), count) : processUnstake(from, TokenType(token), count); } /*/////////////////////////////////////////////////////////////// USER UTILITIES //////////////////////////////////////////////////////////////*/ /// @notice Forwards a user's purchase in SPIT to this contract using EIP-2612 /// @dev This function exists so that the permit and transfer can be done in a single transaction. function purchaseUtility( address owner, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public updateReward(owner) { permit(owner, msg.sender, value, deadline, v, r, s); transferFrom(owner, address(this), value); } /// @notice Calculates the total amount of rewards accumulated for a staker, for staking all owned token types. /// @dev Calculates based on when the staker last withdrew rewards, and compares it with the current block's timestamp. /// @param account The account to calculate the accumulated rewards for. function earned(address account) public view returns (uint256) { return spitPerSecond(account) * (block.timestamp - lastUpdated[account]); } /// @notice Calculates the current balance of the user including the unclaimed rewards. /// @dev Unclaimed rewards are withdrawn automatically when a utility purchase is made or an unstake/stake occurs. function totalBalance(address account) public view returns (uint256) { return balanceOf[account] + earned(account); } /// @notice Calculates the amount of SPIT earned per second by the given user /// @param account The account to calculate the accumulated rewards for. function spitPerSecond(address account) public view returns (uint256) { return ((balances[account][0] * rewards.staticLlama) + (balances[account][1] * rewards.animatedLlama) + (min(balances[account][2], balances[account][0]) * rewards.silverEnergy) + (min(balances[account][3], balances[account][1]) * rewards.goldEnergy) + (balances[account][4] * rewards.pixletCanvas) + (balances[account][5] * rewards.llamaDraws)); } /*/////////////////////////////////////////////////////////////// ADMIN UTILITIES //////////////////////////////////////////////////////////////*/ /// @notice Allows the contract owner to burn SPIT owned by the contract. function burn(uint256 amount) public onlyOwner { _burn(address(this), amount); } /// @notice Allows the contract owner to airdrop SPIT owned by the contract. function airdrop(address[] calldata accounts, uint256[] calldata amounts) public onlyOwner { require(accounts.length == amounts.length); for(uint i = 0; i < accounts.length; i++) { uint amount = amounts[i]; balanceOf[address(this)] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[accounts[i]] += amount; } emit Transfer(address(this), accounts[i], amount); } } /// @notice Allows the contract owner to mint SPIT to the contract. function mint(uint256 amount) public onlyOwner { _mint(address(this), amount); } /// @notice Withdraw $SPIT being held on this contract to the requested address. /// @param recipient The address to withdraw the funds to. /// @param amount The amount of SPIT to withdraw function withdrawSpit(address recipient, uint256 amount) public onlyOwner { balanceOf[address(this)] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[recipient] += amount; } emit Transfer(address(this), recipient, amount); } /// @notice Allows the contract deployer to sets the reward rates for each token type. /// @param staticLlama The reward rate for staking a static llama. /// @param animatedLlama The reward rate for staking an animated llama. /// @param silverEnergy The reward rate for staking a silver llama boost. /// @param goldEnergy The reward rate for staking a gold llama boost. /// @param pixletCanvas The reward rate for staking a pixlet canvas. function setRewardRates( uint256 staticLlama, uint256 animatedLlama, uint256 silverEnergy, uint256 goldEnergy, uint256 pixletCanvas, uint256 llamaDraws ) public onlyOwner { rewards.staticLlama = staticLlama; rewards.animatedLlama = animatedLlama; rewards.silverEnergy = silverEnergy; rewards.goldEnergy = goldEnergy; rewards.pixletCanvas = pixletCanvas; rewards.llamaDraws = llamaDraws; } function updateFxRootRunnel(address _fxRootTunnel) external onlyOwner { fxRootTunnel = _fxRootTunnel; } /*/////////////////////////////////////////////////////////////// HELPERS //////////////////////////////////////////////////////////////*/ function min(uint256 x, uint256 y) internal pure returns (uint256) { return x < y ? x : y; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"checkpointManager","type":"address"},{"internalType":"address","name":"fxRoot","type":"address"},{"internalType":"address","name":"_pixellatedLlamaContract","type":"address"},{"internalType":"address","name":"_llamaDrawsContract","type":"address"},{"internalType":"address","name":"_boostContract","type":"address"},{"internalType":"address","name":"_pixletContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotOwner","type":"error"},{"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":"SEND_MESSAGE_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boostContract","outputs":[{"internalType":"contract ERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"llamas","type":"uint256[]"},{"internalType":"uint128","name":"silverBoosts","type":"uint128"},{"internalType":"uint128","name":"goldBoosts","type":"uint128"},{"internalType":"uint256","name":"pixletStudio","type":"uint256"},{"internalType":"uint256","name":"llamaDraws","type":"uint256"}],"name":"bulkStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"llamas","type":"uint256[]"},{"internalType":"uint128","name":"silverBoosts","type":"uint128"},{"internalType":"uint128","name":"goldBoosts","type":"uint128"},{"internalType":"bool","name":"pixletStudio","type":"bool"},{"internalType":"bool","name":"llamaDraws","type":"bool"}],"name":"bulkUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxChildTunnel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxRoot","outputs":[{"internalType":"contract IFxStateSender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getStakedTokens","outputs":[{"internalType":"uint256[]","name":"llamas","type":"uint256[]"},{"internalType":"uint256","name":"pixletCanvas","type":"uint256"},{"internalType":"uint256","name":"llamaDraws","type":"uint256"},{"internalType":"uint128","name":"silverBoosts","type":"uint128"},{"internalType":"uint128","name":"goldBoosts","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"llamaDrawsContract","outputs":[{"internalType":"contract ERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pixellatedLlamaContract","outputs":[{"internalType":"contract ERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pixletContract","outputs":[{"internalType":"contract ERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"receiveMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pixellatedLlamaContract","type":"address"},{"internalType":"address","name":"_llamaDrawsContract","type":"address"},{"internalType":"address","name":"_boostContract","type":"address"},{"internalType":"address","name":"_pixletContract","type":"address"}],"name":"setContractAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fxChildTunnel","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setStakingPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"silverAmount","type":"uint128"},{"internalType":"uint128","name":"goldAmount","type":"uint128"}],"name":"stakeBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"stakeGoldBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stakeLlama","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stakeLlamaDraws","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stakeMultipleLlamas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stakePixletCanvas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"stakeSilverBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"silverAmount","type":"uint128"},{"internalType":"uint128","name":"goldAmount","type":"uint128"}],"name":"unstakeBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"unstakeGoldBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unstakeLlama","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeLlamaDraws","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"unstakeMultipleLlamas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakePixletCanvas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"unstakeSilverBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"stakedPixletCanvas","type":"uint256"},{"internalType":"uint256","name":"stakedLlamaDraws","type":"uint256"},{"internalType":"uint128","name":"stakedSilverBoosts","type":"uint128"},{"internalType":"uint128","name":"stakedGoldBoosts","type":"uint128"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162004c0938038062004c098339810160408190526200003491620000cf565b600180546001600160a01b03199081166001600160a01b0398891617909155600080548216968816969096179095556004805433908716179055600580548616948716949094179093556006805485169286169290921790915560078054841691851691909117905560088054909216921691909117905562000150565b80516001600160a01b0381168114620000ca57600080fd5b919050565b60008060008060008060c08789031215620000e957600080fd5b620000f487620000b2565b95506200010460208801620000b2565b94506200011460408801620000b2565b93506200012460608801620000b2565b92506200013460808801620000b2565b91506200014460a08801620000b2565b90509295509295509295565b614aa980620001606000396000f3fe608060405234801561001057600080fd5b50600436106102c85760003560e01c8063860420e31161017b578063c0857ba0116100d8578063e72cb05b1161008c578063f2fde38b11610071578063f2fde38b146107b1578063f3fa98a7146107c4578063f953cec7146107d757600080fd5b8063e72cb05b14610765578063f23a6e611461077857600080fd5b8063c7059488116100bd578063c70594881461071d578063de9b771f14610725578063dfcedeee1461074557600080fd5b8063c0857ba0146106ea578063c5bf09641461070a57600080fd5b8063abbe08181161012f578063bbb781cc11610114578063bbb781cc1461068f578063bc197c811461069c578063bd88119f146106d757600080fd5b8063abbe081814610674578063aea4e49e1461067c57600080fd5b80638da5cb5b116101605780638da5cb5b14610623578063972c492814610641578063aaa687771461066157600080fd5b8063860420e3146105fd578063891bc3d21461061057600080fd5b806350acac5511610229578063652972d4116101dd57806370a08231116101c257806370a08231146105cf578063715018a6146105e25780638282052b146105ea57600080fd5b8063652972d41461059c5780636f251724146105bc57600080fd5b80635d939ed01161020e5780635d939ed014610542578063607f2d421461055557806363c28db11461057857600080fd5b806350acac551461050f578063584a22061461052257600080fd5b80631820743d116102805780632176dfce116102655780632176dfce146104d65780633b0d79fa146104e95780634f9ce271146104fc57600080fd5b80631820743d1461042f5780631959a0021461044257600080fd5b80630f147692116102b15780630f1476921461036c578063150b7a02146103b157806315b31bbb1461041a57600080fd5b806301ffc9a7146102cd5780630e387de614610337575b600080fd5b6103226102db366004613e0b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f7f5828d0000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61035e7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b60405190815260200161032e565b60055461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161032e565b6103e96103bf366004613eb8565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161032e565b61042d610428366004613f40565b6107ea565b005b61042d61043d366004613f7b565b61083f565b61049e610450366004613f96565b6009602052600090815260409020600181015460028201546003909201549091906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041684565b6040805194855260208501939093526fffffffffffffffffffffffffffffffff9182169284019290925216606082015260800161032e565b61042d6104e43660046140b1565b610a63565b61042d6104f73660046140e6565b610e28565b61042d61050a366004614119565b610e6e565b61042d61051d366004614119565b611031565b60065461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d610550366004613f7b565b611359565b610322610563366004614119565b60036020526000908152604090205460ff1681565b61058b610586366004613f96565b611535565b60405161032e959493929190614132565b60085461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d6105ca3660046141a3565b611642565b61035e6105dd366004613f96565b61167a565b61042d611752565b61042d6105f83660046140b1565b6117cd565b61042d61060b366004613f7b565b611a2c565b61042d61061e366004614213565b611c4f565b60045473ffffffffffffffffffffffffffffffffffffffff1661038c565b60025461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d61066f366004614293565b611c85565b61042d611d1e565b61042d61068a366004613f96565b611ed2565b600a546103229060ff1681565b6103e96106aa366004614334565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b61042d6106e53660046140e6565b611fa5565b60015461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d610718366004614119565b611fe7565b61042d61211c565b60005461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b60075461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d610773366004613f7b565b6122b8565b6103e96107863660046143f3565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b61042d6107bf366004613f96565b61247d565b61042d6107d2366004614119565b612515565b61042d6107e53660046144b5565b6126b7565b60045473ffffffffffffffffffffffffffffffffffffffff16331461080e57600080fd5b600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600a5460ff16156108975760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e0000000060448201526064015b60405180910390fd5b806fffffffffffffffffffffffffffffffff166000036108f95760405162461bcd60e51b815260206004820152601960248201527f5374616b696e672030206973206e6f7420616c6c6f7765642e00000000000000604482015260640161088e565b336000908152600960205260408120600301805483929061092d9084906fffffffffffffffffffffffffffffffff16614564565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815233600482015230602482015260026044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b1580156109e357600080fd5b505af11580156109f7573d6000803e3d6000fd5b50610a609250339150600290505b6040805173ffffffffffffffffffffffffffffffffffffffff90931660208401528201526fffffffffffffffffffffffffffffffff831660608201526001608082015260a0015b6040516020818303038152906040526126c2565b50565b600a5460ff1615610ab65760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b336000908152600960205260408120815b8351811015610d79576000848281518110610ae457610ae46145c7565b60200260200101519050610b4a83600001805480602002602001604051908101604052809291908181526020018280548015610b3f57602002820191906000526020600020905b815481526020019060010190808311610b2b575b50505050508261274c565b610b965760405162461bcd60e51b815260206004820152601a60248201527f596f7520646f206e6f74206f776e2074686973206c6c616d612e000000000000604482015260640161088e565b6101f4811015610bac57610ba9846145f6565b93505b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810183905273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b158015610c2457600080fd5b505af1158015610c38573d6000803e3d6000fd5b5050845460408051602080840282018101909252828152600094509250869190830182828015610c8757602002820191906000526020600020905b815481526020019060010190808311610c73575b505050505090506000805b8251811015610cd15783838281518110610cae57610cae6145c7565b602002602001015103610cbf578091505b80610cc9816145f6565b915050610c92565b5082828281518110610ce557610ce56145c7565b602002602001015103610d635784548290610d029060019061462e565b81518110610d1257610d126145c7565b6020026020010151856000018281548110610d2f57610d2f6145c7565b6000918252602090912001558454859080610d4c57610d4c614645565b600190038181906000526020600020016000905590555b5050508080610d71906145f6565b915050610ac7565b508115610dc057610dc03360016040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152606081018490526000608082015260a001610a4c565b6000828451610dcf919061462e565b1115610e2357610e23336000848651610de8919061462e565b6040805173ffffffffffffffffffffffffffffffffffffffff909416602085015283019190915260608201526000608082015260a001610a4c565b505050565b6fffffffffffffffffffffffffffffffff821615610e4957610e498261083f565b6fffffffffffffffffffffffffffffffff811615610e6a57610e6a81611359565b5050565b600a5460ff1615610ec15760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b3360009081526009602052604090206002015415610f475760405162461bcd60e51b815260206004820152602560248201527f596f7520616c726561647920686176652061206c6c616d61647261777320737460448201527f616b65642e000000000000000000000000000000000000000000000000000000606482015260840161088e565b336000818152600960205260409081902060020183905560065490517f23b872dd00000000000000000000000000000000000000000000000000000000815260048101929092523060248301526044820183905273ffffffffffffffffffffffffffffffffffffffff16906323b872dd90606401600060405180830381600087803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50610a609250339150600590505b6040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152600160608201819052608082015260a001610a4c565b600a5460ff16156110845760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b3360009081526009602090815260409182902080548351818402810184019094528084526101f485109391926110f1929184918301828280156110e657602002820191906000526020600020905b8154815260200190600101908083116110d2575b50505050508461274c565b61113d5760405162461bcd60e51b815260206004820152601a60248201527f596f7520646f206e6f74206f776e2074686973206c6c616d612e000000000000604482015260640161088e565b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810185905273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b1580156111b557600080fd5b505af11580156111c9573d6000803e3d6000fd5b505082546040805160208084028201810190925282815260009450925084919083018282801561121857602002820191906000526020600020905b815481526020019060010190808311611204575b505050505090506000805b8251811015611262578583828151811061123f5761123f6145c7565b602002602001015103611250578091505b8061125a816145f6565b915050611223565b5084828281518110611276576112766145c7565b602002602001015103611352576112e13385611293576000611296565b60015b60058111156112a7576112a7614598565b6040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152600160608201526000608082015260a001610a4c565b825482906112f19060019061462e565b81518110611301576113016145c7565b602002602001015183600001828154811061131e5761131e6145c7565b600091825260209091200155825483908061133b5761133b614645565b600190038181906000526020600020016000905590555b5050505050565b600a5460ff16156113ac5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b806fffffffffffffffffffffffffffffffff1660000361140e5760405162461bcd60e51b815260206004820152601960248201527f5374616b696e672030206973206e6f7420616c6c6f7765642e00000000000000604482015260640161088e565b336000908152600960205260409020600301805482919060109061145990849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16614564565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815233600482015230602482015260016044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b15801561150f57600080fd5b505af1158015611523573d6000803e3d6000fd5b50610a60925033915060039050610a05565b73ffffffffffffffffffffffffffffffffffffffff811660009081526009602090815260408083208151815460c09481028201850190935260a081018381526060959485948594859485949093919284928491908401828280156115b857602002820191906000526020600020905b8154815260200190600101908083116115a4575b5050509183525050600182015460208083019190915260028301546040808401919091526003909301546fffffffffffffffffffffffffffffffff8082166060808601919091527001000000000000000000000000000000009092041660809384015284519185015193850151908501519490920151909b929a5090985091965090945092505050565b84511561165257611652856117cd565b61165c8484610e28565b811561166b5761166b82612515565b80156113525761135281610e6e565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960209081526040808320805482518185028101850190935280835284938301828280156116e457602002820191906000526020600020905b8154815260200190600101908083116116d0575b5050505050905080516000036116fd5750600092915050565b60005b8151811015611748576101f482828151811061171e5761171e6145c7565b60200260200101511015611736575060019392505050565b80611740816145f6565b915050611700565b5060029392505050565b60045473ffffffffffffffffffffffffffffffffffffffff1633146117a3576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600a5460ff16156118205760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b336000908152600960205260408120815b8351811015611982576101f484828151811061184f5761184f6145c7565b6020026020010151101561186957611866836145f6565b92505b8160000184828151811061187f5761187f6145c7565b60209081029190910181015182546001810184556000938452919092200155600554845173ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90339030908890869081106118d8576118d86145c7565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529290911660248301526044820152606401600060405180830381600087803b15801561195757600080fd5b505af115801561196b573d6000803e3d6000fd5b50505050808061197a906145f6565b915050611831565b5081156119c9576119c93360016040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152606081018490526001608082015260a001610a4c565b60008284516119d8919061462e565b1115610e2357610e233360008486516119f1919061462e565b6040805173ffffffffffffffffffffffffffffffffffffffff909416602085015283019190915260608201526001608082015260a001610a4c565b600a5460ff1615611a7f5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b806fffffffffffffffffffffffffffffffff16600003611ae15760405162461bcd60e51b815260206004820152601b60248201527f556e7374616b696e672030206973206e6f7420616c6c6f7765642e0000000000604482015260640161088e565b3360009081526009602052604090206003018054829190601090611b2c90849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16614674565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815230600482015233602482015260016044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b158015611be257600080fd5b505af1158015611bf6573d6000803e3d6000fd5b50610a609250339150600390505b6040805173ffffffffffffffffffffffffffffffffffffffff90931660208401528201526fffffffffffffffffffffffffffffffff831660608201526000608082015260a001610a4c565b845115611c5f57611c5f85610a63565b611c698484611fa5565b8115611c7757611c77611d1e565b80156113525761135261211c565b60045473ffffffffffffffffffffffffffffffffffffffff163314611ca957600080fd5b6005805473ffffffffffffffffffffffffffffffffffffffff9586167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556006805494861694821694909417909355600780549285169284169290921790915560088054919093169116179055565b600a5460ff1615611d715760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b336000908152600960205260408120600101549003611df85760405162461bcd60e51b815260206004820152602760248201527f596f7520646f206e6f7420686176652061207069786c65742063616e7661732060448201527f7374616b65642e00000000000000000000000000000000000000000000000000606482015260840161088e565b6008543360008181526009602052604080822060019081015491517ff242432a00000000000000000000000000000000000000000000000000000000815230600482015260248101949094526044840191909152606483015260a0608483015260a482015273ffffffffffffffffffffffffffffffffffffffff9091169063f242432a9060c401600060405180830381600087803b158015611e9957600080fd5b505af1158015611ead573d6000803e3d6000fd5b505033600081815260096020526040812060010155611ed09250905060046112a7565b565b60025473ffffffffffffffffffffffffffffffffffffffff1615611f5e5760405162461bcd60e51b815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f53455400000000000000000000000000000000000000000000606482015260840161088e565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6fffffffffffffffffffffffffffffffff821615611fc657611fc6826122b8565b6fffffffffffffffffffffffffffffffff811615610e6a57610e6a81611a2c565b600a5460ff161561203a5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b33600081815260096020908152604080832080546001810182558185529290932090910184905560055490517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810193909352306024840152604483018490526101f484109273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b1580156120e057600080fd5b505af11580156120f4573d6000803e3d6000fd5b50505050610e23338361210857600061210b565b60015b6005811115610ff757610ff7614598565b600a5460ff161561216f5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b3360009081526009602052604081206002015490036121f55760405162461bcd60e51b8152602060048201526024808201527f596f7520646f206e6f7420686176652061206c6c616d6164726177732073746160448201527f6b65642e00000000000000000000000000000000000000000000000000000000606482015260840161088e565b60065433600081815260096020526040908190206002015490517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526024810192909252604482015273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b15801561228157600080fd5b505af1158015612295573d6000803e3d6000fd5b505033600081815260096020526040812060020155611ed09250905060056112a7565b600a5460ff161561230b5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b806fffffffffffffffffffffffffffffffff1660000361236d5760405162461bcd60e51b815260206004820152601b60248201527f556e7374616b696e672030206973206e6f7420616c6c6f7765642e0000000000604482015260640161088e565b33600090815260096020526040812060030180548392906123a19084906fffffffffffffffffffffffffffffffff16614674565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815230600482015233602482015260026044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b15801561245757600080fd5b505af115801561246b573d6000803e3d6000fd5b50610a60925033915060029050611c04565b60045473ffffffffffffffffffffffffffffffffffffffff1633146124ce576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600a5460ff16156125685760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b33600090815260096020526040902060010154156125ee5760405162461bcd60e51b815260206004820152602860248201527f596f7520616c726561647920686176652061207069786c65742063616e76617360448201527f207374616b65642e000000000000000000000000000000000000000000000000606482015260840161088e565b33600081815260096020526040808220600190810185905560085491517ff242432a000000000000000000000000000000000000000000000000000000008152600481019490945230602485015260448401859052606484015260a0608484015260a483019190915273ffffffffffffffffffffffffffffffffffffffff169063f242432a9060c401600060405180830381600087803b15801561269157600080fd5b505af11580156126a5573d6000803e3d6000fd5b50610a60925033915060049050610ff7565b6000610e23826127a1565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b47204779261271e9291169085906004016146d5565b600060405180830381600087803b15801561273857600080fd5b505af1158015611352573d6000803e3d6000fd5b6000805b8351811015612795578284828151811061276c5761276c6145c7565b60200260200101510361278357600191505061279b565b8061278d816145f6565b915050612750565b50600090505b92915050565b606060006127ae83612b1b565b905060006127bb82612b7a565b905060006127c883612ba3565b90506000816127d684612bcc565b6127df86612dba565b6040516020016127f193929190614743565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935291205490915060ff16156128ac5760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f5353454400000000000000000000000000000000000000000000000000000000606482015260840161088e565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556128ec85612dd6565b905060006128f982612f20565b905061290481612fb0565b60025473ffffffffffffffffffffffffffffffffffffffff9081169116146129945760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c000000000000000000000000000000000000000000000000000000606482015260840161088e565b600061299f87612fd9565b90506129bf6129af846020015190565b876129b98a612ff5565b84613011565b612a315760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f460000000000000000000000000000000000000000000000000000000000606482015260840161088e565b612a5f85612a3e896132c4565b612a478a6132e0565b84612a518c6132fc565b612a5a8d613318565b613334565b506000612a6b83613480565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036612aa1612a9c8360006134bc565b6134f4565b14612aee5760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e415455524500604482015260640161088e565b6000612af98461356f565b806020019051810190612b0c9190614770565b9b9a5050505050505050505050565b6040805160208101909152606081526000612b65612b608460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b61358b565b60408051602081019091529081529392505050565b606061279b8260000151600881518110612b9657612b966145c7565b60200260200101516136a1565b600061279b8260000151600281518110612bbf57612bbf6145c7565b60200260200101516134f4565b6040805160208101909152600081528151606091901561279b57600080612bf460008661373e565b60f81c90506001811480612c0b57508060ff166003145b15612ccb57600185516002612c2091906147e7565b612c2a919061462e565b67ffffffffffffffff811115612c4257612c42613fb3565b6040519080825280601f01601f191660200182016040528015612c6c576020820181803683370190505b5092506000612c7c60018761373e565b90508084600081518110612c9257612c926145c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050612d2f565b600285516002612cdb91906147e7565b612ce5919061462e565b67ffffffffffffffff811115612cfd57612cfd613fb3565b6040519080825280601f01601f191660200182016040528015612d27576020820181803683370190505b509250600091505b60ff82165b8351811015612db157612d5e612d4d60ff85168361462e565b612d58906002614824565b8761373e565b848281518110612d7057612d706145c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080612da9816145f6565b915050612d34565b50505092915050565b600061279b8260000151600981518110612bbf57612bbf6145c7565b612dfa60405180606001604052806060815260200160608152602001600081525090565b612e148260000151600681518110612b9657612b966145c7565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152612e4a816137bf565b15612e5f57612e588161358b565b8252612f0c565b60208201518051600090612e759060019061462e565b67ffffffffffffffff811115612e8d57612e8d613fb3565b6040519080825280601f01601f191660200182016040528015612eb7576020820181803683370190505b509050600080836021019150826020019050612ed5828285516137fa565b604080518082018252600080825260209182015281518083019092528451825280850190820152612f059061358b565b8652505050505b612f1583612dba565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000612f6e8360000151600381518110612f6157612f616145c7565b602002602001015161358b565b836040015181518110612f8357612f836145c7565b602002602001015190506040518060400160405280828152602001612fa78361358b565b90529392505050565b600061279b8260200151600081518110612fcc57612fcc6145c7565b6020026020010151613878565b600061279b8260000151600581518110612bbf57612bbf6145c7565b606061279b8260000151600781518110612b9657612b966145c7565b6000806130458460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b905060006130528261358b565b9050606080856000806130648b612bcc565b9050805160000361307f5760009750505050505050506132bc565b60005b86518110156132b35781518311156130a5576000985050505050505050506132bc565b6130c78782815181106130ba576130ba6145c7565b6020026020010151613892565b9550858051906020012084146130e8576000985050505050505050506132bc565b6130fd878281518110612f6157612f616145c7565b945084516011036131cf578151830361315c578c8051906020012061312e86601081518110612b9657612b966145c7565b805190602001200361314b576001985050505050505050506132bc565b6000985050505050505050506132bc565b6000828481518110613170576131706145c7565b016020015160f81c9050601081111561319557600099505050505050505050506132bc565b6131ba868260ff16815181106131ad576131ad6145c7565b6020026020010151613911565b94506131c7600185614824565b9350506132a1565b845160020361314b5760006131fa6131f387600081518110612b9657612b966145c7565b848661393f565b83519091506132098286614824565b0361325c578d8051906020012061322c87600181518110612b9657612b966145c7565b805190602001200361324a57600199505050505050505050506132bc565b600099505050505050505050506132bc565b8060000361327657600099505050505050505050506132bc565b6132808185614824565b9350613298866001815181106131ad576131ad6145c7565b94506132a19050565b806132ab816145f6565b915050613082565b50505050505050505b949350505050565b600061279b8260000151600381518110612bbf57612bbf6145c7565b600061279b8260000151600481518110612bbf57612bbf6145c7565b600061279b8260000151600081518110612bbf57612bbf6145c7565b606061279b8260000151600181518110612b9657612b966145c7565b6001546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a060405180830381865afa1580156133ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d0919061483c565b5093505092509250613427828b6133e7919061462e565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588613a77565b6134735760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f48454144455200000000604482015260640161088e565b9998505050505050505050565b60408051602081019091526060815260405180602001604052806134b48460200151600181518110612f6157612f616145c7565b905292915050565b604080518082019091526000808252602082015282518051839081106134e4576134e46145c7565b6020026020010151905092915050565b80516000901580159061350957508151602110155b61351257600080fd5b60006135218360200151613bf0565b90506000818460000151613535919061462e565b905060008083866020015161354a9190614824565b905080519150602083101561356657826020036101000a820491505b50949350505050565b606061279b8260200151600281518110612b9657612b966145c7565b6060613596826137bf565b61359f57600080fd5b60006135aa83613c72565b905060008167ffffffffffffffff8111156135c7576135c7613fb3565b60405190808252806020026020018201604052801561360c57816020015b60408051808201909152600080825260208201528152602001906001900390816135e55790505b509050600061361e8560200151613bf0565b856020015161362d9190614824565b90506000805b848110156136965761364483613cf7565b915060405180604001604052808381526020018481525084828151811061366d5761366d6145c7565b60209081029190910101526136828284614824565b92508061368e816145f6565b915050613633565b509195945050505050565b80516060906136af57600080fd5b60006136be8360200151613bf0565b905060008184600001516136d2919061462e565b905060008167ffffffffffffffff8111156136ef576136ef613fb3565b6040519080825280601f01601f191660200182016040528015613719576020820181803683370190505b50905060008160200190506135668487602001516137379190614824565b8285613db9565b600061374b6002846148b8565b156137855760108261375e6002866148cc565b8151811061376e5761376e6145c7565b0160200151613780919060f81c6148e0565b6137b5565b6010826137936002866148cc565b815181106137a3576137a36145c7565b01602001516137b5919060f81c614902565b60f81b9392505050565b805160009081036137d257506000919050565b6020820151805160001a9060c08210156137f0575060009392505050565b5060019392505050565b8060000361380757505050565b6020811061383f578251825261381e602084614824565b925061382b602083614824565b915061383860208261462e565b9050613807565b6000600161384e83602061462e565b61385a90610100614a44565b613864919061462e565b935183518516941916939093179091525050565b805160009060151461388957600080fd5b61279b826134f4565b60606000826000015167ffffffffffffffff8111156138b3576138b3613fb3565b6040519080825280601f01601f1916602001820160405280156138dd576020820181803683370190505b50905080516000036138ef5792915050565b600081602001905061390a8460200151828660000151613db9565b5092915050565b805160009060211461392257600080fd5b600080836020015160016139369190614824565b51949350505050565b6000808061394c86612bcc565b90506000815167ffffffffffffffff81111561396a5761396a613fb3565b6040519080825280601f01601f191660200182016040528015613994576020820181803683370190505b509050845b82516139a59087614824565b811015613a485760008782815181106139c0576139c06145c7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016905080836139f5898561462e565b81518110613a0557613a056145c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080613a40906145f6565b915050613999565b508080519060200120828051906020012003613a675781519250613a6c565b600092505b509095945050505050565b600060208251613a8791906148b8565b15613ad45760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642070726f6f66206c656e677468000000000000000000000000604482015260640161088e565b600060208351613ae491906148cc565b9050613af1816002614a44565b8510613b3f5760405162461bcd60e51b815260206004820152601560248201527f4c65616620696e64657820697320746f6f206269670000000000000000000000604482015260640161088e565b60008660205b85518111613be257858101519250613b5e6002896148b8565b600003613b96576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150613bc3565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b613bce6002896148cc565b9750613bdb602082614824565b9050613b45565b509094149695505050505050565b8051600090811a6080811015613c095750600092915050565b60b8811080613c24575060c08110801590613c24575060f881105b15613c325750600192915050565b60c0811015613c6657613c47600160b8614a50565b613c549060ff168261462e565b613c5f906001614824565b9392505050565b613c47600160f8614a50565b80516000908103613c8557506000919050565b600080613c958460200151613bf0565b8460200151613ca49190614824565b9050600084600001518560200151613cbc9190614824565b90505b80821015613cee57613cd082613cf7565b613cda9083614824565b915082613ce6816145f6565b935050613cbf565b50909392505050565b80516000908190811a6080811015613d12576001915061390a565b60b8811015613d3857613d2660808261462e565b613d31906001614824565b915061390a565b60c0811015613d655760b78103600185019450806020036101000a8551046001820181019350505061390a565b60f8811015613d7957613d2660c08261462e565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80600003613dc657505050565b60208110613dfe5782518252613ddd602084614824565b9250613dea602083614824565b9150613df760208261462e565b9050613dc6565b8060000361383f57505050565b600060208284031215613e1d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114613c5f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610a6057600080fd5b60008083601f840112613e8157600080fd5b50813567ffffffffffffffff811115613e9957600080fd5b602083019150836020828501011115613eb157600080fd5b9250929050565b600080600080600060808688031215613ed057600080fd5b8535613edb81613e4d565b94506020860135613eeb81613e4d565b935060408601359250606086013567ffffffffffffffff811115613f0e57600080fd5b613f1a88828901613e6f565b969995985093965092949392505050565b80358015158114613f3b57600080fd5b919050565b600060208284031215613f5257600080fd5b613c5f82613f2b565b80356fffffffffffffffffffffffffffffffff81168114613f3b57600080fd5b600060208284031215613f8d57600080fd5b613c5f82613f5b565b600060208284031215613fa857600080fd5b8135613c5f81613e4d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561402957614029613fb3565b604052919050565b600082601f83011261404257600080fd5b8135602067ffffffffffffffff82111561405e5761405e613fb3565b8160051b61406d828201613fe2565b928352848101820192828101908785111561408757600080fd5b83870192505b848310156140a65782358252918301919083019061408d565b979650505050505050565b6000602082840312156140c357600080fd5b813567ffffffffffffffff8111156140da57600080fd5b6132bc84828501614031565b600080604083850312156140f957600080fd5b61410283613f5b565b915061411060208401613f5b565b90509250929050565b60006020828403121561412b57600080fd5b5035919050565b60a0808252865190820181905260009060209060c0840190828a01845b8281101561416b5781518452928401929084019060010161414f565b505050908301969096525060408101939093526fffffffffffffffffffffffffffffffff918216606084015216608090910152919050565b600080600080600060a086880312156141bb57600080fd5b853567ffffffffffffffff8111156141d257600080fd5b6141de88828901614031565b9550506141ed60208701613f5b565b93506141fb60408701613f5b565b94979396509394606081013594506080013592915050565b600080600080600060a0868803121561422b57600080fd5b853567ffffffffffffffff81111561424257600080fd5b61424e88828901614031565b95505061425d60208701613f5b565b935061426b60408701613f5b565b925061427960608701613f2b565b915061428760808701613f2b565b90509295509295909350565b600080600080608085870312156142a957600080fd5b84356142b481613e4d565b935060208501356142c481613e4d565b925060408501356142d481613e4d565b915060608501356142e481613e4d565b939692955090935050565b60008083601f84011261430157600080fd5b50813567ffffffffffffffff81111561431957600080fd5b6020830191508360208260051b8501011115613eb157600080fd5b60008060008060008060008060a0898b03121561435057600080fd5b883561435b81613e4d565b9750602089013561436b81613e4d565b9650604089013567ffffffffffffffff8082111561438857600080fd5b6143948c838d016142ef565b909850965060608b01359150808211156143ad57600080fd5b6143b98c838d016142ef565b909650945060808b01359150808211156143d257600080fd5b506143df8b828c01613e6f565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561440c57600080fd5b863561441781613e4d565b9550602087013561442781613e4d565b94506040870135935060608701359250608087013567ffffffffffffffff81111561445157600080fd5b61445d89828a01613e6f565b979a9699509497509295939492505050565b600067ffffffffffffffff82111561448957614489613fb3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b6000602082840312156144c757600080fd5b813567ffffffffffffffff8111156144de57600080fd5b8201601f810184136144ef57600080fd5b80356145026144fd8261446f565b613fe2565b81815285602083850101111561451757600080fd5b81602084016020830137600091810160200191909152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006fffffffffffffffffffffffffffffffff80831681851680830382111561458f5761458f614535565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361462757614627614535565b5060010190565b60008282101561464057614640614535565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006fffffffffffffffffffffffffffffffff8381169083168181101561469d5761469d614535565b039392505050565b60005b838110156146c05781810151838201526020016146a8565b838111156146cf576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600082518060408401526147108160608501602087016146a5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b8381526000835161475b8160208501602088016146a5565b60209201918201929092526040019392505050565b60006020828403121561478257600080fd5b815167ffffffffffffffff81111561479957600080fd5b8201601f810184136147aa57600080fd5b80516147b86144fd8261446f565b8181528560208385010111156147cd57600080fd5b6147de8260208301602086016146a5565b95945050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561481f5761481f614535565b500290565b6000821982111561483757614837614535565b500190565b600080600080600060a0868803121561485457600080fd5b85519450602086015193506040860151925060608601519150608086015161487b81613e4d565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826148c7576148c7614889565b500690565b6000826148db576148db614889565b500490565b600060ff8316806148f3576148f3614889565b8060ff84160691505092915050565b600060ff83168061491557614915614889565b8060ff84160491505092915050565b600181815b8085111561497d57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561496357614963614535565b8085161561497057918102915b93841c9390800290614929565b509250929050565b6000826149945750600161279b565b816149a15750600061279b565b81600181146149b757600281146149c1576149dd565b600191505061279b565b60ff8411156149d2576149d2614535565b50506001821b61279b565b5060208310610133831016604e8410600b8410161715614a00575081810a61279b565b614a0a8383614924565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614a3c57614a3c614535565b029392505050565b6000613c5f8383614985565b600060ff821660ff841680821015614a6a57614a6a614535565b9003939250505056fea26469706673582212209217d194649c8ac2c51aa00479d69ea51ac54bd1aa40db13a821cd0d44e3efe164736f6c634300080d003300000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a20000000000000000000000009df8aa7c681f33e442a0d57b838555da863504f300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd4d37e0907c9f564aaa0a7528837b81b25c6050000000000000000000000000612dbc8671270768a10d1f6d5d988fc4ff23a1b
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102c85760003560e01c8063860420e31161017b578063c0857ba0116100d8578063e72cb05b1161008c578063f2fde38b11610071578063f2fde38b146107b1578063f3fa98a7146107c4578063f953cec7146107d757600080fd5b8063e72cb05b14610765578063f23a6e611461077857600080fd5b8063c7059488116100bd578063c70594881461071d578063de9b771f14610725578063dfcedeee1461074557600080fd5b8063c0857ba0146106ea578063c5bf09641461070a57600080fd5b8063abbe08181161012f578063bbb781cc11610114578063bbb781cc1461068f578063bc197c811461069c578063bd88119f146106d757600080fd5b8063abbe081814610674578063aea4e49e1461067c57600080fd5b80638da5cb5b116101605780638da5cb5b14610623578063972c492814610641578063aaa687771461066157600080fd5b8063860420e3146105fd578063891bc3d21461061057600080fd5b806350acac5511610229578063652972d4116101dd57806370a08231116101c257806370a08231146105cf578063715018a6146105e25780638282052b146105ea57600080fd5b8063652972d41461059c5780636f251724146105bc57600080fd5b80635d939ed01161020e5780635d939ed014610542578063607f2d421461055557806363c28db11461057857600080fd5b806350acac551461050f578063584a22061461052257600080fd5b80631820743d116102805780632176dfce116102655780632176dfce146104d65780633b0d79fa146104e95780634f9ce271146104fc57600080fd5b80631820743d1461042f5780631959a0021461044257600080fd5b80630f147692116102b15780630f1476921461036c578063150b7a02146103b157806315b31bbb1461041a57600080fd5b806301ffc9a7146102cd5780630e387de614610337575b600080fd5b6103226102db366004613e0b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f7f5828d0000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61035e7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b60405190815260200161032e565b60055461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161032e565b6103e96103bf366004613eb8565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161032e565b61042d610428366004613f40565b6107ea565b005b61042d61043d366004613f7b565b61083f565b61049e610450366004613f96565b6009602052600090815260409020600181015460028201546003909201549091906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041684565b6040805194855260208501939093526fffffffffffffffffffffffffffffffff9182169284019290925216606082015260800161032e565b61042d6104e43660046140b1565b610a63565b61042d6104f73660046140e6565b610e28565b61042d61050a366004614119565b610e6e565b61042d61051d366004614119565b611031565b60065461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d610550366004613f7b565b611359565b610322610563366004614119565b60036020526000908152604090205460ff1681565b61058b610586366004613f96565b611535565b60405161032e959493929190614132565b60085461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d6105ca3660046141a3565b611642565b61035e6105dd366004613f96565b61167a565b61042d611752565b61042d6105f83660046140b1565b6117cd565b61042d61060b366004613f7b565b611a2c565b61042d61061e366004614213565b611c4f565b60045473ffffffffffffffffffffffffffffffffffffffff1661038c565b60025461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d61066f366004614293565b611c85565b61042d611d1e565b61042d61068a366004613f96565b611ed2565b600a546103229060ff1681565b6103e96106aa366004614334565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b61042d6106e53660046140e6565b611fa5565b60015461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d610718366004614119565b611fe7565b61042d61211c565b60005461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b60075461038c9073ffffffffffffffffffffffffffffffffffffffff1681565b61042d610773366004613f7b565b6122b8565b6103e96107863660046143f3565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b61042d6107bf366004613f96565b61247d565b61042d6107d2366004614119565b612515565b61042d6107e53660046144b5565b6126b7565b60045473ffffffffffffffffffffffffffffffffffffffff16331461080e57600080fd5b600a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600a5460ff16156108975760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e0000000060448201526064015b60405180910390fd5b806fffffffffffffffffffffffffffffffff166000036108f95760405162461bcd60e51b815260206004820152601960248201527f5374616b696e672030206973206e6f7420616c6c6f7765642e00000000000000604482015260640161088e565b336000908152600960205260408120600301805483929061092d9084906fffffffffffffffffffffffffffffffff16614564565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815233600482015230602482015260026044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b1580156109e357600080fd5b505af11580156109f7573d6000803e3d6000fd5b50610a609250339150600290505b6040805173ffffffffffffffffffffffffffffffffffffffff90931660208401528201526fffffffffffffffffffffffffffffffff831660608201526001608082015260a0015b6040516020818303038152906040526126c2565b50565b600a5460ff1615610ab65760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b336000908152600960205260408120815b8351811015610d79576000848281518110610ae457610ae46145c7565b60200260200101519050610b4a83600001805480602002602001604051908101604052809291908181526020018280548015610b3f57602002820191906000526020600020905b815481526020019060010190808311610b2b575b50505050508261274c565b610b965760405162461bcd60e51b815260206004820152601a60248201527f596f7520646f206e6f74206f776e2074686973206c6c616d612e000000000000604482015260640161088e565b6101f4811015610bac57610ba9846145f6565b93505b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810183905273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b158015610c2457600080fd5b505af1158015610c38573d6000803e3d6000fd5b5050845460408051602080840282018101909252828152600094509250869190830182828015610c8757602002820191906000526020600020905b815481526020019060010190808311610c73575b505050505090506000805b8251811015610cd15783838281518110610cae57610cae6145c7565b602002602001015103610cbf578091505b80610cc9816145f6565b915050610c92565b5082828281518110610ce557610ce56145c7565b602002602001015103610d635784548290610d029060019061462e565b81518110610d1257610d126145c7565b6020026020010151856000018281548110610d2f57610d2f6145c7565b6000918252602090912001558454859080610d4c57610d4c614645565b600190038181906000526020600020016000905590555b5050508080610d71906145f6565b915050610ac7565b508115610dc057610dc03360016040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152606081018490526000608082015260a001610a4c565b6000828451610dcf919061462e565b1115610e2357610e23336000848651610de8919061462e565b6040805173ffffffffffffffffffffffffffffffffffffffff909416602085015283019190915260608201526000608082015260a001610a4c565b505050565b6fffffffffffffffffffffffffffffffff821615610e4957610e498261083f565b6fffffffffffffffffffffffffffffffff811615610e6a57610e6a81611359565b5050565b600a5460ff1615610ec15760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b3360009081526009602052604090206002015415610f475760405162461bcd60e51b815260206004820152602560248201527f596f7520616c726561647920686176652061206c6c616d61647261777320737460448201527f616b65642e000000000000000000000000000000000000000000000000000000606482015260840161088e565b336000818152600960205260409081902060020183905560065490517f23b872dd00000000000000000000000000000000000000000000000000000000815260048101929092523060248301526044820183905273ffffffffffffffffffffffffffffffffffffffff16906323b872dd90606401600060405180830381600087803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b50610a609250339150600590505b6040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152600160608201819052608082015260a001610a4c565b600a5460ff16156110845760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b3360009081526009602090815260409182902080548351818402810184019094528084526101f485109391926110f1929184918301828280156110e657602002820191906000526020600020905b8154815260200190600101908083116110d2575b50505050508461274c565b61113d5760405162461bcd60e51b815260206004820152601a60248201527f596f7520646f206e6f74206f776e2074686973206c6c616d612e000000000000604482015260640161088e565b6005546040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810185905273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b1580156111b557600080fd5b505af11580156111c9573d6000803e3d6000fd5b505082546040805160208084028201810190925282815260009450925084919083018282801561121857602002820191906000526020600020905b815481526020019060010190808311611204575b505050505090506000805b8251811015611262578583828151811061123f5761123f6145c7565b602002602001015103611250578091505b8061125a816145f6565b915050611223565b5084828281518110611276576112766145c7565b602002602001015103611352576112e13385611293576000611296565b60015b60058111156112a7576112a7614598565b6040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152600160608201526000608082015260a001610a4c565b825482906112f19060019061462e565b81518110611301576113016145c7565b602002602001015183600001828154811061131e5761131e6145c7565b600091825260209091200155825483908061133b5761133b614645565b600190038181906000526020600020016000905590555b5050505050565b600a5460ff16156113ac5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b806fffffffffffffffffffffffffffffffff1660000361140e5760405162461bcd60e51b815260206004820152601960248201527f5374616b696e672030206973206e6f7420616c6c6f7765642e00000000000000604482015260640161088e565b336000908152600960205260409020600301805482919060109061145990849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16614564565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815233600482015230602482015260016044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b15801561150f57600080fd5b505af1158015611523573d6000803e3d6000fd5b50610a60925033915060039050610a05565b73ffffffffffffffffffffffffffffffffffffffff811660009081526009602090815260408083208151815460c09481028201850190935260a081018381526060959485948594859485949093919284928491908401828280156115b857602002820191906000526020600020905b8154815260200190600101908083116115a4575b5050509183525050600182015460208083019190915260028301546040808401919091526003909301546fffffffffffffffffffffffffffffffff8082166060808601919091527001000000000000000000000000000000009092041660809384015284519185015193850151908501519490920151909b929a5090985091965090945092505050565b84511561165257611652856117cd565b61165c8484610e28565b811561166b5761166b82612515565b80156113525761135281610e6e565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960209081526040808320805482518185028101850190935280835284938301828280156116e457602002820191906000526020600020905b8154815260200190600101908083116116d0575b5050505050905080516000036116fd5750600092915050565b60005b8151811015611748576101f482828151811061171e5761171e6145c7565b60200260200101511015611736575060019392505050565b80611740816145f6565b915050611700565b5060029392505050565b60045473ffffffffffffffffffffffffffffffffffffffff1633146117a3576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600a5460ff16156118205760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b336000908152600960205260408120815b8351811015611982576101f484828151811061184f5761184f6145c7565b6020026020010151101561186957611866836145f6565b92505b8160000184828151811061187f5761187f6145c7565b60209081029190910181015182546001810184556000938452919092200155600554845173ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90339030908890869081106118d8576118d86145c7565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529290911660248301526044820152606401600060405180830381600087803b15801561195757600080fd5b505af115801561196b573d6000803e3d6000fd5b50505050808061197a906145f6565b915050611831565b5081156119c9576119c93360016040805173ffffffffffffffffffffffffffffffffffffffff9093166020840152820152606081018490526001608082015260a001610a4c565b60008284516119d8919061462e565b1115610e2357610e233360008486516119f1919061462e565b6040805173ffffffffffffffffffffffffffffffffffffffff909416602085015283019190915260608201526001608082015260a001610a4c565b600a5460ff1615611a7f5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b806fffffffffffffffffffffffffffffffff16600003611ae15760405162461bcd60e51b815260206004820152601b60248201527f556e7374616b696e672030206973206e6f7420616c6c6f7765642e0000000000604482015260640161088e565b3360009081526009602052604090206003018054829190601090611b2c90849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16614674565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815230600482015233602482015260016044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b158015611be257600080fd5b505af1158015611bf6573d6000803e3d6000fd5b50610a609250339150600390505b6040805173ffffffffffffffffffffffffffffffffffffffff90931660208401528201526fffffffffffffffffffffffffffffffff831660608201526000608082015260a001610a4c565b845115611c5f57611c5f85610a63565b611c698484611fa5565b8115611c7757611c77611d1e565b80156113525761135261211c565b60045473ffffffffffffffffffffffffffffffffffffffff163314611ca957600080fd5b6005805473ffffffffffffffffffffffffffffffffffffffff9586167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216179091556006805494861694821694909417909355600780549285169284169290921790915560088054919093169116179055565b600a5460ff1615611d715760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b336000908152600960205260408120600101549003611df85760405162461bcd60e51b815260206004820152602760248201527f596f7520646f206e6f7420686176652061207069786c65742063616e7661732060448201527f7374616b65642e00000000000000000000000000000000000000000000000000606482015260840161088e565b6008543360008181526009602052604080822060019081015491517ff242432a00000000000000000000000000000000000000000000000000000000815230600482015260248101949094526044840191909152606483015260a0608483015260a482015273ffffffffffffffffffffffffffffffffffffffff9091169063f242432a9060c401600060405180830381600087803b158015611e9957600080fd5b505af1158015611ead573d6000803e3d6000fd5b505033600081815260096020526040812060010155611ed09250905060046112a7565b565b60025473ffffffffffffffffffffffffffffffffffffffff1615611f5e5760405162461bcd60e51b815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f53455400000000000000000000000000000000000000000000606482015260840161088e565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6fffffffffffffffffffffffffffffffff821615611fc657611fc6826122b8565b6fffffffffffffffffffffffffffffffff811615610e6a57610e6a81611a2c565b600a5460ff161561203a5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b33600081815260096020908152604080832080546001810182558185529290932090910184905560055490517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810193909352306024840152604483018490526101f484109273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b1580156120e057600080fd5b505af11580156120f4573d6000803e3d6000fd5b50505050610e23338361210857600061210b565b60015b6005811115610ff757610ff7614598565b600a5460ff161561216f5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b3360009081526009602052604081206002015490036121f55760405162461bcd60e51b8152602060048201526024808201527f596f7520646f206e6f7420686176652061206c6c616d6164726177732073746160448201527f6b65642e00000000000000000000000000000000000000000000000000000000606482015260840161088e565b60065433600081815260096020526040908190206002015490517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526024810192909252604482015273ffffffffffffffffffffffffffffffffffffffff909116906323b872dd90606401600060405180830381600087803b15801561228157600080fd5b505af1158015612295573d6000803e3d6000fd5b505033600081815260096020526040812060020155611ed09250905060056112a7565b600a5460ff161561230b5760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b806fffffffffffffffffffffffffffffffff1660000361236d5760405162461bcd60e51b815260206004820152601b60248201527f556e7374616b696e672030206973206e6f7420616c6c6f7765642e0000000000604482015260640161088e565b33600090815260096020526040812060030180548392906123a19084906fffffffffffffffffffffffffffffffff16614674565b82546101009290920a6fffffffffffffffffffffffffffffffff8181021990931691831602179091556007546040517ff242432a00000000000000000000000000000000000000000000000000000000815230600482015233602482015260026044820152918416606483015260a06084830152600060a483015273ffffffffffffffffffffffffffffffffffffffff16915063f242432a9060c401600060405180830381600087803b15801561245757600080fd5b505af115801561246b573d6000803e3d6000fd5b50610a60925033915060029050611c04565b60045473ffffffffffffffffffffffffffffffffffffffff1633146124ce576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600a5460ff16156125685760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604482015260640161088e565b33600090815260096020526040902060010154156125ee5760405162461bcd60e51b815260206004820152602860248201527f596f7520616c726561647920686176652061207069786c65742063616e76617360448201527f207374616b65642e000000000000000000000000000000000000000000000000606482015260840161088e565b33600081815260096020526040808220600190810185905560085491517ff242432a000000000000000000000000000000000000000000000000000000008152600481019490945230602485015260448401859052606484015260a0608484015260a483019190915273ffffffffffffffffffffffffffffffffffffffff169063f242432a9060c401600060405180830381600087803b15801561269157600080fd5b505af11580156126a5573d6000803e3d6000fd5b50610a60925033915060049050610ff7565b6000610e23826127a1565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b47204779261271e9291169085906004016146d5565b600060405180830381600087803b15801561273857600080fd5b505af1158015611352573d6000803e3d6000fd5b6000805b8351811015612795578284828151811061276c5761276c6145c7565b60200260200101510361278357600191505061279b565b8061278d816145f6565b915050612750565b50600090505b92915050565b606060006127ae83612b1b565b905060006127bb82612b7a565b905060006127c883612ba3565b90506000816127d684612bcc565b6127df86612dba565b6040516020016127f193929190614743565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935291205490915060ff16156128ac5760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f5353454400000000000000000000000000000000000000000000000000000000606482015260840161088e565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556128ec85612dd6565b905060006128f982612f20565b905061290481612fb0565b60025473ffffffffffffffffffffffffffffffffffffffff9081169116146129945760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c000000000000000000000000000000000000000000000000000000606482015260840161088e565b600061299f87612fd9565b90506129bf6129af846020015190565b876129b98a612ff5565b84613011565b612a315760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f460000000000000000000000000000000000000000000000000000000000606482015260840161088e565b612a5f85612a3e896132c4565b612a478a6132e0565b84612a518c6132fc565b612a5a8d613318565b613334565b506000612a6b83613480565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036612aa1612a9c8360006134bc565b6134f4565b14612aee5760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e415455524500604482015260640161088e565b6000612af98461356f565b806020019051810190612b0c9190614770565b9b9a5050505050505050505050565b6040805160208101909152606081526000612b65612b608460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b61358b565b60408051602081019091529081529392505050565b606061279b8260000151600881518110612b9657612b966145c7565b60200260200101516136a1565b600061279b8260000151600281518110612bbf57612bbf6145c7565b60200260200101516134f4565b6040805160208101909152600081528151606091901561279b57600080612bf460008661373e565b60f81c90506001811480612c0b57508060ff166003145b15612ccb57600185516002612c2091906147e7565b612c2a919061462e565b67ffffffffffffffff811115612c4257612c42613fb3565b6040519080825280601f01601f191660200182016040528015612c6c576020820181803683370190505b5092506000612c7c60018761373e565b90508084600081518110612c9257612c926145c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050612d2f565b600285516002612cdb91906147e7565b612ce5919061462e565b67ffffffffffffffff811115612cfd57612cfd613fb3565b6040519080825280601f01601f191660200182016040528015612d27576020820181803683370190505b509250600091505b60ff82165b8351811015612db157612d5e612d4d60ff85168361462e565b612d58906002614824565b8761373e565b848281518110612d7057612d706145c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080612da9816145f6565b915050612d34565b50505092915050565b600061279b8260000151600981518110612bbf57612bbf6145c7565b612dfa60405180606001604052806060815260200160608152602001600081525090565b612e148260000151600681518110612b9657612b966145c7565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152612e4a816137bf565b15612e5f57612e588161358b565b8252612f0c565b60208201518051600090612e759060019061462e565b67ffffffffffffffff811115612e8d57612e8d613fb3565b6040519080825280601f01601f191660200182016040528015612eb7576020820181803683370190505b509050600080836021019150826020019050612ed5828285516137fa565b604080518082018252600080825260209182015281518083019092528451825280850190820152612f059061358b565b8652505050505b612f1583612dba565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000612f6e8360000151600381518110612f6157612f616145c7565b602002602001015161358b565b836040015181518110612f8357612f836145c7565b602002602001015190506040518060400160405280828152602001612fa78361358b565b90529392505050565b600061279b8260200151600081518110612fcc57612fcc6145c7565b6020026020010151613878565b600061279b8260000151600581518110612bbf57612bbf6145c7565b606061279b8260000151600781518110612b9657612b966145c7565b6000806130458460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b905060006130528261358b565b9050606080856000806130648b612bcc565b9050805160000361307f5760009750505050505050506132bc565b60005b86518110156132b35781518311156130a5576000985050505050505050506132bc565b6130c78782815181106130ba576130ba6145c7565b6020026020010151613892565b9550858051906020012084146130e8576000985050505050505050506132bc565b6130fd878281518110612f6157612f616145c7565b945084516011036131cf578151830361315c578c8051906020012061312e86601081518110612b9657612b966145c7565b805190602001200361314b576001985050505050505050506132bc565b6000985050505050505050506132bc565b6000828481518110613170576131706145c7565b016020015160f81c9050601081111561319557600099505050505050505050506132bc565b6131ba868260ff16815181106131ad576131ad6145c7565b6020026020010151613911565b94506131c7600185614824565b9350506132a1565b845160020361314b5760006131fa6131f387600081518110612b9657612b966145c7565b848661393f565b83519091506132098286614824565b0361325c578d8051906020012061322c87600181518110612b9657612b966145c7565b805190602001200361324a57600199505050505050505050506132bc565b600099505050505050505050506132bc565b8060000361327657600099505050505050505050506132bc565b6132808185614824565b9350613298866001815181106131ad576131ad6145c7565b94506132a19050565b806132ab816145f6565b915050613082565b50505050505050505b949350505050565b600061279b8260000151600381518110612bbf57612bbf6145c7565b600061279b8260000151600481518110612bbf57612bbf6145c7565b600061279b8260000151600081518110612bbf57612bbf6145c7565b606061279b8260000151600181518110612b9657612b966145c7565b6001546040517f41539d4a0000000000000000000000000000000000000000000000000000000081526004810184905260009182918291829173ffffffffffffffffffffffffffffffffffffffff909116906341539d4a9060240160a060405180830381865afa1580156133ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d0919061483c565b5093505092509250613427828b6133e7919061462e565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588613a77565b6134735760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f48454144455200000000604482015260640161088e565b9998505050505050505050565b60408051602081019091526060815260405180602001604052806134b48460200151600181518110612f6157612f616145c7565b905292915050565b604080518082019091526000808252602082015282518051839081106134e4576134e46145c7565b6020026020010151905092915050565b80516000901580159061350957508151602110155b61351257600080fd5b60006135218360200151613bf0565b90506000818460000151613535919061462e565b905060008083866020015161354a9190614824565b905080519150602083101561356657826020036101000a820491505b50949350505050565b606061279b8260200151600281518110612b9657612b966145c7565b6060613596826137bf565b61359f57600080fd5b60006135aa83613c72565b905060008167ffffffffffffffff8111156135c7576135c7613fb3565b60405190808252806020026020018201604052801561360c57816020015b60408051808201909152600080825260208201528152602001906001900390816135e55790505b509050600061361e8560200151613bf0565b856020015161362d9190614824565b90506000805b848110156136965761364483613cf7565b915060405180604001604052808381526020018481525084828151811061366d5761366d6145c7565b60209081029190910101526136828284614824565b92508061368e816145f6565b915050613633565b509195945050505050565b80516060906136af57600080fd5b60006136be8360200151613bf0565b905060008184600001516136d2919061462e565b905060008167ffffffffffffffff8111156136ef576136ef613fb3565b6040519080825280601f01601f191660200182016040528015613719576020820181803683370190505b50905060008160200190506135668487602001516137379190614824565b8285613db9565b600061374b6002846148b8565b156137855760108261375e6002866148cc565b8151811061376e5761376e6145c7565b0160200151613780919060f81c6148e0565b6137b5565b6010826137936002866148cc565b815181106137a3576137a36145c7565b01602001516137b5919060f81c614902565b60f81b9392505050565b805160009081036137d257506000919050565b6020820151805160001a9060c08210156137f0575060009392505050565b5060019392505050565b8060000361380757505050565b6020811061383f578251825261381e602084614824565b925061382b602083614824565b915061383860208261462e565b9050613807565b6000600161384e83602061462e565b61385a90610100614a44565b613864919061462e565b935183518516941916939093179091525050565b805160009060151461388957600080fd5b61279b826134f4565b60606000826000015167ffffffffffffffff8111156138b3576138b3613fb3565b6040519080825280601f01601f1916602001820160405280156138dd576020820181803683370190505b50905080516000036138ef5792915050565b600081602001905061390a8460200151828660000151613db9565b5092915050565b805160009060211461392257600080fd5b600080836020015160016139369190614824565b51949350505050565b6000808061394c86612bcc565b90506000815167ffffffffffffffff81111561396a5761396a613fb3565b6040519080825280601f01601f191660200182016040528015613994576020820181803683370190505b509050845b82516139a59087614824565b811015613a485760008782815181106139c0576139c06145c7565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016905080836139f5898561462e565b81518110613a0557613a056145c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350508080613a40906145f6565b915050613999565b508080519060200120828051906020012003613a675781519250613a6c565b600092505b509095945050505050565b600060208251613a8791906148b8565b15613ad45760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642070726f6f66206c656e677468000000000000000000000000604482015260640161088e565b600060208351613ae491906148cc565b9050613af1816002614a44565b8510613b3f5760405162461bcd60e51b815260206004820152601560248201527f4c65616620696e64657820697320746f6f206269670000000000000000000000604482015260640161088e565b60008660205b85518111613be257858101519250613b5e6002896148b8565b600003613b96576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150613bc3565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b613bce6002896148cc565b9750613bdb602082614824565b9050613b45565b509094149695505050505050565b8051600090811a6080811015613c095750600092915050565b60b8811080613c24575060c08110801590613c24575060f881105b15613c325750600192915050565b60c0811015613c6657613c47600160b8614a50565b613c549060ff168261462e565b613c5f906001614824565b9392505050565b613c47600160f8614a50565b80516000908103613c8557506000919050565b600080613c958460200151613bf0565b8460200151613ca49190614824565b9050600084600001518560200151613cbc9190614824565b90505b80821015613cee57613cd082613cf7565b613cda9083614824565b915082613ce6816145f6565b935050613cbf565b50909392505050565b80516000908190811a6080811015613d12576001915061390a565b60b8811015613d3857613d2660808261462e565b613d31906001614824565b915061390a565b60c0811015613d655760b78103600185019450806020036101000a8551046001820181019350505061390a565b60f8811015613d7957613d2660c08261462e565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80600003613dc657505050565b60208110613dfe5782518252613ddd602084614824565b9250613dea602083614824565b9150613df760208261462e565b9050613dc6565b8060000361383f57505050565b600060208284031215613e1d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114613c5f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610a6057600080fd5b60008083601f840112613e8157600080fd5b50813567ffffffffffffffff811115613e9957600080fd5b602083019150836020828501011115613eb157600080fd5b9250929050565b600080600080600060808688031215613ed057600080fd5b8535613edb81613e4d565b94506020860135613eeb81613e4d565b935060408601359250606086013567ffffffffffffffff811115613f0e57600080fd5b613f1a88828901613e6f565b969995985093965092949392505050565b80358015158114613f3b57600080fd5b919050565b600060208284031215613f5257600080fd5b613c5f82613f2b565b80356fffffffffffffffffffffffffffffffff81168114613f3b57600080fd5b600060208284031215613f8d57600080fd5b613c5f82613f5b565b600060208284031215613fa857600080fd5b8135613c5f81613e4d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561402957614029613fb3565b604052919050565b600082601f83011261404257600080fd5b8135602067ffffffffffffffff82111561405e5761405e613fb3565b8160051b61406d828201613fe2565b928352848101820192828101908785111561408757600080fd5b83870192505b848310156140a65782358252918301919083019061408d565b979650505050505050565b6000602082840312156140c357600080fd5b813567ffffffffffffffff8111156140da57600080fd5b6132bc84828501614031565b600080604083850312156140f957600080fd5b61410283613f5b565b915061411060208401613f5b565b90509250929050565b60006020828403121561412b57600080fd5b5035919050565b60a0808252865190820181905260009060209060c0840190828a01845b8281101561416b5781518452928401929084019060010161414f565b505050908301969096525060408101939093526fffffffffffffffffffffffffffffffff918216606084015216608090910152919050565b600080600080600060a086880312156141bb57600080fd5b853567ffffffffffffffff8111156141d257600080fd5b6141de88828901614031565b9550506141ed60208701613f5b565b93506141fb60408701613f5b565b94979396509394606081013594506080013592915050565b600080600080600060a0868803121561422b57600080fd5b853567ffffffffffffffff81111561424257600080fd5b61424e88828901614031565b95505061425d60208701613f5b565b935061426b60408701613f5b565b925061427960608701613f2b565b915061428760808701613f2b565b90509295509295909350565b600080600080608085870312156142a957600080fd5b84356142b481613e4d565b935060208501356142c481613e4d565b925060408501356142d481613e4d565b915060608501356142e481613e4d565b939692955090935050565b60008083601f84011261430157600080fd5b50813567ffffffffffffffff81111561431957600080fd5b6020830191508360208260051b8501011115613eb157600080fd5b60008060008060008060008060a0898b03121561435057600080fd5b883561435b81613e4d565b9750602089013561436b81613e4d565b9650604089013567ffffffffffffffff8082111561438857600080fd5b6143948c838d016142ef565b909850965060608b01359150808211156143ad57600080fd5b6143b98c838d016142ef565b909650945060808b01359150808211156143d257600080fd5b506143df8b828c01613e6f565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561440c57600080fd5b863561441781613e4d565b9550602087013561442781613e4d565b94506040870135935060608701359250608087013567ffffffffffffffff81111561445157600080fd5b61445d89828a01613e6f565b979a9699509497509295939492505050565b600067ffffffffffffffff82111561448957614489613fb3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b6000602082840312156144c757600080fd5b813567ffffffffffffffff8111156144de57600080fd5b8201601f810184136144ef57600080fd5b80356145026144fd8261446f565b613fe2565b81815285602083850101111561451757600080fd5b81602084016020830137600091810160200191909152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006fffffffffffffffffffffffffffffffff80831681851680830382111561458f5761458f614535565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361462757614627614535565b5060010190565b60008282101561464057614640614535565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006fffffffffffffffffffffffffffffffff8381169083168181101561469d5761469d614535565b039392505050565b60005b838110156146c05781810151838201526020016146a8565b838111156146cf576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600082518060408401526147108160608501602087016146a5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b8381526000835161475b8160208501602088016146a5565b60209201918201929092526040019392505050565b60006020828403121561478257600080fd5b815167ffffffffffffffff81111561479957600080fd5b8201601f810184136147aa57600080fd5b80516147b86144fd8261446f565b8181528560208385010111156147cd57600080fd5b6147de8260208301602086016146a5565b95945050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561481f5761481f614535565b500290565b6000821982111561483757614837614535565b500190565b600080600080600060a0868803121561485457600080fd5b85519450602086015193506040860151925060608601519150608086015161487b81613e4d565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826148c7576148c7614889565b500690565b6000826148db576148db614889565b500490565b600060ff8316806148f3576148f3614889565b8060ff84160691505092915050565b600060ff83168061491557614915614889565b8060ff84160491505092915050565b600181815b8085111561497d57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561496357614963614535565b8085161561497057918102915b93841c9390800290614929565b509250929050565b6000826149945750600161279b565b816149a15750600061279b565b81600181146149b757600281146149c1576149dd565b600191505061279b565b60ff8411156149d2576149d2614535565b50506001821b61279b565b5060208310610133831016604e8410600b8410161715614a00575081810a61279b565b614a0a8383614924565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614a3c57614a3c614535565b029392505050565b6000613c5f8383614985565b600060ff821660ff841680821015614a6a57614a6a614535565b9003939250505056fea26469706673582212209217d194649c8ac2c51aa00479d69ea51ac54bd1aa40db13a821cd0d44e3efe164736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a20000000000000000000000009df8aa7c681f33e442a0d57b838555da863504f300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd4d37e0907c9f564aaa0a7528837b81b25c6050000000000000000000000000612dbc8671270768a10d1f6d5d988fc4ff23a1b
-----Decoded View---------------
Arg [0] : checkpointManager (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [1] : fxRoot (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
Arg [2] : _pixellatedLlamaContract (address): 0x9df8Aa7C681f33E442A0d57B838555da863504f3
Arg [3] : _llamaDrawsContract (address): 0x0000000000000000000000000000000000000000
Arg [4] : _boostContract (address): 0x0BD4D37E0907C9F564aaa0a7528837B81B25c605
Arg [5] : _pixletContract (address): 0x0612DBC8671270768A10d1F6D5D988fc4FF23A1B
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [1] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Arg [2] : 0000000000000000000000009df8aa7c681f33e442a0d57b838555da863504f3
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000bd4d37e0907c9f564aaa0a7528837b81b25c605
Arg [5] : 0000000000000000000000000612dbc8671270768a10d1f6d5d988fc4ff23a1b
Deployed Bytecode Sourcemap
557:19180:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;840:201:9;;;;;;:::i;:::-;975:25;;;;;840:201;;;;516:14:12;;509:22;491:41;;479:2;464:18;840:201:9;;;;;;;;1166:115:5;;1215:66;1166:115;;;;;689:25:12;;;677:2;662:18;1166:115:5;543:177:12;850:37:6;;;;;;;;;;;;916:42:12;904:55;;;886:74;;874:2;859:18;850:37:6;725:241:12;17016:224:6;;;;;;:::i;:::-;17188:45;17016:224;;;;;;;;;;;2415:66:12;2403:79;;;2385:98;;2373:2;2358:18;17016:224:6;2241:248:12;3304:95:6;;;;;;:::i;:::-;;:::i;:::-;;10451:514;;;;;;:::i;:::-;;:::i;1380:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3711:25:12;;;3767:2;3752:18;;3745:34;;;;3798;3868:15;;;3848:18;;;3841:43;;;;3920:15;3915:2;3900:18;;3893:43;3698:3;3683:19;1380:42:6;3480:462:12;6574:1696:6;;;;;;:::i;:::-;;:::i;12931:199::-;;;;;;:::i;:::-;;:::i;14841:508::-;;;;;;:::i;:::-;;:::i;9135:1220::-;;;;;;:::i;:::-;;:::i;953:32::-;;;;;;;;;11783:507;;;;;;:::i;:::-;;:::i;1564:46:5:-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;3878:533:6;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;1145:29::-;;;;;;;;;4603:417;;;;;;:::i;:::-;;:::i;3476:296::-;;;;;;:::i;:::-;;:::i;708:126:9:-;;;:::i;5421:1147:6:-;;;;;;:::i;:::-;;:::i;12413:512::-;;;;;;:::i;:::-;;:::i;5026:389::-;;;;;;:::i;:::-;;:::i;473:79:9:-;539:6;;;;473:79;;1489:28:5;;;;;;;;;2693:430:6;;;;;;:::i;:::-;;:::i;14126:609::-;;;:::i;1841:198:5:-;;;;;;:::i;:::-;;:::i;1429:25:6:-;;;;;;;;;19450:285;;;;;;:::i;:::-;19676:52;19450:285;;;;;;;;;;;13136:205;;;;;;:::i;:::-;;:::i;1377:43:5:-;;;;;;;;;8375:651:6;;;;;;:::i;:::-;;:::i;15396:565::-;;;:::i;1317:28:5:-;;;;;;;;;1054::6;;;;;;;;;11065:597;;;;;;:::i;:::-;;:::i;18189:251::-;;;;;;:::i;:::-;18386:47;18189:251;;;;;;;;;558:144:9;;;;;;:::i;:::-;;:::i;13480:596:6:-;;;;;;:::i;:::-;;:::i;6492:183:5:-;;;;;;:::i;:::-;;:::i;3304:95:6:-;372:6:9;;:20;:6;382:10;372:20;364:29;;;;;;3370:13:6::1;:22:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;3304:95::o;10451:514::-;10520:13;;;;10519:14;10511:55;;;;-1:-1:-1;;;10511:55:6;;13974:2:12;10511:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;10511:55:6;;;;;;;;;10584:6;:11;;10594:1;10584:11;10576:49;;;;-1:-1:-1;;;10576:49:6;;14331:2:12;10576:49:6;;;14313:21:12;14370:2;14350:18;;;14343:30;14409:27;14389:18;;;14382:55;14454:18;;10576:49:6;14129:349:12;10576:49:6;10645:10;10636:20;;;;:8;:20;;;;;:39;;:49;;10679:6;;10636:20;:49;;10679:6;;10636:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;10695:13;;:142;;;;;10739:10;10695:142;;;15294:34:12;10771:4:6;15344:18:12;;;15337:43;10790:1:6;15396:18:12;;;15389:34;15459:47;;;15439:18;;;15432:75;15544:3;15523:19;;;15516:32;-1:-1:-1;15564:19:12;;;15557:30;10695:13:6;;;-1:-1:-1;10695:30:6;;15604:19:12;;10695:142:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10847:111:6;;-1:-1:-1;10891:10:6;;-1:-1:-1;10911:21:6;;-1:-1:-1;10903:30:6;10880:68;;;16078:42:12;16066:55;;;10880:68:6;;;16048:74:12;16138:18;;16131:34;16213;16201:47;;16181:18;;;16174:75;10943:4:6;16265:18:12;;;16258:50;16020:19;;10880:68:6;;;;;;;;;;;;;10847:19;:111::i;:::-;10451:514;:::o;6574:1696::-;6658:13;;;;6657:14;6649:55;;;;-1:-1:-1;;;6649:55:6;;13974:2:12;6649:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;6649:55:6;13772:352:12;6649:55:6;6782:10;6714:21;6773:20;;;:8;:20;;;;;6714:21;6803:856;6827:8;:15;6823:1;:19;6803:856;;;6863:15;6881:8;6890:1;6881:11;;;;;;;;:::i;:::-;;;;;;;6863:29;;6914:45;6930:6;:19;;6914:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6951:7;6914:15;:45::i;:::-;6906:84;;;;-1:-1:-1;;;6906:84:6;;16710:2:12;6906:84:6;;;16692:21:12;16749:2;16729:18;;;16722:30;16788:28;16768:18;;;16761:56;16834:18;;6906:84:6;16508:350:12;6906:84:6;7018:3;7008:7;:13;7004:34;;;7023:15;;;:::i;:::-;;;7004:34;7052:23;;:134;;;;;7114:4;7052:134;;;17326:34:12;7137:10:6;17376:18:12;;;17369:43;17428:18;;;17421:34;;;7052:23:6;;;;;:36;;17238:18:12;;7052:134:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7201:51:6;;;;;;;;;;;;;;;;;;;:29;;-1:-1:-1;7201:51:6;-1:-1:-1;7233:6:6;;7201:51;;;7233:6;7201:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7266:13;7298:9;7293:120;7313:12;:19;7309:1;:23;7293:120;;;7380:7;7361:12;7374:1;7361:15;;;;;;;;:::i;:::-;;;;;;;:26;7357:41;;7397:1;7389:9;;7357:41;7334:3;;;;:::i;:::-;;;;7293:120;;;;7453:7;7430:12;7443:5;7430:19;;;;;;;;:::i;:::-;;;;;;;:30;7426:223;;7543:26;;7509:12;;7543:30;;7572:1;;7543:30;:::i;:::-;7509:82;;;;;;;;:::i;:::-;;;;;;;7480:6;:19;;7500:5;7480:26;;;;;;;;:::i;:::-;;;;;;;;;;:111;7609:25;;:6;;:25;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;7426:223;6849:810;;;6844:3;;;;;:::i;:::-;;;;6803:856;;;-1:-1:-1;7673:17:6;;7669:275;;7706:227;7775:10;7815:23;7743:176;;;18040:42:12;18028:55;;;7743:176:6;;;18010:74:12;18100:18;;18093:34;18143:18;;;18136:34;;;7896:5:6;18186:18:12;;;18179:50;17982:19;;7743:176:6;17785:450:12;7706:227:6;7993:1;7976:13;7958:8;:15;:31;;;;:::i;:::-;7957:37;7953:311;;;8010:243;8079:10;8119:21;8181:13;8163:8;:15;:31;;;;:::i;:::-;8047:192;;;18040:42:12;18028:55;;;8047:192:6;;;18010:74:12;18100:18;;18093:34;;;;18143:18;;;18136:34;8216:5:6;18186:18:12;;;18179:50;17982:19;;8047:192:6;17785:450:12;8010:243:6;6639:1631;;6574:1696;:::o;12931:199::-;13015:17;;;;13011:54;;13034:31;13052:12;13034:17;:31::i;:::-;13079:15;;;;13075:48;;13096:27;13112:10;13096:15;:27::i;:::-;12931:199;;:::o;14841:508::-;14909:13;;;;14908:14;14900:55;;;;-1:-1:-1;;;14900:55:6;;13974:2:12;14900:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;14900:55:6;13772:352:12;14900:55:6;14995:10;14986:20;;;;:8;:20;;;;;:37;;;:42;14965:126;;;;-1:-1:-1;;;14965:126:6;;18442:2:12;14965:126:6;;;18424:21:12;18481:2;18461:18;;;18454:30;18520:34;18500:18;;;18493:62;18591:7;18571:18;;;18564:35;18616:19;;14965:126:6;18240:401:12;14965:126:6;15111:10;15102:20;;;;:8;:20;;;;;;;:37;;:47;;;15159:18;;:67;;;;;;;;17326:34:12;;;;15211:4:6;17376:18:12;;;17369:43;17428:18;;;17421:34;;;15102:20:6;15159:18;;:31;;17238:18:12;;15159:67:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15237:105:6;;-1:-1:-1;15281:10:6;;-1:-1:-1;15301:20:6;;-1:-1:-1;15293:29:6;15270:62;;;18907:42:12;18895:55;;;15270:62:6;;;18877:74:12;18967:18;;18960:34;15324:1:6;19010:18:12;;;19003:45;;;19064:18;;;19057:50;18849:19;;15270:62:6;18646:467:12;9135:1220:6;9202:13;;;;9201:14;9193:55;;;;-1:-1:-1;;;9193:55:6;;13974:2:12;9193:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;9193:55:6;13772:352:12;9193:55:6;9330:10;9258:13;9321:20;;;:8;:20;;;;;;;;;9359:45;;;;;;;;;;;;;;;;;9284:3;9274:13;;;9321:20;;9359:45;;;9321:20;;9359:45;;9321:20;9359:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9396:7;9359:15;:45::i;:::-;9351:84;;;;-1:-1:-1;;;9351:84:6;;16710:2:12;9351:84:6;;;16692:21:12;16749:2;16729:18;;;16722:30;16788:28;16768:18;;;16761:56;16834:18;;9351:84:6;16508:350:12;9351:84:6;9446:23;;:118;;;;;9504:4;9446:118;;;17326:34:12;9523:10:6;17376:18:12;;;17369:43;17428:18;;;17421:34;;;9446:23:6;;;;;:36;;17238:18:12;;9446:118:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9575:51:6;;;;;;;;;;;;;;;;;;;:29;;-1:-1:-1;9575:51:6;-1:-1:-1;9607:6:6;;9575:51;;;9607:6;9575:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9636:13;9664:9;9659:112;9679:12;:19;9675:1;:23;9659:112;;;9742:7;9723:12;9736:1;9723:15;;;;;;;;:::i;:::-;;;;;;;:26;9719:41;;9759:1;9751:9;;9719:41;9700:3;;;;:::i;:::-;;;;9659:112;;;;9807:7;9784:12;9797:5;9784:19;;;;;;;;:::i;:::-;;;;;;;:30;9780:569;;9830:352;9899:10;9964:8;:114;;10057:21;9964:114;;;10003:23;9964:114;9931:169;;;;;;;;:::i;:::-;9867:301;;;18907:42:12;18895:55;;;9867:301:6;;;18877:74:12;18967:18;;18960:34;10122:1:6;19010:18:12;;;19003:45;10145:5:6;19064:18:12;;;19057:50;18849:19;;9867:301:6;18646:467:12;9830:352:6;10255:26;;10225:12;;10255:30;;10284:1;;10255:30;:::i;:::-;10225:74;;;;;;;;:::i;:::-;;;;;;;10196:6;:19;;10216:5;10196:26;;;;;;;;:::i;:::-;;;;;;;;;;:103;10313:25;;:6;;:25;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;9780:569;9183:1172;;;;9135:1220;:::o;11783:507::-;11850:13;;;;11849:14;11841:55;;;;-1:-1:-1;;;11841:55:6;;13974:2:12;11841:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;11841:55:6;13772:352:12;11841:55:6;11914:6;:11;;11924:1;11914:11;11906:49;;;;-1:-1:-1;;;11906:49:6;;14331:2:12;11906:49:6;;;14313:21:12;14370:2;14350:18;;;14343:30;14409:27;14389:18;;;14382:55;14454:18;;11906:49:6;14129:349:12;11906:49:6;11974:10;11965:20;;;;:8;:20;;;;;:37;;:47;;12006:6;;11965:37;;;:47;;12006:6;;11965:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;12022:13;;:142;;;;;12066:10;12022:142;;;15294:34:12;12098:4:6;15344:18:12;;;15337:43;-1:-1:-1;15396:18:12;;;15389:34;15459:47;;;15439:18;;;15432:75;15544:3;15523:19;;;15516:32;-1:-1:-1;15564:19:12;;;15557:30;12022:13:6;;;-1:-1:-1;12022:30:6;;15604:19:12;;12022:142:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12174:109:6;;-1:-1:-1;12218:10:6;;-1:-1:-1;12238:19:6;;-1:-1:-1;12230:28:6;;3878:533;4178:14;;;4012:20;4178:14;;;:8;:14;;;;;;;;4155:37;;;;;;;;;;;;;;;;;;;;;3975:23;;4012:20;;;;;;;;;4155:37;;4178:14;;4155:37;;4178:14;;4155:37;;;4178:14;4155:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4155:37:6;;;-1:-1:-1;;4155:37:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4223:19;;4256:25;;;;4295:23;;;;4332:25;;;;4371:23;;;;;4223:19;;4256:25;;-1:-1:-1;4295:23:6;;-1:-1:-1;4332:25:6;;-1:-1:-1;4371:23:6;;-1:-1:-1;3878:533:6;-1:-1:-1;;;3878:533:6:o;4603:417::-;4798:13;;:17;4794:50;;4817:27;4837:6;4817:19;:27::i;:::-;4854:37;4866:12;4880:10;4854:11;:37::i;:::-;4905:17;;4901:54;;4924:31;4942:12;4924:17;:31::i;:::-;4969:15;;4965:48;;4986:27;5002:10;4986:15;:27::i;3476:296::-;3573:15;;;3531:7;3573:15;;;:8;:15;;;;;;;;3550:51;;;;;;;;;;;;;;;;;3531:7;;3550:51;;3573:15;3550:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3614:6;:13;3631:1;3614:18;3611:31;;-1:-1:-1;3641:1:6;;3476:296;-1:-1:-1;;3476:296:6:o;3611:31::-;3657:9;3652:96;3676:6;:13;3672:1;:17;3652:96;;;3724:3;3712:6;3719:1;3712:9;;;;;;;;:::i;:::-;;;;;;;:15;3709:28;;;-1:-1:-1;3736:1:6;;3476:296;-1:-1:-1;;;3476:296:6:o;3709:28::-;3691:3;;;;:::i;:::-;;;;3652:96;;;-1:-1:-1;3764:1:6;;3476:296;-1:-1:-1;;;3476:296:6:o;708:126:9:-;772:6;;;;758:10;:20;754:43;;787:10;;;;;;;;;;;;;;754:43;808:6;:19;;;;;;708:126::o;5421:1147:6:-;5503:13;;;;5502:14;5494:55;;;;-1:-1:-1;;;5494:55:6;;13974:2:12;5494:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;5494:55:6;13772:352:12;5494:55:6;5627:10;5559:21;5618:20;;;:8;:20;;;;;5559:21;5648:312;5672:8;:15;5668:1;:19;5648:312;;;5726:3;5712:8;5721:1;5712:11;;;;;;;;:::i;:::-;;;;;;;:17;5708:38;;;5731:15;;;:::i;:::-;;;5708:38;5760:6;:19;;5785:8;5794:1;5785:11;;;;;;;;:::i;:::-;;;;;;;;;;;;5760:37;;;;;;;-1:-1:-1;5760:37:6;;;;;;;;;5811:23;;5924:11;;5811:23;;;;;:36;;5865:10;;5901:4;;5924:8;;5933:1;;5924:11;;;;;;:::i;:::-;;;;;;;;;;;5811:138;;;;;;;;;;17275:42:12;17344:15;;;5811:138:6;;;17326:34:12;17396:15;;;;17376:18;;;17369:43;17428:18;;;17421:34;17238:18;;5811:138:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5689:3;;;;;:::i;:::-;;;;5648:312;;;-1:-1:-1;5973:17:6;;5969:274;;6006:226;6075:10;6115:23;6043:175;;;18040:42:12;18028:55;;;6043:175:6;;;18010:74:12;18100:18;;18093:34;18143:18;;;18136:34;;;6196:4:6;18186:18:12;;;18179:50;17982:19;;6043:175:6;17785:450:12;6006:226:6;6292:1;6275:13;6257:8;:15;:31;;;;:::i;:::-;6256:37;6252:310;;;6309:242;6378:10;6418:21;6480:13;6462:8;:15;:31;;;;:::i;:::-;6346:191;;;18040:42:12;18028:55;;;6346:191:6;;;18010:74:12;18100:18;;18093:34;;;;18143:18;;;18136:34;6515:4:6;18186:18:12;;;18179:50;17982:19;;6346:191:6;17785:450:12;12413:512:6;12482:13;;;;12481:14;12473:55;;;;-1:-1:-1;;;12473:55:6;;13974:2:12;12473:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;12473:55:6;13772:352:12;12473:55:6;12546:6;:11;;12556:1;12546:11;12538:51;;;;-1:-1:-1;;;12538:51:6;;20024:2:12;12538:51:6;;;20006:21:12;20063:2;20043:18;;;20036:30;20102:29;20082:18;;;20075:57;20149:18;;12538:51:6;19822:351:12;12538:51:6;12608:10;12599:20;;;;:8;:20;;;;;:37;;:47;;12640:6;;12599:37;;;:47;;12640:6;;12599:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;12656:13;;:142;;;;;12708:4;12656:142;;;15294:34:12;12727:10:6;15344:18:12;;;15337:43;-1:-1:-1;15396:18:12;;;15389:34;15459:47;;;15439:18;;;15432:75;15544:3;15523:19;;;15516:32;-1:-1:-1;15564:19:12;;;15557:30;12656:13:6;;;-1:-1:-1;12656:30:6;;15604:19:12;;12656:142:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12808:110:6;;-1:-1:-1;12852:10:6;;-1:-1:-1;12872:19:6;;-1:-1:-1;12864:28:6;12841:67;;;16078:42:12;16066:55;;;12841:67:6;;;16048:74:12;16138:18;;16131:34;16213;16201:47;;16181:18;;;16174:75;12902:5:6;16265:18:12;;;16258:50;16020:19;;12841:67:6;15823:491:12;5026:389:6;5217:13;;:17;5213:52;;5236:29;5258:6;5236:21;:29::i;:::-;5275:39;5289:12;5303:10;5275:13;:39::i;:::-;5328:12;5324:39;;;5342:21;:19;:21::i;:::-;5377:10;5373:35;;;5389:19;:17;:19::i;2693:430::-;372:6:9;;:20;:6;382:10;372:20;364:29;;;;;;2900:23:6::1;:58:::0;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;;2968:18:::1;:48:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;3026:13:::1;:39:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;3075:14:::1;:41:::0;;;;;::::1;::::0;::::1;;::::0;;2693:430::o;14126:609::-;14183:13;;;;14182:14;14174:55;;;;-1:-1:-1;;;14174:55:6;;13974:2:12;14174:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;14174:55:6;13772:352:12;14174:55:6;14269:10;14260:20;;;;:8;:20;;;;;:39;;;:44;;14239:130;;;;-1:-1:-1;;;14239:130:6;;20631:2:12;14239:130:6;;;20613:21:12;20670:2;20650:18;;;20643:30;20709:34;20689:18;;;20682:62;20780:9;20760:18;;;20753:37;20807:19;;14239:130:6;20429:403:12;14239:130:6;14380:14;;14452:10;14380:14;14476:20;;;:8;:20;;;;;;14380:14;14476:39;;;;14380:176;;;;;14433:4;14380:176;;;21201:34:12;21251:18;;;21244:43;;;;21303:18;;;21296:34;;;;21346:18;;;21339:34;21410:3;21389:19;;;21382:32;21430:19;;;21423:30;14380:14:6;;;;;:31;;21470:19:12;;14380:176:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14575:10:6;14608:1;14566:20;;;:8;:20;;;;;:39;;:43;14620:108;;-1:-1:-1;14575:10:6;-1:-1:-1;14684:22:6;14676:31;;14620:108;14126:609::o;1841:198:5:-;1916:13;;:29;:13;:29;1908:84;;;;-1:-1:-1;;;1908:84:5;;21702:2:12;1908:84:5;;;21684:21:12;21741:2;21721:18;;;21714:30;21780:34;21760:18;;;21753:62;21851:12;21831:18;;;21824:40;21881:19;;1908:84:5;21500:406:12;1908:84:5;2002:13;:30;;;;;;;;;;;;;;;1841:198::o;13136:205:6:-;13222:17;;;;13218:56;;13241:33;13261:12;13241:19;:33::i;:::-;13288:15;;;;13284:50;;13305:29;13323:10;13305:17;:29::i;8375:651::-;8440:13;;;;8439:14;8431:55;;;;-1:-1:-1;;;8431:55:6;;13974:2:12;8431:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;8431:55:6;13772:352:12;8431:55:6;8568:10;8496:13;8559:20;;;:8;:20;;;;;;;;8589:33;;;;;;;;;;;;;;;;;;;;8632:23;;:118;;;;;;;;17326:34:12;;;;8714:4:6;17376:18:12;;;17369:43;17428:18;;;17421:34;;;8522:3:6;8512:13;;;8559:20;8632:23;;;;:36;;17238:18:12;;8632:118:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8760:259;8821:10;8878:8;:58;;8915:21;8878:58;;;8889:23;8878:58;8849:105;;;;;;;;:::i;15396:565::-;15451:13;;;;15450:14;15442:55;;;;-1:-1:-1;;;15442:55:6;;13974:2:12;15442:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;15442:55:6;13772:352:12;15442:55:6;15537:10;15528:20;;;;:8;:20;;;;;:37;;;:42;;15507:125;;;;-1:-1:-1;;;15507:125:6;;22113:2:12;15507:125:6;;;22095:21:12;22152:2;22132:18;;;22125:30;22191:34;22171:18;;;22164:62;22262:6;22242:18;;;22235:34;22286:19;;15507:125:6;21911:400:12;15507:125:6;15643:18;;15715:10;15643:18;15739:20;;;:8;:20;;;;;;;:37;;;15643:143;;;;;15696:4;15643:143;;;17326:34:12;17376:18;;;17369:43;;;;17428:18;;;17421:34;15643:18:6;;;;;:31;;17238:18:12;;15643:143:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15805:10:6;15836:1;15796:20;;;:8;:20;;;;;:37;;:41;15848:106;;-1:-1:-1;15805:10:6;-1:-1:-1;15912:20:6;15904:29;;11065:597;11136:13;;;;11135:14;11127:55;;;;-1:-1:-1;;;11127:55:6;;13974:2:12;11127:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;11127:55:6;13772:352:12;11127:55:6;11200:6;:11;;11210:1;11200:11;11192:51;;;;-1:-1:-1;;;11192:51:6;;20024:2:12;11192:51:6;;;20006:21:12;20063:2;20043:18;;;20036:30;20102:29;20082:18;;;20075:57;20149:18;;11192:51:6;19822:351:12;11192:51:6;11263:10;11254:20;;;;:8;:20;;;;;:39;;:49;;11297:6;;11254:20;:49;;11297:6;;11254:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;11313:13;;:142;;;;;11365:4;11313:142;;;15294:34:12;11384:10:6;15344:18:12;;;15337:43;11408:1:6;15396:18:12;;;15389:34;15459:47;;;15439:18;;;15432:75;15544:3;15523:19;;;15516:32;-1:-1:-1;15564:19:12;;;15557:30;11313:13:6;;;-1:-1:-1;11313:30:6;;15604:19:12;;11313:142:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11465:190:6;;-1:-1:-1;11526:10:6;;-1:-1:-1;11562:21:6;;-1:-1:-1;11554:30:6;;558:144:9;641:6;;;;627:10;:20;623:43;;656:10;;;;;;;;;;;;;;623:43;677:6;:18;;;;;;;;;;;;;;;558:144::o;13480:596:6:-;13550:13;;;;13549:14;13541:55;;;;-1:-1:-1;;;13541:55:6;;13974:2:12;13541:55:6;;;13956:21:12;14013:2;13993:18;;;13986:30;14052;14032:18;;;14025:58;14100:18;;13541:55:6;13772:352:12;13541:55:6;13636:10;13627:20;;;;:8;:20;;;;;:39;;;:44;13606:131;;;;-1:-1:-1;;;13606:131:6;;22518:2:12;13606:131:6;;;22500:21:12;22557:2;22537:18;;;22530:30;22596:34;22576:18;;;22569:62;22667:10;22647:18;;;22640:38;22695:19;;13606:131:6;22316:404:12;13606:131:6;13757:10;13748:20;;;;:8;:20;;;;;;:39;;;;:49;;;13807:14;;:144;;;;;;;;21201:34:12;;;;13884:4:6;21251:18:12;;;21244:43;21303:18;;;21296:34;;;21346:18;;;21339:34;21410:3;21389:19;;;21382:32;21430:19;;;21423:30;;;;13748:20:6;13807:14;;:31;;21470:19:12;;13807:144:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13962:107:6;;-1:-1:-1;14006:10:6;;-1:-1:-1;14026:22:6;;-1:-1:-1;14018:31:6;;6492:183:5;6565:20;6588:37;6615:9;6588:26;:37::i;2334:126::-;2404:6;;2430:13;;2404:49;;;;;:6;;;;;:25;;:49;;2430:13;;;2445:7;;2404:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16100:233:6;16181:4;;16197:108;16221:8;:15;16217:1;:19;16197:108;;;16274:7;16259:8;16268:1;16259:11;;;;;;;;:::i;:::-;;;;;;;:22;16256:38;;16290:4;16283:11;;;;;16256:38;16238:3;;;;:::i;:::-;;;;16197:108;;;;16321:5;16314:12;;16100:233;;;;;:::o;2466:2358:5:-;2544:12;2568:44;2615:25;:9;:23;:25::i;:::-;2568:72;;2651:28;2682:30;:7;:28;:30::i;:::-;2651:61;;2722:19;2744:24;:7;:22;:24::i;:::-;2722:46;;2927:16;3003:11;3295:52;3331:15;3295:35;:52::i;:::-;3365:28;:7;:26;:28::i;:::-;2969:438;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;2946:471;;2969:438;2946:471;;;;3435:24;;;;:14;:24;;;;;;2946:471;;-1:-1:-1;3435:24:5;;:33;3427:82;;;;-1:-1:-1;;;3427:82:5;;24191:2:12;3427:82:5;;;24173:21:12;24230:2;24210:18;;;24203:30;24269:34;24249:18;;;24242:62;24340:6;24320:18;;;24313:34;24364:19;;3427:82:5;23989:400:12;3427:82:5;3519:24;;;;:14;:24;;;;;:31;;;;3546:4;3519:31;;;3604:20;:7;:18;:20::i;:::-;3561:63;;3634:32;3669:16;:7;:14;:16::i;:::-;3634:51;;3751:16;:3;:14;:16::i;:::-;3734:13;;:33;:13;;;:33;;;3726:83;;;;-1:-1:-1;;;3726:83:5;;24596:2:12;3726:83:5;;;24578:21:12;24635:2;24615:18;;;24608:30;24674:34;24654:18;;;24647:62;24745:7;24725:18;;;24718:35;24770:19;;3726:83:5;24394:401:12;3726:83:5;3820:19;3842:24;:7;:22;:24::i;:::-;3820:46;;3933:102;3960:17;:7;4045:11:3;;;;3950:113;3960:17:5;3979:15;3996:25;:7;:23;:25::i;:::-;4023:11;3933:26;:102::i;:::-;3912:184;;;;-1:-1:-1;;;3912:184:5;;25002:2:12;3912:184:5;;;24984:21:12;25041:2;25021:18;;;25014:30;25080:34;25060:18;;;25053:62;25151:5;25131:18;;;25124:33;25174:19;;3912:184:5;24800:399:12;3912:184:5;4146:238;4193:11;4218:22;:7;:20;:22::i;:::-;4254:19;:7;:17;:19::i;:::-;4287:11;4312:25;:7;:23;:25::i;:::-;4351:23;:7;:21;:23::i;:::-;4146:33;:238::i;:::-;;4395:41;4439:15;:3;:13;:15::i;:::-;4395:59;-1:-1:-1;1215:66:5;4494:27;:18;4395:59;4526:22;4494:15;:18::i;:::-;:25;:27::i;:::-;4486:62;4465:163;;;;-1:-1:-1;;;4465:163:5;;25406:2:12;4465:163:5;;;25388:21:12;25445:2;25425:18;;;25418:30;25484:33;25464:18;;;25457:61;25535:18;;4465:163:5;25204:355:12;4465:163:5;4672:20;4706:13;:3;:11;:13::i;:::-;4695:34;;;;;;;;;;;;:::i;:::-;4672:57;2466:2358;-1:-1:-1;;;;;;;;;;;2466:2358:5:o;1373:210:3:-;-1:-1:-1;;;;;;;;;;;;1468:38:3;1509:25;:16;:4;-1:-1:-1;;;;;;;;;;;;;;;;;1650:28:10;;;;;;;;1658:11;;1650:28;;1608:15;;;1650:28;;;;;;;;1464:221;1509:16:3;:23;:25::i;:::-;1552:24;;;;;;;;;;;;;1373:210;-1:-1:-1;;;1373:210:3:o;3492:144::-;3573:12;3604:25;:7;:12;;;3617:1;3604:15;;;;;;;;:::i;:::-;;;;;;;:23;:25::i;1871:132::-;1946:7;1972:24;:7;:12;;;1985:1;1972:15;;;;;;;;:::i;:::-;;;;;;;:22;:24::i;3875:775:8:-;3963:25;;;;;;;;;:20;:25;;4002:8;;3939:12;;3963:25;4002:12;3998:622;;4030:12;4056:14;4079:26;4100:1;4103;4079:20;:26::i;:::-;4073:33;;;-1:-1:-1;4136:1:8;4124:13;;;:30;;;4141:8;:13;;4153:1;4141:13;4124:30;4120:341;;;4209:1;4194;:8;4205:1;4194:12;;;;:::i;:::-;:16;;;;:::i;:::-;4184:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4184:27:8;;4174:37;;4229:16;4248:26;4269:1;4272;4248:20;:26::i;:::-;4229:45;;4305:9;4292:7;4300:1;4292:10;;;;;;;;:::i;:::-;;;;:22;;;;;;;;;;;4341:1;4332:10;;4156:201;4120:341;;;4416:1;4401;:8;4412:1;4401:12;;;;:::i;:::-;:16;;;;:::i;:::-;4391:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4391:27:8;;4381:37;;4445:1;4436:10;;4120:341;4480:18;;;4475:135;4504:7;:14;4500:1;:18;4475:135;;;4556:39;4577:10;;;;:1;:10;:::i;:::-;:14;;4590:1;4577:14;:::i;:::-;4593:1;4556:20;:39::i;:::-;4543:7;4551:1;4543:10;;;;;;;;:::i;:::-;;;;:52;;;;;;;;;;-1:-1:-1;4520:3:8;;;;:::i;:::-;;;;4475:135;;;;4016:604;;4636:7;3875:775;-1:-1:-1;;3875:775:8:o;3785:136:3:-;3864:7;3890:24;:7;:12;;;3903:1;3890:15;;;;;;;;:::i;2434:907::-;2505:22;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;2505:22:3;2553:25;:7;:12;;;2566:1;2553:15;;;;;;;;:::i;:25::-;2539:11;;;;:39;;;-1:-1:-1;;;;;;;;;;;;;;;;1650:28:10;;;;;;;;1658:11;;1650:28;;1608:15;;;1650:28;;;;2665:20:3;1650:28:10;2665:18:3;:20::i;:::-;2661:593;;;2741:20;:11;:18;:20::i;:::-;2726:35;;2661:593;;;2872:11;;;;2929:17;;2846:23;;2929:21;;2949:1;;2929:21;:::i;:::-;2919:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2919:32:3;;2897:54;;2965:14;2993:15;3067:10;3063:2;3059:19;3049:29;;3116:6;3110:4;3106:17;3095:28;;3151:36;3156:6;3164:7;3173:6;:13;3151:4;:36::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;1650:28:10;;;;;;;;1658:11;;1650:28;;1608:15;;;1650:28;;;;3216:27:3;;1509:23;:25::i;3216:27::-;3201:42;;-1:-1:-1;;;;2661:593:3;3283:27;3302:7;3283:18;:27::i;:::-;3264:16;;;:46;-1:-1:-1;3264:7:3;2434:907;-1:-1:-1;2434:907:3:o;4069:216::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4154:32:3;4189:24;:7;:12;;;4202:1;4189:15;;;;;;;;:::i;:::-;;;;;;;:22;:24::i;:::-;4214:7;:16;;;4189:42;;;;;;;;:::i;:::-;;;;;;;4154:77;;4248:30;;;;;;;;4252:7;4248:30;;;;4261:16;:7;:14;:16::i;:::-;4248:30;;4241:37;4069:216;-1:-1:-1;;;4069:216:3:o;4310:124::-;4369:7;4395:32;4415:3;:8;;;4424:1;4415:11;;;;;;;;:::i;:::-;;;;;;;4395:19;:32::i;2287:141::-;2362:7;2396:24;:7;:12;;;2409:1;2396:15;;;;;;;;:::i;3347:139::-;3423:12;3454:25;:7;:12;;;3467:1;3454:15;;;;;;;;:::i;473:2402:8:-;639:4;655:29;687:35;707:14;-1:-1:-1;;;;;;;;;;;;;;;;;1650:28:10;;;;;;;;1658:11;;1650:28;;1608:15;;;1650:28;;;;;;;;1464:221;687:35:8;655:67;;732:38;773:22;790:4;773:16;:22::i;:::-;732:63;-1:-1:-1;806:24:8;;911:4;893:15;;975:28;991:11;975:15;:28::i;:::-;955:48;;1017:4;:11;1032:1;1017:16;1013:59;;1056:5;1049:12;;;;;;;;;;;1013:59;1087:9;1082:1787;1106:11;:18;1102:1;:22;1082:1787;;;1159:4;:11;1149:7;:21;1145:72;;;1197:5;1190:12;;;;;;;;;;;;1145:72;1245:36;1266:11;1278:1;1266:14;;;;;;;;:::i;:::-;;;;;;;1245:20;:36::i;:::-;1231:50;;1320:11;1310:22;;;;;;1299:7;:33;1295:84;;1359:5;1352:12;;;;;;;;;;;;1295:84;1410:32;1427:11;1439:1;1427:14;;;;;;;;:::i;1410:32::-;1392:50;;1461:15;:22;1487:2;1461:28;1457:1402;;1524:4;:11;1513:7;:22;1509:270;;1626:5;1616:16;;;;;;1573:38;1591:15;1607:2;1591:19;;;;;;;;:::i;1573:38::-;1563:49;;;;;;:69;1559:202;;1667:4;1660:11;;;;;;;;;;;;1559:202;1733:5;1726:12;;;;;;;;;;;;1559:202;1797:20;1826:4;1831:7;1826:13;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;1879:2:8;1862:19;;1858:78;;;1912:5;1905:12;;;;;;;;;;;;;1858:78;1971:55;1994:15;2010:14;1994:31;;;;;;;;;;:::i;:::-;;;;;;;1971:22;:55::i;:::-;1963:64;-1:-1:-1;2045:12:8;2056:1;2045:12;;:::i;:::-;;;1491:581;1457:1402;;;2082:15;:22;2108:1;2082:27;2078:781;;2129:17;2149:72;2168:37;2186:15;2202:1;2186:18;;;;;;;;:::i;2168:37::-;2207:4;2213:7;2149:18;:72::i;:::-;2266:11;;2129:92;;-1:-1:-1;2243:19:8;2129:92;2243:7;:19;:::i;:::-;:34;2239:313;;2399:5;2389:16;;;;;;2347:37;2365:15;2381:1;2365:18;;;;;;;;:::i;2347:37::-;2337:48;;;;;;:68;2333:201;;2440:4;2433:11;;;;;;;;;;;;;2333:201;2506:5;2499:12;;;;;;;;;;;;;2333:201;2607:9;2620:1;2607:14;2603:73;;2652:5;2645:12;;;;;;;;;;;;;2603:73;2694:20;2705:9;2694:20;;:::i;:::-;;;2750:42;2773:15;2789:1;2773:18;;;;;;;;:::i;2750:42::-;2742:51;-1:-1:-1;2078:781:8;;-1:-1:-1;2078:781:8;;1126:3;;;;:::i;:::-;;;;1082:1787;;;;645:2230;;;;;;;473:2402;;;;;;;:::o;2009:130:3:-;2082:7;2108:24;:7;:12;;;2121:1;2108:15;;;;;;;;:::i;2145:136::-;2215:7;2249:24;:7;:12;;;2262:1;2249:15;;;;;;;;:::i;1589:133::-;1665:7;1691:24;:7;:12;;;1704:1;1691:15;;;;;;;;:::i;1728:137::-;1802:12;1833:25;:7;:12;;;1846:1;1833:15;;;;;;;;:::i;4830:691:5:-;5158:17;;:44;;;;;;;;689:25:12;;;5073:7:5;;;;;;;;5158:17;;;;;:30;;662:18:12;;5158:44:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5092:110;;;;;;;;5234:200;5354:10;5340:11;:24;;;;:::i;:::-;5244:61;;;;;;;27284:19:12;;;27319:12;;;27312:28;;;27356:12;;;27349:28;;;27393:12;;;;27386:28;;;5244:61:5;;;;;;;;;;27430:13:12;;;;5244:61:5;;;5234:72;;;;;;5382:10;5410;5234:88;:200::i;:::-;5213:275;;;;-1:-1:-1;;;5213:275:5;;27656:2:12;5213:275:5;;;27638:21:12;27695:2;27675:18;;;27668:30;27734;27714:18;;;27707:58;27782:18;;5213:275:5;27454:352:12;5213:275:5;5505:9;4830:691;-1:-1:-1;;;;;;;;;4830:691:5:o;4440:131:3:-;-1:-1:-1;;;;;;;;;;;;4533:31:3;;;;;;;;4543:20;:3;:8;;;4552:1;4543:11;;;;;;;;:::i;:20::-;4533:31;;4526:38;4440:131;-1:-1:-1;;4440:131:3:o;4847:149::-;-1:-1:-1;;;;;;;;;;;;;;;;;4971:11:3;;:18;;4983:5;;4971:18;;;;;;:::i;:::-;;;;;;;4964:25;;4847:149;;;;:::o;5560:546:10:-;5647:8;;5620:7;;5647:12;;;;:30;;-1:-1:-1;5663:8:10;;5675:2;-1:-1:-1;5663:14:10;5647:30;5639:39;;;;;;5689:14;5706:27;5721:4;:11;;;5706:14;:27::i;:::-;5689:44;;5743:11;5768:6;5757:4;:8;;;:17;;;;:::i;:::-;5743:31;;5785:14;5809;5840:6;5826:4;:11;;;:20;;;;:::i;:::-;5809:37;;5895:6;5889:13;5879:23;;5985:2;5980:3;5977:11;5974:92;;;6046:3;6042:2;6038:12;6033:3;6029:22;6021:6;6017:35;6007:45;;5974:92;-1:-1:-1;6093:6:10;5560:546;-1:-1:-1;;;;5560:546:10:o;4577:115:3:-;4633:12;4664:21;:3;:8;;;4673:1;4664:11;;;;;;;;:::i;2483:519:10:-;2543:16;2579:12;2586:4;2579:6;:12::i;:::-;2571:21;;;;;;2603:13;2619:14;2628:4;2619:8;:14::i;:::-;2603:30;;2643:23;2683:5;2669:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;2669:20:10;;;;;;;;;;;;;;;;2643:46;;2700:14;2731:27;2746:4;:11;;;2731:14;:27::i;:::-;2717:4;:11;;;:41;;;;:::i;:::-;2700:58;-1:-1:-1;2768:15:10;;2793:179;2817:5;2813:1;:9;2793:179;;;2853:19;2865:6;2853:11;:19::i;:::-;2843:29;;2898:24;;;;;;;;2906:7;2898:24;;;;2915:6;2898:24;;;2886:6;2893:1;2886:9;;;;;;;;:::i;:::-;;;;;;;;;;:36;2945:16;2954:7;2945:6;:16;:::i;:::-;2936:25;-1:-1:-1;2824:3:10;;;;:::i;:::-;;;;2793:179;;;-1:-1:-1;2989:6:10;;2483:519;-1:-1:-1;;;;;2483:519:10:o;6447:440::-;6540:8;;6508:12;;6532:21;;;;;;6564:14;6581:27;6596:4;:11;;;6581:14;:27::i;:::-;6564:44;;6618:11;6643:6;6632:4;:8;;;:17;;;;:::i;:::-;6618:31;;6674:19;6706:3;6696:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6696:14:10;;6674:36;;6721:15;6790:6;6784:4;6780:17;6769:28;;6817:40;6836:6;6822:4;:11;;;:20;;;;:::i;:::-;6844:7;6853:3;6817:4;:40::i;4656:185:8:-;4737:6;4769:5;4773:1;4769;:5;:::i;:::-;:10;:64;;4829:4;4815:3;4819:5;4823:1;4819;:5;:::i;:::-;4815:10;;;;;;;;:::i;:::-;;;;;4809:24;;;4815:10;;4809:24;:::i;:::-;4769:64;;;4802:4;4788:3;4792:5;4796:1;4792;:5;:::i;:::-;4788:10;;;;;;;;:::i;:::-;;;;;4782:24;;;4788:10;;4782:24;:::i;:::-;4762:72;;;4656:185;-1:-1:-1;;;4656:185:8:o;3106:321:10:-;3186:8;;3166:4;;3186:13;;3182:31;;-1:-1:-1;3208:5:10;;3106:321;-1:-1:-1;3106:321:10:o;3182:31::-;3262:11;;;;3323:13;;3224:11;3315:22;;279:4;3361:24;;3357:42;;;-1:-1:-1;3394:5:10;;3106:321;-1:-1:-1;;;3106:321:10:o;3357:42::-;-1:-1:-1;3416:4:10;;3106:321;-1:-1:-1;;;3106:321:10:o;630:737:3:-;741:3;748:1;741:8;737:21;;630:737;;;:::o;737:21::-;203:2;822:16;;815:194;;912:10;;899:24;;951:16;203:2;918:3;951:16;:::i;:::-;;-1:-1:-1;981:17:3;203:2;981:17;;:::i;:::-;;-1:-1:-1;840:16:3;203:2;840:16;;:::i;:::-;;;815:194;;;1099:12;1139:1;1120:15;1132:3;203:2;1120:15;:::i;:::-;1114:22;;:3;:22;:::i;:::-;:26;;;;:::i;:::-;1192:10;;1263:11;;1259:22;;1204:9;;1188:26;1329:21;;;;1316:35;;;-1:-1:-1;;630:737:3:o;5354:200:10:-;5484:8;;5417:7;;5496:2;5484:14;5476:23;;;;;;5533:12;5540:4;5533:6;:12::i;4673:337::-;4737:12;4761:19;4793:4;:8;;;4783:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4783:19:10;;4761:41;;4816:6;:13;4833:1;4816:18;4812:37;;4843:6;4673:337;-1:-1:-1;;4673:337:10:o;4812:37::-;4860:11;4921:6;4915:4;4911:17;4904:24;;4948:32;4953:4;:11;;;4966:3;4971:4;:8;;;4948:4;:32::i;:::-;-1:-1:-1;4997:6:10;4673:337;-1:-1:-1;;4673:337:10:o;6143:298::-;6263:8;;6209:7;;6275:2;6263:14;6255:23;;;;;;6289:14;6313;6330:4;:11;;;6344:1;6330:15;;;;:::i;:::-;6388:13;;6143:298;-1:-1:-1;;;;6143:298:10:o;2881:954:8:-;3030:7;;;3286:35;3302:18;3286:15;:35::i;:::-;3259:62;;3331:23;3367:11;:18;3357:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3357:29:8;-1:-1:-1;3331:55:8;-1:-1:-1;3509:7:8;3492:167;3532:18;;3522:28;;:7;:28;:::i;:::-;3518:1;:32;3492:167;;;3571:17;3591:4;3596:1;3591:7;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;3591:7:8;3612:10;3623:11;3627:7;3623:1;:11;:::i;:::-;3612:23;;;;;;;;:::i;:::-;;;;:36;;;;;;;;;;;3557:102;3552:3;;;;;:::i;:::-;;;;3492:167;;;;3709:10;3699:21;;;;;;3683:11;3673:22;;;;;;:47;3669:140;;3742:11;:18;3736:24;;3669:140;;;3797:1;3791:7;;3669:140;-1:-1:-1;3825:3:8;;2881:954;-1:-1:-1;;;;;2881:954:8:o;78:1018:7:-;231:4;270:2;255:5;:12;:17;;;;:::i;:::-;:22;247:55;;;;-1:-1:-1;;;247:55:7;;30270:2:12;247:55:7;;;30252:21:12;30309:2;30289:18;;;30282:30;30348:22;30328:18;;;30321:50;30388:18;;247:55:7;30068:344:12;247:55:7;312:19;349:2;334:5;:12;:17;;;;:::i;:::-;312:39;-1:-1:-1;503:14:7;312:39;503:1;:14;:::i;:::-;495:5;:22;487:56;;;;-1:-1:-1;;;487:56:7;;30619:2:12;487:56:7;;;30601:21:12;30658:2;30638:18;;;30631:30;30697:23;30677:18;;;30670:51;30738:18;;487:56:7;30417:345:12;487:56:7;554:20;607:4;638:2;621:428;647:5;:12;642:1;:17;621:428;;733:13;;;727:20;;-1:-1:-1;779:9:7;787:1;779:5;:9;:::i;:::-;792:1;779:14;775:232;;838:44;;;;;;30924:19:12;;;30959:12;;;30952:28;;;30996:12;;838:44:7;;;;;;;;;;;;828:55;;;;;;813:70;;775:232;;;947:44;;;;;;30924:19:12;;;30959:12;;;30952:28;;;30996:12;;947:44:7;;;;;;;;;;;;937:55;;;;;;922:70;;775:232;1029:9;1037:1;1029:5;:9;:::i;:::-;1021:17;-1:-1:-1;661:7:7;666:2;661:7;;:::i;:::-;;;621:428;;;-1:-1:-1;1065:24:7;;;;78:1018;-1:-1:-1;;;;;;78:1018:7:o;8750:521:10:-;8894:13;;8812:7;;8886:22;;190:4;8932:26;;8928:336;;;-1:-1:-1;8967:1:10;;8750:521;-1:-1:-1;;8750:521:10:o;8928:336::-;235:4;8987:25;;;:83;;-1:-1:-1;279:4:10;9017:25;;;;;:52;;-1:-1:-1;322:4:10;9046:23;;9017:52;8983:281;;;-1:-1:-1;9079:1:10;;8750:521;-1:-1:-1;;8750:521:10:o;8983:281::-;279:4;9099:24;;9095:169;;;9183:21;9203:1;235:4;9183:21;:::i;:::-;9174:31;;;;:5;:31;:::i;:::-;:35;;9208:1;9174:35;:::i;:::-;9167:42;8750:521;-1:-1:-1;;;8750:521:10:o;9095:169::-;9240:19;9258:1;322:4;9240:19;:::i;6995:424::-;7079:8;;7056:7;;7079:13;;7075:27;;-1:-1:-1;7101:1:10;;6995:424;-1:-1:-1;6995:424:10:o;7075:27::-;7113:13;7140:15;7172:27;7187:4;:11;;;7172:14;:27::i;:::-;7158:4;:11;;;:41;;;;:::i;:::-;7140:59;;7209:14;7240:4;:8;;;7226:4;:11;;;:22;;;;:::i;:::-;7209:39;;7258:132;7275:6;7265:7;:16;7258:132;;;7317:20;7329:7;7317:11;:20::i;:::-;7307:30;;:7;:30;:::i;:::-;7297:40;-1:-1:-1;7372:7:10;;;;:::i;:::-;;;;7258:132;;;-1:-1:-1;7407:5:10;;6995:424;-1:-1:-1;;;6995:424:10:o;7468:1230::-;7634:13;;7527:7;;;;7626:22;;190:4;7672:26;;7668:999;;;7710:1;7700:11;;7668:999;;;235:4;7730:25;;7726:941;;;7767:26;190:4;7767:5;:26;:::i;:::-;:30;;7796:1;7767:30;:::i;:::-;7757:40;;7726:941;;;279:4;7816:24;;7812:855;;;7909:4;7902:5;7898:16;7988:1;7980:6;7976:14;7966:24;;8126:7;8122:2;8118:16;8113:3;8109:26;8100:6;8094:13;8090:46;8223:1;8214:7;8210:15;8201:7;8197:29;8186:40;;;;7812:855;;;322:4;8260:23;;8256:411;;;8309:24;279:4;8309:5;:24;:::i;8256:411::-;8465:1;8453:14;;;;8504:13;8532:2;8528:16;;;8421:4;8528:16;8523:3;8519:26;8500:46;;8614:29;;;8627:15;8614:29;;8684:7;-1:-1:-1;;7468:1230:10:o;9429:769::-;9540:3;9547:1;9540:8;9536:21;;9429:769;;;:::o;9536:21::-;359:2;9621:16;;9614:194;;9711:10;;9698:24;;9750:16;359:2;9717:3;9750:16;:::i;:::-;;-1:-1:-1;9780:17:10;359:2;9780:17;;:::i;:::-;;-1:-1:-1;9639:16:10;359:2;9639:16;;:::i;:::-;;;9614:194;;;9822:3;9829:1;9822:8;9818:21;;9429:769;;;:::o;14:332:12:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;971:154;1057:42;1050:5;1046:54;1039:5;1036:65;1026:93;;1115:1;1112;1105:12;1130:347;1181:8;1191:6;1245:3;1238:4;1230:6;1226:17;1222:27;1212:55;;1263:1;1260;1253:12;1212:55;-1:-1:-1;1286:20:12;;1329:18;1318:30;;1315:50;;;1361:1;1358;1351:12;1315:50;1398:4;1390:6;1386:17;1374:29;;1450:3;1443:4;1434:6;1426;1422:19;1418:30;1415:39;1412:59;;;1467:1;1464;1457:12;1412:59;1130:347;;;;;:::o;1482:754::-;1579:6;1587;1595;1603;1611;1664:3;1652:9;1643:7;1639:23;1635:33;1632:53;;;1681:1;1678;1671:12;1632:53;1720:9;1707:23;1739:31;1764:5;1739:31;:::i;:::-;1789:5;-1:-1:-1;1846:2:12;1831:18;;1818:32;1859:33;1818:32;1859:33;:::i;:::-;1911:7;-1:-1:-1;1965:2:12;1950:18;;1937:32;;-1:-1:-1;2020:2:12;2005:18;;1992:32;2047:18;2036:30;;2033:50;;;2079:1;2076;2069:12;2033:50;2118:58;2168:7;2159:6;2148:9;2144:22;2118:58;:::i;:::-;1482:754;;;;-1:-1:-1;1482:754:12;;-1:-1:-1;2195:8:12;;2092:84;1482:754;-1:-1:-1;;;1482:754:12:o;2494:160::-;2559:20;;2615:13;;2608:21;2598:32;;2588:60;;2644:1;2641;2634:12;2588:60;2494:160;;;:::o;2659:180::-;2715:6;2768:2;2756:9;2747:7;2743:23;2739:32;2736:52;;;2784:1;2781;2774:12;2736:52;2807:26;2823:9;2807:26;:::i;2844:188::-;2912:20;;2972:34;2961:46;;2951:57;;2941:85;;3022:1;3019;3012:12;3037:186;3096:6;3149:2;3137:9;3128:7;3124:23;3120:32;3117:52;;;3165:1;3162;3155:12;3117:52;3188:29;3207:9;3188:29;:::i;3228:247::-;3287:6;3340:2;3328:9;3319:7;3315:23;3311:32;3308:52;;;3356:1;3353;3346:12;3308:52;3395:9;3382:23;3414:31;3439:5;3414:31;:::i;3947:184::-;3999:77;3996:1;3989:88;4096:4;4093:1;4086:15;4120:4;4117:1;4110:15;4136:334;4207:2;4201:9;4263:2;4253:13;;4268:66;4249:86;4237:99;;4366:18;4351:34;;4387:22;;;4348:62;4345:88;;;4413:18;;:::i;:::-;4449:2;4442:22;4136:334;;-1:-1:-1;4136:334:12:o;4475:712::-;4529:5;4582:3;4575:4;4567:6;4563:17;4559:27;4549:55;;4600:1;4597;4590:12;4549:55;4636:6;4623:20;4662:4;4685:18;4681:2;4678:26;4675:52;;;4707:18;;:::i;:::-;4753:2;4750:1;4746:10;4776:28;4800:2;4796;4792:11;4776:28;:::i;:::-;4838:15;;;4908;;;4904:24;;;4869:12;;;;4940:15;;;4937:35;;;4968:1;4965;4958:12;4937:35;5004:2;4996:6;4992:15;4981:26;;5016:142;5032:6;5027:3;5024:15;5016:142;;;5098:17;;5086:30;;5049:12;;;;5136;;;;5016:142;;;5176:5;4475:712;-1:-1:-1;;;;;;;4475:712:12:o;5192:348::-;5276:6;5329:2;5317:9;5308:7;5304:23;5300:32;5297:52;;;5345:1;5342;5335:12;5297:52;5385:9;5372:23;5418:18;5410:6;5407:30;5404:50;;;5450:1;5447;5440:12;5404:50;5473:61;5526:7;5517:6;5506:9;5502:22;5473:61;:::i;5545:260::-;5613:6;5621;5674:2;5662:9;5653:7;5649:23;5645:32;5642:52;;;5690:1;5687;5680:12;5642:52;5713:29;5732:9;5713:29;:::i;:::-;5703:39;;5761:38;5795:2;5784:9;5780:18;5761:38;:::i;:::-;5751:48;;5545:260;;;;;:::o;5810:180::-;5869:6;5922:2;5910:9;5901:7;5897:23;5893:32;5890:52;;;5938:1;5935;5928:12;5890:52;-1:-1:-1;5961:23:12;;5810:180;-1:-1:-1;5810:180:12:o;6180:993::-;6482:3;6495:22;;;6566:13;;6467:19;;;6588:22;;;6434:4;;6664;;6641:3;6626:19;;;6691:15;;;6434:4;6734:169;6748:6;6745:1;6742:13;6734:169;;;6809:13;;6797:26;;6843:12;;;;6878:15;;;;6770:1;6763:9;6734:169;;;-1:-1:-1;;;6939:18:12;;;6932:34;;;;-1:-1:-1;6997:2:12;6982:18;;6975:34;;;;7028;7098:15;;;7093:2;7078:18;;7071:43;7151:15;7145:3;7130:19;;;7123:44;6920:3;6180:993;-1:-1:-1;6180:993:12:o;7424:634::-;7544:6;7552;7560;7568;7576;7629:3;7617:9;7608:7;7604:23;7600:33;7597:53;;;7646:1;7643;7636:12;7597:53;7686:9;7673:23;7719:18;7711:6;7708:30;7705:50;;;7751:1;7748;7741:12;7705:50;7774:61;7827:7;7818:6;7807:9;7803:22;7774:61;:::i;:::-;7764:71;;;7854:38;7888:2;7877:9;7873:18;7854:38;:::i;:::-;7844:48;;7911:38;7945:2;7934:9;7930:18;7911:38;:::i;:::-;7424:634;;;;-1:-1:-1;7901:48:12;;7996:2;7981:18;;7968:32;;-1:-1:-1;8047:3:12;8032:19;8019:33;;7424:634;-1:-1:-1;;7424:634:12:o;8245:::-;8359:6;8367;8375;8383;8391;8444:3;8432:9;8423:7;8419:23;8415:33;8412:53;;;8461:1;8458;8451:12;8412:53;8501:9;8488:23;8534:18;8526:6;8523:30;8520:50;;;8566:1;8563;8556:12;8520:50;8589:61;8642:7;8633:6;8622:9;8618:22;8589:61;:::i;:::-;8579:71;;;8669:38;8703:2;8692:9;8688:18;8669:38;:::i;:::-;8659:48;;8726:38;8760:2;8749:9;8745:18;8726:38;:::i;:::-;8716:48;;8783:35;8814:2;8803:9;8799:18;8783:35;:::i;:::-;8773:45;;8837:36;8868:3;8857:9;8853:19;8837:36;:::i;:::-;8827:46;;8245:634;;;;;;;;:::o;9115:671::-;9201:6;9209;9217;9225;9278:3;9266:9;9257:7;9253:23;9249:33;9246:53;;;9295:1;9292;9285:12;9246:53;9334:9;9321:23;9353:31;9378:5;9353:31;:::i;:::-;9403:5;-1:-1:-1;9460:2:12;9445:18;;9432:32;9473:33;9432:32;9473:33;:::i;:::-;9525:7;-1:-1:-1;9584:2:12;9569:18;;9556:32;9597:33;9556:32;9597:33;:::i;:::-;9649:7;-1:-1:-1;9708:2:12;9693:18;;9680:32;9721:33;9680:32;9721:33;:::i;:::-;9115:671;;;;-1:-1:-1;9115:671:12;;-1:-1:-1;;9115:671:12:o;9791:367::-;9854:8;9864:6;9918:3;9911:4;9903:6;9899:17;9895:27;9885:55;;9936:1;9933;9926:12;9885:55;-1:-1:-1;9959:20:12;;10002:18;9991:30;;9988:50;;;10034:1;10031;10024:12;9988:50;10071:4;10063:6;10059:17;10047:29;;10131:3;10124:4;10114:6;10111:1;10107:14;10099:6;10095:27;10091:38;10088:47;10085:67;;;10148:1;10145;10138:12;10163:1338;10323:6;10331;10339;10347;10355;10363;10371;10379;10432:3;10420:9;10411:7;10407:23;10403:33;10400:53;;;10449:1;10446;10439:12;10400:53;10488:9;10475:23;10507:31;10532:5;10507:31;:::i;:::-;10557:5;-1:-1:-1;10614:2:12;10599:18;;10586:32;10627:33;10586:32;10627:33;:::i;:::-;10679:7;-1:-1:-1;10737:2:12;10722:18;;10709:32;10760:18;10790:14;;;10787:34;;;10817:1;10814;10807:12;10787:34;10856:70;10918:7;10909:6;10898:9;10894:22;10856:70;:::i;:::-;10945:8;;-1:-1:-1;10830:96:12;-1:-1:-1;11033:2:12;11018:18;;11005:32;;-1:-1:-1;11049:16:12;;;11046:36;;;11078:1;11075;11068:12;11046:36;11117:72;11181:7;11170:8;11159:9;11155:24;11117:72;:::i;:::-;11208:8;;-1:-1:-1;11091:98:12;-1:-1:-1;11296:3:12;11281:19;;11268:33;;-1:-1:-1;11313:16:12;;;11310:36;;;11342:1;11339;11332:12;11310:36;;11381:60;11433:7;11422:8;11411:9;11407:24;11381:60;:::i;:::-;10163:1338;;;;-1:-1:-1;10163:1338:12;;-1:-1:-1;10163:1338:12;;;;;;11460:8;-1:-1:-1;;;10163:1338:12:o;12018:823::-;12124:6;12132;12140;12148;12156;12164;12217:3;12205:9;12196:7;12192:23;12188:33;12185:53;;;12234:1;12231;12224:12;12185:53;12273:9;12260:23;12292:31;12317:5;12292:31;:::i;:::-;12342:5;-1:-1:-1;12399:2:12;12384:18;;12371:32;12412:33;12371:32;12412:33;:::i;:::-;12464:7;-1:-1:-1;12518:2:12;12503:18;;12490:32;;-1:-1:-1;12569:2:12;12554:18;;12541:32;;-1:-1:-1;12624:3:12;12609:19;;12596:33;12652:18;12641:30;;12638:50;;;12684:1;12681;12674:12;12638:50;12723:58;12773:7;12764:6;12753:9;12749:22;12723:58;:::i;:::-;12018:823;;;;-1:-1:-1;12018:823:12;;-1:-1:-1;12018:823:12;;12800:8;;12018:823;-1:-1:-1;;;12018:823:12:o;12846:245::-;12894:4;12927:18;12919:6;12916:30;12913:56;;;12949:18;;:::i;:::-;-1:-1:-1;13006:2:12;12994:15;13011:66;12990:88;13080:4;12986:99;;12846:245::o;13096:671::-;13164:6;13217:2;13205:9;13196:7;13192:23;13188:32;13185:52;;;13233:1;13230;13223:12;13185:52;13273:9;13260:23;13306:18;13298:6;13295:30;13292:50;;;13338:1;13335;13328:12;13292:50;13361:22;;13414:4;13406:13;;13402:27;-1:-1:-1;13392:55:12;;13443:1;13440;13433:12;13392:55;13479:2;13466:16;13504:48;13520:31;13548:2;13520:31;:::i;:::-;13504:48;:::i;:::-;13575:2;13568:5;13561:17;13615:7;13610:2;13605;13601;13597:11;13593:20;13590:33;13587:53;;;13636:1;13633;13626:12;13587:53;13691:2;13686;13682;13678:11;13673:2;13666:5;13662:14;13649:45;13735:1;13714:14;;;13730:2;13710:23;13703:34;;;;13718:5;13096:671;-1:-1:-1;;;;13096:671:12:o;14483:184::-;14535:77;14532:1;14525:88;14632:4;14629:1;14622:15;14656:4;14653:1;14646:15;14672:253;14712:3;14740:34;14801:2;14798:1;14794:10;14831:2;14828:1;14824:10;14862:3;14858:2;14854:12;14849:3;14846:21;14843:47;;;14870:18;;:::i;:::-;14906:13;;14672:253;-1:-1:-1;;;;14672:253:12:o;15634:184::-;15686:77;15683:1;15676:88;15783:4;15780:1;15773:15;15807:4;15804:1;15797:15;16319:184;16371:77;16368:1;16361:88;16468:4;16465:1;16458:15;16492:4;16489:1;16482:15;16863:195;16902:3;16933:66;16926:5;16923:77;16920:103;;17003:18;;:::i;:::-;-1:-1:-1;17050:1:12;17039:13;;16863:195::o;17466:125::-;17506:4;17534:1;17531;17528:8;17525:34;;;17539:18;;:::i;:::-;-1:-1:-1;17576:9:12;;17466:125::o;17596:184::-;17648:77;17645:1;17638:88;17745:4;17742:1;17735:15;17769:4;17766:1;17759:15;20178:246;20218:4;20247:34;20331:10;;;;20301;;20353:12;;;20350:38;;;20368:18;;:::i;:::-;20405:13;;20178:246;-1:-1:-1;;;20178:246:12:o;22725:258::-;22797:1;22807:113;22821:6;22818:1;22815:13;22807:113;;;22897:11;;;22891:18;22878:11;;;22871:39;22843:2;22836:10;22807:113;;;22938:6;22935:1;22932:13;22929:48;;;22973:1;22964:6;22959:3;22955:16;22948:27;22929:48;;22725:258;;;:::o;22988:560::-;23175:42;23167:6;23163:55;23152:9;23145:74;23255:2;23250;23239:9;23235:18;23228:30;23126:4;23287:6;23281:13;23330:6;23325:2;23314:9;23310:18;23303:34;23346:66;23405:6;23400:2;23389:9;23385:18;23380:2;23372:6;23368:15;23346:66;:::i;:::-;23464:2;23452:15;23469:66;23448:88;23433:104;;;;23539:2;23429:113;;22988:560;-1:-1:-1;;;22988:560:12:o;23553:431::-;23768:6;23763:3;23756:19;23738:3;23804:6;23798:13;23820:60;23873:6;23868:2;23863:3;23859:12;23854:2;23846:6;23842:15;23820:60;:::i;:::-;23939:2;23899:16;;23931:11;;;23924:27;;;;23975:2;23967:11;;23553:431;-1:-1:-1;;;23553:431:12:o;25564:634::-;25643:6;25696:2;25684:9;25675:7;25671:23;25667:32;25664:52;;;25712:1;25709;25702:12;25664:52;25745:9;25739:16;25778:18;25770:6;25767:30;25764:50;;;25810:1;25807;25800:12;25764:50;25833:22;;25886:4;25878:13;;25874:27;-1:-1:-1;25864:55:12;;25915:1;25912;25905:12;25864:55;25944:2;25938:9;25969:48;25985:31;26013:2;25985:31;:::i;25969:48::-;26040:2;26033:5;26026:17;26080:7;26075:2;26070;26066;26062:11;26058:20;26055:33;26052:53;;;26101:1;26098;26091:12;26052:53;26114:54;26165:2;26160;26153:5;26149:14;26144:2;26140;26136:11;26114:54;:::i;:::-;26187:5;25564:634;-1:-1:-1;;;;;25564:634:12:o;26203:228::-;26243:7;26369:1;26301:66;26297:74;26294:1;26291:81;26286:1;26279:9;26272:17;26268:105;26265:131;;;26376:18;;:::i;:::-;-1:-1:-1;26416:9:12;;26203:228::o;26436:128::-;26476:3;26507:1;26503:6;26500:1;26497:13;26494:39;;;26513:18;;:::i;:::-;-1:-1:-1;26549:9:12;;26436:128::o;26569:497::-;26675:6;26683;26691;26699;26707;26760:3;26748:9;26739:7;26735:23;26731:33;26728:53;;;26777:1;26774;26767:12;26728:53;26806:9;26800:16;26790:26;;26856:2;26845:9;26841:18;26835:25;26825:35;;26900:2;26889:9;26885:18;26879:25;26869:35;;26944:2;26933:9;26929:18;26923:25;26913:35;;26991:3;26980:9;26976:19;26970:26;27005:31;27030:5;27005:31;:::i;:::-;27055:5;27045:15;;;26569:497;;;;;;;;:::o;27811:184::-;27863:77;27860:1;27853:88;27960:4;27957:1;27950:15;27984:4;27981:1;27974:15;28000:112;28032:1;28058;28048:35;;28063:18;;:::i;:::-;-1:-1:-1;28097:9:12;;28000:112::o;28117:120::-;28157:1;28183;28173:35;;28188:18;;:::i;:::-;-1:-1:-1;28222:9:12;;28117:120::o;28242:157::-;28272:1;28306:4;28303:1;28299:12;28330:3;28320:37;;28337:18;;:::i;:::-;28389:3;28382:4;28379:1;28375:12;28371:22;28366:27;;;28242:157;;;;:::o;28404:165::-;28442:1;28476:4;28473:1;28469:12;28500:3;28490:37;;28507:18;;:::i;:::-;28559:3;28552:4;28549:1;28545:12;28541:22;28536:27;;;28404:165;;;;:::o;28574:482::-;28663:1;28706:5;28663:1;28720:330;28741:7;28731:8;28728:21;28720:330;;;28860:4;28792:66;28788:77;28782:4;28779:87;28776:113;;;28869:18;;:::i;:::-;28919:7;28909:8;28905:22;28902:55;;;28939:16;;;;28902:55;29018:22;;;;28978:15;;;;28720:330;;;28724:3;28574:482;;;;;:::o;29061:866::-;29110:5;29140:8;29130:80;;-1:-1:-1;29181:1:12;29195:5;;29130:80;29229:4;29219:76;;-1:-1:-1;29266:1:12;29280:5;;29219:76;29311:4;29329:1;29324:59;;;;29397:1;29392:130;;;;29304:218;;29324:59;29354:1;29345:10;;29368:5;;;29392:130;29429:3;29419:8;29416:17;29413:43;;;29436:18;;:::i;:::-;-1:-1:-1;;29492:1:12;29478:16;;29507:5;;29304:218;;29606:2;29596:8;29593:16;29587:3;29581:4;29578:13;29574:36;29568:2;29558:8;29555:16;29550:2;29544:4;29541:12;29537:35;29534:77;29531:159;;;-1:-1:-1;29643:19:12;;;29675:5;;29531:159;29722:34;29747:8;29741:4;29722:34;:::i;:::-;29852:6;29784:66;29780:79;29771:7;29768:92;29765:118;;;29863:18;;:::i;:::-;29901:20;;29061:866;-1:-1:-1;;;29061:866:12:o;29932:131::-;29992:5;30021:36;30048:8;30042:4;30021:36;:::i;31019:195::-;31057:4;31094;31091:1;31087:12;31126:4;31123:1;31119:12;31151:3;31146;31143:12;31140:38;;;31158:18;;:::i;:::-;31195:13;;;31019:195;-1:-1:-1;;;31019:195:12:o
Swarm Source
ipfs://9217d194649c8ac2c51aa00479d69ea51ac54bd1aa40db13a821cd0d44e3efe1
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.