ETH Price: $1,857.07 (-4.40%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve66476932018-11-05 11:17:152667 days ago1541416635IN
0x16Da1694...a9CFD8ddb
0 ETH0.0018656641
Approve66358252018-11-03 12:40:502669 days ago1541248850IN
0x16Da1694...a9CFD8ddb
0 ETH0.0018630441
Approve66313932018-11-02 19:20:522669 days ago1541186452IN
0x16Da1694...a9CFD8ddb
0 ETH0.0018682841
Approve66305292018-11-02 15:51:112670 days ago1541173871IN
0x16Da1694...a9CFD8ddb
0 ETH0.0018682841
Approve66303222018-11-02 15:04:552670 days ago1541171095IN
0x16Da1694...a9CFD8ddb
0 ETH0.0018630441
Approve66303222018-11-02 15:04:552670 days ago1541171095IN
0x16Da1694...a9CFD8ddb
0 ETH0.0018630441
Withdraw Collate...66303072018-11-02 15:01:262670 days ago1541170886IN
0x16Da1694...a9CFD8ddb
0 ETH0.0010223341
Deposit Collater...65818082018-10-25 16:06:112678 days ago1540483571IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012784842
Approve65817962018-10-25 16:04:372678 days ago1540483477IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012784842
Deposit Collater...65754152018-10-24 15:07:282679 days ago1540393648IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012784842
Approve65753442018-10-24 14:52:262679 days ago1540392746IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012784842
Upgrade Tokens65730882018-10-24 6:01:342679 days ago1540360894IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012308542
Upgrade Tokens65730202018-10-24 5:45:432679 days ago1540359943IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012308542
Deposit Collater...65730072018-10-24 5:42:512679 days ago1540359771IN
0x16Da1694...a9CFD8ddb
0 ETH0.0020453142
Deposit Collater...65730052018-10-24 5:42:252679 days ago1540359745IN
0x16Da1694...a9CFD8ddb
0 ETH0.0020453142
Deposit Collater...65729892018-10-24 5:38:032679 days ago1540359483IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012784842
Approve65729742018-10-24 5:34:522679 days ago1540359292IN
0x16Da1694...a9CFD8ddb
0 ETH0.0012784842
Deposit Collater...65729562018-10-24 5:30:112679 days ago1540359011IN
0x16Da1694...a9CFD8ddb
0 ETH0.0020453142
Deposit Collater...65729432018-10-24 5:27:022679 days ago1540358822IN
0x16Da1694...a9CFD8ddb
0 ETH0.0019084842
Approve65728982018-10-24 5:19:022679 days ago1540358342IN
0x16Da1694...a9CFD8ddb
0 ETH0.0019084842
Vote Proposal65710722018-10-23 22:06:232679 days ago1540332383IN
0x16Da1694...a9CFD8ddb
0 ETH0.0014466317
Become Voter65710452018-10-23 22:02:252679 days ago1540332145IN
0x16Da1694...a9CFD8ddb
0 ETH0.0015307317
Set Masternode C...65710402018-10-23 22:01:102679 days ago1540332070IN
0x16Da1694...a9CFD8ddb
0 ETH0.0010926917
Become Voter65709942018-10-23 21:49:482679 days ago1540331388IN
0x16Da1694...a9CFD8ddb
0 ETH0.0003898617
Become Voter65709842018-10-23 21:47:062679 days ago1540331226IN
0x16Da1694...a9CFD8ddb
0 ETH0.000137596
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CaelumToken

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2018-10-23
*/

pragma solidity ^0.4.24;


/**
 * Libraries
**/

library ExtendedMath {
    function limitLessThan(uint a, uint b) internal pure returns(uint c) {
        if (a > b) return b;
        return a;
    }
}

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 Ownable {
  address public owner;


  event OwnershipRenounced(address indexed previousOwner);
  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(owner);
    owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

contract ERC20Basic {
    function totalSupply() public view returns(uint256);

    function balanceOf(address _who) public view returns(uint256);

    function transfer(address _to, uint256 _value) public returns(bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
}

contract ERC20 is ERC20Basic {
    function allowance(address _owner, address _spender) public view returns(uint256);

    function transferFrom(address _from, address _to, uint256 _value) public returns(bool);

    function approve(address _spender, uint256 _value) public returns(bool);

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

contract BasicToken is ERC20Basic {
    using SafeMath
    for uint256;

    mapping(address => uint256) internal balances;

    uint256 internal totalSupply_;

    /**
     * @dev Total number of tokens in existence
     */
    function totalSupply() public view returns(uint256) {
        return totalSupply_;
    }

    /**
     * @dev Transfer token for a specified address
     * @param _to The address to transfer to.
     * @param _value The amount to be transferred.
     */
    function transfer(address _to, uint256 _value) public returns(bool) {
        //require(_value <= balances[msg.sender]);
        require(_to != address(0));

        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        emit Transfer(msg.sender, _to, _value);
        return true;
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param _owner The address to query the the balance of.
     * @return An uint256 representing the amount owned by the passed address.
     */
    function balanceOf(address _owner) public view returns(uint256) {
        return balances[_owner];
    }

}

contract StandardToken is ERC20, BasicToken {

    mapping(address => mapping(address => uint256)) internal allowed;


    /**
     * @dev Transfer tokens from one address to another
     * @param _from address The address which you want to send tokens from
     * @param _to address The address which you want to transfer to
     * @param _value uint256 the amount of tokens to be transferred
     */
    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    )
    public
    returns(bool) {
        //require(_value <= balances[_from]);
        //require(_value <= allowed[_from][msg.sender]);
        require(_to != address(0));

        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
        emit Transfer(_from, _to, _value);
        return true;
    }

    /**
     * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
     * Beware that changing an allowance with this method brings the risk that someone may use both the old
     * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
     * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     * @param _spender The address which will spend the funds.
     * @param _value The amount of tokens to be spent.
     */
    function approve(address _spender, uint256 _value) public returns(bool) {
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }

    /**
     * @dev Function to check the amount of tokens that an owner allowed to a spender.
     * @param _owner address The address which owns the funds.
     * @param _spender address The address which will spend the funds.
     * @return A uint256 specifying the amount of tokens still available for the spender.
     */
    function allowance(
        address _owner,
        address _spender
    )
    public
    view
    returns(uint256) {
        return allowed[_owner][_spender];
    }

    /**
     * @dev Increase the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed[_spender] == 0. To increment
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @param _spender The address which will spend the funds.
     * @param _addedValue The amount of tokens to increase the allowance by.
     */
    function increaseApproval(
        address _spender,
        uint256 _addedValue
    )
    public
    returns(bool) {
        allowed[msg.sender][_spender] = (
            allowed[msg.sender][_spender].add(_addedValue));
        emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }

    /**
     * @dev Decrease the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed[_spender] == 0. To decrement
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @param _spender The address which will spend the funds.
     * @param _subtractedValue The amount of tokens to decrease the allowance by.
     */
    function decreaseApproval(
        address _spender,
        uint256 _subtractedValue
    )
    public
    returns(bool) {
        uint256 oldValue = allowed[msg.sender][_spender];
        if (_subtractedValue >= oldValue) {
            allowed[msg.sender][_spender] = 0;
        } else {
            allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
        }
        emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }

}

interface IRemoteFunctions {
  function _externalAddMasternode(address) external;
  function _externalStopMasternode(address) external;
}

interface IcaelumVoting {
    function getTokenProposalDetails() external view returns(address, uint, uint, uint);
    function getExpiry() external view returns (uint);
    function getContractType () external view returns (uint);
}

interface EIP918Interface  {

    /*
     * Externally facing mint function that is called by miners to validate challenge digests, calculate reward,
     * populate statistics, mutate epoch variables and adjust the solution difficulty as required. Once complete,
     * a Mint event is emitted before returning a success indicator.
     **/
  	function mint(uint256 nonce, bytes32 challenge_digest) external returns (bool success);


	/*
     * Returns the challenge number
     **/
    function getChallengeNumber() external constant returns (bytes32);

    /*
     * Returns the mining difficulty. The number of digits that the digest of the PoW solution requires which
     * typically auto adjusts during reward generation.
     **/
    function getMiningDifficulty() external constant returns (uint);

    /*
     * Returns the mining target
     **/
    function getMiningTarget() external constant returns (uint);

    /*
     * Return the current reward amount. Depending on the algorithm, typically rewards are divided every reward era
     * as tokens are mined to provide scarcity
     **/
    function getMiningReward() external constant returns (uint);

    /*
     * Upon successful verification and reward the mint method dispatches a Mint Event indicating the reward address,
     * the reward amount, the epoch count and newest challenge number.
     **/
    event Mint(address indexed from, uint reward_amount, uint epochCount, bytes32 newChallengeNumber);

}

contract NewMinerProposal is IcaelumVoting {

    enum VOTE_TYPE {MINER, MASTER, TOKEN}

    VOTE_TYPE public contractType = VOTE_TYPE.TOKEN;
    address contractAddress;
    uint validUntil;
    uint votingDurationInDays;

    /**
     * @dev Create a new vote proposal for an ERC20 token.
     * @param _contract ERC20 contract
     * @param _valid How long do we accept these tokens on the contract (UNIX timestamp)
     * @param _voteDuration How many days is this vote available
     */
    constructor(address _contract, uint _valid, uint _voteDuration) public {
        require(_voteDuration >= 14 && _voteDuration <= 50, "Proposed voting duration does not meet requirements");

        contractAddress = _contract;
        validUntil = _valid;
        votingDurationInDays = _voteDuration;
    }

    /**
     * @dev Returns all details about this proposal
     */
    function getTokenProposalDetails() public view returns(address, uint, uint, uint) {
        return (contractAddress, 0, validUntil, uint(contractType));
    }

    /**
     * @dev Displays the expiry date of contract
     * @return uint Days valid
     */
    function getExpiry() external view returns (uint) {
        return votingDurationInDays;
    }

    /**
     * @dev Displays the type of contract
     * @return uint Enum value {TOKEN, TEAM}
     */
    function getContractType () external view returns (uint){
        return uint(contractType);
    }
}

contract CaelumVotings is Ownable {
    using SafeMath for uint;

    enum VOTE_TYPE {MINER, MASTER, TOKEN}

    struct Proposals {
        address tokenContract;
        uint totalVotes;
        uint proposedOn;
        uint acceptedOn;
        VOTE_TYPE proposalType;
    }

    struct Voters {
        bool isVoter;
        address owner;
        uint[] votedFor;
    }

    uint MAJORITY_PERCENTAGE_NEEDED = 60;
    uint MINIMUM_VOTERS_NEEDED = 1;
    bool public proposalPending;

    mapping(uint => Proposals) public proposalList;
    mapping (address => Voters) public voterMap;
    mapping(uint => address) public voterProposals;
    uint public proposalCounter;
    uint public votersCount;
    uint public votersCountTeam;


    function setMasternodeContractFromVote(address _t) internal ;
    function setTokenContractFromVote(address _t) internal;
    function setMiningContractFromVote (address _t) internal;

    event NewProposal(uint ProposalID);
    event ProposalAccepted(uint ProposalID);

    address _CaelumMasternodeContract;
    CaelumMasternode public MasternodeContract;

    function setMasternodeContractForData(address _t) onlyOwner public {
        MasternodeContract = CaelumMasternode(_t);
        _CaelumMasternodeContract = (_t);
    }

    function setVotingMinority(uint _total) onlyOwner public {
        require(_total > MINIMUM_VOTERS_NEEDED);
        MINIMUM_VOTERS_NEEDED = _total;
    }


    /**
     * @dev Create a new proposal.
     * @param _contract Proposal contract address
     * @return uint ProposalID
     */
    function pushProposal(address _contract) onlyOwner public returns (uint) {
        if(proposalCounter != 0)
        require (pastProposalTimeRules (), "You need to wait 90 days before submitting a new proposal.");
        require (!proposalPending, "Another proposal is pending.");

        uint _contractType = IcaelumVoting(_contract).getContractType();
        proposalList[proposalCounter] = Proposals(_contract, 0, now, 0, VOTE_TYPE(_contractType));

        emit NewProposal(proposalCounter);

        proposalCounter++;
        proposalPending = true;

        return proposalCounter.sub(1);
    }

    /**
     * @dev Internal function that handles the proposal after it got accepted.
     * This function determines if the proposal is a token or team member proposal and executes the corresponding functions.
     * @return uint Returns the proposal ID.
     */
    function handleLastProposal () internal returns (uint) {
        uint _ID = proposalCounter.sub(1);

        proposalList[_ID].acceptedOn = now;
        proposalPending = false;

        address _address;
        uint _required;
        uint _valid;
        uint _type;
        (_address, _required, _valid, _type) = getTokenProposalDetails(_ID);

        if(_type == uint(VOTE_TYPE.MINER)) {
            setMiningContractFromVote(_address);
        }

        if(_type == uint(VOTE_TYPE.MASTER)) {
            setMasternodeContractFromVote(_address);
        }

        if(_type == uint(VOTE_TYPE.TOKEN)) {
            setTokenContractFromVote(_address);
        }

        emit ProposalAccepted(_ID);

        return _ID;
    }

    /**
     * @dev Rejects the last proposal after the allowed voting time has expired and it's not accepted.
     */
    function discardRejectedProposal() onlyOwner public returns (bool) {
        require(proposalPending);
        require (LastProposalCanDiscard());
        proposalPending = false;
        return (true);
    }

    /**
     * @dev Checks if the last proposal allowed voting time has expired and it's not accepted.
     * @return bool
     */
    function LastProposalCanDiscard () public view returns (bool) {

        uint daysBeforeDiscard = IcaelumVoting(proposalList[proposalCounter - 1].tokenContract).getExpiry();
        uint entryDate = proposalList[proposalCounter - 1].proposedOn;
        uint expiryDate = entryDate + (daysBeforeDiscard * 1 days);

        if (now >= expiryDate)
        return true;
    }

    /**
     * @dev Returns all details about a proposal
     */
    function getTokenProposalDetails(uint proposalID) public view returns(address, uint, uint, uint) {
        return IcaelumVoting(proposalList[proposalID].tokenContract).getTokenProposalDetails();
    }

    /**
     * @dev Returns if our 90 day cooldown has passed
     * @return bool
     */
    function pastProposalTimeRules() public view returns (bool) {
        uint lastProposal = proposalList[proposalCounter - 1].proposedOn;
        if (now >= lastProposal + 90 days)
        return true;
    }


    /**
     * @dev Allow any masternode user to become a voter.
     */
    function becomeVoter() public  {
        require (MasternodeContract.isMasternodeOwner(msg.sender), "User has no masternodes");
        require (!voterMap[msg.sender].isVoter, "User Already voted for this proposal");

        voterMap[msg.sender].owner = msg.sender;
        voterMap[msg.sender].isVoter = true;
        votersCount = votersCount + 1;

        if (MasternodeContract.isTeamMember(msg.sender))
        votersCountTeam = votersCountTeam + 1;
    }

    /**
     * @dev Allow voters to submit their vote on a proposal. Voters can only cast 1 vote per proposal.
     * If the proposed vote is about adding Team members, only Team members are able to vote.
     * A proposal can only be published if the total of votes is greater then MINIMUM_VOTERS_NEEDED.
     * @param proposalID proposalID
     */
    function voteProposal(uint proposalID) public returns (bool success) {
        require(voterMap[msg.sender].isVoter, "Sender not listed as voter");
        require(proposalID >= 0, "No proposal was selected.");
        require(proposalID <= proposalCounter, "Proposal out of limits.");
        require(voterProposals[proposalID] != msg.sender, "Already voted.");


        require(votersCount >= MINIMUM_VOTERS_NEEDED, "Not enough voters in existence to push a proposal");
        voterProposals[proposalID] = msg.sender;
        proposalList[proposalID].totalVotes++;

        if(reachedMajority(proposalID)) {
            // This is the prefered way of handling vote results. It costs more gas but prevents tampering.
            // If gas is an issue, you can comment handleLastProposal out and call it manually as onlyOwner.
            handleLastProposal();
            return true;

        }

    }

    /**
     * @dev Check if a proposal has reached the majority vote
     * @param proposalID Token ID
     * @return bool
     */
    function reachedMajority (uint proposalID) public view returns (bool) {
        uint getProposalVotes = proposalList[proposalID].totalVotes;
        if (getProposalVotes >= majority())
        return true;
    }

    /**
     * @dev Internal function that calculates the majority
     * @return uint Total of votes needed for majority
     */
    function majority () internal view returns (uint) {
        uint a = (votersCount * MAJORITY_PERCENTAGE_NEEDED );
        return a / 100;
    }

    /**
     * @dev Check if a proposal has reached the majority vote for a team member
     * @param proposalID Token ID
     * @return bool
     */
    function reachedMajorityForTeam (uint proposalID) public view returns (bool) {
        uint getProposalVotes = proposalList[proposalID].totalVotes;
        if (getProposalVotes >= majorityForTeam())
        return true;
    }

    /**
     * @dev Internal function that calculates the majority
     * @return uint Total of votes needed for majority
     */
    function majorityForTeam () internal view returns (uint) {
        uint a = (votersCountTeam * MAJORITY_PERCENTAGE_NEEDED );
        return a / 100;
    }

}

contract CaelumAcceptERC20 is Ownable  {
    using SafeMath for uint;

    IRemoteFunctions public DataVault;

    address[] public tokensList;
    bool setOwnContract = true;

    struct _whitelistTokens {
        address tokenAddress;
        bool active;
        uint requiredAmount;
        uint validUntil;
        uint timestamp;
    }

    mapping(address => mapping(address => uint)) public tokens;
    mapping(address => _whitelistTokens) acceptedTokens;

    event Deposit(address token, address user, uint amount, uint balance);
    event Withdraw(address token, address user, uint amount, uint balance);

    


    /**
     * @notice Allow the dev to set it's own token as accepted payment.
     * @dev Can be hardcoded in the constructor. Given the contract size, we decided to separate it.
     * @return bool
     */
    function addOwnToken() onlyOwner public returns (bool) {
        require(setOwnContract);
        addToWhitelist(this, 5000 * 1e8, 36500);
        setOwnContract = false;
        return true;
    }


    /**
     * @notice Add a new token as accepted payment method.
     * @param _token Token contract address.
     * @param _amount Required amount of this Token as collateral
     * @param daysAllowed How many days will we accept this token?
     */
    function addToWhitelist(address _token, uint _amount, uint daysAllowed) internal {
        _whitelistTokens storage newToken = acceptedTokens[_token];
        newToken.tokenAddress = _token;
        newToken.requiredAmount = _amount;
        newToken.timestamp = now;
        newToken.validUntil = now + (daysAllowed * 1 days);
        newToken.active = true;

        tokensList.push(_token);
    }

    /**
     * @dev internal function to determine if we accept this token.
     * @param _ad Token contract address
     * @return bool
     */
    function isAcceptedToken(address _ad) internal view returns(bool) {
        return acceptedTokens[_ad].active;
    }

    /**
     * @dev internal function to determine the requiredAmount for a specific token.
     * @param _ad Token contract address
     * @return bool
     */
    function getAcceptedTokenAmount(address _ad) internal view returns(uint) {
        return acceptedTokens[_ad].requiredAmount;
    }

    /**
     * @dev internal function to determine if the token is still accepted timewise.
     * @param _ad Token contract address
     * @return bool
     */
    function isValid(address _ad) internal view returns(bool) {
        uint endTime = acceptedTokens[_ad].validUntil;
        if (block.timestamp < endTime) return true;
        return false;
    }

    /**
     * @notice Returns an array of all accepted token. You can get more details by calling getTokenDetails function with this address.
     * @return array Address
     */
    function listAcceptedTokens() public view returns(address[]) {
        return tokensList;
    }

    /**
     * @notice Returns a full list of the token details
     * @param token Token contract address
     */
    function getTokenDetails(address token) public view returns(address ad,uint required, bool active, uint valid) {
        return (acceptedTokens[token].tokenAddress, acceptedTokens[token].requiredAmount,acceptedTokens[token].active, acceptedTokens[token].validUntil);
    }

    /**
     * @notice Public function that allows any user to deposit accepted tokens as collateral to become a masternode.
     * @param token Token contract address
     * @param amount Amount to deposit
     */
    function depositCollateral(address token, uint amount) public {
        require(isAcceptedToken(token), "ERC20 not authorised");  // Should be a token from our list
        require(amount == getAcceptedTokenAmount(token));         // The amount needs to match our set amount
        require(isValid(token));                                  // It should be called within the setup timeframe

        tokens[token][msg.sender] = tokens[token][msg.sender].add(amount);

        require(StandardToken(token).transferFrom(msg.sender, this, amount), "error with token");
        emit Deposit(token, msg.sender, amount, tokens[token][msg.sender]);

        DataVault._externalAddMasternode(msg.sender);
    }


    /**
     * @notice Public function that allows any user to withdraw deposited tokens and stop as masternode
     * @param token Token contract address
     * @param amount Amount to withdraw
     */
    function withdrawCollateral(address token, uint amount) public {
        require(token != 0);                                        // token should be an actual address
        require(isAcceptedToken(token), "ERC20 not authorised");    // Should be a token from our list
        require(amount == getAcceptedTokenAmount(token));           // The amount needs to match our set amount, allow only one withdrawal at a time.
        require(tokens[token][msg.sender] >= amount);               // The owner must own at least this amount of tokens.

        uint amountToWithdraw = tokens[token][msg.sender];
        tokens[token][msg.sender] = 0;

        DataVault._externalStopMasternode(msg.sender);

        if (!StandardToken(token).transfer(msg.sender, amountToWithdraw)) revert();
        emit Withdraw(token, msg.sender, amountToWithdraw, amountToWithdraw);
    }

    function setDataStorage (address _masternodeContract) onlyOwner public {
        DataVault = IRemoteFunctions(_masternodeContract);
    }
}

contract CaelumAbstractMasternode is Ownable{
    using SafeMath for uint;

    bool onTestnet = false;
    bool genesisAdded = false;

    uint public masternodeRound;
    uint public masternodeCandidate;
    uint public masternodeCounter;
    uint public masternodeEpoch;
    uint public miningEpoch;

    uint public rewardsProofOfWork;
    uint public rewardsMasternode;
    uint rewardsGlobal = 50 * 1e8;

    uint public MINING_PHASE_DURATION_BLOCKS = 4500;

    struct MasterNode {
        address accountOwner;
        bool isActive;
        bool isTeamMember;
        uint storedIndex;
        uint startingRound;
        uint[] indexcounter;
    }

    uint[] userArray;
    address[] userAddressArray;

    mapping(uint => MasterNode) userByIndex; // UINT masterMapping
    mapping(address => MasterNode) userByAddress; //masterMapping
    mapping(address => uint) userAddressIndex;

    event Deposit(address token, address user, uint amount, uint balance);
    event Withdraw(address token, address user, uint amount, uint balance);

    event NewMasternode(address candidateAddress, uint timeStamp);
    event RemovedMasternode(address candidateAddress, uint timeStamp);

    /**
     * @dev Add the genesis accounts
     */
    function addGenesis(address _genesis, bool _team) onlyOwner public {
        require(!genesisAdded);

        addMasternode(_genesis);

        if (_team) {
            updateMasternodeAsTeamMember(msg.sender);
        }

    }

    /**
     * @dev Close the genesis accounts
     */
    function closeGenesis() onlyOwner public {
        genesisAdded = true; // Forever lock this.
    }

    /**
     * @dev Add a user as masternode. Called as internal since we only add masternodes by depositing collateral or by voting.
     * @param _candidate Candidate address
     * @return uint Masternode index
     */
    function addMasternode(address _candidate) internal returns(uint) {
        userByIndex[masternodeCounter].accountOwner = _candidate;
        userByIndex[masternodeCounter].isActive = true;
        userByIndex[masternodeCounter].startingRound = masternodeRound + 1;
        userByIndex[masternodeCounter].storedIndex = masternodeCounter;

        userByAddress[_candidate].accountOwner = _candidate;
        userByAddress[_candidate].indexcounter.push(masternodeCounter);

        userArray.push(userArray.length);
        masternodeCounter++;

        emit NewMasternode(_candidate, now);
        return masternodeCounter - 1; //
    }

    /**
     * @dev Allow us to update a masternode's round to keep progress
     * @param _candidate ID of masternode
     */
    function updateMasternode(uint _candidate) internal returns(bool) {
        userByIndex[_candidate].startingRound++;
        return true;
    }

    /**
     * @dev Allow us to update a masternode to team member status
     * @param _member address
     */
    function updateMasternodeAsTeamMember(address _member) internal returns (bool) {
        userByAddress[_member].isTeamMember = true;
        return (true);
    }

    /**
     * @dev Let us know if an address is part of the team.
     * @param _member address
     */
    function isTeamMember (address _member) public view returns (bool) {
        if (userByAddress[_member].isTeamMember)
        return true;
    }

    /**
     * @dev Remove a specific masternode
     * @param _masternodeID ID of the masternode to remove
     */
    function deleteMasternode(uint _masternodeID) internal returns(bool success) {

        uint rowToDelete = userByIndex[_masternodeID].storedIndex;
        uint keyToMove = userArray[userArray.length - 1];

        userByIndex[_masternodeID].isActive = userByIndex[_masternodeID].isActive = (false);
        userArray[rowToDelete] = keyToMove;
        userByIndex[keyToMove].storedIndex = rowToDelete;
        userArray.length = userArray.length - 1;

        removeFromUserCounter(_masternodeID);

        emit RemovedMasternode(userByIndex[_masternodeID].accountOwner, now);

        return true;
    }

    /**
     * @dev returns what account belongs to a masternode
     */
    function isPartOf(uint mnid) public view returns (address) {
        return userByIndex[mnid].accountOwner;
    }

    /**
     * @dev Internal function to remove a masternode from a user address if this address holds multpile masternodes
     * @param index MasternodeID
     */
    function removeFromUserCounter(uint index)  internal returns(uint[]) {
        address belong = isPartOf(index);

        if (index >= userByAddress[belong].indexcounter.length) return;

        for (uint i = index; i<userByAddress[belong].indexcounter.length-1; i++){
            userByAddress[belong].indexcounter[i] = userByAddress[belong].indexcounter[i+1];
        }

        delete userByAddress[belong].indexcounter[userByAddress[belong].indexcounter.length-1];
        userByAddress[belong].indexcounter.length--;
        return userByAddress[belong].indexcounter;
    }

    /**
     * @dev Primary contract function to update the current user and prepare the next one.
     * A number of steps have been token to ensure the contract can never run out of gas when looping over our masternodes.
     */
    function setMasternodeCandidate() internal returns(address) {

        uint hardlimitCounter = 0;

        while (getFollowingCandidate() == 0x0) {
            // We must return a value not to break the contract. Require is a secondary killswitch now.
            require(hardlimitCounter < 6, "Failsafe switched on");
            // Choose if loop over revert/require to terminate the loop and return a 0 address.
            if (hardlimitCounter == 5) return (0);
            masternodeRound = masternodeRound + 1;
            masternodeCandidate = 0;
            hardlimitCounter++;
        }

        if (masternodeCandidate == masternodeCounter - 1) {
            masternodeRound = masternodeRound + 1;
            masternodeCandidate = 0;
        }

        for (uint i = masternodeCandidate; i < masternodeCounter; i++) {
            if (userByIndex[i].isActive) {
                if (userByIndex[i].startingRound == masternodeRound) {
                    updateMasternode(i);
                    masternodeCandidate = i;
                    return (userByIndex[i].accountOwner);
                }
            }
        }

        masternodeRound = masternodeRound + 1;
        return (0);

    }

    /**
     * @dev Helper function to loop through our masternodes at start and return the correct round
     */
    function getFollowingCandidate() internal view returns(address _address) {
        uint tmpRound = masternodeRound;
        uint tmpCandidate = masternodeCandidate;

        if (tmpCandidate == masternodeCounter - 1) {
            tmpRound = tmpRound + 1;
            tmpCandidate = 0;
        }

        for (uint i = masternodeCandidate; i < masternodeCounter; i++) {
            if (userByIndex[i].isActive) {
                if (userByIndex[i].startingRound == tmpRound) {
                    tmpCandidate = i;
                    return (userByIndex[i].accountOwner);
                }
            }
        }

        tmpRound = tmpRound + 1;
        return (0);
    }

    /**
     * @dev Displays all masternodes belonging to a user address.
     */
    function belongsToUser(address userAddress) public view returns(uint[]) {
        return (userByAddress[userAddress].indexcounter);
    }

    /**
     * @dev Helper function to know if an address owns masternodes
     */
    function isMasternodeOwner(address _candidate) public view returns(bool) {
        if(userByAddress[_candidate].indexcounter.length <= 0) return false;
        if (userByAddress[_candidate].accountOwner == _candidate)
        return true;
    }

    /**
     * @dev Helper function to get the last masternode belonging to a user
     */
    function getLastPerUser(address _candidate) public view returns (uint) {
        return userByAddress[_candidate].indexcounter[userByAddress[_candidate].indexcounter.length - 1];
    }

    /**
     * @dev Return the base rewards. This should be overrided by the miner contract.
     * Return a base value for standalone usage ONLY.
     */
    function getMiningReward() public view returns(uint) {
        return 50 * 1e8;
    }

    /**
     * @dev Calculate and set the reward schema for Caelum.
     * Each mining phase is decided by multiplying the MINING_PHASE_DURATION_BLOCKS with factor 10.
     * Depending on the outcome (solidity always rounds), we can detect the current stage of mining.
     * First stage we cut the rewards to 5% to prevent instamining.
     * Last stage we leave 2% for miners to incentivize keeping miners running.
     */
    function calculateRewardStructures() internal {
        //ToDo: Set
        uint _global_reward_amount = getMiningReward();
        uint getStageOfMining = miningEpoch / MINING_PHASE_DURATION_BLOCKS * 10;

        if (getStageOfMining < 10) {
            rewardsProofOfWork = _global_reward_amount / 100 * 5;
            rewardsMasternode = 0;
            return;
        }

        if (getStageOfMining > 90) {
            rewardsProofOfWork = _global_reward_amount / 100 * 2;
            rewardsMasternode = _global_reward_amount / 100 * 98;
            return;
        }

        uint _mnreward = (_global_reward_amount / 100) * getStageOfMining;
        uint _powreward = (_global_reward_amount - _mnreward);

        setBaseRewards(_powreward, _mnreward);
    }

    function setBaseRewards(uint _pow, uint _mn) internal {
        rewardsMasternode = _mn;
        rewardsProofOfWork = _pow;
    }

    /**
     * @dev Executes the masternode flow. Should be called after mining a block.
     */
    function _arrangeMasternodeFlow() internal {
        calculateRewardStructures();
        setMasternodeCandidate();
        miningEpoch++;
    }

    /**
     * @dev Executes the masternode flow. Should be called after mining a block.
     * This is an emergency manual loop method.
     */
    function _emergencyLoop() onlyOwner public {
        calculateRewardStructures();
        setMasternodeCandidate();
        miningEpoch++;
    }

    function masternodeInfo(uint index) public view returns
    (
        address,
        bool,
        uint,
        uint
    )
    {
        return (
            userByIndex[index].accountOwner,
            userByIndex[index].isActive,
            userByIndex[index].storedIndex,
            userByIndex[index].startingRound
        );
    }

    function contractProgress() public view returns
    (
        uint epoch,
        uint candidate,
        uint round,
        uint miningepoch,
        uint globalreward,
        uint powreward,
        uint masternodereward,
        uint usercounter
    )
    {
        return (
            masternodeEpoch,
            masternodeCandidate,
            masternodeRound,
            miningEpoch,
            getMiningReward(),
            rewardsProofOfWork,
            rewardsMasternode,
            masternodeCounter
        );
    }

}

contract CaelumMasternode is CaelumVotings, CaelumAbstractMasternode {

    /**
     * @dev Hardcoded token mining address. For trust and safety we do not allow changing this.
     * Should anything change, a new instance needs to be redeployed.
     */
    address public miningContract;
    address public tokenContract;
    
    bool minerSet = false;
    bool tokenSet = false;

    function setMiningContract(address _t) onlyOwner public {
        require(!minerSet);
        miningContract = _t;
        minerSet = true;
    }

    function setTokenContract(address _t) onlyOwner public {
        require(!tokenSet);
        tokenContract = _t;
        tokenSet = true;
    }

    function setMasternodeContractFromVote(address _t) internal {
    }

    function setTokenContractFromVote(address _t) internal{
        tokenContract = _t;
    }

    function setMiningContractFromVote (address _t) internal {
        miningContract = _t;
    }

    /**
     * @dev Only allow the token mining contract to call this function when used remotely.
     * Use the internal function when working within the same contract.
     */
    modifier onlyMiningContract() {
        require(msg.sender == miningContract);
        _;
    }

    /**
     * @dev Only allow the token contract to call this function when used remotely.
     * Use the internal function when working within the same contract.
     */
    modifier onlyTokenContract() {
        require(msg.sender == tokenContract);
        _;
    }

    /**
     * @dev Only allow the token contract to call this function when used remotely.
     * Use the internal function when working within the same contract.
     */
    modifier bothRemoteContracts() {
        require(msg.sender == tokenContract || msg.sender == miningContract);
        _;
    }

    /**
     * @dev Use this to externaly call the _arrangeMasternodeFlow function. ALWAYS set a modifier !
     */
    function _externalArrangeFlow() onlyMiningContract external {
        _arrangeMasternodeFlow();
    }

    /**
     * @dev Use this to externaly call the addMasternode function. ALWAYS set a modifier !
     */
    function _externalAddMasternode(address _received) onlyMiningContract external {
        addMasternode(_received);
    }

    /**
     * @dev Use this to externaly call the deleteMasternode function. ALWAYS set a modifier !
     */
    function _externalStopMasternode(address _received) onlyMiningContract external {
        deleteMasternode(getLastPerUser(_received));
    }

    function getMiningReward() public view returns(uint) {
        return CaelumMiner(miningContract).getMiningReward();
    }
    
    address cloneDataFrom = 0x7600bF5112945F9F006c216d5d6db0df2806eDc6;
    
    function getDataFromContract () onlyOwner public returns(uint) {
        
        CaelumMasternode prev = CaelumMasternode(cloneDataFrom);
        (uint epoch,
        uint candidate,
        uint round,
        uint miningepoch,
        uint globalreward,
        uint powreward,
        uint masternodereward,
        uint usercounter) = prev.contractProgress();
        
        masternodeEpoch = epoch;
        masternodeRound = round;
        miningEpoch = miningepoch;
        rewardsProofOfWork = powreward;
        rewardsMasternode = masternodereward;

    }

}

contract CaelumToken is Ownable, StandardToken, CaelumVotings, CaelumAcceptERC20 {
    using SafeMath for uint;

    ERC20 previousContract;
    
    bool contractSet = false;
    bool public swapClosed = false;
    uint public swapCounter;

    string public symbol = "CLM";
    string public name = "Caelum Token";
    uint8 public decimals = 8;
    uint256 public totalSupply = 2100000000000000;
    
    address public miningContract = 0x0;

    /**
     * @dev Only allow the token mining contract to call this function when used remotely.
     * Use the internal function when working within the same contract.
     */
    modifier onlyMiningContract() {
        require(msg.sender == miningContract);
        _;
    }

    constructor(address _previousContract) public {
        previousContract = ERC20(_previousContract);
        swapClosed = false;
        swapCounter = 0;
    }

    function setMiningContract (address _t) onlyOwner public {
        require(!contractSet);
        miningContract = _t;
        contractSet = true;
    }

    function setMasternodeContractFromVote(address _t) internal {
        return;
    }

    function setTokenContractFromVote(address _t) internal{
        return;
    }

    function setMiningContractFromVote (address _t) internal {
        miningContract = _t;
    }
    
    function changeSwapState (bool _state) onlyOwner public {
        require(swapCounter <= 9);
        swapClosed = _state;
        swapCounter++;
    }

    function rewardExternal(address _receiver, uint _amount) onlyMiningContract external {
        balances[_receiver] = balances[_receiver].add(_amount);
        emit Transfer(this, _receiver, _amount);
    }


    function upgradeTokens() public{
        require(!swapClosed);
        uint amountToUpgrade = previousContract.balanceOf(msg.sender);
        require(amountToUpgrade <= previousContract.allowance(msg.sender, this));
        
        if(previousContract.transferFrom(msg.sender, this, amountToUpgrade)){
            balances[msg.sender] = balances[msg.sender].add(amountToUpgrade); // 2% Premine as determined by the community meeting.
            emit Transfer(this, msg.sender, amountToUpgrade);
        }
        
        require(previousContract.balanceOf(msg.sender) == 0);
    }
}



contract AbstractERC918 is EIP918Interface {

    // generate a new challenge number after a new reward is minted
    bytes32 public challengeNumber;

    // the current mining difficulty
    uint public difficulty;

    // cumulative counter of the total minted tokens
    uint public tokensMinted;

    // track read only minting statistics
    struct Statistics {
        address lastRewardTo;
        uint lastRewardAmount;
        uint lastRewardEthBlockNumber;
        uint lastRewardTimestamp;
    }

    Statistics public statistics;

    /*
     * Externally facing mint function that is called by miners to validate challenge digests, calculate reward,
     * populate statistics, mutate epoch variables and adjust the solution difficulty as required. Once complete,
     * a Mint event is emitted before returning a success indicator.
     **/
    function mint(uint256 nonce, bytes32 challenge_digest) public returns (bool success);


    /*
     * Internal interface function _hash. Overide in implementation to define hashing algorithm and
     * validation
     **/
    function _hash(uint256 nonce, bytes32 challenge_digest) internal returns (bytes32 digest);

    /*
     * Internal interface function _reward. Overide in implementation to calculate and return reward
     * amount
     **/
    function _reward() internal returns (uint);

    /*
     * Internal interface function _newEpoch. Overide in implementation to define a cutpoint for mutating
     * mining variables in preparation for the next epoch
     **/
    function _newEpoch(uint256 nonce) internal returns (uint);

    /*
     * Internal interface function _adjustDifficulty. Overide in implementation to adjust the difficulty
     * of the mining as required
     **/
    function _adjustDifficulty() internal returns (uint);

}

contract CaelumAbstractMiner is AbstractERC918 {
    /**
     * CaelumMiner contract.
     *
     * We need to make sure the contract is 100% compatible when using the EIP918Interface.
     * This contract is an abstract Caelum miner contract.
     *
     * Function 'mint', and '_reward' are overriden in the CaelumMiner contract.
     * Function '_reward_masternode' is added and needs to be overriden in the CaelumMiner contract.
     */

    using SafeMath for uint;
    using ExtendedMath for uint;

    uint256 public totalSupply = 2100000000000000;

    uint public latestDifficultyPeriodStarted;
    uint public epochCount;
    uint public baseMiningReward = 50;
    uint public blocksPerReadjustment = 512;
    uint public _MINIMUM_TARGET = 2 ** 16;
    uint public _MAXIMUM_TARGET = 2 ** 234;
    uint public rewardEra = 0;

    uint public maxSupplyForEra;
    uint public MAX_REWARD_ERA = 39;
    uint public MINING_RATE_FACTOR = 60; //mint the token 60 times less often than ether

    uint public MAX_ADJUSTMENT_PERCENT = 100;
    uint public TARGET_DIVISOR = 2000;
    uint public QUOTIENT_LIMIT = TARGET_DIVISOR.div(2);
    mapping(bytes32 => bytes32) solutionForChallenge;
    mapping(address => mapping(address => uint)) allowed;

    bytes32 public challengeNumber;
    uint public difficulty;
    uint public tokensMinted;


    Statistics public statistics;

    event Mint(address indexed from, uint reward_amount, uint epochCount, bytes32 newChallengeNumber);
    event RewardMasternode(address candidate, uint amount);

    constructor() public {
        tokensMinted = 0;
        maxSupplyForEra = totalSupply.div(2);
        difficulty = _MAXIMUM_TARGET;
        latestDifficultyPeriodStarted = block.number;
        _newEpoch(0);
    }



    function _newEpoch(uint256 nonce) internal returns(uint) {

        if (tokensMinted.add(getMiningReward()) > maxSupplyForEra && rewardEra < MAX_REWARD_ERA) {
            rewardEra = rewardEra + 1;
        }
        maxSupplyForEra = totalSupply - totalSupply.div(2 ** (rewardEra + 1));
        epochCount = epochCount.add(1);
        challengeNumber = blockhash(block.number - 1);
        return (epochCount);
    }

    function mint(uint256 nonce, bytes32 challenge_digest) public returns(bool success);

    function _hash(uint256 nonce, bytes32 challenge_digest) internal returns(bytes32 digest) {
        digest = keccak256(challengeNumber, msg.sender, nonce);
        if (digest != challenge_digest) revert();
        if (uint256(digest) > difficulty) revert();
        bytes32 solution = solutionForChallenge[challengeNumber];
        solutionForChallenge[challengeNumber] = digest;
        if (solution != 0x0) revert(); //prevent the same answer from awarding twice
    }

    function _reward() internal returns(uint);

    function _reward_masternode() internal returns(uint);

    function _adjustDifficulty() internal returns(uint) {
        //every so often, readjust difficulty. Dont readjust when deploying
        if (epochCount % blocksPerReadjustment != 0) {
            return difficulty;
        }

        uint ethBlocksSinceLastDifficultyPeriod = block.number - latestDifficultyPeriodStarted;
        //assume 360 ethereum blocks per hour
        //we want miners to spend 10 minutes to mine each 'block', about 60 ethereum blocks = one 0xbitcoin epoch
        uint epochsMined = blocksPerReadjustment;
        uint targetEthBlocksPerDiffPeriod = epochsMined * MINING_RATE_FACTOR;
        //if there were less eth blocks passed in time than expected
        if (ethBlocksSinceLastDifficultyPeriod < targetEthBlocksPerDiffPeriod) {
            uint excess_block_pct = (targetEthBlocksPerDiffPeriod.mul(MAX_ADJUSTMENT_PERCENT)).div(ethBlocksSinceLastDifficultyPeriod);
            uint excess_block_pct_extra = excess_block_pct.sub(100).limitLessThan(QUOTIENT_LIMIT);
            // If there were 5% more blocks mined than expected then this is 5.  If there were 100% more blocks mined than expected then this is 100.
            //make it harder
            difficulty = difficulty.sub(difficulty.div(TARGET_DIVISOR).mul(excess_block_pct_extra)); //by up to 50 %
        } else {
            uint shortage_block_pct = (ethBlocksSinceLastDifficultyPeriod.mul(MAX_ADJUSTMENT_PERCENT)).div(targetEthBlocksPerDiffPeriod);
            uint shortage_block_pct_extra = shortage_block_pct.sub(100).limitLessThan(QUOTIENT_LIMIT); //always between 0 and 1000
            //make it easier
            difficulty = difficulty.add(difficulty.div(TARGET_DIVISOR).mul(shortage_block_pct_extra)); //by up to 50 %
        }
        latestDifficultyPeriodStarted = block.number;
        if (difficulty < _MINIMUM_TARGET) //very difficult
        {
            difficulty = _MINIMUM_TARGET;
        }
        if (difficulty > _MAXIMUM_TARGET) //very easy
        {
            difficulty = _MAXIMUM_TARGET;
        }
    }

    function getChallengeNumber() public view returns(bytes32) {
        return challengeNumber;
    }

    function getMiningDifficulty() public view returns(uint) {
        return _MAXIMUM_TARGET.div(difficulty);
    }

    function getMiningTarget() public view returns(uint) {
        return difficulty;
    }

    function getMiningReward() public view returns(uint) {
        return (baseMiningReward * 1e8).div(2 ** rewardEra);
    }

    function getMintDigest(
        uint256 nonce,
        bytes32 challenge_digest,
        bytes32 challenge_number
    )
    public view returns(bytes32 digesttest) {
        bytes32 digest = keccak256(challenge_number, msg.sender, nonce);
        return digest;
    }

    function checkMintSolution(
        uint256 nonce,
        bytes32 challenge_digest,
        bytes32 challenge_number,
        uint testTarget
    )
    public view returns(bool success) {
        bytes32 digest = keccak256(challenge_number, msg.sender, nonce);
        if (uint256(digest) > testTarget) revert();
        return (digest == challenge_digest);
    }
}

contract CaelumMiner is CaelumVotings, CaelumAbstractMiner {

    /**
     * CaelumMiner main contract
     *
     * Inherit from our abstract CaelumMiner contract and override some functions
     * of the AbstractERC918 contract to allow masternode rewardings.
     *
     * @dev use this contract to make all changes needed for your project.
     */

    address cloneDataFrom = 0x7600bF5112945F9F006c216d5d6db0df2806eDc6;

    bool ACTIVE_CONTRACT_STATE = true;
    bool MasternodeSet = false;
    bool TokenSet = false;

    address _CaelumMasternodeContract;
    address _CaelumTokenContract;

    CaelumMasternode public MasternodeContract;
    CaelumToken public tokenContract;

    function setMasternodeContract(address _t) onlyOwner public {
        require(!MasternodeSet);
        MasternodeContract = CaelumMasternode(_t);
        _CaelumMasternodeContract = (_t);
        MasternodeSet = true;
    }

    function setTokenContract(address _t) onlyOwner public {
        require(!TokenSet);
        tokenContract = CaelumToken(_t);
        _CaelumTokenContract = (_t);
        TokenSet = true;
    }

    function setMiningContract (address _t) onlyOwner public {
        return; 
    }

    function setMasternodeContractFromVote(address _t) internal {
        MasternodeContract = CaelumMasternode(_t);
        _CaelumMasternodeContract = (_t);
    }

    function setTokenContractFromVote(address _t) internal{
        tokenContract = CaelumToken(_t);
        _CaelumTokenContract = (_t);
    }

    function setMiningContractFromVote (address _t) internal {
        return;
    }
    
    function lockMiningContract () onlyOwner public {
        ACTIVE_CONTRACT_STATE = false;
    }

    function getDataFromContract () onlyOwner public {

        require(_CaelumTokenContract != 0);
        require(_CaelumMasternodeContract != 0);

        CaelumMiner prev = CaelumMiner(cloneDataFrom);
        difficulty = prev.difficulty();
        rewardEra = prev.rewardEra();
        MINING_RATE_FACTOR = prev.MINING_RATE_FACTOR();
        maxSupplyForEra = prev.maxSupplyForEra();
        tokensMinted = prev.tokensMinted();
        epochCount = prev.epochCount();
        latestDifficultyPeriodStarted = prev.latestDifficultyPeriodStarted();

        ACTIVE_CONTRACT_STATE = true;
    }
    

    /**
     * @dev override of the original function since we want to call the masternode contract remotely.
     */
    function mint(uint256 nonce, bytes32 challenge_digest) public returns(bool success) {
        // If contract is no longer active, stop accepting solutions.
        require(ACTIVE_CONTRACT_STATE);

        _hash(nonce, challenge_digest);

        MasternodeContract._externalArrangeFlow();

        uint rewardAmount =_reward();
        uint rewardMasternode = _reward_masternode();

        tokensMinted += rewardAmount.add(rewardMasternode);

        uint epochCounter = _newEpoch(nonce);

        _adjustDifficulty();

        statistics = Statistics(msg.sender, rewardAmount, block.number, now);

        emit Mint(msg.sender, rewardAmount, epochCounter, challengeNumber);

        return true;
    }

    /**
     * @dev override of the original function since we want to call the masternode contract remotely.
     */
    function _reward() internal returns(uint) {

        uint _pow = MasternodeContract.rewardsProofOfWork();

        tokenContract.rewardExternal(msg.sender, _pow);

        return _pow;
    }

    /**
     * @dev override of the original function since we want to call the masternode contract remotely.
     */
    function _reward_masternode() internal returns(uint) {

        uint _mnReward = MasternodeContract.rewardsMasternode();
        if (MasternodeContract.masternodeCounter() == 0) return 0;

        uint getCandidate = MasternodeContract.masternodeCandidate();
        address _mnCandidate = MasternodeContract.isPartOf(getCandidate);
        if (_mnCandidate == 0x0) return 0;

        tokenContract.rewardExternal(_mnCandidate, _mnReward);

        emit RewardMasternode(_mnCandidate, _mnReward);

        return _mnReward;
    }
    
    function getMiningReward() public view returns(uint) {
        return MasternodeContract.rewardsProofOfWork();
    }
}


/**
 * Burn some gas and create all contracts in a single call :-)
 */

contract caelumFactory { 

    CaelumMiner public MINER;
    CaelumMasternode public MASTER;
    CaelumToken public TOKEN;

    function newCookie() public {
        MINER = new CaelumMiner();
        MASTER = new CaelumMasternode();
        TOKEN = new CaelumToken(0x0);

        MASTER.setMiningContract(MINER);
        MASTER.setTokenContract(TOKEN);

        MINER.setMasternodeContract(MASTER);
        MINER.setTokenContract(TOKEN);

        TOKEN.setMiningContract(MINER);
        TOKEN.setDataStorage(MASTER);

        MASTER.transferOwnership(msg.sender);
        TOKEN.transferOwnership(msg.sender);
        MINER.transferOwnership(msg.sender);
    }

}

Contract Security Audit

Contract ABI

API
[{"constant":false,"inputs":[{"name":"_masternodeContract","type":"address"}],"name":"setDataStorage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_state","type":"bool"}],"name":"changeSwapState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"proposalCounter","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"discardRejectedProposal","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"voterMap","outputs":[{"name":"isVoter","type":"bool"},{"name":"owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"swapCounter","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"upgradeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"voterProposals","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"addOwnToken","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokensList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"tokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MasternodeContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"proposalID","type":"uint256"}],"name":"getTokenProposalDetails","outputs":[{"name":"","type":"address"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"becomeVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"},{"name":"_amount","type":"uint256"}],"name":"rewardExternal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_t","type":"address"}],"name":"setMasternodeContractForData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_t","type":"address"}],"name":"setMiningContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"swapClosed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"proposalID","type":"uint256"}],"name":"voteProposal","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_total","type":"uint256"}],"name":"setVotingMinority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"listAcceptedTokens","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getTokenDetails","outputs":[{"name":"ad","type":"address"},{"name":"required","type":"uint256"},{"name":"active","type":"bool"},{"name":"valid","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_contract","type":"address"}],"name":"pushProposal","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"miningContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"proposalID","type":"uint256"}],"name":"reachedMajorityForTeam","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"proposalID","type":"uint256"}],"name":"reachedMajority","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"votersCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pastProposalTimeRules","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"}],"name":"depositCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"proposalPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposalList","outputs":[{"name":"tokenContract","type":"address"},{"name":"totalVotes","type":"uint256"},{"name":"proposedOn","type":"uint256"},{"name":"acceptedOn","type":"uint256"},{"name":"proposalType","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LastProposalCanDiscard","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DataVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"votersCountTeam","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_previousContract","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"balance","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"user","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"balance","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ProposalID","type":"uint256"}],"name":"NewProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ProposalID","type":"uint256"}],"name":"ProposalAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]

603c600455600160058190556011805460ff191690911790556014805460a060020a61ffff021916905560c0604052600360808190527f434c4d000000000000000000000000000000000000000000000000000000000060a09081526200006a91601691906200013c565b5060408051808201909152600c8082527f4361656c756d20546f6b656e00000000000000000000000000000000000000006020909201918252620000b1916017916200013c565b506018805460ff19166008179055660775f05a074000601955601a8054600160a060020a0319169055348015620000e757600080fd5b50604051602080620029f983398101604052516002805433600160a060020a03199182161790915560148054909116600160a060020a039092169190911760a860020a60ff02191690556000601555620001e1565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200017f57805160ff1916838001178555620001af565b82800160010185558215620001af579182015b82811115620001af57825182559160200191906001019062000192565b50620001bd929150620001c1565b5090565b620001de91905b80821115620001bd5760008155600101620001c8565b90565b61280880620001f16000396000f3006080604052600436106102505763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663047e2b27811461025557806306fdde0314610278578063095ea7b3146103025780630ae580851461033a5780630c0512e9146103545780630f8143f61461037b57806318160ddd1461039057806323b872dd146103a55780632be65225146103cf578063313ce5671461041357806333bce8c31461043e578063350c35e9146104535780633d0b1e2c14610477578063415fe9c41461048c578063493953de146104c05780634d12e34e146104d5578063508493bc146104ed5780635632215d146105145780635a43fa901461052957806363d494ea146105715780636618846314610586578063680d5762146105aa5780636f1383a2146105ce578063702f5321146105ef57806370a0823114610610578063715018a6146106315780637d33bf5414610646578063807896d51461065b578063833016c0146106735780638843c1ba1461068b57806388aa8bee146106f05780638da5cb5b146107415780638e95597814610756578063915646971461077757806391fb45831461078c57806395d89b41146107a45780639601065d146107b957806398c07938146107d15780639b598caf146107e6578063a5d5db0c146107fb578063a9059cbb1461081f578063c5efa85f14610843578063c6311e3f14610858578063cf866d6f146108c2578063d53ff76f146108d7578063d73dd623146108ec578063dd62ed3e14610910578063f2f3eb8214610937578063f2fde38b1461094c575b600080fd5b34801561026157600080fd5b50610276600160a060020a036004351661096d565b005b34801561028457600080fd5b5061028d6109a6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102c75781810151838201526020016102af565b50505050905090810190601f1680156102f45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561030e57600080fd5b50610326600160a060020a0360043516602435610a34565b604080519115158252519081900360200190f35b34801561034657600080fd5b506102766004351515610a9a565b34801561036057600080fd5b50610369610b0c565b60408051918252519081900360200190f35b34801561038757600080fd5b50610326610b12565b34801561039c57600080fd5b50610369610b60565b3480156103b157600080fd5b50610326600160a060020a0360043581169060243516604435610b66565b3480156103db57600080fd5b506103f0600160a060020a0360043516610c76565b604080519215158352600160a060020a0390911660208301528051918290030190f35b34801561041f57600080fd5b50610428610c9b565b6040805160ff9092168252519081900360200190f35b34801561044a57600080fd5b50610369610ca4565b34801561045f57600080fd5b50610276600160a060020a0360043516602435610caa565b34801561048357600080fd5b50610276610ef6565b34801561049857600080fd5b506104a46004356111f7565b60408051600160a060020a039092168252519081900360200190f35b3480156104cc57600080fd5b50610326611212565b3480156104e157600080fd5b506104a460043561125f565b3480156104f957600080fd5b50610369600160a060020a0360043581169060243516611287565b34801561052057600080fd5b506104a46112a4565b34801561053557600080fd5b506105416004356112b3565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b34801561057d57600080fd5b5061027661136e565b34801561059257600080fd5b50610326600160a060020a03600435166024356115ca565b3480156105b657600080fd5b50610276600160a060020a03600435166024356116b9565b3480156105da57600080fd5b50610276600160a060020a036004351661173e565b3480156105fb57600080fd5b50610276600160a060020a0360043516611781565b34801561061c57600080fd5b50610369600160a060020a03600435166117f6565b34801561063d57600080fd5b50610276611815565b34801561065257600080fd5b50610326611876565b34801561066757600080fd5b50610326600435611898565b34801561067f57600080fd5b50610276600435611af9565b34801561069757600080fd5b506106a0611b23565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106dc5781810151838201526020016106c4565b505050509050019250505060405180910390f35b3480156106fc57600080fd5b50610711600160a060020a0360043516611b85565b60408051600160a060020a0390951685526020850193909352901515838301526060830152519081900360800190f35b34801561074d57600080fd5b506104a4611bbf565b34801561076257600080fd5b50610369600160a060020a0360043516611bce565b34801561078357600080fd5b506104a4611e97565b34801561079857600080fd5b50610326600435611ea6565b3480156107b057600080fd5b5061028d611ecf565b3480156107c557600080fd5b50610326600435611f2a565b3480156107dd57600080fd5b50610369611f44565b3480156107f257600080fd5b50610326611f4a565b34801561080757600080fd5b50610276600160a060020a0360043516602435611f78565b34801561082b57600080fd5b50610326600160a060020a0360043516602435612229565b34801561084f57600080fd5b506103266122dc565b34801561086457600080fd5b506108706004356122e5565b6040518086600160a060020a0316600160a060020a031681526020018581526020018481526020018381526020018260028111156108aa57fe5b60ff1681526020019550505050505060405180910390f35b3480156108ce57600080fd5b50610326612321565b3480156108e357600080fd5b506104a46123fa565b3480156108f857600080fd5b50610326600160a060020a0360043516602435612409565b34801561091c57600080fd5b50610369600160a060020a03600435811690602435166124a2565b34801561094357600080fd5b506103696124cd565b34801561095857600080fd5b50610276600160a060020a03600435166124d3565b600254600160a060020a0316331461098457600080fd5b600f8054600160a060020a031916600160a060020a0392909216919091179055565b6017805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b820191906000526020600020905b815481529060010190602001808311610a0f57829003601f168201915b505050505081565b336000818152600360209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b600254600160a060020a03163314610ab157600080fd5b60155460091015610ac157600080fd5b6014805491151575010000000000000000000000000000000000000000000275ff00000000000000000000000000000000000000000019909216919091179055601580546001019055565b600a5481565b600254600090600160a060020a03163314610b2c57600080fd5b60065460ff161515610b3d57600080fd5b610b45612321565b1515610b5057600080fd5b506006805460ff19169055600190565b60195481565b6000600160a060020a0383161515610b7d57600080fd5b600160a060020a038416600090815260208190526040902054610ba6908363ffffffff6124f316565b600160a060020a038086166000908152602081905260408082209390935590851681522054610bdb908363ffffffff61250a16565b600160a060020a03808516600090815260208181526040808320949094559187168152600382528281203382529091522054610c1d908363ffffffff6124f316565b600160a060020a03808616600081815260036020908152604080832033845282529182902094909455805186815290519287169391926000805160206127bd833981519152929181900390910190a35060019392505050565b60086020526000908152604090205460ff8116906101009004600160a060020a031682565b60185460ff1681565b60155481565b6000600160a060020a0383161515610cc157600080fd5b610cca83612523565b1515610d20576040805160e560020a62461bcd02815260206004820152601460248201527f4552433230206e6f7420617574686f7269736564000000000000000000000000604482015290519081900360640190fd5b610d2983612548565b8214610d3457600080fd5b600160a060020a0383166000908152601260209081526040808320338452909152902054821115610d6457600080fd5b50600160a060020a038281166000908152601260209081526040808320338085529252808320805490849055600f5482517fc56280b1000000000000000000000000000000000000000000000000000000008152600481019490945291519094919091169263c56280b1926024808201939182900301818387803b158015610deb57600080fd5b505af1158015610dff573d6000803e3d6000fd5b5050604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018590529051600160a060020a038716935063a9059cbb925060448083019260209291908290030181600087803b158015610e6b57600080fd5b505af1158015610e7f573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b50511515610ea257600080fd5b60408051600160a060020a03851681523360208201528082018390526060810183905290517ff341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb5679181900360800190a1505050565b6014546000907501000000000000000000000000000000000000000000900460ff1615610f2257600080fd5b601454604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b158015610f8857600080fd5b505af1158015610f9c573d6000803e3d6000fd5b505050506040513d6020811015610fb257600080fd5b5051601454604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051929350600160a060020a039091169163dd62ed3e916044808201926020929091908290030181600087803b15801561102357600080fd5b505af1158015611037573d6000803e3d6000fd5b505050506040513d602081101561104d57600080fd5b505181111561105b57600080fd5b601454604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018490529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b505050506040513d60208110156110f857600080fd5b505115611158573360009081526020819052604090205461111f908263ffffffff61250a16565b33600081815260208181526040918290209390935580518481529051919230926000805160206127bd8339815191529281900390910190a35b601454604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b1580156111be57600080fd5b505af11580156111d2573d6000803e3d6000fd5b505050506040513d60208110156111e857600080fd5b5051156111f457600080fd5b50565b600960205260009081526040902054600160a060020a031681565b600254600090600160a060020a0316331461122c57600080fd5b60115460ff16151561123d57600080fd5b61124f3064746a528800618e94612566565b506011805460ff19169055600190565b601080548290811061126d57fe5b600091825260209091200154600160a060020a0316905081565b601260209081526000928352604080842090915290825290205481565b600e54600160a060020a031681565b6000818152600760205260408082205481517f08a1b5740000000000000000000000000000000000000000000000000000000081529151839283928392600160a060020a03909116916308a1b57491600480830192608092919082900301818787803b15801561132257600080fd5b505af1158015611336573d6000803e3d6000fd5b505050506040513d608081101561134c57600080fd5b5080516020820151604083015160609093015191989097509195509350915050565b600e54604080517f9fc753540000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639fc75354916024808201926020929091908290030181600087803b1580156113d457600080fd5b505af11580156113e8573d6000803e3d6000fd5b505050506040513d60208110156113fe57600080fd5b50511515611456576040805160e560020a62461bcd02815260206004820152601760248201527f5573657220686173206e6f206d61737465726e6f646573000000000000000000604482015290519081900360640190fd5b3360009081526008602052604090205460ff16156114e3576040805160e560020a62461bcd028152602060048201526024808201527f5573657220416c726561647920766f74656420666f7220746869732070726f7060448201527f6f73616c00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3360008181526008602090815260408083208054600174ffffffffffffffffffffffffffffffffffffffff001990911661010087021760ff19168117909155600b80549091019055600e5481517fbbe9f99d00000000000000000000000000000000000000000000000000000000815260048101959095529051600160a060020a039091169363bbe9f99d9360248083019493928390030190829087803b15801561158d57600080fd5b505af11580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b5051156115c857600c805460010190555b565b336000908152600360209081526040808320600160a060020a038616845290915281205480831061161e57336000908152600360209081526040808320600160a060020a0388168452909152812055611653565b61162e818463ffffffff6124f316565b336000908152600360209081526040808320600160a060020a03891684529091529020555b336000818152600360209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b601a54600160a060020a031633146116d057600080fd5b600160a060020a0382166000908152602081905260409020546116f9908263ffffffff61250a16565b600160a060020a038316600081815260208181526040918290209390935580518481529051919230926000805160206127bd8339815191529281900390910190a35050565b600254600160a060020a0316331461175557600080fd5b600e8054600160a060020a03909216600160a060020a03199283168117909155600d8054909216179055565b600254600160a060020a0316331461179857600080fd5b60145460a060020a900460ff16156117af57600080fd5b601a8054600160a060020a03909216600160a060020a03199092169190911790556014805474ff0000000000000000000000000000000000000000191660a060020a179055565b600160a060020a0381166000908152602081905260409020545b919050565b600254600160a060020a0316331461182c57600080fd5b600254604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a260028054600160a060020a0319169055565b6014547501000000000000000000000000000000000000000000900460ff1681565b3360009081526008602052604081205460ff161515611901576040805160e560020a62461bcd02815260206004820152601a60248201527f53656e646572206e6f74206c697374656420617320766f746572000000000000604482015290519081900360640190fd5b600082101561195a576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f2070726f706f73616c207761732073656c65637465642e00000000000000604482015290519081900360640190fd5b600a548211156119b4576040805160e560020a62461bcd02815260206004820152601760248201527f50726f706f73616c206f7574206f66206c696d6974732e000000000000000000604482015290519081900360640190fd5b600082815260096020526040902054600160a060020a0316331415611a23576040805160e560020a62461bcd02815260206004820152600e60248201527f416c726561647920766f7465642e000000000000000000000000000000000000604482015290519081900360640190fd5b600554600b541015611aa5576040805160e560020a62461bcd02815260206004820152603160248201527f4e6f7420656e6f75676820766f7465727320696e206578697374656e6365207460448201527f6f207075736820612070726f706f73616c000000000000000000000000000000606482015290519081900360840190fd5b60008281526009602090815260408083208054600160a060020a0319163317905560079091529020600190810180549091019055611ae282611f2a565b1561181057611aef612608565b5060019050611810565b600254600160a060020a03163314611b1057600080fd5b6005548111611b1e57600080fd5b600555565b60606010805480602002602001604051908101604052809291908181526020018280548015611b7b57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611b5d575b5050505050905090565b600160a060020a0390811660009081526013602052604090208054600182015460029092015492811693919260a060020a90910460ff1691565b600254600160a060020a031681565b6002546000908190600160a060020a03163314611bea57600080fd5b600a5415611c7657611bfa611f4a565b1515611c76576040805160e560020a62461bcd02815260206004820152603a60248201527f596f75206e65656420746f20776169742039302064617973206265666f72652060448201527f7375626d697474696e672061206e65772070726f706f73616c2e000000000000606482015290519081900360840190fd5b60065460ff1615611cd1576040805160e560020a62461bcd02815260206004820152601c60248201527f416e6f746865722070726f706f73616c2069732070656e64696e672e00000000604482015290519081900360640190fd5b82600160a060020a031663c51a29e06040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611d2857600080fd5b505af1158015611d3c573d6000803e3d6000fd5b505050506040513d6020811015611d5257600080fd5b50516040805160a081018252600160a060020a03861681526000602082018190524292820192909252606081019190915290915060808101826002811115611d9657fe5b6002811115611da157fe5b81525060076000600a54815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff02191690836002811115611e2857fe5b021790555050600a5460408051918252517f9a863892f20a6b9c6cec64d611b5864be6373191ce2cacc3b05a299bce3bf80e92509081900360200190a1600a80546001908101918290556006805460ff191682179055611e8e919063ffffffff6124f316565b91505b50919050565b601a54600160a060020a031681565b600081815260076020526040812060010154611ec06126cc565b8110611e915760019150611e91565b6016805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b600081815260076020526040812060010154611ec06126e1565b600b5481565b600a54600019016000908152600760205260408120600201546276a70081014210611f7457600191505b5090565b611f8182612523565b1515611fd7576040805160e560020a62461bcd02815260206004820152601460248201527f4552433230206e6f7420617574686f7269736564000000000000000000000000604482015290519081900360640190fd5b611fe082612548565b8114611feb57600080fd5b611ff4826126f3565b1515611fff57600080fd5b600160a060020a0382166000908152601260209081526040808320338452909152902054612033908263ffffffff61250a16565b600160a060020a0383166000818152601260209081526040808320338085529083528184209590955580517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810195909552306024860152604485018690525192936323b872dd9360648083019491928390030190829087803b1580156120bd57600080fd5b505af11580156120d1573d6000803e3d6000fd5b505050506040513d60208110156120e757600080fd5b5051151561213f576040805160e560020a62461bcd02815260206004820152601060248201527f6572726f72207769746820746f6b656e00000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03821660008181526012602090815260408083203380855290835292819020548151948552918401929092528282018490526060830152517fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79181900360800190a1600f54604080517fd230df6a0000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a039092169163d230df6a9160248082019260009290919082900301818387803b15801561220d57600080fd5b505af1158015612221573d6000803e3d6000fd5b505050505050565b6000600160a060020a038316151561224057600080fd5b33600090815260208190526040902054612260908363ffffffff6124f316565b3360009081526020819052604080822092909255600160a060020a03851681522054612292908363ffffffff61250a16565b600160a060020a038416600081815260208181526040918290209390935580518581529051919233926000805160206127bd8339815191529281900390910190a350600192915050565b60065460ff1681565b60076020526000908152604090208054600182015460028301546003840154600490940154600160a060020a0390931693919290919060ff1685565b600a546000190160009081526007602090815260408083205481517ff61c266b0000000000000000000000000000000000000000000000000000000081529151849384938493600160a060020a03169263f61c266b9260048084019391929182900301818787803b15801561239557600080fd5b505af11580156123a9573d6000803e3d6000fd5b505050506040513d60208110156123bf57600080fd5b5051600a546000190160009081526007602052604090206002015490935091505062015180820281014281116123f457600193505b50505090565b600f54600160a060020a031681565b336000908152600360209081526040808320600160a060020a038616845290915281205461243d908363ffffffff61250a16565b336000818152600360209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b600c5481565b600254600160a060020a031633146124ea57600080fd5b6111f481612729565b6000808383111561250357600080fd5b5050900390565b60008282018381101561251c57600080fd5b9392505050565b600160a060020a031660009081526013602052604090205460a060020a900460ff1690565b600160a060020a031660009081526013602052604090206001015490565b600160a060020a0390921660008181526013602052604081208054600180830195909555426003830181905562015180909602909501600282015574ff000000000000000000000000000000000000000019600160a060020a031995861684171660a060020a17905560108054938401815590527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6729091018054909216179055565b6000806000806000806126276001600a546124f390919063ffffffff16565b6000818152600760205260409020426003909101556006805460ff191690559450612651856112b3565b9296509094509250905080151561266b5761266b8461279a565b600181141561267d5761267d846111f4565b600281141561268f5761268f846111f4565b6040805186815290517fd24c2047577899547bacebb29e319fc7d73f6712b5adb401d45556f34bb2aa3b9181900360200190a15092949350505050565b600454600c54600091026064815b0491505090565b600454600b54600091026064816126da565b600160a060020a038116600090815260136020526040812060020154428111156127205760019150611e91565b50600092915050565b600160a060020a038116151561273e57600080fd5b600254604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360028054600160a060020a031916600160a060020a0392909216919091179055565b601a8054600160a060020a031916600160a060020a03929092169190911790555600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820291711d9a848e18435dfd55244206d498f173b8e304bff9682aa5f9275a063bf00290000000000000000000000007600bf5112945f9f006c216d5d6db0df2806edc6

Deployed Bytecode

0x6080604052600436106102505763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663047e2b27811461025557806306fdde0314610278578063095ea7b3146103025780630ae580851461033a5780630c0512e9146103545780630f8143f61461037b57806318160ddd1461039057806323b872dd146103a55780632be65225146103cf578063313ce5671461041357806333bce8c31461043e578063350c35e9146104535780633d0b1e2c14610477578063415fe9c41461048c578063493953de146104c05780634d12e34e146104d5578063508493bc146104ed5780635632215d146105145780635a43fa901461052957806363d494ea146105715780636618846314610586578063680d5762146105aa5780636f1383a2146105ce578063702f5321146105ef57806370a0823114610610578063715018a6146106315780637d33bf5414610646578063807896d51461065b578063833016c0146106735780638843c1ba1461068b57806388aa8bee146106f05780638da5cb5b146107415780638e95597814610756578063915646971461077757806391fb45831461078c57806395d89b41146107a45780639601065d146107b957806398c07938146107d15780639b598caf146107e6578063a5d5db0c146107fb578063a9059cbb1461081f578063c5efa85f14610843578063c6311e3f14610858578063cf866d6f146108c2578063d53ff76f146108d7578063d73dd623146108ec578063dd62ed3e14610910578063f2f3eb8214610937578063f2fde38b1461094c575b600080fd5b34801561026157600080fd5b50610276600160a060020a036004351661096d565b005b34801561028457600080fd5b5061028d6109a6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102c75781810151838201526020016102af565b50505050905090810190601f1680156102f45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561030e57600080fd5b50610326600160a060020a0360043516602435610a34565b604080519115158252519081900360200190f35b34801561034657600080fd5b506102766004351515610a9a565b34801561036057600080fd5b50610369610b0c565b60408051918252519081900360200190f35b34801561038757600080fd5b50610326610b12565b34801561039c57600080fd5b50610369610b60565b3480156103b157600080fd5b50610326600160a060020a0360043581169060243516604435610b66565b3480156103db57600080fd5b506103f0600160a060020a0360043516610c76565b604080519215158352600160a060020a0390911660208301528051918290030190f35b34801561041f57600080fd5b50610428610c9b565b6040805160ff9092168252519081900360200190f35b34801561044a57600080fd5b50610369610ca4565b34801561045f57600080fd5b50610276600160a060020a0360043516602435610caa565b34801561048357600080fd5b50610276610ef6565b34801561049857600080fd5b506104a46004356111f7565b60408051600160a060020a039092168252519081900360200190f35b3480156104cc57600080fd5b50610326611212565b3480156104e157600080fd5b506104a460043561125f565b3480156104f957600080fd5b50610369600160a060020a0360043581169060243516611287565b34801561052057600080fd5b506104a46112a4565b34801561053557600080fd5b506105416004356112b3565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b34801561057d57600080fd5b5061027661136e565b34801561059257600080fd5b50610326600160a060020a03600435166024356115ca565b3480156105b657600080fd5b50610276600160a060020a03600435166024356116b9565b3480156105da57600080fd5b50610276600160a060020a036004351661173e565b3480156105fb57600080fd5b50610276600160a060020a0360043516611781565b34801561061c57600080fd5b50610369600160a060020a03600435166117f6565b34801561063d57600080fd5b50610276611815565b34801561065257600080fd5b50610326611876565b34801561066757600080fd5b50610326600435611898565b34801561067f57600080fd5b50610276600435611af9565b34801561069757600080fd5b506106a0611b23565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106dc5781810151838201526020016106c4565b505050509050019250505060405180910390f35b3480156106fc57600080fd5b50610711600160a060020a0360043516611b85565b60408051600160a060020a0390951685526020850193909352901515838301526060830152519081900360800190f35b34801561074d57600080fd5b506104a4611bbf565b34801561076257600080fd5b50610369600160a060020a0360043516611bce565b34801561078357600080fd5b506104a4611e97565b34801561079857600080fd5b50610326600435611ea6565b3480156107b057600080fd5b5061028d611ecf565b3480156107c557600080fd5b50610326600435611f2a565b3480156107dd57600080fd5b50610369611f44565b3480156107f257600080fd5b50610326611f4a565b34801561080757600080fd5b50610276600160a060020a0360043516602435611f78565b34801561082b57600080fd5b50610326600160a060020a0360043516602435612229565b34801561084f57600080fd5b506103266122dc565b34801561086457600080fd5b506108706004356122e5565b6040518086600160a060020a0316600160a060020a031681526020018581526020018481526020018381526020018260028111156108aa57fe5b60ff1681526020019550505050505060405180910390f35b3480156108ce57600080fd5b50610326612321565b3480156108e357600080fd5b506104a46123fa565b3480156108f857600080fd5b50610326600160a060020a0360043516602435612409565b34801561091c57600080fd5b50610369600160a060020a03600435811690602435166124a2565b34801561094357600080fd5b506103696124cd565b34801561095857600080fd5b50610276600160a060020a03600435166124d3565b600254600160a060020a0316331461098457600080fd5b600f8054600160a060020a031916600160a060020a0392909216919091179055565b6017805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b820191906000526020600020905b815481529060010190602001808311610a0f57829003601f168201915b505050505081565b336000818152600360209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b600254600160a060020a03163314610ab157600080fd5b60155460091015610ac157600080fd5b6014805491151575010000000000000000000000000000000000000000000275ff00000000000000000000000000000000000000000019909216919091179055601580546001019055565b600a5481565b600254600090600160a060020a03163314610b2c57600080fd5b60065460ff161515610b3d57600080fd5b610b45612321565b1515610b5057600080fd5b506006805460ff19169055600190565b60195481565b6000600160a060020a0383161515610b7d57600080fd5b600160a060020a038416600090815260208190526040902054610ba6908363ffffffff6124f316565b600160a060020a038086166000908152602081905260408082209390935590851681522054610bdb908363ffffffff61250a16565b600160a060020a03808516600090815260208181526040808320949094559187168152600382528281203382529091522054610c1d908363ffffffff6124f316565b600160a060020a03808616600081815260036020908152604080832033845282529182902094909455805186815290519287169391926000805160206127bd833981519152929181900390910190a35060019392505050565b60086020526000908152604090205460ff8116906101009004600160a060020a031682565b60185460ff1681565b60155481565b6000600160a060020a0383161515610cc157600080fd5b610cca83612523565b1515610d20576040805160e560020a62461bcd02815260206004820152601460248201527f4552433230206e6f7420617574686f7269736564000000000000000000000000604482015290519081900360640190fd5b610d2983612548565b8214610d3457600080fd5b600160a060020a0383166000908152601260209081526040808320338452909152902054821115610d6457600080fd5b50600160a060020a038281166000908152601260209081526040808320338085529252808320805490849055600f5482517fc56280b1000000000000000000000000000000000000000000000000000000008152600481019490945291519094919091169263c56280b1926024808201939182900301818387803b158015610deb57600080fd5b505af1158015610dff573d6000803e3d6000fd5b5050604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018590529051600160a060020a038716935063a9059cbb925060448083019260209291908290030181600087803b158015610e6b57600080fd5b505af1158015610e7f573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b50511515610ea257600080fd5b60408051600160a060020a03851681523360208201528082018390526060810183905290517ff341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb5679181900360800190a1505050565b6014546000907501000000000000000000000000000000000000000000900460ff1615610f2257600080fd5b601454604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b158015610f8857600080fd5b505af1158015610f9c573d6000803e3d6000fd5b505050506040513d6020811015610fb257600080fd5b5051601454604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051929350600160a060020a039091169163dd62ed3e916044808201926020929091908290030181600087803b15801561102357600080fd5b505af1158015611037573d6000803e3d6000fd5b505050506040513d602081101561104d57600080fd5b505181111561105b57600080fd5b601454604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018490529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b505050506040513d60208110156110f857600080fd5b505115611158573360009081526020819052604090205461111f908263ffffffff61250a16565b33600081815260208181526040918290209390935580518481529051919230926000805160206127bd8339815191529281900390910190a35b601454604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b1580156111be57600080fd5b505af11580156111d2573d6000803e3d6000fd5b505050506040513d60208110156111e857600080fd5b5051156111f457600080fd5b50565b600960205260009081526040902054600160a060020a031681565b600254600090600160a060020a0316331461122c57600080fd5b60115460ff16151561123d57600080fd5b61124f3064746a528800618e94612566565b506011805460ff19169055600190565b601080548290811061126d57fe5b600091825260209091200154600160a060020a0316905081565b601260209081526000928352604080842090915290825290205481565b600e54600160a060020a031681565b6000818152600760205260408082205481517f08a1b5740000000000000000000000000000000000000000000000000000000081529151839283928392600160a060020a03909116916308a1b57491600480830192608092919082900301818787803b15801561132257600080fd5b505af1158015611336573d6000803e3d6000fd5b505050506040513d608081101561134c57600080fd5b5080516020820151604083015160609093015191989097509195509350915050565b600e54604080517f9fc753540000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a0390921691639fc75354916024808201926020929091908290030181600087803b1580156113d457600080fd5b505af11580156113e8573d6000803e3d6000fd5b505050506040513d60208110156113fe57600080fd5b50511515611456576040805160e560020a62461bcd02815260206004820152601760248201527f5573657220686173206e6f206d61737465726e6f646573000000000000000000604482015290519081900360640190fd5b3360009081526008602052604090205460ff16156114e3576040805160e560020a62461bcd028152602060048201526024808201527f5573657220416c726561647920766f74656420666f7220746869732070726f7060448201527f6f73616c00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3360008181526008602090815260408083208054600174ffffffffffffffffffffffffffffffffffffffff001990911661010087021760ff19168117909155600b80549091019055600e5481517fbbe9f99d00000000000000000000000000000000000000000000000000000000815260048101959095529051600160a060020a039091169363bbe9f99d9360248083019493928390030190829087803b15801561158d57600080fd5b505af11580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b5051156115c857600c805460010190555b565b336000908152600360209081526040808320600160a060020a038616845290915281205480831061161e57336000908152600360209081526040808320600160a060020a0388168452909152812055611653565b61162e818463ffffffff6124f316565b336000908152600360209081526040808320600160a060020a03891684529091529020555b336000818152600360209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b601a54600160a060020a031633146116d057600080fd5b600160a060020a0382166000908152602081905260409020546116f9908263ffffffff61250a16565b600160a060020a038316600081815260208181526040918290209390935580518481529051919230926000805160206127bd8339815191529281900390910190a35050565b600254600160a060020a0316331461175557600080fd5b600e8054600160a060020a03909216600160a060020a03199283168117909155600d8054909216179055565b600254600160a060020a0316331461179857600080fd5b60145460a060020a900460ff16156117af57600080fd5b601a8054600160a060020a03909216600160a060020a03199092169190911790556014805474ff0000000000000000000000000000000000000000191660a060020a179055565b600160a060020a0381166000908152602081905260409020545b919050565b600254600160a060020a0316331461182c57600080fd5b600254604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a260028054600160a060020a0319169055565b6014547501000000000000000000000000000000000000000000900460ff1681565b3360009081526008602052604081205460ff161515611901576040805160e560020a62461bcd02815260206004820152601a60248201527f53656e646572206e6f74206c697374656420617320766f746572000000000000604482015290519081900360640190fd5b600082101561195a576040805160e560020a62461bcd02815260206004820152601960248201527f4e6f2070726f706f73616c207761732073656c65637465642e00000000000000604482015290519081900360640190fd5b600a548211156119b4576040805160e560020a62461bcd02815260206004820152601760248201527f50726f706f73616c206f7574206f66206c696d6974732e000000000000000000604482015290519081900360640190fd5b600082815260096020526040902054600160a060020a0316331415611a23576040805160e560020a62461bcd02815260206004820152600e60248201527f416c726561647920766f7465642e000000000000000000000000000000000000604482015290519081900360640190fd5b600554600b541015611aa5576040805160e560020a62461bcd02815260206004820152603160248201527f4e6f7420656e6f75676820766f7465727320696e206578697374656e6365207460448201527f6f207075736820612070726f706f73616c000000000000000000000000000000606482015290519081900360840190fd5b60008281526009602090815260408083208054600160a060020a0319163317905560079091529020600190810180549091019055611ae282611f2a565b1561181057611aef612608565b5060019050611810565b600254600160a060020a03163314611b1057600080fd5b6005548111611b1e57600080fd5b600555565b60606010805480602002602001604051908101604052809291908181526020018280548015611b7b57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611b5d575b5050505050905090565b600160a060020a0390811660009081526013602052604090208054600182015460029092015492811693919260a060020a90910460ff1691565b600254600160a060020a031681565b6002546000908190600160a060020a03163314611bea57600080fd5b600a5415611c7657611bfa611f4a565b1515611c76576040805160e560020a62461bcd02815260206004820152603a60248201527f596f75206e65656420746f20776169742039302064617973206265666f72652060448201527f7375626d697474696e672061206e65772070726f706f73616c2e000000000000606482015290519081900360840190fd5b60065460ff1615611cd1576040805160e560020a62461bcd02815260206004820152601c60248201527f416e6f746865722070726f706f73616c2069732070656e64696e672e00000000604482015290519081900360640190fd5b82600160a060020a031663c51a29e06040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611d2857600080fd5b505af1158015611d3c573d6000803e3d6000fd5b505050506040513d6020811015611d5257600080fd5b50516040805160a081018252600160a060020a03861681526000602082018190524292820192909252606081019190915290915060808101826002811115611d9657fe5b6002811115611da157fe5b81525060076000600a54815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff02191690836002811115611e2857fe5b021790555050600a5460408051918252517f9a863892f20a6b9c6cec64d611b5864be6373191ce2cacc3b05a299bce3bf80e92509081900360200190a1600a80546001908101918290556006805460ff191682179055611e8e919063ffffffff6124f316565b91505b50919050565b601a54600160a060020a031681565b600081815260076020526040812060010154611ec06126cc565b8110611e915760019150611e91565b6016805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610a2c5780601f10610a0157610100808354040283529160200191610a2c565b600081815260076020526040812060010154611ec06126e1565b600b5481565b600a54600019016000908152600760205260408120600201546276a70081014210611f7457600191505b5090565b611f8182612523565b1515611fd7576040805160e560020a62461bcd02815260206004820152601460248201527f4552433230206e6f7420617574686f7269736564000000000000000000000000604482015290519081900360640190fd5b611fe082612548565b8114611feb57600080fd5b611ff4826126f3565b1515611fff57600080fd5b600160a060020a0382166000908152601260209081526040808320338452909152902054612033908263ffffffff61250a16565b600160a060020a0383166000818152601260209081526040808320338085529083528184209590955580517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810195909552306024860152604485018690525192936323b872dd9360648083019491928390030190829087803b1580156120bd57600080fd5b505af11580156120d1573d6000803e3d6000fd5b505050506040513d60208110156120e757600080fd5b5051151561213f576040805160e560020a62461bcd02815260206004820152601060248201527f6572726f72207769746820746f6b656e00000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03821660008181526012602090815260408083203380855290835292819020548151948552918401929092528282018490526060830152517fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79181900360800190a1600f54604080517fd230df6a0000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a039092169163d230df6a9160248082019260009290919082900301818387803b15801561220d57600080fd5b505af1158015612221573d6000803e3d6000fd5b505050505050565b6000600160a060020a038316151561224057600080fd5b33600090815260208190526040902054612260908363ffffffff6124f316565b3360009081526020819052604080822092909255600160a060020a03851681522054612292908363ffffffff61250a16565b600160a060020a038416600081815260208181526040918290209390935580518581529051919233926000805160206127bd8339815191529281900390910190a350600192915050565b60065460ff1681565b60076020526000908152604090208054600182015460028301546003840154600490940154600160a060020a0390931693919290919060ff1685565b600a546000190160009081526007602090815260408083205481517ff61c266b0000000000000000000000000000000000000000000000000000000081529151849384938493600160a060020a03169263f61c266b9260048084019391929182900301818787803b15801561239557600080fd5b505af11580156123a9573d6000803e3d6000fd5b505050506040513d60208110156123bf57600080fd5b5051600a546000190160009081526007602052604090206002015490935091505062015180820281014281116123f457600193505b50505090565b600f54600160a060020a031681565b336000908152600360209081526040808320600160a060020a038616845290915281205461243d908363ffffffff61250a16565b336000818152600360209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b600c5481565b600254600160a060020a031633146124ea57600080fd5b6111f481612729565b6000808383111561250357600080fd5b5050900390565b60008282018381101561251c57600080fd5b9392505050565b600160a060020a031660009081526013602052604090205460a060020a900460ff1690565b600160a060020a031660009081526013602052604090206001015490565b600160a060020a0390921660008181526013602052604081208054600180830195909555426003830181905562015180909602909501600282015574ff000000000000000000000000000000000000000019600160a060020a031995861684171660a060020a17905560108054938401815590527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6729091018054909216179055565b6000806000806000806126276001600a546124f390919063ffffffff16565b6000818152600760205260409020426003909101556006805460ff191690559450612651856112b3565b9296509094509250905080151561266b5761266b8461279a565b600181141561267d5761267d846111f4565b600281141561268f5761268f846111f4565b6040805186815290517fd24c2047577899547bacebb29e319fc7d73f6712b5adb401d45556f34bb2aa3b9181900360200190a15092949350505050565b600454600c54600091026064815b0491505090565b600454600b54600091026064816126da565b600160a060020a038116600090815260136020526040812060020154428111156127205760019150611e91565b50600092915050565b600160a060020a038116151561273e57600080fd5b600254604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360028054600160a060020a031916600160a060020a0392909216919091179055565b601a8054600160a060020a031916600160a060020a03929092169190911790555600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820291711d9a848e18435dfd55244206d498f173b8e304bff9682aa5f9275a063bf0029

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000007600bf5112945f9f006c216d5d6db0df2806edc6

-----Decoded View---------------
Arg [0] : _previousContract (address): 0x7600bF5112945F9F006c216d5d6db0df2806eDc6

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007600bf5112945f9f006c216d5d6db0df2806edc6


Swarm Source

bzzr://291711d9a848e18435dfd55244206d498f173b8e304bff9682aa5f9275a063bf

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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