Latest 2 txns

TxHash Age From To Value [TxFee]
0xee7e47560b19fbd8212a8f24e6c4b5570245b43c000317946d627064632b301991 days 15 hrs ago0x13b9c9cb389f5ba7cd5ffb2cec60749ff04ab94a  IN   0x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether0.004194525
0x1d9a83e124e8f6db35807058cd4e41ced118a93a4b40bae1f49b7a39696dcdfd91 days 16 hrs ago0x13b9c9cb389f5ba7cd5ffb2cec60749ff04ab94a  IN    Contract Creation0 Ether0.1498751


[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click here To View More View All
ParentTxHash Block Age From To Value
0x0adfccc95a302d86239a4ec19009471255c611d490282bc8f8d9af0cbff1a07139146971 day 53 mins ago0xdc81648652687096aebaa5007d0da108030ffa140x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x5a360e2bf9bcff61ea8d2ebd15ccc61428526873227418ef6c88e2aa6758c7cd39145991 day 1 hr ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x5a360e2bf9bcff61ea8d2ebd15ccc61428526873227418ef6c88e2aa6758c7cd39145991 day 1 hr ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x7ab8728d1580943e1d82da03c6a3b15dcda95fd9465014f63c4557ed22516b7f39145891 day 1 hr ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x7ab8728d1580943e1d82da03c6a3b15dcda95fd9465014f63c4557ed22516b7f39145891 day 1 hr ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0xbe787683e0feae3ed2953fce20cfbb484dead61af41d9f825279296533a1bb9239143261 day 2 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0xbe787683e0feae3ed2953fce20cfbb484dead61af41d9f825279296533a1bb9239143261 day 2 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0xbe787683e0feae3ed2953fce20cfbb484dead61af41d9f825279296533a1bb9239143261 day 2 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x3f549728bacd78113cae4ab616a3f82fae3ea595d0d08a72099374d25dfe9bf139142101 day 2 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0xf38f10f8038899236c2b3c824ef5118749c9012747a719d65228df7346a10f8b39142021 day 2 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x95f9ca70bff45bd4460238b8ecb62e70d42353aa3e98390e1576da5121d92acd39135501 day 5 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x813fdc945271503dfa4e32f9163f6aec04f9b9a64075da56c0d6caeb30f015bf39135471 day 5 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x64b7cb6b7664af7668cf3f52e6e4463b37b67258811cfaf720bfc7957e36912239094321 day 22 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x41c2504310ca8bb45bd326aa12c9bd4dc798183b25cf9965821ff30755c537b639093961 day 22 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x41c2504310ca8bb45bd326aa12c9bd4dc798183b25cf9965821ff30755c537b639093961 day 22 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x41c2504310ca8bb45bd326aa12c9bd4dc798183b25cf9965821ff30755c537b639093961 day 22 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x4a47a45fe9f186de52131504b126af1d1574bb13bf495e700e373996a087499739093861 day 23 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x9ad9373d78a4a69c05553bb2fcf13d0bd69b605e73163fb2fa233d9b564076a139093791 day 23 hrs ago0xa6ec23c74a0b1a1a1a0b301a647f366b9860e3c50x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0xe8da2a99c18dae7dd22a29b923527684e1d2ef421a7c7598c737c9ecd96b2c9139091362 days 4 mins ago0xb3b07d8da75cd7663e1200ae33469eb2188351520x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x850e876aa5ca7fbfff260aee65680461eedc274d06b5fd1ef0f29de34a2909d139091362 days 4 mins ago0xb3b07d8da75cd7663e1200ae33469eb2188351520x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x7927d158657da6f1db0a33d910b082d533ba1099da8674721c08099462299da339091342 days 4 mins ago0xb3b07d8da75cd7663e1200ae33469eb2188351520x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x7f69a2cc706aab4786d60c5ec9ffa6374998cdf964a602cc15372706375be21639091112 days 10 mins ago0xb3b07d8da75cd7663e1200ae33469eb2188351520x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x432777fdc8bc88b9f1408a74384f4d67c539ddfe114b891d17964c55d3e1239d39083142 days 3 hrs ago0x74ae697af47246040d3365f77cf80e45c2d42f740x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x7f9fbef0335772dd7d0840d23ab0e851f6d4c05742a9ac406f82433219df271039083122 days 3 hrs ago0x74ae697af47246040d3365f77cf80e45c2d42f740x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
0x973d47e40c7fad03c635fa367c3a9ca969071ddc57af4ec71dbfc578098e38d139079122 days 5 hrs ago0x2486e6feea406f4206a75f83657b93d53fcf712f0x8942595a2dc5181df0465af0d7be08c8f23c93af0 Ether
[ Download CSV Export  ] 
Contract Source Code Verified (Exact Match)
Contract Name: GnosisSafe
Compiler Version: v0.5.0+commit.1d4f565a
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.5.0;


/// @title Enum - Collection of enums
/// @author Richard Meissner - <[email protected]>
contract Enum {
enum Operation {
Call,
DelegateCall,
Create
}
}



/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments
/// @author Richard Meissner - <[email protected]>
contract EtherPaymentFallback {

/// @dev Fallback function accepts Ether transactions.
function ()
external
payable
{

}
}

/// @title SelfAuthorized - authorizes current contract to perform actions
/// @author Richard Meissner - <[email protected]>
contract SelfAuthorized {
modifier authorized() {
require(msg.sender == address(this), "Method can only be called from this contract");
_;
}
}

/// @title MasterCopy - Base for master copy contracts (should always be first super contract)
/// @author Richard Meissner - <[email protected]>
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;
}
}

/// @title Executor - A contract that can execute transactions
/// @author Richard Meissner - <[email protected]>
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))
}
}
}



/// @title Module - Base class for modules.
/// @author Stefan George - <[email protected]>
/// @author Richard Meissner - <[email protected]>
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);
}
}



/// @title Module Manager - A contract that manages modules that can execute transactions via this contract
/// @author Stefan George - <[email protected]>
/// @author Richard Meissner - <[email protected]>
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(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;
}
}


/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.
/// @author Stefan George - <[email protected]>
/// @author Richard Meissner - <[email protected]>
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 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;
}
}



/// @title Base Safe - A multisignature wallet with support for modules and owners. This contract needs to be extented to add functionality to execute transactions.
/// @author Stefan George - <[email protected]>
/// @author Richard Meissner - <[email protected]>
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);
}
}

/// @title SignatureDecoder - Decodes signatures that a encoded as bytes
/// @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) 
/// @author Richard Meissner - <[email protected]>
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`
/// @param pos which signature to read
/// @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)
}
}
}



/// @title SecuredTokenTransfer - Secure token transfer
/// @author Richard Meissner - <[email protected]>
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 ISignatureValidator {
/**
* @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 a bool upon valid or invalid signature with corresponding _data
* MUST take (bytes, bytes) as arguments
*/ 
function isValidSignature(
bytes calldata _data, 
bytes calldata _signature)
external
returns (bool isValid); 
}

/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
* TODO: remove once open zeppelin update to solc 0.5.0
*/
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;
}
}

/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.
/// @author Stefan George - <[email protected]>
/// @author Richard Meissner - <[email protected]>
/// @author Ricardo Guilherme Schmidt - (Status Research & Development GmbH) - Gas Token Payment
contract GnosisSafe is MasterCopy, BaseSafe, SignatureDecoder, SecuredTokenTransfer, ISignatureValidator {

using SafeMath for uint256;

string public constant NAME = "Gnosis Safe";
string public constant VERSION = "0.1.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 dataGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)"
//);
bytes32 public constant SAFE_TX_TYPEHASH = 0x14d461bc7412367e924637b363c7bf29b8f47e2f84869f4426e5633d8af47b20;

//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.
function setup(address[] calldata _owners, uint256 _threshold, address to, bytes calldata data)
external
{
require(domainSeparator == 0, "Domain Separator already set!");
domainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, this));
setupSafe(_owners, _threshold, to, data);
}

/// @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 dataGas Gas costs for data used to trigger the safe transaction and to pay the payment transfer
/// @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 dataGas,
uint256 gasPrice,
address gasToken,
address payable refundReceiver,
bytes calldata signatures
)
external
returns (bool success)
{
uint256 startGas = gasleft();
bytes memory txHashData = encodeTransactionData(
to, value, data, operation, // Transaction info
safeTxGas, dataGas, gasPrice, gasToken, refundReceiver, // Payment info
nonce
);
require(checkSignatures(keccak256(txHashData), txHashData, signatures, true), "Invalid signatures provided");
// Increase nonce and execute transaction.
nonce++;
require(gasleft() >= safeTxGas, "Not enough gas to execute safe transaction");
// 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);
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(startGas, dataGas, gasPrice, gasToken, refundReceiver);
}
}

function handlePayment(
uint256 startGas,
uint256 dataGas,
uint256 gasPrice,
address gasToken,
address payable refundReceiver
)
private
{
uint256 amount = startGas.sub(gasleft()).add(dataGas).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 Should return whether the signature provided is valid for the provided data, hash
* @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
* @return a bool upon valid or invalid signature with corresponding _data
*/
function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures, bool consumeHash)
internal
returns (bool)
{
// Check that the provided signature data is not too short
if (signatures.length < threshold * 65) {
return false;
}
// 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));
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)
}
if (!ISignatureValidator(currentOwner).isValidSignature(data, contractSignature)) {
return false;
}
// 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
if (msg.sender != currentOwner && approvedHashes[currentOwner][dataHash] == 0) {
return false;
}
// 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);
}
if (currentOwner <= lastOwner || owners[currentOwner] == address(0)) {
return false;
}
lastOwner = currentOwner;
}
return true;
}

/// @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 (bool isValid)
{
bytes32 messageHash = getMessageHash(_data);
if (_signature.length == 0) {
isValid = signedMessages[messageHash] != 0;
} else {
// consumeHash needs to be false, as the state should not be changed
isValid = checkSignatures(messageHash, _data, _signature, false);
}
}

/// @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 dataGas 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 dataGas, 
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, dataGas, 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 dataGas 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 dataGas, 
uint256 gasPrice,
address gasToken,
address refundReceiver,
uint256 _nonce
)
public
view
returns (bytes32)
{
return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, dataGas, gasPrice, gasToken, refundReceiver, _nonce));
}
}

    Contract ABI  
[{"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":false,"inputs":[{"name":"_owners","type":"address[]"},{"name":"_threshold","type":"uint256"},{"name":"to","type":"address"},{"name":"data","type":"bytes"}],"name":"setup","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":"isValid","type":"bool"}],"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":"dataGas","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":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":"dataGas","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":"dataGas","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 Switch To Opcodes View
608060405234801561001057600080fd5b506158ca80620000216000396000f3fe608060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630a1028c4146101985780630d582f13146102745780630ec78d9e146102cf5780631db61b54146103d457806320c13b0b146103ff5780632f54bf6e146104f2578063468721a71461055b5780635ae6bd3714610672578063610b5925146106c1578063694e80c3146107125780636a7612021461074d5780637d832974146108d65780637de7edef1461094557806385a5affe1461099657806385e332cd14610a1c5780638cff635514610a73578063a0e67e2b14610aca578063a3f4df7e14610b36578063affed0e014610bc6578063b2494df314610bf1578063c0856ffc14610c5d578063c4ca3a9c14610c88578063ccafc38714610d59578063d4d9bdcd14610d84578063d8d11f7814610dbf578063e009cfde14610f3b578063e318b52b14610fac578063e75235b81461103d578063e86637db14611068578063f698da2514611249578063f8dc5dd914611274578063ffa1ad74146112ef575b005b3480156101a457600080fd5b5061025e600480360360208110156101bb57600080fd5b81019080803590602001906401000000008111156101d857600080fd5b8201836020820111156101ea57600080fd5b8035906020019184600183028401116401000000008311171561020c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061137f565b6040518082815260200191505060405180910390f35b34801561028057600080fd5b506102cd6004803603604081101561029757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114f4565b005b3480156102db57600080fd5b506103d2600480360360808110156102f257600080fd5b810190808035906020019064010000000081111561030f57600080fd5b82018360208201111561032157600080fd5b8035906020019184602083028401116401000000008311171561034357600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561038e57600080fd5b8201836020820111156103a057600080fd5b803590602001918460018302840111640100000000831117156103c257600080fd5b9091929391929390505050611989565b005b3480156103e057600080fd5b506103e9611b23565b6040518082815260200191505060405180910390f35b34801561040b57600080fd5b506104d86004803603604081101561042257600080fd5b810190808035906020019064010000000081111561043f57600080fd5b82018360208201111561045157600080fd5b8035906020019184600183028401116401000000008311171561047357600080fd5b90919293919293908035906020019064010000000081111561049457600080fd5b8201836020820111156104a657600080fd5b803590602001918460018302840111640100000000831117156104c857600080fd5b9091929391929390505050611b4a565b604051808215151515815260200191505060405180910390f35b3480156104fe57600080fd5b506105416004803603602081101561051557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c68565b604051808215151515815260200191505060405180910390f35b34801561056757600080fd5b506106586004803603608081101561057e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156105c557600080fd5b8201836020820111156105d757600080fd5b803590602001918460018302840111640100000000831117156105f957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050611d00565b604051808215151515815260200191505060405180910390f35b34801561067e57600080fd5b506106ab6004803603602081101561069557600080fd5b8101908080359060200190929190505050611e42565b6040518082815260200191505060405180910390f35b3480156106cd57600080fd5b50610710600480360360208110156106e457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e5a565b005b34801561071e57600080fd5b5061074b6004803603602081101561073557600080fd5b81019080803590602001909291905050506122c7565b005b34801561075957600080fd5b506108bc600480360361014081101561077157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156107b857600080fd5b8201836020820111156107ca57600080fd5b803590602001918460018302840111640100000000831117156107ec57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561087857600080fd5b82018360208201111561088a57600080fd5b803590602001918460018302840111640100000000831117156108ac57600080fd5b9091929391929390505050612512565b604051808215151515815260200191505060405180910390f35b3480156108e257600080fd5b5061092f600480360360408110156108f957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506127cd565b6040518082815260200191505060405180910390f35b34801561095157600080fd5b506109946004803603602081101561096857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506127f2565b005b3480156109a257600080fd5b50610a1a600480360360208110156109b957600080fd5b81019080803590602001906401000000008111156109d657600080fd5b8201836020820111156109e857600080fd5b80359060200191846001830284011164010000000083111715610a0a57600080fd5b90919293919293905050506129c9565b005b348015610a2857600080fd5b50610a31612afb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a7f57600080fd5b50610a88612b00565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610ad657600080fd5b50610adf612b05565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610b22578082015181840152602081019050610b07565b505050509050019250505060405180910390f35b348015610b4257600080fd5b50610b4b612ca0565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b8b578082015181840152602081019050610b70565b50505050905090810190601f168015610bb85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610bd257600080fd5b50610bdb612cd9565b6040518082815260200191505060405180910390f35b348015610bfd57600080fd5b50610c06612cdf565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610c49578082015181840152602081019050610c2e565b505050509050019250505060405180910390f35b348015610c6957600080fd5b50610c72612f86565b6040518082815260200191505060405180910390f35b348015610c9457600080fd5b50610d4360048036036080811015610cab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610cf257600080fd5b820183602082011115610d0457600080fd5b80359060200191846001830284011164010000000083111715610d2657600080fd5b9091929391929390803560ff169060200190929190505050612fad565b6040518082815260200191505060405180910390f35b348015610d6557600080fd5b50610d6e6131a1565b6040518082815260200191505060405180910390f35b348015610d9057600080fd5b50610dbd60048036036020811015610da757600080fd5b81019080803590602001909291905050506131c8565b005b348015610dcb57600080fd5b50610f256004803603610140811015610de357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610e2a57600080fd5b820183602082011115610e3c57600080fd5b80359060200191846001830284011164010000000083111715610e5e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613325565b6040518082815260200191505060405180910390f35b348015610f4757600080fd5b50610faa60048036036040811015610f5e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613350565b005b348015610fb857600080fd5b5061103b60048036036060811015610fcf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506137e2565b005b34801561104957600080fd5b50611052613f37565b6040518082815260200191505060405180910390f35b34801561107457600080fd5b506111ce600480360361014081101561108c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156110d357600080fd5b8201836020820111156110e557600080fd5b8035906020019184600183028401116401000000008311171561110757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613f41565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561120e5780820151818401526020810190506111f3565b50505050905090810190601f16801561123b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561125557600080fd5b5061125e614193565b6040518082815260200191505060405180910390f35b34801561128057600080fd5b506112ed6004803603606081101561129757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614199565b005b3480156112fb57600080fd5b506113046146f7565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611344578082015181840152602081019050611329565b50505050905090810190601f1680156113715780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca6001028380519060200120604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120905060197f01000000000000000000000000000000000000000000000000000000000000000260017f0100000000000000000000000000000000000000000000000000000000000000026006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156115bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156116275750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b151561169b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561179e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414151561198557611984816122c7565b5b5050565b6000600102600654141515611a06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f446f6d61696e20536570617261746f7220616c7265616479207365742100000081525060200191505060405180910390fd5b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960010230604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405160208183030381529060405280519060200120600681905550611b1b868680806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050614730565b505050505050565b7f035aff83d86937d35b32e04f0ddc6ff469290eef2f1b692d8a815c89404d474960010281565b600080611b9a86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061137f565b90506000848490501415611bc7576000600760008381526020019081526020016000205414159150611c5f565b611c5c8187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600061474a565b91505b50949350505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515611e2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d206181526020017f6e20656e61626c6564206d6f64756c650000000000000000000000000000000081525060400191505060405180910390fd5b611e38858585855a614bfe565b9050949350505050565b60076020528060005260406000206000915090505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015611f8d5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515612001576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4d6f64756c652068617320616c7265616479206265656e20616464656400000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612390576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b6003548111151515612430576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f81526020017f756e74000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600181101515156124cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f5468726573686f6c64206e6565647320746f206265206772656174657220746881526020017f616e20300000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000805a905060606125728f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e8e8e8e8e600554613f41565b90506125cc81805190602001208287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050600161474a565b1515612640576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e76616c6964207369676e6174757265732070726f7669646564000000000081525060200191505060405180910390fd5b600560008154809291906001019190505550895a101515156126f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a8152602001807f4e6f7420656e6f7567682067617320746f20657865637574652073616665207481526020017f72616e73616374696f6e0000000000000000000000000000000000000000000081525060400191505060405180910390fd5b61275c8f8f8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e60008f14801561274b575060008d145b612755578e612757565b5a5b614bfe565b92508215156127a4577fabfd711ecdd15ae3a6b3ad16ff2e9d81aec026a39d16725ee164be4fbf857a7c81805190602001206040518082815260200191505060405180910390a15b60008811156127bb576127ba828a8a8a8a614d11565b5b50509c9b505050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156128bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612986576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160076000612ae585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061137f565b8152602001908152602001600020819055505050565b600181565b600181565b606080600354604051908082528060200260200182016040528015612b395781602001602082028038833980820191505090505b5090506000809050600060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515612c9757808383815181101515612bec57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612ba7565b82935050505090565b6040805190810160405280600b81526020017f476e6f736973205361666500000000000000000000000000000000000000000081525081565b60055481565b60606000809050600060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515612df157600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508180600101925050612d4c565b606082604051908082528060200260200182016040528015612e225781602001602082028038833980820191505090505b5090506000925060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505b600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515612f7d57818184815181101515612ed257fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508280600101935050612e8d565b80935050505090565b7f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60010281565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60005a90506130ce878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a614bfe565b15156130d957600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561316657808201518184015260208101905061314b565b50505050905090810190601f1680156131935780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b7f14d461bc7412367e924637b363c7bf29b8f47e2f84869f4426e5633d8af47b2060010281565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515156132cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f6e6c79206f776e6572732063616e20617070726f766520612068617368000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000208190555050565b60006133398b8b8b8b8b8b8b8b8b8b613f41565b8051906020012090509a9950505050505050505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613419576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156134835750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15156134f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e76616c6964206d6f64756c6520616464726573732070726f76696465640081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561361f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f496e76616c696420707265764d6f64756c652c206d6f64756c6520706169722081526020017f70726f766964656400000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156138ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156139155750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b1515613989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613a8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4164647265737320697320616c726561647920616e206f776e6572000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613af65750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b1515613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613c92576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f496e76616c696420707265764f776e65722c206f776e6572207061697220707281526020017f6f7669646564000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007f14d461bc7412367e924637b363c7bf29b8f47e2f84869f4426e5633d8af47b206001028c8c8c805190602001208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a8152602001898152602001886002811115613fd157fe5b60ff1681526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b50505050505050505050505060405160208183030381529060405280519060200120905060197f01000000000000000000000000000000000000000000000000000000000000000260017f0100000000000000000000000000000000000000000000000000000000000000026006548360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509a9950505050505050505050565b60065481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515614262576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b8060016003540310151515614305576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001807f4e6577206f776e657220636f756e74206e6565647320746f206265206c61726781526020017f6572207468616e206e6577207468726573686f6c64000000000000000000000081525060400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561436f5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15156143e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561450b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001807f496e76616c696420707265764f776e65722c206f776e6572207061697220707281526020017f6f7669646564000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1806004541415156146f2576146f1816122c7565b5b505050565b6040805190810160405280600581526020017f302e312e3000000000000000000000000000000000000000000000000000000081525081565b61473a8484614f43565b6147448282615430565b50505050565b6000604160045402835110156147635760009050614bf6565b600080905060008060008060008090505b600454811015614beb576147888982615693565b80945081955082965050505060008460ff161415614949578260019004945060606020838b010190508573ffffffffffffffffffffffffffffffffffffffff166320c13b0b8c836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561483e578082015181840152602081019050614823565b50505050905090810190601f16801561486b5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156148a4578082015181840152602081019050614889565b50505050905090810190601f1680156148d15780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156148f257600080fd5b505af1158015614906573d6000803e3d6000fd5b505050506040513d602081101561491c57600080fd5b81019080805190602001909291905050501515614943576000975050505050505050614bf6565b50614b01565b60018460ff161415614a9657826001900494508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156149e857506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d815260200190815260200160002054145b156149fc5760009650505050505050614bf6565b878015614a3557508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15614a91576000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d8152602001908152602001600020819055505b614b00565b60018b85858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015614af3573d6000803e3d6000fd5b5050506020604051035194505b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16111580614bc75750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15614bdb5760009650505050505050614bf6565b8495508080600101915050614774565b600196505050505050505b949350505050565b6000806002811115614c0c57fe5b836002811115614c1857fe5b1415614c3157614c2a868686856156c2565b9050614d08565b60016002811115614c3e57fe5b836002811115614c4a57fe5b1415614c6257614c5b8685846156db565b9050614d07565b6000614c6d856156f2565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141591507f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51181604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505b5b95945050505050565b6000614d4a84614d3c87614d2e5a8b61570490919063ffffffff16565b61572690919063ffffffff16565b61574790919063ffffffff16565b905060008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614614d875782614d89565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415614e94578073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050501515614e8f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f436f756c64206e6f74207061792067617320636f73747320776974682065746881526020017f657200000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b614f3a565b614e9f848284615785565b1515614f39576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001807f436f756c64206e6f74207061792067617320636f737473207769746820746f6b81526020017f656e00000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b5b50505050505050565b6000600454141515614fbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4f776e657273206861766520616c7265616479206265656e207365747570000081525060200191505060405180910390fd5b8151811115151561505c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001807f5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f81526020017f756e74000000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600181101515156150fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f5468726573686f6c64206e6565647320746f206265206772656174657220746881526020017f616e20300000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b60006001905060008090505b835181101561539c576000848281518110151561512057fe5b906020019060200201519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156151965750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b151561520a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e76616c6964206f776e657220616464726573732070726f7669646564000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561530d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4475706c6963617465206f776e657220616464726573732070726f766964656481525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550809250508080600101915050615107565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561555a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001807f4d6f64756c6573206861766520616c7265616479206265656e20696e6974696181526020017f6c697a656400000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151561568f5761561a82825a6156db565b151561568e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f436f756c64206e6f742066696e69736820696e697469616c697a6174696f6e0081525060200191505060405180910390fd5b5b5050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b6000806000845160208601878987f19050949350505050565b60008060008451602086018786f490509392505050565b60008151602083016000f09050919050565b600082821115151561571557600080fd5b600082840390508091505092915050565b600080828401905083811015151561573d57600080fd5b8091505092915050565b60008083141561575a576000905061577f565b6000828402905082848281151561576d57fe5b0414151561577a57600080fd5b809150505b92915050565b600060608383604051602401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000808251602084016000896127105a03f16040513d6000823e3d6000811461588157602081146158895760009450615893565b829450615893565b8151158315171594505b50505050939250505056fea165627a7a7230582008fea11a1cf1ba14ad3ca2c37fa255361fba5b8832b7ed3abcf44651f47977ab0029

   Swarm Source:
bzzr://08fea11a1cf1ba14ad3ca2c37fa255361fba5b8832b7ed3abcf44651f47977ab

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward