Overview
ETH Balance
10 wei
Eth Value
Less Than $0.01 (@ $2,965.28/ETH)More Info
Private Name Tags
ContractCreator
Latest 5 from a total of 5 transactions
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
15653086 | 579 days ago | 10 wei |
Loading...
Loading
Contract Name:
GnosisSafe
Compiler Version
v0.5.0+commit.1d4f565a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion, Audited
Contract Source Code (Solidity)Audit Report
/** *Submitted for verification at Etherscan.io on 2019-03-28 */ pragma solidity ^0.5.0; contract Enum { enum Operation { Call, DelegateCall, Create } } contract EtherPaymentFallback { /// @dev Fallback function accepts Ether transactions. function () external payable { } } contract Executor is EtherPaymentFallback { event ContractCreation(address newContract); function execute(address to, uint256 value, bytes memory data, Enum.Operation operation, uint256 txGas) internal returns (bool success) { if (operation == Enum.Operation.Call) success = executeCall(to, value, data, txGas); else if (operation == Enum.Operation.DelegateCall) success = executeDelegateCall(to, data, txGas); else { address newContract = executeCreate(data); success = newContract != address(0); emit ContractCreation(newContract); } } function executeCall(address to, uint256 value, bytes memory data, uint256 txGas) internal returns (bool success) { // solium-disable-next-line security/no-inline-assembly assembly { success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0) } } function executeDelegateCall(address to, bytes memory data, uint256 txGas) internal returns (bool success) { // solium-disable-next-line security/no-inline-assembly assembly { success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0) } } function executeCreate(bytes memory data) internal returns (address newContract) { // solium-disable-next-line security/no-inline-assembly assembly { newContract := create(0, add(data, 0x20), mload(data)) } } } contract SecuredTokenTransfer { /// @dev Transfers a token and returns if it was a success /// @param token Token that should be transferred /// @param receiver Receiver to whom the token should be transferred /// @param amount The amount of tokens that should be transferred function transferToken ( address token, address receiver, uint256 amount ) internal returns (bool transferred) { bytes memory data = abi.encodeWithSignature("transfer(address,uint256)", receiver, amount); // solium-disable-next-line security/no-inline-assembly assembly { let success := call(sub(gas, 10000), token, 0, add(data, 0x20), mload(data), 0, 0) let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize) switch returndatasize case 0 { transferred := success } case 0x20 { transferred := iszero(or(iszero(success), iszero(mload(ptr)))) } default { transferred := 0 } } } } contract SelfAuthorized { modifier authorized() { require(msg.sender == address(this), "Method can only be called from this contract"); _; } } contract ModuleManager is SelfAuthorized, Executor { event EnabledModule(Module module); event DisabledModule(Module module); address public constant SENTINEL_MODULES = address(0x1); mapping (address => address) internal modules; function setupModules(address to, bytes memory data) internal { require(modules[SENTINEL_MODULES] == address(0), "Modules have already been initialized"); modules[SENTINEL_MODULES] = SENTINEL_MODULES; if (to != address(0)) // Setup has to complete successfully or transaction fails. require(executeDelegateCall(to, data, gasleft()), "Could not finish initialization"); } /// @dev Allows to add a module to the whitelist. /// This can only be done via a Safe transaction. /// @param module Module to be whitelisted. function enableModule(Module module) public authorized { // Module address cannot be null or sentinel. require(address(module) != address(0) && address(module) != SENTINEL_MODULES, "Invalid module address provided"); // Module cannot be added twice. require(modules[address(module)] == address(0), "Module has already been added"); modules[address(module)] = modules[SENTINEL_MODULES]; modules[SENTINEL_MODULES] = address(module); emit EnabledModule(module); } /// @dev Allows to remove a module from the whitelist. /// This can only be done via a Safe transaction. /// @param prevModule Module that pointed to the module to be removed in the linked list /// @param module Module to be removed. function disableModule(Module prevModule, Module module) public authorized { // Validate module address and check that it corresponds to module index. require(address(module) != address(0) && address(module) != SENTINEL_MODULES, "Invalid module address provided"); require(modules[address(prevModule)] == address(module), "Invalid prevModule, module pair provided"); modules[address(prevModule)] = modules[address(module)]; modules[address(module)] = address(0); emit DisabledModule(module); } /// @dev Allows a Module to execute a Safe transaction without any further confirmations. /// @param to Destination address of module transaction. /// @param value Ether value of module transaction. /// @param data Data payload of module transaction. /// @param operation Operation type of module transaction. function execTransactionFromModule(address to, uint256 value, bytes memory data, Enum.Operation operation) public returns (bool success) { // Only whitelisted modules are allowed. require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), "Method can only be called from an enabled module"); // Execute transaction without further confirmations. success = execute(to, value, data, operation, gasleft()); } /// @dev Returns array of modules. /// @return Array of modules. function getModules() public view returns (address[] memory) { // Calculate module count uint256 moduleCount = 0; address currentModule = modules[SENTINEL_MODULES]; while(currentModule != SENTINEL_MODULES) { currentModule = modules[currentModule]; moduleCount ++; } address[] memory array = new address[](moduleCount); // populate return array moduleCount = 0; currentModule = modules[SENTINEL_MODULES]; while(currentModule != SENTINEL_MODULES) { array[moduleCount] = currentModule; currentModule = modules[currentModule]; moduleCount ++; } return array; } } contract OwnerManager is SelfAuthorized { event AddedOwner(address owner); event RemovedOwner(address owner); event ChangedThreshold(uint256 threshold); address public constant SENTINEL_OWNERS = address(0x1); mapping(address => address) internal owners; uint256 ownerCount; uint256 internal threshold; /// @dev Setup function sets initial storage of contract. /// @param _owners List of Safe owners. /// @param _threshold Number of required confirmations for a Safe transaction. function setupOwners(address[] memory _owners, uint256 _threshold) internal { // Threshold can only be 0 at initialization. // Check ensures that setup function can only be called once. require(threshold == 0, "Owners have already been setup"); // Validate that threshold is smaller than number of added owners. require(_threshold <= _owners.length, "Threshold cannot exceed owner count"); // There has to be at least one Safe owner. require(_threshold >= 1, "Threshold needs to be greater than 0"); // Initializing Safe owners. address currentOwner = SENTINEL_OWNERS; for (uint256 i = 0; i < _owners.length; i++) { // Owner address cannot be null. address owner = _owners[i]; require(owner != address(0) && owner != SENTINEL_OWNERS, "Invalid owner address provided"); // No duplicate owners allowed. require(owners[owner] == address(0), "Duplicate owner address provided"); owners[currentOwner] = owner; currentOwner = owner; } owners[currentOwner] = SENTINEL_OWNERS; ownerCount = _owners.length; threshold = _threshold; } /// @dev Allows to add a new owner to the Safe and update the threshold at the same time. /// This can only be done via a Safe transaction. /// @param owner New owner address. /// @param _threshold New threshold. function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized { // Owner address cannot be null. require(owner != address(0) && owner != SENTINEL_OWNERS, "Invalid owner address provided"); // No duplicate owners allowed. require(owners[owner] == address(0), "Address is already an owner"); owners[owner] = owners[SENTINEL_OWNERS]; owners[SENTINEL_OWNERS] = owner; ownerCount++; emit AddedOwner(owner); // Change threshold if threshold was changed. if (threshold != _threshold) changeThreshold(_threshold); } /// @dev Allows to remove an owner from the Safe and update the threshold at the same time. /// This can only be done via a Safe transaction. /// @param prevOwner Owner that pointed to the owner to be removed in the linked list /// @param owner Owner address to be removed. /// @param _threshold New threshold. function removeOwner(address prevOwner, address owner, uint256 _threshold) public authorized { // Only allow to remove an owner, if threshold can still be reached. require(ownerCount - 1 >= _threshold, "New owner count needs to be larger than new threshold"); // Validate owner address and check that it corresponds to owner index. require(owner != address(0) && owner != SENTINEL_OWNERS, "Invalid owner address provided"); require(owners[prevOwner] == owner, "Invalid prevOwner, owner pair provided"); owners[prevOwner] = owners[owner]; owners[owner] = address(0); ownerCount--; emit RemovedOwner(owner); // Change threshold if threshold was changed. if (threshold != _threshold) changeThreshold(_threshold); } /// @dev Allows to swap/replace an owner from the Safe with another address. /// This can only be done via a Safe transaction. /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list /// @param oldOwner Owner address to be replaced. /// @param newOwner New owner address. function swapOwner(address prevOwner, address oldOwner, address newOwner) public authorized { // Owner address cannot be null. require(newOwner != address(0) && newOwner != SENTINEL_OWNERS, "Invalid owner address provided"); // No duplicate owners allowed. require(owners[newOwner] == address(0), "Address is already an owner"); // Validate oldOwner address and check that it corresponds to owner index. require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, "Invalid owner address provided"); require(owners[prevOwner] == oldOwner, "Invalid prevOwner, owner pair provided"); owners[newOwner] = owners[oldOwner]; owners[prevOwner] = newOwner; owners[oldOwner] = address(0); emit RemovedOwner(oldOwner); emit AddedOwner(newOwner); } /// @dev Allows to update the number of required confirmations by Safe owners. /// This can only be done via a Safe transaction. /// @param _threshold New threshold. function changeThreshold(uint256 _threshold) public authorized { // Validate that threshold is smaller than number of owners. require(_threshold <= ownerCount, "Threshold cannot exceed owner count"); // There has to be at least one Safe owner. require(_threshold >= 1, "Threshold needs to be greater than 0"); threshold = _threshold; emit ChangedThreshold(threshold); } function getThreshold() public view returns (uint256) { return threshold; } function isOwner(address owner) public view returns (bool) { return owner != SENTINEL_OWNERS && owners[owner] != address(0); } /// @dev Returns array of owners. /// @return Array of Safe owners. function getOwners() public view returns (address[] memory) { address[] memory array = new address[](ownerCount); // populate return array uint256 index = 0; address currentOwner = owners[SENTINEL_OWNERS]; while(currentOwner != SENTINEL_OWNERS) { array[index] = currentOwner; currentOwner = owners[currentOwner]; index ++; } return array; } } contract BaseSafe is ModuleManager, OwnerManager { /// @dev Setup function sets initial storage of contract. /// @param _owners List of Safe owners. /// @param _threshold Number of required confirmations for a Safe transaction. /// @param to Contract address for optional delegate call. /// @param data Data payload for optional delegate call. function setupSafe(address[] memory _owners, uint256 _threshold, address to, bytes memory data) internal { setupOwners(_owners, _threshold); // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules setupModules(to, data); } } contract MasterCopy is SelfAuthorized { // masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract. // It should also always be ensured that the address is stored alone (uses a full word) address masterCopy; /// @dev Allows to upgrade the contract. This can only be done via a Safe transaction. /// @param _masterCopy New contract address. function changeMasterCopy(address _masterCopy) public authorized { // Master copy address cannot be null. require(_masterCopy != address(0), "Invalid master copy address provided"); masterCopy = _masterCopy; } } contract Module is MasterCopy { ModuleManager public manager; modifier authorized() { require(msg.sender == address(manager), "Method can only be called from manager"); _; } function setManager() internal { // manager can only be 0 at initalization of contract. // Check ensures that setup function can only be called once. require(address(manager) == address(0), "Manager has already been set"); manager = ModuleManager(msg.sender); } } contract SignatureDecoder { /// @dev Recovers address who signed the message /// @param messageHash operation ethereum signed message hash /// @param messageSignature message `txHash` signature /// @param pos which signature to read function recoverKey ( bytes32 messageHash, bytes memory messageSignature, uint256 pos ) internal pure returns (address) { uint8 v; bytes32 r; bytes32 s; (v, r, s) = signatureSplit(messageSignature, pos); return ecrecover(messageHash, v, r, s); } /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`. /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access /// @param signatures concatenated rsv signatures function signatureSplit(bytes memory signatures, uint256 pos) internal pure returns (uint8 v, bytes32 r, bytes32 s) { // The signature format is a compact form of: // {bytes32 r}{bytes32 s}{uint8 v} // Compact means, uint8 is not padded to 32 bytes. // solium-disable-next-line security/no-inline-assembly assembly { let signaturePos := mul(0x41, pos) r := mload(add(signatures, add(signaturePos, 0x20))) s := mload(add(signatures, add(signaturePos, 0x40))) // Here we are loading the last 32 bytes, including 31 bytes // of 's'. There is no 'mload8' to do this. // // 'byte' is not working due to the Solidity parser, so lets // use the second best option, 'and' v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff) } } } library SafeMath { /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0); // Solidity only automatically asserts when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } contract ISignatureValidator { // bytes4(keccak256("isValidSignature(bytes,bytes)") bytes4 constant internal EIP1271_MAGIC_VALUE = 0x20c13b0b; /** * @dev Should return whether the signature provided is valid for the provided data * @param _data Arbitrary length data signed on the behalf of address(this) * @param _signature Signature byte array associated with _data * * MUST return the bytes4 magic value 0x20c13b0b when function passes. * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) * MUST allow external calls */ function isValidSignature( bytes calldata _data, bytes calldata _signature) external returns (bytes4); } contract GnosisSafe is MasterCopy, BaseSafe, SignatureDecoder, SecuredTokenTransfer, ISignatureValidator { using SafeMath for uint256; string public constant NAME = "Gnosis Safe"; string public constant VERSION = "1.0.0"; //keccak256( // "EIP712Domain(address verifyingContract)" //); bytes32 public constant DOMAIN_SEPARATOR_TYPEHASH = 0x035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d4749; //keccak256( // "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)" //); bytes32 public constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8; //keccak256( // "SafeMessage(bytes message)" //); bytes32 public constant SAFE_MSG_TYPEHASH = 0x60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca; event ExecutionFailed(bytes32 txHash); uint256 public nonce; bytes32 public domainSeparator; // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners mapping(bytes32 => uint256) public signedMessages; // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners mapping(address => mapping(bytes32 => uint256)) public approvedHashes; /// @dev Setup function sets initial storage of contract. /// @param _owners List of Safe owners. /// @param _threshold Number of required confirmations for a Safe transaction. /// @param to Contract address for optional delegate call. /// @param data Data payload for optional delegate call. /// @param paymentToken Token that should be used for the payment (0 is ETH) /// @param payment Value that should be paid /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin) function setup(address[] calldata _owners, uint256 _threshold, address to, bytes calldata data, address paymentToken, uint256 payment, address payable paymentReceiver) external { require(domainSeparator == 0, "Domain Separator already set!"); domainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, this)); setupSafe(_owners, _threshold, to, data); if (payment > 0) { // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself) // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment handlePayment(payment, 0, 1, paymentToken, paymentReceiver); } } /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction. /// Note: The fees are always transfered, even if the user transaction fails. /// @param to Destination address of Safe transaction. /// @param value Ether value of Safe transaction. /// @param data Data payload of Safe transaction. /// @param operation Operation type of Safe transaction. /// @param safeTxGas Gas that should be used for the Safe transaction. /// @param baseGas Gas costs for that are indipendent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund) /// @param gasPrice Gas price that should be used for the payment calculation. /// @param gasToken Token address (or 0 if ETH) that is used for the payment. /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin). /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v}) function execTransaction( address to, uint256 value, bytes calldata data, Enum.Operation operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address payable refundReceiver, bytes calldata signatures ) external returns (bool success) { bytes memory txHashData = encodeTransactionData( to, value, data, operation, // Transaction info safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, // Payment info nonce ); // Increase nonce and execute transaction. nonce++; checkSignatures(keccak256(txHashData), txHashData, signatures, true); require(gasleft() >= safeTxGas, "Not enough gas to execute safe transaction"); uint256 gasUsed = gasleft(); // If no safeTxGas has been set and the gasPrice is 0 we assume that all available gas can be used success = execute(to, value, data, operation, safeTxGas == 0 && gasPrice == 0 ? gasleft() : safeTxGas); gasUsed = gasUsed.sub(gasleft()); if (!success) { emit ExecutionFailed(keccak256(txHashData)); } // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls if (gasPrice > 0) { handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver); } } function handlePayment( uint256 gasUsed, uint256 baseGas, uint256 gasPrice, address gasToken, address payable refundReceiver ) private { uint256 amount = gasUsed.add(baseGas).mul(gasPrice); // solium-disable-next-line security/no-tx-origin address payable receiver = refundReceiver == address(0) ? tx.origin : refundReceiver; if (gasToken == address(0)) { // solium-disable-next-line security/no-send require(receiver.send(amount), "Could not pay gas costs with ether"); } else { require(transferToken(gasToken, receiver, amount), "Could not pay gas costs with token"); } } /** * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise. * @param dataHash Hash of the data (could be either a message hash or transaction hash) * @param data That should be signed (this is passed to an external validator contract) * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash. * @param consumeHash Indicates that in case of an approved hash the storage can be freed to save gas */ function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures, bool consumeHash) internal { // Check that the provided signature data is not too short require(signatures.length >= threshold.mul(65), "Signatures data too short"); // There cannot be an owner with address 0. address lastOwner = address(0); address currentOwner; uint8 v; bytes32 r; bytes32 s; uint256 i; for (i = 0; i < threshold; i++) { (v, r, s) = signatureSplit(signatures, i); // If v is 0 then it is a contract signature if (v == 0) { // When handling contract signatures the address of the contract is encoded into r currentOwner = address(uint256(r)); // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes // This check is not completely accurate, since it is possible that more signatures than the threshold are send. // Here we only check that the pointer is not pointing inside the part that is being processed require(uint256(s) >= threshold.mul(65), "Invalid contract signature location: inside static part"); // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes) require(uint256(s).add(32) <= signatures.length, "Invalid contract signature location: length not present"); // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length uint256 contractSignatureLen; // solium-disable-next-line security/no-inline-assembly assembly { contractSignatureLen := mload(add(add(signatures, s), 0x20)) } require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, "Invalid contract signature location: data not complete"); // Check signature bytes memory contractSignature; // solium-disable-next-line security/no-inline-assembly assembly { // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s contractSignature := add(add(signatures, s), 0x20) } require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, "Invalid contract signature provided"); // If v is 1 then it is an approved hash } else if (v == 1) { // When handling approved hashes the address of the approver is encoded into r currentOwner = address(uint256(r)); // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, "Hash has not been approved"); // Hash has been marked for consumption. If this hash was pre-approved free storage if (consumeHash && msg.sender != currentOwner) { approvedHashes[currentOwner][dataHash] = 0; } } else { // Use ecrecover with the messageHash for EOA signatures currentOwner = ecrecover(dataHash, v, r, s); } require (currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, "Invalid owner provided"); lastOwner = currentOwner; } } /// @dev Allows to estimate a Safe transaction. /// This method is only meant for estimation purpose, therfore two different protection mechanism against execution in a transaction have been made: /// 1.) The method can only be called from the safe itself /// 2.) The response is returned with a revert /// When estimating set `from` to the address of the safe. /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction` /// @param to Destination address of Safe transaction. /// @param value Ether value of Safe transaction. /// @param data Data payload of Safe transaction. /// @param operation Operation type of Safe transaction. /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs). function requiredTxGas(address to, uint256 value, bytes calldata data, Enum.Operation operation) external authorized returns (uint256) { uint256 startGas = gasleft(); // We don't provide an error message here, as we use it to return the estimate // solium-disable-next-line error-reason require(execute(to, value, data, operation, gasleft())); uint256 requiredGas = startGas - gasleft(); // Convert response to string and return via error message revert(string(abi.encodePacked(requiredGas))); } /** * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature. * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract. */ function approveHash(bytes32 hashToApprove) external { require(owners[msg.sender] != address(0), "Only owners can approve a hash"); approvedHashes[msg.sender][hashToApprove] = 1; } /** * @dev Marks a message as signed * @param _data Arbitrary length data that should be marked as signed on the behalf of address(this) */ function signMessage(bytes calldata _data) external authorized { signedMessages[getMessageHash(_data)] = 1; } /** * @dev Should return whether the signature provided is valid for the provided data * @param _data Arbitrary length data signed on the behalf of address(this) * @param _signature Signature byte array associated with _data * @return a bool upon valid or invalid signature with corresponding _data */ function isValidSignature(bytes calldata _data, bytes calldata _signature) external returns (bytes4) { bytes32 messageHash = getMessageHash(_data); if (_signature.length == 0) { require(signedMessages[messageHash] != 0, "Hash not approved"); } else { // consumeHash needs to be false, as the state should not be changed checkSignatures(messageHash, _data, _signature, false); } return EIP1271_MAGIC_VALUE; } /// @dev Returns hash of a message that can be signed by owners. /// @param message Message that should be hashed /// @return Message hash. function getMessageHash( bytes memory message ) public view returns (bytes32) { bytes32 safeMessageHash = keccak256( abi.encode(SAFE_MSG_TYPEHASH, keccak256(message)) ); return keccak256( abi.encodePacked(byte(0x19), byte(0x01), domainSeparator, safeMessageHash) ); } /// @dev Returns the bytes that are hashed to be signed by owners. /// @param to Destination address. /// @param value Ether value. /// @param data Data payload. /// @param operation Operation type. /// @param safeTxGas Fas that should be used for the safe transaction. /// @param baseGas Gas costs for data used to trigger the safe transaction. /// @param gasPrice Maximum gas price that should be used for this transaction. /// @param gasToken Token address (or 0 if ETH) that is used for the payment. /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin). /// @param _nonce Transaction nonce. /// @return Transaction hash bytes. function encodeTransactionData( address to, uint256 value, bytes memory data, Enum.Operation operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce ) public view returns (bytes memory) { bytes32 safeTxHash = keccak256( abi.encode(SAFE_TX_TYPEHASH, to, value, keccak256(data), operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce) ); return abi.encodePacked(byte(0x19), byte(0x01), domainSeparator, safeTxHash); } /// @dev Returns hash to be signed by owners. /// @param to Destination address. /// @param value Ether value. /// @param data Data payload. /// @param operation Operation type. /// @param safeTxGas Fas that should be used for the safe transaction. /// @param baseGas Gas costs for data used to trigger the safe transaction. /// @param gasPrice Maximum gas price that should be used for this transaction. /// @param gasToken Token address (or 0 if ETH) that is used for the payment. /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin). /// @param _nonce Transaction nonce. /// @return Transaction hash. function getTransactionHash( address to, uint256 value, bytes memory data, Enum.Operation operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce ) public view returns (bytes32) { return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce)); } }
Contract Security Audit
- Runtime Verification - February 27th, 2020 - Security Audit Report
[{"constant":true,"inputs":[{"name":"message","type":"bytes"}],"name":"getMessageHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"owner","type":"address"},{"name":"_threshold","type":"uint256"}],"name":"addOwnerWithThreshold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR_TYPEHASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_data","type":"bytes"},{"name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"operation","type":"uint8"}],"name":"execTransactionFromModule","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"signedMessages","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"module","type":"address"}],"name":"enableModule","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_threshold","type":"uint256"}],"name":"changeThreshold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"operation","type":"uint8"},{"name":"safeTxGas","type":"uint256"},{"name":"baseGas","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasToken","type":"address"},{"name":"refundReceiver","type":"address"},{"name":"signatures","type":"bytes"}],"name":"execTransaction","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"bytes32"}],"name":"approvedHashes","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_masterCopy","type":"address"}],"name":"changeMasterCopy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_data","type":"bytes"}],"name":"signMessage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SENTINEL_MODULES","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SENTINEL_OWNERS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOwners","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NAME","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owners","type":"address[]"},{"name":"_threshold","type":"uint256"},{"name":"to","type":"address"},{"name":"data","type":"bytes"},{"name":"paymentToken","type":"address"},{"name":"payment","type":"uint256"},{"name":"paymentReceiver","type":"address"}],"name":"setup","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getModules","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SAFE_MSG_TYPEHASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"operation","type":"uint8"}],"name":"requiredTxGas","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SAFE_TX_TYPEHASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"hashToApprove","type":"bytes32"}],"name":"approveHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"operation","type":"uint8"},{"name":"safeTxGas","type":"uint256"},{"name":"baseGas","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasToken","type":"address"},{"name":"refundReceiver","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"getTransactionHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"prevModule","type":"address"},{"name":"module","type":"address"}],"name":"disableModule","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"prevOwner","type":"address"},{"name":"oldOwner","type":"address"},{"name":"newOwner","type":"address"}],"name":"swapOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getThreshold","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"operation","type":"uint8"},{"name":"safeTxGas","type":"uint256"},{"name":"baseGas","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"gasToken","type":"address"},{"name":"refundReceiver","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"encodeTransactionData","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"domainSeparator","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"prevOwner","type":"address"},{"name":"owner","type":"address"},{"name":"_threshold","type":"uint256"}],"name":"removeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"VERSION","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"txHash","type":"bytes32"}],"name":"ExecutionFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"}],"name":"AddedOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"}],"name":"RemovedOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"threshold","type":"uint256"}],"name":"ChangedThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"module","type":"address"}],"name":"EnabledModule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"module","type":"address"}],"name":"DisabledModule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractCreation","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b50615e9380620000216000396000f3fe608060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630a1028c4146101985780630d582f13146102745780631db61b54146102cf57806320c13b0b146102fa5780632f54bf6e14610427578063468721a7146104905780635ae6bd37146105a7578063610b5925146105f6578063694e80c3146106475780636a761202146106825780637d8329741461080b5780637de7edef1461087a57806385a5affe146108cb57806385e332cd146109515780638cff6355146109a8578063a0e67e2b146109ff578063a3f4df7e14610a6b578063a97ab18a14610afb578063affed0e014610c4a578063b2494df314610c75578063c0856ffc14610ce1578063c4ca3a9c14610d0c578063ccafc38714610ddd578063d4d9bdcd14610e08578063d8d11f7814610e43578063e009cfde14610fbf578063e318b52b14611030578063e75235b8146110c1578063e86637db146110ec578063f698da25146112cd578063f8dc5dd9146112f8578063ffa1ad7414611373575b005b3480156101a457600080fd5b5061025e600480360360208110156101bb57600080fd5b81019080803590602001906401000000008111156101d857600080fd5b8201836020820111156101ea57600080fd5b8035906020019184600183028401116401000000008311171561020c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611403565b6040518082815260200191505060405180910390f35b34801561028057600080fd5b506102cd6004803603604081101561029757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611578565b005b3480156102db57600080fd5b506102e4611a0d565b6040518082815260200191505060405180910390f35b34801561030657600080fd5b506103d36004803603604081101561031d57600080fd5b810190808035906020019064010000000081111561033a57600080fd5b82018360208201111561034c57600080fd5b8035906020019184600183028401116401000000008311171561036e57600080fd5b90919293919293908035906020019064010000000081111561038f57600080fd5b8201836020820111156103a157600080fd5b803590602001918460018302840111640100000000831117156103c357600080fd5b9091929391929390505050611a34565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561043357600080fd5b506104766004803603602081101561044a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611be8565b604051808215151515815260200191505060405180910390f35b34801561049c57600080fd5b5061058d600480360360808110156104b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156104fa57600080fd5b82018360208201111561050c57600080fd5b8035906020019184600183028401116401000000008311171561052e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611cba565b604051808215151515815260200191505060405180910390f35b3480156105b357600080fd5b506105e0600480360360208110156105ca57600080fd5b8101908080359060200190929190505050611e36565b6040518082815260200191505060405180910390f35b34801561060257600080fd5b506106456004803603602081101561061957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e4e565b005b34801561065357600080fd5b506106806004803603602081101561066a57600080fd5b81019080803590602001909291905050506122bb565b005b34801561068e57600080fd5b506107f160048036036101408110156106a657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106ed57600080fd5b8201836020820111156106ff57600080fd5b8035906020019184600183028401116401000000008311171561072157600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156107ad57600080fd5b8201836020820111156107bf57600080fd5b803590602001918460018302840111640100000000831117156107e157600080fd5b9091929391929390505050612506565b604051808215151515815260200191505060405180910390f35b34801561081757600080fd5b506108646004803603604081101561082e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612763565b6040518082815260200191505060405180910390f35b34801561088657600080fd5b506108c96004803603602081101561089d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612788565b005b3480156108d757600080fd5b5061094f600480360360208110156108ee57600080fd5b810190808035906020019064010000000081111561090b57600080fd5b82018360208201111561091d57600080fd5b8035906020019184600183028401116401000000008311171561093f57600080fd5b909192939192939050505061295f565b005b34801561095d57600080fd5b50610966612a91565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156109b457600080fd5b506109bd612a96565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a0b57600080fd5b50610a14612a9b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610a57578082015181840152602081019050610a3c565b505050509050019250505060405180910390f35b348015610a7757600080fd5b50610a80612c36565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ac0578082015181840152602081019050610aa5565b50505050905090810190601f168015610aed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b0757600080fd5b50610c48600480360360e0811015610b1e57600080fd5b8101908080359060200190640100000000811115610b3b57600080fd5b820183602082011115610b4d57600080fd5b80359060200191846020830284011164010000000083111715610b6f57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610bba57600080fd5b820183602082011115610bcc57600080fd5b80359060200191846001830284011164010000000083111715610bee57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c6f565b005b348015610c5657600080fd5b50610c5f612e25565b6040518082815260200191505060405180910390f35b348015610c8157600080fd5b50610c8a612e2b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ccd578082015181840152602081019050610cb2565b505050509050019250505060405180910390f35b348015610ced57600080fd5b50610cf66130d2565b6040518082815260200191505060405180910390f35b348015610d1857600080fd5b50610dc760048036036080811015610d2f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610d7657600080fd5b820183602082011115610d8857600080fd5b80359060200191846001830284011164010000000083111715610daa57600080fd5b9091929391929390803560ff1690602001909291905050506130f9565b6040518082815260200191505060405180910390f35b348015610de957600080fd5b50610df26132ed565b6040518082815260200191505060405180910390f35b348015610e1457600080fd5b50610e4160048036036020811015610e2b57600080fd5b8101908080359060200190929190505050613314565b005b348015610e4f57600080fd5b50610fa96004803603610140811015610e6757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610eae57600080fd5b820183602082011115610ec057600080fd5b80359060200191846001830284011164010000000083111715610ee257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613471565b6040518082815260200191505060405180910390f35b348015610fcb57600080fd5b5061102e60048036036040811015610fe257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061349c565b005b34801561103c57600080fd5b506110bf6004803603606081101561105357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061392e565b005b3480156110cd57600080fd5b506110d6614083565b6040518082815260200191505060405180910390f35b3480156110f857600080fd5b50611252600480360361014081101561111057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561115757600080fd5b82018360208201111561116957600080fd5b8035906020019184600183028401116401000000008311171561118b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061408d565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611292578082015181840152602081019050611277565b50505050905090810190601f1680156112bf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156112d957600080fd5b506112e26142df565b6040518082815260200191505060405180910390f35b34801561130457600080fd5b506113716004803603606081101561131b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506142e5565b005b34801561137f57600080fd5b50611388614843565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156113c85780820151818401526020810190506113ad565b50505050905090810190601f1680156113f55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca6001028380519060200120604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120905060197f01000000000000000000000000000000000000000000000000000000000000000260017f0100000000000000000000000000000000000000000000000000000000000000026006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156116ab5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b151561171f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180600454141515611a0957611a08816122bb565b5b5050565b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960010281565b600080611a8486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611403565b90506000848490501415611b23576000600760008381526020019081526020016000205414151515611b1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f48617368206e6f7420617070726f76656400000000000000000000000000000081525060200191505060405180910390fd5b611bb9565b611bb88187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600061487c565b5b6320c13b0b7c010000000000000000000000000000000000000000000000000000000002915050949350505050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611cb35750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015611d855750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1515611e1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d206181526020017f6e20656e61626c6564206d6f64756c650000000000000000000000000000000081525060400191505060405180910390fd5b611e2c858585855a6151bf565b9050949350505050565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015611f815750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515611ff5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4d6f64756c652068617320616c7265616479206265656e20616464656400000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b6003548111151515612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f81526020017f756e74000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600181101515156124c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f5468726573686f6c64206e6565647320746f206265206772656174657220746881526020017f616e20300000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b600060606125628e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8d8d8d8d60055461408d565b90506005600081548092919060010191905055506125ce81805190602001208286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600161487c565b885a1015151561266c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001807f4e6f7420656e6f7567682067617320746f20657865637574652073616665207481526020017f72616e73616374696f6e0000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60005a90506126dd8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008f1480156126cc575060008d145b6126d6578e6126d8565b5a5b6151bf565b92506126f25a826152d290919063ffffffff16565b905082151561273a577fabfd711ecdd15ae3a6b3ad16ff2e9d81aec026a39d16725ee164be4fbf857a7c82805190602001206040518082815260200191505060405180910390a15b600088111561275157612750818a8a8a8a6152f4565b5b50509c9b505050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612851576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561291c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160076000612a7b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611403565b8152602001908152602001600020819055505050565b600181565b600181565b606080600354604051908082528060200260200182016040528015612acf5781602001602082028038833980820191505090505b5090506000809050600060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515612c2d57808383815181101515612b8257fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612b3d565b82935050505090565b6040805190810160405280600b81526020017f476e6f736973205361666500000000000000000000000000000000000000000081525081565b6000600102600654141515612cec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f446f6d61696e20536570617261746f7220616c7265616479207365742100000081525060200191505060405180910390fd5b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960010230604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405160208183030381529060405280519060200120600681905550612e01898980806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615514565b6000821115612e1a57612e19826000600186856152f4565b5b505050505050505050565b60055481565b60606000809050600060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515612f3d57600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612e98565b606082604051908082528060200260200182016040528015612f6e5781602001602082028038833980820191505090505b5090506000925060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505b600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415156130c95781818481518110151561301e57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508280600101935050612fd9565b80935050505090565b7f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60010281565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60005a905061321a878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a6151bf565b151561322557600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156132b2578082015181840152602081019050613297565b50505050905090810190601f1680156132df5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b7fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860010281565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515613418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f6e6c79206f776e6572732063616e20617070726f766520612068617368000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000208190555050565b60006134858b8b8b8b8b8b8b8b8b8b61408d565b8051906020012090509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613565576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135cf5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515613643576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561376b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f496e76616c696420707265764d6f64756c652c206d6f64756c6520706169722081526020017f70726f766964656400000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156139f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613a615750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515613ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613bd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613c425750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b1515613cb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613dde576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f496e76616c696420707265764f776e65722c206f776e6572207061697220707281526020017f6f7669646564000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d86001028c8c8c805190602001208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600281111561411d57fe5b60ff1681526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b50505050505050505050505060405160208183030381529060405280519060200120905060197f01000000000000000000000000000000000000000000000000000000000000000260017f0100000000000000000000000000000000000000000000000000000000000000026006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509a9950505050505050505050565b60065481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156143ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b8060016003540310151515614451576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001807f4e6577206f776e657220636f756e74206e6565647320746f206265206c61726781526020017f6572207468616e206e6577207468726573686f6c64000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156144bb5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b151561452f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515614657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f496e76616c696420707265764f776e65722c206f776e6572207061697220707281526020017f6f7669646564000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414151561483e5761483d816122bb565b5b505050565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b614892604160045461552e90919063ffffffff16565b82511015151561490a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5369676e617475726573206461746120746f6f2073686f72740000000000000081525060200191505060405180910390fd5b600080905060008060008060008090505b6004548110156151b35761492f888261556c565b80945081955082965050505060008460ff161415614e185782600190049450614964604160045461552e90919063ffffffff16565b826001900410151515614a05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001807f496e76616c696420636f6e7472616374207369676e6174757265206c6f63617481526020017f696f6e3a20696e7369646520737461746963207061727400000000000000000081525060400191505060405180910390fd5b8751614a1f6020846001900461559b90919063ffffffff16565b11151515614abb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001807f496e76616c696420636f6e7472616374207369676e6174757265206c6f63617481526020017f696f6e3a206c656e677468206e6f742070726573656e7400000000000000000081525060400191505060405180910390fd5b60006020838a01015190508851614af282614ae46020876001900461559b90919063ffffffff16565b61559b90919063ffffffff16565b11151515614b8e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f496e76616c696420636f6e7472616374207369676e6174757265206c6f63617481526020017f696f6e3a2064617461206e6f7420636f6d706c6574650000000000000000000081525060400191505060405180910390fd5b60606020848b010190506320c13b0b7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015614c68578082015181840152602081019050614c4d565b50505050905090810190601f168015614c955780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015614cce578082015181840152602081019050614cb3565b50505050905090810190601f168015614cfb5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015614d1c57600080fd5b505af1158015614d30573d6000803e3d6000fd5b505050506040513d6020811015614d4657600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141515614e11576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f496e76616c696420636f6e7472616374207369676e61747572652070726f766981526020017f646564000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b505061502f565b60018460ff161415614fc457826001900494508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480614eb657506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b1515614f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4861736820686173206e6f74206265656e20617070726f76656400000000000081525060200191505060405180910390fd5b868015614f6357508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15614fbf576000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c8152602001908152602001600020819055505b61502e565b60018a85858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015615021573d6000803e3d6000fd5b5050506020604051035194505b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156150f65750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b801561512f5750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15156151a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f496e76616c6964206f776e65722070726f76696465640000000000000000000081525060200191505060405180910390fd5b849550808060010191505061491b565b50505050505050505050565b60008060028111156151cd57fe5b8360028111156151d957fe5b14156151f2576151eb868686856155bc565b90506152c9565b600160028111156151ff57fe5b83600281111561520b57fe5b14156152235761521c8685846155d5565b90506152c8565b600061522e856155ec565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141591507f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51181604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505b5b95945050505050565b60008282111515156152e357600080fd5b600082840390508091505092915050565b600061531b8461530d878961559b90919063ffffffff16565b61552e90919063ffffffff16565b905060008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615358578261535a565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615465578073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501515615460576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f436f756c64206e6f74207061792067617320636f73747320776974682065746881526020017f657200000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b61550b565b6154708482846155fe565b151561550a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f436f756c64206e6f74207061792067617320636f737473207769746820746f6b81526020017f656e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b5b50505050505050565b61551e8484615717565b6155288282615c04565b50505050565b6000808314156155415760009050615566565b6000828402905082848281151561555457fe5b0414151561556157600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b60008082840190508381101515156155b257600080fd5b8091505092915050565b6000806000845160208601878987f19050949350505050565b60008060008451602086018786f490509392505050565b60008151602083016000f09050919050565b600060608383604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808251602084016000896127105a03f16040513d6000823e3d600081146156fa5760208114615702576000945061570c565b82945061570c565b8151158315171594505b505050509392505050565b6000600454141515615791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f776e657273206861766520616c7265616479206265656e207365747570000081525060200191505060405180910390fd5b81518111151515615830576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f81526020017f756e74000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600181101515156158cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f5468726573686f6c64206e6565647320746f206265206772656174657220746881526020017f616e20300000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60006001905060008090505b8351811015615b7057600084828151811015156158f457fe5b906020019060200201519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561596a5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15156159de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515615ae1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4475706c6963617465206f776e657220616464726573732070726f766964656481525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506158db565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515615d2e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001807f4d6f64756c6573206861766520616c7265616479206265656e20696e6974696181526020017f6c697a656400000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515615e6357615dee82825a6155d5565b1515615e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f436f756c64206e6f742066696e69736820696e697469616c697a6174696f6e0081525060200191505060405180910390fd5b5b505056fea165627a7a723058209f84e9c455ada449820011f0d2e6ea824d13a9f8d4d45f094ba34e15de427e9f0029
Deployed Bytecode
0x608060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630a1028c4146101985780630d582f13146102745780631db61b54146102cf57806320c13b0b146102fa5780632f54bf6e14610427578063468721a7146104905780635ae6bd37146105a7578063610b5925146105f6578063694e80c3146106475780636a761202146106825780637d8329741461080b5780637de7edef1461087a57806385a5affe146108cb57806385e332cd146109515780638cff6355146109a8578063a0e67e2b146109ff578063a3f4df7e14610a6b578063a97ab18a14610afb578063affed0e014610c4a578063b2494df314610c75578063c0856ffc14610ce1578063c4ca3a9c14610d0c578063ccafc38714610ddd578063d4d9bdcd14610e08578063d8d11f7814610e43578063e009cfde14610fbf578063e318b52b14611030578063e75235b8146110c1578063e86637db146110ec578063f698da25146112cd578063f8dc5dd9146112f8578063ffa1ad7414611373575b005b3480156101a457600080fd5b5061025e600480360360208110156101bb57600080fd5b81019080803590602001906401000000008111156101d857600080fd5b8201836020820111156101ea57600080fd5b8035906020019184600183028401116401000000008311171561020c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611403565b6040518082815260200191505060405180910390f35b34801561028057600080fd5b506102cd6004803603604081101561029757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611578565b005b3480156102db57600080fd5b506102e4611a0d565b6040518082815260200191505060405180910390f35b34801561030657600080fd5b506103d36004803603604081101561031d57600080fd5b810190808035906020019064010000000081111561033a57600080fd5b82018360208201111561034c57600080fd5b8035906020019184600183028401116401000000008311171561036e57600080fd5b90919293919293908035906020019064010000000081111561038f57600080fd5b8201836020820111156103a157600080fd5b803590602001918460018302840111640100000000831117156103c357600080fd5b9091929391929390505050611a34565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561043357600080fd5b506104766004803603602081101561044a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611be8565b604051808215151515815260200191505060405180910390f35b34801561049c57600080fd5b5061058d600480360360808110156104b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156104fa57600080fd5b82018360208201111561050c57600080fd5b8035906020019184600183028401116401000000008311171561052e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611cba565b604051808215151515815260200191505060405180910390f35b3480156105b357600080fd5b506105e0600480360360208110156105ca57600080fd5b8101908080359060200190929190505050611e36565b6040518082815260200191505060405180910390f35b34801561060257600080fd5b506106456004803603602081101561061957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e4e565b005b34801561065357600080fd5b506106806004803603602081101561066a57600080fd5b81019080803590602001909291905050506122bb565b005b34801561068e57600080fd5b506107f160048036036101408110156106a657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106ed57600080fd5b8201836020820111156106ff57600080fd5b8035906020019184600183028401116401000000008311171561072157600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156107ad57600080fd5b8201836020820111156107bf57600080fd5b803590602001918460018302840111640100000000831117156107e157600080fd5b9091929391929390505050612506565b604051808215151515815260200191505060405180910390f35b34801561081757600080fd5b506108646004803603604081101561082e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612763565b6040518082815260200191505060405180910390f35b34801561088657600080fd5b506108c96004803603602081101561089d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612788565b005b3480156108d757600080fd5b5061094f600480360360208110156108ee57600080fd5b810190808035906020019064010000000081111561090b57600080fd5b82018360208201111561091d57600080fd5b8035906020019184600183028401116401000000008311171561093f57600080fd5b909192939192939050505061295f565b005b34801561095d57600080fd5b50610966612a91565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156109b457600080fd5b506109bd612a96565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a0b57600080fd5b50610a14612a9b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610a57578082015181840152602081019050610a3c565b505050509050019250505060405180910390f35b348015610a7757600080fd5b50610a80612c36565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ac0578082015181840152602081019050610aa5565b50505050905090810190601f168015610aed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b0757600080fd5b50610c48600480360360e0811015610b1e57600080fd5b8101908080359060200190640100000000811115610b3b57600080fd5b820183602082011115610b4d57600080fd5b80359060200191846020830284011164010000000083111715610b6f57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610bba57600080fd5b820183602082011115610bcc57600080fd5b80359060200191846001830284011164010000000083111715610bee57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c6f565b005b348015610c5657600080fd5b50610c5f612e25565b6040518082815260200191505060405180910390f35b348015610c8157600080fd5b50610c8a612e2b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ccd578082015181840152602081019050610cb2565b505050509050019250505060405180910390f35b348015610ced57600080fd5b50610cf66130d2565b6040518082815260200191505060405180910390f35b348015610d1857600080fd5b50610dc760048036036080811015610d2f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610d7657600080fd5b820183602082011115610d8857600080fd5b80359060200191846001830284011164010000000083111715610daa57600080fd5b9091929391929390803560ff1690602001909291905050506130f9565b6040518082815260200191505060405180910390f35b348015610de957600080fd5b50610df26132ed565b6040518082815260200191505060405180910390f35b348015610e1457600080fd5b50610e4160048036036020811015610e2b57600080fd5b8101908080359060200190929190505050613314565b005b348015610e4f57600080fd5b50610fa96004803603610140811015610e6757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610eae57600080fd5b820183602082011115610ec057600080fd5b80359060200191846001830284011164010000000083111715610ee257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613471565b6040518082815260200191505060405180910390f35b348015610fcb57600080fd5b5061102e60048036036040811015610fe257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061349c565b005b34801561103c57600080fd5b506110bf6004803603606081101561105357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061392e565b005b3480156110cd57600080fd5b506110d6614083565b6040518082815260200191505060405180910390f35b3480156110f857600080fd5b50611252600480360361014081101561111057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561115757600080fd5b82018360208201111561116957600080fd5b8035906020019184600183028401116401000000008311171561118b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061408d565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611292578082015181840152602081019050611277565b50505050905090810190601f1680156112bf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156112d957600080fd5b506112e26142df565b6040518082815260200191505060405180910390f35b34801561130457600080fd5b506113716004803603606081101561131b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506142e5565b005b34801561137f57600080fd5b50611388614843565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156113c85780820151818401526020810190506113ad565b50505050905090810190601f1680156113f55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca6001028380519060200120604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120905060197f01000000000000000000000000000000000000000000000000000000000000000260017f0100000000000000000000000000000000000000000000000000000000000000026006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611641576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156116ab5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b151561171f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180600454141515611a0957611a08816122bb565b5b5050565b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960010281565b600080611a8486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611403565b90506000848490501415611b23576000600760008381526020019081526020016000205414151515611b1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f48617368206e6f7420617070726f76656400000000000000000000000000000081525060200191505060405180910390fd5b611bb9565b611bb88187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600061487c565b5b6320c13b0b7c010000000000000000000000000000000000000000000000000000000002915050949350505050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611cb35750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015611d855750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1515611e1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d206181526020017f6e20656e61626c6564206d6f64756c650000000000000000000000000000000081525060400191505060405180910390fd5b611e2c858585855a6151bf565b9050949350505050565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015611f815750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515611ff5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4d6f64756c652068617320616c7265616479206265656e20616464656400000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b6003548111151515612424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f81526020017f756e74000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600181101515156124c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f5468726573686f6c64206e6565647320746f206265206772656174657220746881526020017f616e20300000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b600060606125628e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d8d8d8d8d8d60055461408d565b90506005600081548092919060010191905055506125ce81805190602001208286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600161487c565b885a1015151561266c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001807f4e6f7420656e6f7567682067617320746f20657865637574652073616665207481526020017f72616e73616374696f6e0000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60005a90506126dd8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008f1480156126cc575060008d145b6126d6578e6126d8565b5a5b6151bf565b92506126f25a826152d290919063ffffffff16565b905082151561273a577fabfd711ecdd15ae3a6b3ad16ff2e9d81aec026a39d16725ee164be4fbf857a7c82805190602001206040518082815260200191505060405180910390a15b600088111561275157612750818a8a8a8a6152f4565b5b50509c9b505050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612851576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561291c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612a28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160076000612a7b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611403565b8152602001908152602001600020819055505050565b600181565b600181565b606080600354604051908082528060200260200182016040528015612acf5781602001602082028038833980820191505090505b5090506000809050600060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515612c2d57808383815181101515612b8257fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612b3d565b82935050505090565b6040805190810160405280600b81526020017f476e6f736973205361666500000000000000000000000000000000000000000081525081565b6000600102600654141515612cec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f446f6d61696e20536570617261746f7220616c7265616479207365742100000081525060200191505060405180910390fd5b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960010230604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405160208183030381529060405280519060200120600681905550612e01898980806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615514565b6000821115612e1a57612e19826000600186856152f4565b5b505050505050505050565b60055481565b60606000809050600060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515612f3d57600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612e98565b606082604051908082528060200260200182016040528015612f6e5781602001602082028038833980820191505090505b5090506000925060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505b600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415156130c95781818481518110151561301e57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508280600101935050612fd9565b80935050505090565b7f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60010281565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156131c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60005a905061321a878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a6151bf565b151561322557600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156132b2578082015181840152602081019050613297565b50505050905090810190601f1680156132df5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b7fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860010281565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515613418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f6e6c79206f776e6572732063616e20617070726f766520612068617368000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000208190555050565b60006134858b8b8b8b8b8b8b8b8b8b61408d565b8051906020012090509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613565576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156135cf5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515613643576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561376b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f496e76616c696420707265764d6f64756c652c206d6f64756c6520706169722081526020017f70726f766964656400000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156139f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613a615750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515613ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613bd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613c425750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b1515613cb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613dde576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f496e76616c696420707265764f776e65722c206f776e6572207061697220707281526020017f6f7669646564000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d86001028c8c8c805190602001208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600281111561411d57fe5b60ff1681526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b50505050505050505050505060405160208183030381529060405280519060200120905060197f01000000000000000000000000000000000000000000000000000000000000000260017f0100000000000000000000000000000000000000000000000000000000000000026006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509a9950505050505050505050565b60065481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156143ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b8060016003540310151515614451576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001807f4e6577206f776e657220636f756e74206e6565647320746f206265206c61726781526020017f6572207468616e206e6577207468726573686f6c64000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156144bb5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b151561452f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515614657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f496e76616c696420707265764f776e65722c206f776e6572207061697220707281526020017f6f7669646564000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414151561483e5761483d816122bb565b5b505050565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b614892604160045461552e90919063ffffffff16565b82511015151561490a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5369676e617475726573206461746120746f6f2073686f72740000000000000081525060200191505060405180910390fd5b600080905060008060008060008090505b6004548110156151b35761492f888261556c565b80945081955082965050505060008460ff161415614e185782600190049450614964604160045461552e90919063ffffffff16565b826001900410151515614a05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001807f496e76616c696420636f6e7472616374207369676e6174757265206c6f63617481526020017f696f6e3a20696e7369646520737461746963207061727400000000000000000081525060400191505060405180910390fd5b8751614a1f6020846001900461559b90919063ffffffff16565b11151515614abb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001807f496e76616c696420636f6e7472616374207369676e6174757265206c6f63617481526020017f696f6e3a206c656e677468206e6f742070726573656e7400000000000000000081525060400191505060405180910390fd5b60006020838a01015190508851614af282614ae46020876001900461559b90919063ffffffff16565b61559b90919063ffffffff16565b11151515614b8e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f496e76616c696420636f6e7472616374207369676e6174757265206c6f63617481526020017f696f6e3a2064617461206e6f7420636f6d706c6574650000000000000000000081525060400191505060405180910390fd5b60606020848b010190506320c13b0b7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835285818151815260200191508051906020019080838360005b83811015614c68578082015181840152602081019050614c4d565b50505050905090810190601f168015614c955780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b83811015614cce578082015181840152602081019050614cb3565b50505050905090810190601f168015614cfb5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015614d1c57600080fd5b505af1158015614d30573d6000803e3d6000fd5b505050506040513d6020811015614d4657600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141515614e11576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f496e76616c696420636f6e7472616374207369676e61747572652070726f766981526020017f646564000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b505061502f565b60018460ff161415614fc457826001900494508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480614eb657506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b1515614f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4861736820686173206e6f74206265656e20617070726f76656400000000000081525060200191505060405180910390fd5b868015614f6357508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15614fbf576000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c8152602001908152602001600020819055505b61502e565b60018a85858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015615021573d6000803e3d6000fd5b5050506020604051035194505b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156150f65750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b801561512f5750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15156151a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f496e76616c6964206f776e65722070726f76696465640000000000000000000081525060200191505060405180910390fd5b849550808060010191505061491b565b50505050505050505050565b60008060028111156151cd57fe5b8360028111156151d957fe5b14156151f2576151eb868686856155bc565b90506152c9565b600160028111156151ff57fe5b83600281111561520b57fe5b14156152235761521c8685846155d5565b90506152c8565b600061522e856155ec565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141591507f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51181604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505b5b95945050505050565b60008282111515156152e357600080fd5b600082840390508091505092915050565b600061531b8461530d878961559b90919063ffffffff16565b61552e90919063ffffffff16565b905060008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615358578261535a565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615465578073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501515615460576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f436f756c64206e6f74207061792067617320636f73747320776974682065746881526020017f657200000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b61550b565b6154708482846155fe565b151561550a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f436f756c64206e6f74207061792067617320636f737473207769746820746f6b81526020017f656e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b5b50505050505050565b61551e8484615717565b6155288282615c04565b50505050565b6000808314156155415760009050615566565b6000828402905082848281151561555457fe5b0414151561556157600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b60008082840190508381101515156155b257600080fd5b8091505092915050565b6000806000845160208601878987f19050949350505050565b60008060008451602086018786f490509392505050565b60008151602083016000f09050919050565b600060608383604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808251602084016000896127105a03f16040513d6000823e3d600081146156fa5760208114615702576000945061570c565b82945061570c565b8151158315171594505b505050509392505050565b6000600454141515615791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f776e657273206861766520616c7265616479206265656e207365747570000081525060200191505060405180910390fd5b81518111151515615830576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f81526020017f756e74000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600181101515156158cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f5468726573686f6c64206e6565647320746f206265206772656174657220746881526020017f616e20300000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60006001905060008090505b8351811015615b7057600084828151811015156158f457fe5b906020019060200201519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561596a5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15156159de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515615ae1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4475706c6963617465206f776e657220616464726573732070726f766964656481525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506158db565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515615d2e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001807f4d6f64756c6573206861766520616c7265616479206265656e20696e6974696181526020017f6c697a656400000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515615e6357615dee82825a6155d5565b1515615e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f436f756c64206e6f742066696e69736820696e697469616c697a6174696f6e0081525060200191505060405180910390fd5b5b505056fea165627a7a723058209f84e9c455ada449820011f0d2e6ea824d13a9f8d4d45f094ba34e15de427e9f0029
Swarm Source
bzzr://9f84e9c455ada449820011f0d2e6ea824d13a9f8d4d45f094ba34e15de427e9f
Loading...
Loading
Loading...
Loading
OVERVIEW
Logic for Gnosis Safe proxies version 1.0.0Multichain Portfolio | 25 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $2,965.28 | 0.00000000000000001 | <$0.000001 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.