- Contract name:
- DiamondCutFacet
- Optimization enabled
- false
- Compiler version
- v0.8.17+commit.8df45f5f
- Verified at
- 2024-01-05T17:54:18.762900Z
contracts/facets/DiamondCutFacet.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; import { LibDiamond } from "../libraries/LibDiamond.sol"; // Remember to add the loupe functions from DiamondLoupeFacet to the diamond. // The loupe functions are required by the EIP2535 Diamonds standard contract DiamondCutFacet is IDiamondCut { /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external override { LibDiamond.enforceIsContractOwner(); LibDiamond.diamondCut(_diamondCut, _init, _calldata); } }
contracts/interfaces/IDiamond.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface IDiamond { enum FacetCutAction { Add, Replace, Remove } // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
contracts/interfaces/IDiamondCut.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import { IDiamond } from "./IDiamond.sol"; interface IDiamondCut is IDiamond { /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; }
contracts/libraries/LibDiamond.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import { IDiamond } from "../interfaces/IDiamond.sol"; import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; // Remember to add the loupe functions from DiamondLoupeFacet to the diamond. // The loupe functions are required by the EIP2535 Diamonds standard error NoSelectorsGivenToAdd(); error NotContractOwner(address _user, address _contractOwner); error NoSelectorsProvidedForFacetForCut(address _facetAddress); error CannotAddSelectorsToZeroAddress(bytes4[] _selectors); error NoBytecodeAtAddress(address _contractAddress, string _message); error IncorrectFacetCutAction(uint8 _action); error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector); error CannotReplaceFunctionsFromFacetWithZeroAddress(bytes4[] _selectors); error CannotReplaceImmutableFunction(bytes4 _selector); error CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet( bytes4 _selector ); error CannotReplaceFunctionThatDoesNotExists(bytes4 _selector); error RemoveFacetAddressMustBeZeroAddress(address _facetAddress); error CannotRemoveFunctionThatDoesNotExist(bytes4 _selector); error CannotRemoveImmutableFunction(bytes4 _selector); error InitializationFunctionReverted( address _initializationContractAddress, bytes _calldata ); library LibDiamond { bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); struct FacetAddressAndSelectorPosition { address facetAddress; uint16 selectorPosition; } struct DiamondStorage { // function selector => facet address and selector position in selectors array mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition; bytes4[] selectors; mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; } function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } } event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; ds.contractOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); } function contractOwner() internal view returns (address contractOwner_) { contractOwner_ = diamondStorage().contractOwner; } function enforceIsContractOwner() internal view { if (msg.sender != diamondStorage().contractOwner) { revert NotContractOwner(msg.sender, diamondStorage().contractOwner); } } event DiamondCut( IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata ); // Internal function version of diamondCut function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata ) internal { for ( uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++ ) { bytes4[] memory functionSelectors = _diamondCut[facetIndex] .functionSelectors; address facetAddress = _diamondCut[facetIndex].facetAddress; if (functionSelectors.length == 0) { revert NoSelectorsProvidedForFacetForCut(facetAddress); } IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; if (action == IDiamond.FacetCutAction.Add) { addFunctions(facetAddress, functionSelectors); } else if (action == IDiamond.FacetCutAction.Replace) { replaceFunctions(facetAddress, functionSelectors); } else if (action == IDiamond.FacetCutAction.Remove) { removeFunctions(facetAddress, functionSelectors); } else { revert IncorrectFacetCutAction(uint8(action)); } } emit DiamondCut(_diamondCut, _init, _calldata); initializeDiamondCut(_init, _calldata); } function addFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { if (_facetAddress == address(0)) { revert CannotAddSelectorsToZeroAddress(_functionSelectors); } DiamondStorage storage ds = diamondStorage(); uint16 selectorCount = uint16(ds.selectors.length); enforceHasContractCode( _facetAddress, "LibDiamondCut: Add facet has no code" ); for ( uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++ ) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds .facetAddressAndSelectorPosition[selector] .facetAddress; if (oldFacetAddress != address(0)) { revert CannotAddFunctionToDiamondThatAlreadyExists(selector); } ds.facetAddressAndSelectorPosition[ selector ] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount); ds.selectors.push(selector); selectorCount++; } } function replaceFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { DiamondStorage storage ds = diamondStorage(); if (_facetAddress == address(0)) { revert CannotReplaceFunctionsFromFacetWithZeroAddress( _functionSelectors ); } enforceHasContractCode( _facetAddress, "LibDiamondCut: Replace facet has no code" ); for ( uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++ ) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds .facetAddressAndSelectorPosition[selector] .facetAddress; // can't replace immutable functions -- functions defined directly in the diamond in this case if (oldFacetAddress == address(this)) { revert CannotReplaceImmutableFunction(selector); } if (oldFacetAddress == _facetAddress) { revert CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet( selector ); } if (oldFacetAddress == address(0)) { revert CannotReplaceFunctionThatDoesNotExists(selector); } // replace old facet address ds .facetAddressAndSelectorPosition[selector] .facetAddress = _facetAddress; } } function removeFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { DiamondStorage storage ds = diamondStorage(); uint256 selectorCount = ds.selectors.length; if (_facetAddress != address(0)) { revert RemoveFacetAddressMustBeZeroAddress(_facetAddress); } for ( uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++ ) { bytes4 selector = _functionSelectors[selectorIndex]; FacetAddressAndSelectorPosition memory oldFacetAddressAndSelectorPosition = ds .facetAddressAndSelectorPosition[selector]; if (oldFacetAddressAndSelectorPosition.facetAddress == address(0)) { revert CannotRemoveFunctionThatDoesNotExist(selector); } // can't remove immutable functions -- functions defined directly in the diamond if ( oldFacetAddressAndSelectorPosition.facetAddress == address(this) ) { revert CannotRemoveImmutableFunction(selector); } // replace selector with last selector selectorCount--; if ( oldFacetAddressAndSelectorPosition.selectorPosition != selectorCount ) { bytes4 lastSelector = ds.selectors[selectorCount]; ds.selectors[ oldFacetAddressAndSelectorPosition.selectorPosition ] = lastSelector; ds .facetAddressAndSelectorPosition[lastSelector] .selectorPosition = oldFacetAddressAndSelectorPosition .selectorPosition; } // delete last selector ds.selectors.pop(); delete ds.facetAddressAndSelectorPosition[selector]; } } function initializeDiamondCut( address _init, bytes memory _calldata ) internal { if (_init == address(0)) { return; } enforceHasContractCode( _init, "LibDiamondCut: _init address has no code" ); (bool success, bytes memory error) = _init.delegatecall(_calldata); if (!success) { if (error.length > 0) { // bubble up error /// @solidity memory-safe-assembly assembly { let returndata_size := mload(error) revert(add(32, error), returndata_size) } } else { revert InitializationFunctionReverted(_init, _calldata); } } } function enforceHasContractCode( address _contract, string memory _errorMessage ) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } if (contractSize == 0) { revert NoBytecodeAtAddress(_contract, _errorMessage); } } }
Contract ABI
[{"type":"error","name":"CannotAddFunctionToDiamondThatAlreadyExists","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"error","name":"CannotAddSelectorsToZeroAddress","inputs":[{"type":"bytes4[]","name":"_selectors","internalType":"bytes4[]"}]},{"type":"error","name":"CannotRemoveFunctionThatDoesNotExist","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"error","name":"CannotRemoveImmutableFunction","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"error","name":"CannotReplaceFunctionThatDoesNotExists","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"error","name":"CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"error","name":"CannotReplaceFunctionsFromFacetWithZeroAddress","inputs":[{"type":"bytes4[]","name":"_selectors","internalType":"bytes4[]"}]},{"type":"error","name":"CannotReplaceImmutableFunction","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"error","name":"IncorrectFacetCutAction","inputs":[{"type":"uint8","name":"_action","internalType":"uint8"}]},{"type":"error","name":"InitializationFunctionReverted","inputs":[{"type":"address","name":"_initializationContractAddress","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"error","name":"NoBytecodeAtAddress","inputs":[{"type":"address","name":"_contractAddress","internalType":"address"},{"type":"string","name":"_message","internalType":"string"}]},{"type":"error","name":"NoSelectorsProvidedForFacetForCut","inputs":[{"type":"address","name":"_facetAddress","internalType":"address"}]},{"type":"error","name":"NotContractOwner","inputs":[{"type":"address","name":"_user","internalType":"address"},{"type":"address","name":"_contractOwner","internalType":"address"}]},{"type":"error","name":"RemoveFacetAddressMustBeZeroAddress","inputs":[{"type":"address","name":"_facetAddress","internalType":"address"}]},{"type":"event","name":"DiamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamond.FacetCut[]","indexed":false,"components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamond.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address","indexed":false},{"type":"bytes","name":"_calldata","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamond.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamond.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50611c64806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004a60048036038101906100459190611160565b61004c565b005b6100546100b6565b6100af85859061006491906114fe565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610180565b5050505050565b6100be61039d565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461017e573361011d61039d565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fff4127cb000000000000000000000000000000000000000000000000000000008152600401610175929190611522565b60405180910390fd5b565b60005b83518110156103525760008482815181106101a1576101a061154b565b5b602002602001015160400151905060008583815181106101c4576101c361154b565b5b6020026020010151600001519050600082510361021857806040517fe767f91f00000000000000000000000000000000000000000000000000000000815260040161020f919061157a565b60405180910390fd5b600086848151811061022d5761022c61154b565b5b60200260200101516020015190506000600281111561024f5761024e611595565b5b81600281111561026257610261611595565b5b036102765761027182846103ca565b61033c565b6001600281111561028a57610289611595565b5b81600281111561029d5761029c611595565b5b036102b1576102ac82846106f2565b61033b565b6002808111156102c4576102c3611595565b5b8160028111156102d7576102d6611595565b5b036102eb576102e68284610a38565b61033a565b8060028111156102fe576102fd611595565b5b6040517f7fe9a41e00000000000000000000000000000000000000000000000000000000815260040161033191906115e0565b60405180910390fd5b5b5b505050808061034a90611634565b915050610183565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161038693929190611922565b60405180910390a16103988282610ebf565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361043b57806040517f0ae3681c00000000000000000000000000000000000000000000000000000000815260040161043291906119d6565b60405180910390fd5b600061044561039d565b905060008160010180549050905061047584604051806060016040528060248152602001611bbb60249139610fe1565b60005b83518110156106eb5760008482815181106104965761049561154b565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058c57816040517febbf5d070000000000000000000000000000000000000000000000000000000081526004016105839190611a07565b60405180910390fd5b60405180604001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018561ffff16815250856000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548161ffff021916908361ffff160217905550905050846001018290806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555083806106d390611a30565b945050505080806106e390611634565b915050610478565b5050505050565b60006106fc61039d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361076f57816040517fcd98a96f00000000000000000000000000000000000000000000000000000000815260040161076691906119d6565b60405180910390fd5b61079183604051806060016040528060288152602001611c0760289139610fe1565b60005b8251811015610a325760008382815181106107b2576107b161154b565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108a757816040517f520300da00000000000000000000000000000000000000000000000000000000815260040161089e9190611a07565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361091757816040517f358d9d1a00000000000000000000000000000000000000000000000000000000815260040161090e9190611a07565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361098857816040517f7479f93900000000000000000000000000000000000000000000000000000000815260040161097f9190611a07565b60405180910390fd5b85846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050508080610a2a90611634565b915050610794565b50505050565b6000610a4261039d565b9050600081600101805490509050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610ac157836040517fd091bc81000000000000000000000000000000000000000000000000000000008152600401610ab8919061157a565b60405180910390fd5b60005b8351811015610eb8576000848281518110610ae257610ae161154b565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900461ffff1661ffff1661ffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610c3957816040517f7a08a22d000000000000000000000000000000000000000000000000000000008152600401610c309190611a07565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610cad57816040517f6fafeb08000000000000000000000000000000000000000000000000000000008152600401610ca49190611a07565b60405180910390fd5b8380610cb890611a5a565b94505083816020015161ffff1614610dcd576000856001018581548110610ce257610ce161154b565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b90508086600101836020015161ffff1681548110610d2657610d2561154b565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c02179055508160200151866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a81548161ffff021916908361ffff160217905550505b84600101805480610de157610de0611a83565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549061ffff0219169055505050508080610eb090611634565b915050610ac4565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160315610fdd57610f1682604051806060016040528060288152602001611bdf60289139610fe1565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610f3e9190611aee565b600060405180830381855af49150503d8060008114610f79576040519150601f19603f3d011682016040523d82523d6000602084013e610f7e565b606091505b509150915081610fda57600081511115610f9b5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610fd1929190611b05565b60405180910390fd5b50505b5050565b6000823b90506000810361102e5782826040517f919834b9000000000000000000000000000000000000000000000000000000008152600401611025929190611b8a565b60405180910390fd5b505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261106c5761106b611047565b5b8235905067ffffffffffffffff8111156110895761108861104c565b5b6020830191508360208202830111156110a5576110a4611051565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006110d7826110ac565b9050919050565b6110e7816110cc565b81146110f257600080fd5b50565b600081359050611104816110de565b92915050565b60008083601f8401126111205761111f611047565b5b8235905067ffffffffffffffff81111561113d5761113c61104c565b5b60208301915083600182028301111561115957611158611051565b5b9250929050565b60008060008060006060868803121561117c5761117b61103d565b5b600086013567ffffffffffffffff81111561119a57611199611042565b5b6111a688828901611056565b955095505060206111b9888289016110f5565b935050604086013567ffffffffffffffff8111156111da576111d9611042565b5b6111e68882890161110a565b92509250509295509295909350565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61123e826111f5565b810181811067ffffffffffffffff8211171561125d5761125c611206565b5b80604052505050565b6000611270611033565b905061127c8282611235565b919050565b600067ffffffffffffffff82111561129c5761129b611206565b5b602082029050602081019050919050565b600080fd5b600080fd5b600381106112c457600080fd5b50565b6000813590506112d6816112b7565b92915050565b600067ffffffffffffffff8211156112f7576112f6611206565b5b602082029050602081019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61133d81611308565b811461134857600080fd5b50565b60008135905061135a81611334565b92915050565b600061137361136e846112dc565b611266565b9050808382526020820190506020840283018581111561139657611395611051565b5b835b818110156113bf57806113ab888261134b565b845260208401935050602081019050611398565b5050509392505050565b600082601f8301126113de576113dd611047565b5b81356113ee848260208601611360565b91505092915050565b60006060828403121561140d5761140c6112ad565b5b6114176060611266565b90506000611427848285016110f5565b600083015250602061143b848285016112c7565b602083015250604082013567ffffffffffffffff81111561145f5761145e6112b2565b5b61146b848285016113c9565b60408301525092915050565b600061148a61148584611281565b611266565b905080838252602082019050602084028301858111156114ad576114ac611051565b5b835b818110156114f457803567ffffffffffffffff8111156114d2576114d1611047565b5b8086016114df89826113f7565b855260208501945050506020810190506114af565b5050509392505050565b600061150b368484611477565b905092915050565b61151c816110cc565b82525050565b60006040820190506115376000830185611513565b6115446020830184611513565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208201905061158f6000830184611513565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060ff82169050919050565b6115da816115c4565b82525050565b60006020820190506115f560008301846115d1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600061163f8261162a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611671576116706115fb565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6116b1816110cc565b82525050565b600381106116c8576116c7611595565b5b50565b60008190506116d9826116b7565b919050565b60006116e9826116cb565b9050919050565b6116f9816116de565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61173481611308565b82525050565b6000611746838361172b565b60208301905092915050565b6000602082019050919050565b600061176a826116ff565b611774818561170a565b935061177f8361171b565b8060005b838110156117b0578151611797888261173a565b97506117a283611752565b925050600181019050611783565b5085935050505092915050565b60006060830160008301516117d560008601826116a8565b5060208301516117e860208601826116f0565b5060408301518482036040860152611800828261175f565b9150508091505092915050565b600061181983836117bd565b905092915050565b6000602082019050919050565b60006118398261167c565b6118438185611687565b93508360208202850161185585611698565b8060005b858110156118915784840389528151611872858261180d565b945061187d83611821565b925060208a01995050600181019050611859565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156118dd5780820151818401526020810190506118c2565b60008484015250505050565b60006118f4826118a3565b6118fe81856118ae565b935061190e8185602086016118bf565b611917816111f5565b840191505092915050565b6000606082019050818103600083015261193c818661182e565b905061194b6020830185611513565b818103604083015261195d81846118e9565b9050949350505050565b600082825260208201905092915050565b6000611983826116ff565b61198d8185611967565b93506119988361171b565b8060005b838110156119c95781516119b0888261173a565b97506119bb83611752565b92505060018101905061199c565b5085935050505092915050565b600060208201905081810360008301526119f08184611978565b905092915050565b611a0181611308565b82525050565b6000602082019050611a1c60008301846119f8565b92915050565b600061ffff82169050919050565b6000611a3b82611a22565b915061ffff8203611a4f57611a4e6115fb565b5b600182019050919050565b6000611a658261162a565b915060008203611a7857611a776115fb565b5b600182039050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081905092915050565b6000611ac8826118a3565b611ad28185611ab2565b9350611ae28185602086016118bf565b80840191505092915050565b6000611afa8284611abd565b915081905092915050565b6000604082019050611b1a6000830185611513565b8181036020830152611b2c81846118e9565b90509392505050565b600081519050919050565b600082825260208201905092915050565b6000611b5c82611b35565b611b668185611b40565b9350611b768185602086016118bf565b611b7f816111f5565b840191505092915050565b6000604082019050611b9f6000830185611513565b8181036020830152611bb18184611b51565b9050939250505056fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212207585b52d66ac09f271c6e67f08530b2244d6f74f6c5c7bd709040384a3c565a864736f6c63430008110033
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004a60048036038101906100459190611160565b61004c565b005b6100546100b6565b6100af85859061006491906114fe565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610180565b5050505050565b6100be61039d565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461017e573361011d61039d565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fff4127cb000000000000000000000000000000000000000000000000000000008152600401610175929190611522565b60405180910390fd5b565b60005b83518110156103525760008482815181106101a1576101a061154b565b5b602002602001015160400151905060008583815181106101c4576101c361154b565b5b6020026020010151600001519050600082510361021857806040517fe767f91f00000000000000000000000000000000000000000000000000000000815260040161020f919061157a565b60405180910390fd5b600086848151811061022d5761022c61154b565b5b60200260200101516020015190506000600281111561024f5761024e611595565b5b81600281111561026257610261611595565b5b036102765761027182846103ca565b61033c565b6001600281111561028a57610289611595565b5b81600281111561029d5761029c611595565b5b036102b1576102ac82846106f2565b61033b565b6002808111156102c4576102c3611595565b5b8160028111156102d7576102d6611595565b5b036102eb576102e68284610a38565b61033a565b8060028111156102fe576102fd611595565b5b6040517f7fe9a41e00000000000000000000000000000000000000000000000000000000815260040161033191906115e0565b60405180910390fd5b5b5b505050808061034a90611634565b915050610183565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161038693929190611922565b60405180910390a16103988282610ebf565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361043b57806040517f0ae3681c00000000000000000000000000000000000000000000000000000000815260040161043291906119d6565b60405180910390fd5b600061044561039d565b905060008160010180549050905061047584604051806060016040528060248152602001611bbb60249139610fe1565b60005b83518110156106eb5760008482815181106104965761049561154b565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461058c57816040517febbf5d070000000000000000000000000000000000000000000000000000000081526004016105839190611a07565b60405180910390fd5b60405180604001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018561ffff16815250856000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548161ffff021916908361ffff160217905550905050846001018290806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555083806106d390611a30565b945050505080806106e390611634565b915050610478565b5050505050565b60006106fc61039d565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361076f57816040517fcd98a96f00000000000000000000000000000000000000000000000000000000815260040161076691906119d6565b60405180910390fd5b61079183604051806060016040528060288152602001611c0760289139610fe1565b60005b8251811015610a325760008382815181106107b2576107b161154b565b5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108a757816040517f520300da00000000000000000000000000000000000000000000000000000000815260040161089e9190611a07565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361091757816040517f358d9d1a00000000000000000000000000000000000000000000000000000000815260040161090e9190611a07565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361098857816040517f7479f93900000000000000000000000000000000000000000000000000000000815260040161097f9190611a07565b60405180910390fd5b85846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050508080610a2a90611634565b915050610794565b50505050565b6000610a4261039d565b9050600081600101805490509050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610ac157836040517fd091bc81000000000000000000000000000000000000000000000000000000008152600401610ab8919061157a565b60405180910390fd5b60005b8351811015610eb8576000848281518110610ae257610ae161154b565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900461ffff1661ffff1661ffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610c3957816040517f7a08a22d000000000000000000000000000000000000000000000000000000008152600401610c309190611a07565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610cad57816040517f6fafeb08000000000000000000000000000000000000000000000000000000008152600401610ca49190611a07565b60405180910390fd5b8380610cb890611a5a565b94505083816020015161ffff1614610dcd576000856001018581548110610ce257610ce161154b565b5b90600052602060002090600891828204019190066004029054906101000a900460e01b90508086600101836020015161ffff1681548110610d2657610d2561154b565b5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c02179055508160200151866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a81548161ffff021916908361ffff160217905550505b84600101805480610de157610de0611a83565b5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549061ffff0219169055505050508080610eb090611634565b915050610ac4565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160315610fdd57610f1682604051806060016040528060288152602001611bdf60289139610fe1565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610f3e9190611aee565b600060405180830381855af49150503d8060008114610f79576040519150601f19603f3d011682016040523d82523d6000602084013e610f7e565b606091505b509150915081610fda57600081511115610f9b5780518082602001fd5b83836040517f192105d7000000000000000000000000000000000000000000000000000000008152600401610fd1929190611b05565b60405180910390fd5b50505b5050565b6000823b90506000810361102e5782826040517f919834b9000000000000000000000000000000000000000000000000000000008152600401611025929190611b8a565b60405180910390fd5b505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261106c5761106b611047565b5b8235905067ffffffffffffffff8111156110895761108861104c565b5b6020830191508360208202830111156110a5576110a4611051565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006110d7826110ac565b9050919050565b6110e7816110cc565b81146110f257600080fd5b50565b600081359050611104816110de565b92915050565b60008083601f8401126111205761111f611047565b5b8235905067ffffffffffffffff81111561113d5761113c61104c565b5b60208301915083600182028301111561115957611158611051565b5b9250929050565b60008060008060006060868803121561117c5761117b61103d565b5b600086013567ffffffffffffffff81111561119a57611199611042565b5b6111a688828901611056565b955095505060206111b9888289016110f5565b935050604086013567ffffffffffffffff8111156111da576111d9611042565b5b6111e68882890161110a565b92509250509295509295909350565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61123e826111f5565b810181811067ffffffffffffffff8211171561125d5761125c611206565b5b80604052505050565b6000611270611033565b905061127c8282611235565b919050565b600067ffffffffffffffff82111561129c5761129b611206565b5b602082029050602081019050919050565b600080fd5b600080fd5b600381106112c457600080fd5b50565b6000813590506112d6816112b7565b92915050565b600067ffffffffffffffff8211156112f7576112f6611206565b5b602082029050602081019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61133d81611308565b811461134857600080fd5b50565b60008135905061135a81611334565b92915050565b600061137361136e846112dc565b611266565b9050808382526020820190506020840283018581111561139657611395611051565b5b835b818110156113bf57806113ab888261134b565b845260208401935050602081019050611398565b5050509392505050565b600082601f8301126113de576113dd611047565b5b81356113ee848260208601611360565b91505092915050565b60006060828403121561140d5761140c6112ad565b5b6114176060611266565b90506000611427848285016110f5565b600083015250602061143b848285016112c7565b602083015250604082013567ffffffffffffffff81111561145f5761145e6112b2565b5b61146b848285016113c9565b60408301525092915050565b600061148a61148584611281565b611266565b905080838252602082019050602084028301858111156114ad576114ac611051565b5b835b818110156114f457803567ffffffffffffffff8111156114d2576114d1611047565b5b8086016114df89826113f7565b855260208501945050506020810190506114af565b5050509392505050565b600061150b368484611477565b905092915050565b61151c816110cc565b82525050565b60006040820190506115376000830185611513565b6115446020830184611513565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208201905061158f6000830184611513565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060ff82169050919050565b6115da816115c4565b82525050565b60006020820190506115f560008301846115d1565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b600061163f8261162a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611671576116706115fb565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6116b1816110cc565b82525050565b600381106116c8576116c7611595565b5b50565b60008190506116d9826116b7565b919050565b60006116e9826116cb565b9050919050565b6116f9816116de565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61173481611308565b82525050565b6000611746838361172b565b60208301905092915050565b6000602082019050919050565b600061176a826116ff565b611774818561170a565b935061177f8361171b565b8060005b838110156117b0578151611797888261173a565b97506117a283611752565b925050600181019050611783565b5085935050505092915050565b60006060830160008301516117d560008601826116a8565b5060208301516117e860208601826116f0565b5060408301518482036040860152611800828261175f565b9150508091505092915050565b600061181983836117bd565b905092915050565b6000602082019050919050565b60006118398261167c565b6118438185611687565b93508360208202850161185585611698565b8060005b858110156118915784840389528151611872858261180d565b945061187d83611821565b925060208a01995050600181019050611859565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156118dd5780820151818401526020810190506118c2565b60008484015250505050565b60006118f4826118a3565b6118fe81856118ae565b935061190e8185602086016118bf565b611917816111f5565b840191505092915050565b6000606082019050818103600083015261193c818661182e565b905061194b6020830185611513565b818103604083015261195d81846118e9565b9050949350505050565b600082825260208201905092915050565b6000611983826116ff565b61198d8185611967565b93506119988361171b565b8060005b838110156119c95781516119b0888261173a565b97506119bb83611752565b92505060018101905061199c565b5085935050505092915050565b600060208201905081810360008301526119f08184611978565b905092915050565b611a0181611308565b82525050565b6000602082019050611a1c60008301846119f8565b92915050565b600061ffff82169050919050565b6000611a3b82611a22565b915061ffff8203611a4f57611a4e6115fb565b5b600182019050919050565b6000611a658261162a565b915060008203611a7857611a776115fb565b5b600182039050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081905092915050565b6000611ac8826118a3565b611ad28185611ab2565b9350611ae28185602086016118bf565b80840191505092915050565b6000611afa8284611abd565b915081905092915050565b6000604082019050611b1a6000830185611513565b8181036020830152611b2c81846118e9565b90509392505050565b600081519050919050565b600082825260208201905092915050565b6000611b5c82611b35565b611b668185611b40565b9350611b768185602086016118bf565b611b7f816111f5565b840191505092915050565b6000604082019050611b9f6000830185611513565b8181036020830152611bb18184611b51565b9050939250505056fe4c69624469616d6f6e644375743a2041646420666163657420686173206e6f20636f64654c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a205265706c61636520666163657420686173206e6f20636f6465a26469706673582212207585b52d66ac09f271c6e67f08530b2244d6f74f6c5c7bd709040384a3c565a864736f6c63430008110033