ETH Price: $3,397.87 (-1.46%)
Gas: 1 Gwei

Contract

0x5EeAA2DCb23056F4E8654a349E57eBE5e76b5e6e
 

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Value
Transfer201960632024-06-29 8:10:473 hrs ago1719648647IN
Virtue Poker: VPP Token
0 ETH0.000361889
Approve201960422024-06-29 8:06:353 hrs ago1719648395IN
Virtue Poker: VPP Token
0 ETH0.000137892.96787489
Approve201953262024-06-29 5:42:236 hrs ago1719639743IN
Virtue Poker: VPP Token
0 ETH0.000137552.96060992
Transfer201916012024-06-28 17:13:1118 hrs ago1719594791IN
Virtue Poker: VPP Token
0 ETH0.00026586.61048622
Transfer201913092024-06-28 16:14:1119 hrs ago1719591251IN
Virtue Poker: VPP Token
0 ETH0.0006747715
Transfer201855912024-06-27 21:04:1138 hrs ago1719522251IN
Virtue Poker: VPP Token
0 ETH0.0006299514
Approve201853982024-06-27 20:25:2339 hrs ago1719519923IN
Virtue Poker: VPP Token
0 ETH0.000276935.9681701
Transfer201845062024-06-27 17:26:1142 hrs ago1719509171IN
Virtue Poker: VPP Token
0 ETH0.0025449941
Approve201839792024-06-27 15:40:1144 hrs ago1719502811IN
Virtue Poker: VPP Token
0 ETH0.0006772814.59596706
Approve201838702024-06-27 15:17:5944 hrs ago1719501479IN
Virtue Poker: VPP Token
0 ETH0.0007060715.1967758
Transfer201838212024-06-27 15:08:1144 hrs ago1719500891IN
Virtue Poker: VPP Token
0 ETH0.0014900424
Transfer201830292024-06-27 12:29:1147 hrs ago1719491351IN
Virtue Poker: VPP Token
0 ETH0.000807113
Transfer201793802024-06-27 0:16:112 days ago1719447371IN
Virtue Poker: VPP Token
0 ETH0.000682811
Transfer201790492024-06-26 23:09:472 days ago1719443387IN
Virtue Poker: VPP Token
0 ETH0.000233114.0677008
Transfer201782742024-06-26 20:34:112 days ago1719434051IN
Virtue Poker: VPP Token
0 ETH0.0009310915
Approve201772642024-06-26 17:10:112 days ago1719421811IN
Virtue Poker: VPP Token
0 ETH0.000571219.65454215
Approve201771182024-06-26 16:40:472 days ago1719420047IN
Virtue Poker: VPP Token
0 ETH0.0005497211.83181665
Transfer201769482024-06-26 16:06:112 days ago1719417971IN
Virtue Poker: VPP Token
0 ETH0.0011173118
Approve201769172024-06-26 15:59:592 days ago1719417599IN
Virtue Poker: VPP Token
0 ETH0.000456369.87846664
Transfer201765562024-06-26 14:47:112 days ago1719413231IN
Virtue Poker: VPP Token
0 ETH0.0014897524
Approve201749572024-06-26 9:26:353 days ago1719393995IN
Virtue Poker: VPP Token
0 ETH0.000185844
Approve201747462024-06-26 8:44:113 days ago1719391451IN
Virtue Poker: VPP Token
0 ETH0.00022664.87721553
Approve201739792024-06-26 6:09:353 days ago1719382175IN
Virtue Poker: VPP Token
0 ETH0.000102782.21509934
Transfer201691232024-06-25 13:54:113 days ago1719323651IN
Virtue Poker: VPP Token
0 ETH0.0010554417
Approve201685122024-06-25 11:51:113 days ago1719316271IN
Virtue Poker: VPP Token
0 ETH0.000156043.37777732
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To Value
54725542018-04-20 5:43:112262 days ago1524202991  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Token

Compiler Version
v0.4.19+commit.c4cbbb05

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-05-24
*/

/**
 *Submitted for verification at Etherscan.io on 2018-04-20
*/

pragma solidity 0.4.19;

// File: zeppelin-solidity/contracts/math/SafeMath.sol

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws 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 Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

// File: zeppelin-solidity/contracts/ownership/Ownable.sol

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


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


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() 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 transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}

// File: zeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
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);
}

// File: zeppelin-solidity/contracts/token/ERC20/ERC20.sol

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
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);
}

// File: @tokenfoundry/sale-contracts/contracts/DisbursementHandler.sol

/// @title Disbursement handler - Manages time locked disbursements of ERC20 tokens
contract DisbursementHandler is Ownable {
    using SafeMath for uint256;

    struct Disbursement {
        // Tokens cannot be withdrawn before this timestamp
        uint256 timestamp;

        // Amount of tokens to be disbursed
        uint256 tokens;
    }

    event LogSetup(address indexed vestor, uint256 timestamp, uint256 tokens);
    event LogWithdraw(address indexed to, uint256 value);

    ERC20 public token;
    uint256 public totalAmount;
    mapping(address => Disbursement[]) public disbursements;
    mapping(address => uint256) public withdrawnTokens;

    function DisbursementHandler(address _token) public {
        token = ERC20(_token);
    }

    /// @dev Called by the sale contract to create a disbursement.
    /// @param vestor The address of the beneficiary.
    /// @param tokens Amount of tokens to be locked.
    /// @param timestamp Funds will be locked until this timestamp.
    function setupDisbursement(
        address vestor,
        uint256 tokens,
        uint256 timestamp
    )
        external
        onlyOwner
    {
        require(block.timestamp < timestamp);
        disbursements[vestor].push(Disbursement(timestamp, tokens));
        totalAmount = totalAmount.add(tokens);
        LogSetup(vestor, timestamp, tokens);
    }

    /// @dev Transfers tokens to the withdrawer
    function withdraw()
        external
    {
        uint256 withdrawAmount = calcMaxWithdraw(msg.sender);
        require(withdrawAmount != 0);
        withdrawnTokens[msg.sender] = withdrawnTokens[msg.sender].add(withdrawAmount);
        require(token.transfer(msg.sender, withdrawAmount));
        LogWithdraw(msg.sender, withdrawAmount);
    }

    /// @dev Calculates the maximum amount of vested tokens
    /// @return Number of vested tokens that can be withdrawn
    function calcMaxWithdraw(address beneficiary)
        public
        view
        returns (uint256)
    {
        uint256 maxTokens = 0;

        // Go over all the disbursements and calculate how many tokens can be withdrawn
        Disbursement[] storage temp = disbursements[beneficiary];
        uint256 tempLength = temp.length;
        for (uint256 i = 0; i < tempLength; i++) {
            if (block.timestamp > temp[i].timestamp) {
                maxTokens = maxTokens.add(temp[i].tokens);
            }
        }

        // Return the computed amount minus the tokens already withdrawn
        return maxTokens.sub(withdrawnTokens[beneficiary]);
    }
}

// File: zeppelin-solidity/contracts/math/Math.sol

/**
 * @title Math
 * @dev Assorted math operations
 */
library Math {
  function max64(uint64 a, uint64 b) internal pure returns (uint64) {
    return a >= b ? a : b;
  }

  function min64(uint64 a, uint64 b) internal pure returns (uint64) {
    return a < b ? a : b;
  }

  function max256(uint256 a, uint256 b) internal pure returns (uint256) {
    return a >= b ? a : b;
  }

  function min256(uint256 a, uint256 b) internal pure returns (uint256) {
    return a < b ? a : b;
  }
}

// File: @tokenfoundry/sale-contracts/contracts/Vault.sol

// Adapted from Open Zeppelin's RefundVault

/**
 * @title Vault
 * @dev This contract is used for storing funds while a crowdsale
 * is in progress. Supports refunding the money if crowdsale fails,
 * and forwarding it if crowdsale is successful.
 */
contract Vault is Ownable {
    using SafeMath for uint256;

    enum State { Active, Success, Refunding, Closed }

    uint256 public constant DISBURSEMENT_DURATION = 4 weeks;

    mapping (address => uint256) public deposited;
    uint256 public disbursementAmount; // The amount to be disbursed to the wallet every month
    address public trustedWallet; // Wallet from the project team

    uint256 public initialAmount; // The eth amount the team will get initially if the sale is successful

    uint256 public lastDisbursement; // Timestamp of the last disbursement made

    uint256 public totalDeposited; // Total amount that was deposited
    uint256 public refundable; // Amount that can be refunded

    uint256 public closingDuration;
    uint256 public closingDeadline; // Vault can't be closed before this deadline

    State public state;

    event LogClosed();
    event LogRefundsEnabled();
    event LogRefunded(address indexed contributor, uint256 amount);

    modifier atState(State _state) {
        require(state == _state);
        _;
    }

    function Vault(
        address wallet,
        uint256 _initialAmount,
        uint256 _disbursementAmount,
        uint256 _closingDuration
    ) 
        public 
    {
        require(wallet != address(0));
        require(_disbursementAmount != 0);
        require(_closingDuration != 0);
        trustedWallet = wallet;
        initialAmount = _initialAmount;
        disbursementAmount = _disbursementAmount;
        closingDuration = _closingDuration;
        state = State.Active;
    }

    /// @dev Called by the sale contract to deposit ether for a contributor.
    function deposit(address contributor) onlyOwner external payable {
        require(state == State.Active || state == State.Success);
        totalDeposited = totalDeposited.add(msg.value);
        refundable = refundable.add(msg.value);
        deposited[contributor] = deposited[contributor].add(msg.value);
    }

    /// @dev Sends initial funds to the wallet.
    function saleSuccessful() onlyOwner external atState(State.Active){
        state = State.Success;
        refundable = refundable.sub(initialAmount);
        if (initialAmount != 0) {
          trustedWallet.transfer(initialAmount);
        }
    }

    /// @dev Called by the owner if the project didn't deliver the testnet contracts or if we need to stop disbursements for any reasone.
    function enableRefunds() onlyOwner external {
        state = State.Refunding;
        LogRefundsEnabled();
    }

    /// @dev Refunds ether to the contributors if in the Refunding state.
    function refund(address contributor) external atState(State.Refunding) {
        uint256 refundAmount = deposited[contributor].mul(refundable).div(totalDeposited);
        deposited[contributor] = 0;
        contributor.transfer(refundAmount);
        LogRefunded(contributor, refundAmount);
    }

    /// @dev Sets the closingDeadline variable
    function beginClosingPeriod() external onlyOwner atState(State.Success) {
        require(closingDeadline == 0);
        closingDeadline = now.add(closingDuration);
    }

    /// @dev Called by anyone if the sale was successful and the project delivered.
    function close() external atState(State.Success) {
        require(closingDeadline != 0 && closingDeadline <= now);
        state = State.Closed;
        LogClosed();
    }

    /// @dev Sends the disbursement amount to the wallet after the disbursement period has passed. Can be called by anyone.
    function sendFundsToWallet() external atState(State.Closed) {
        require(lastDisbursement.add(DISBURSEMENT_DURATION) <= now);

        lastDisbursement = now;
        uint256 amountToSend = Math.min256(address(this).balance, disbursementAmount);
        refundable = amountToSend > refundable ? 0 : refundable.sub(amountToSend);
        trustedWallet.transfer(amountToSend);
    }
}

// File: @tokenfoundry/sale-contracts/contracts/Whitelistable.sol

/**
 * @title Whitelistable
 * @dev This contract is used to implement a signature based whitelisting mechanism
 */
contract Whitelistable is Ownable {
    bytes constant PREFIX = "\x19Ethereum Signed Message:\n32";

    address public whitelistAdmin;

    // addresses map to false by default
    mapping(address => bool) public blacklist;

    event LogAdminUpdated(address indexed newAdmin);

    modifier validAdmin(address _admin) {
        require(_admin != 0);
        _;
    }

    modifier onlyAdmin {
        require(msg.sender == whitelistAdmin);
        _;
    }

    /// @dev Constructor for Whitelistable contract
    /// @param _admin the address of the admin that will generate the signatures
    function Whitelistable(address _admin) public validAdmin(_admin) {
        whitelistAdmin = _admin;        
    }

    /// @dev Updates whitelistAdmin address 
    /// @dev Can only be called by the current owner
    /// @param _admin the new admin address
    function changeAdmin(address _admin)
        external
        onlyOwner
        validAdmin(_admin)
    {
        LogAdminUpdated(_admin);
        whitelistAdmin = _admin;
    }

    // @dev blacklists the given address to ban them from contributing
    // @param _contributor Address of the contributor to blacklist 
    function addToBlacklist(address _contributor)
        external
        onlyAdmin
    {
        blacklist[_contributor] = true;
    }

    // @dev removes a previously blacklisted contributor from the blacklist
    // @param _contributor Address of the contributor remove 
    function removeFromBlacklist(address _contributor)
        external
        onlyAdmin
    {
        blacklist[_contributor] = false;
    }

    /// @dev Checks if contributor is whitelisted (main Whitelistable function)
    /// @param contributor Address of who was whitelisted
    /// @param contributionLimit Limit for the user contribution
    /// @param currentSaleCap Cap of contributions to the sale at the current point in time
    /// @param v Recovery id
    /// @param r Component of the ECDSA signature
    /// @param s Component of the ECDSA signature
    /// @return Is the signature correct?
    function checkWhitelisted(
        address contributor,
        uint256 contributionLimit,
        uint256 currentSaleCap,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public view returns(bool) {
        bytes32 prefixed = keccak256(PREFIX, keccak256(contributor, contributionLimit, currentSaleCap));
        return !(blacklist[contributor]) && (whitelistAdmin == ecrecover(prefixed, v, r, s));
    }
}

// File: @tokenfoundry/state-machine/contracts/StateMachine.sol

contract StateMachine {

    struct State { 
        bytes32 nextStateId;
        mapping(bytes4 => bool) allowedFunctions;
        function() internal[] transitionCallbacks;
        function(bytes32) internal returns(bool)[] startConditions;
    }

    mapping(bytes32 => State) states;

    // The current state id
    bytes32 private currentStateId;

    event LogTransition(bytes32 stateId, uint256 blockNumber);

    /* This modifier performs the conditional transitions and checks that the function 
     * to be executed is allowed in the current State
     */
    modifier checkAllowed {
        conditionalTransitions();
        require(states[currentStateId].allowedFunctions[msg.sig]);
        _;
    }

    ///@dev transitions the state machine into the state it should currently be in
    ///@dev by taking into account the current conditions and how many further transitions can occur 
    function conditionalTransitions() public {

        bytes32 next = states[currentStateId].nextStateId;
        bool stateChanged;

        while (next != 0) {
            // If one of the next state's conditions is met, go to this state and continue
            stateChanged = false;
            for (uint256 i = 0; i < states[next].startConditions.length; i++) {
                if (states[next].startConditions[i](next)) {
                    goToNextState();
                    next = states[next].nextStateId;
                    stateChanged = true;
                    break;
                }
            }
            // If none of the next state's conditions are met, then we are in the right current state
            if (!stateChanged) break;
        }
    }

    function getCurrentStateId() view public returns(bytes32) {
        return currentStateId;
    }


    /// @dev Setup the state machine with the given states.
    /// @param _stateIds Array of state ids.
    function setStates(bytes32[] _stateIds) internal {
        require(_stateIds.length > 0);
        require(currentStateId == 0);

        require(_stateIds[0] != 0);

        currentStateId = _stateIds[0];

        for (uint256 i = 1; i < _stateIds.length; i++) {
            require(_stateIds[i] != 0);

            states[_stateIds[i - 1]].nextStateId = _stateIds[i];

            // Check that the state appears only once in the array
            require(states[_stateIds[i]].nextStateId == 0);
        }
    }

    /// @dev Allow a function in the given state.
    /// @param _stateId The id of the state
    /// @param _functionSelector A function selector (bytes4[keccak256(functionSignature)])
    function allowFunction(bytes32 _stateId, bytes4 _functionSelector) internal {
        states[_stateId].allowedFunctions[_functionSelector] = true;
    }

    /// @dev Goes to the next state if possible (if the next state is valid)
    function goToNextState() internal {
        bytes32 next = states[currentStateId].nextStateId;
        require(next != 0);

        currentStateId = next;
        for (uint256 i = 0; i < states[next].transitionCallbacks.length; i++) {
            states[next].transitionCallbacks[i]();
        }

        LogTransition(next, block.number);
    }

    ///@dev add a function returning a boolean as a start condition for a state
    ///@param _stateId The ID of the state to add the condition for
    ///@param _condition Start condition function - returns true if a start condition (for a given state ID) is met
    function addStartCondition(bytes32 _stateId, function(bytes32) internal returns(bool) _condition) internal {
        states[_stateId].startConditions.push(_condition);
    }

    ///@dev add a callback function for a state
    ///@param _stateId The ID of the state to add a callback function for
    ///@param _callback The callback function to add
    function addCallback(bytes32 _stateId, function() internal _callback) internal {
        states[_stateId].transitionCallbacks.push(_callback);
    }

}

// File: @tokenfoundry/state-machine/contracts/TimedStateMachine.sol

/// @title A contract that implements the state machine pattern and adds time dependant transitions.
contract TimedStateMachine is StateMachine {

    event LogSetStateStartTime(bytes32 indexed _stateId, uint256 _startTime);

    // Stores the start timestamp for each state (the value is 0 if the state doesn't have a start timestamp).
    mapping(bytes32 => uint256) private startTime;

    /// @dev Returns the timestamp for the given state id.
    /// @param _stateId The id of the state for which we want to set the start timestamp.
    function getStateStartTime(bytes32 _stateId) public view returns(uint256) {
        return startTime[_stateId];
    }

    /// @dev Sets the starting timestamp for a state.
    /// @param _stateId The id of the state for which we want to set the start timestamp.
    /// @param _timestamp The start timestamp for the given state. It should be bigger than the current one.
    function setStateStartTime(bytes32 _stateId, uint256 _timestamp) internal {
        require(block.timestamp < _timestamp);

        if (startTime[_stateId] == 0) {
            addStartCondition(_stateId, hasStartTimePassed);
        }

        startTime[_stateId] = _timestamp;

        LogSetStateStartTime(_stateId, _timestamp);
    }

    function hasStartTimePassed(bytes32 _stateId) internal returns(bool) {
        return startTime[_stateId] <= block.timestamp;
    }

}

// File: @tokenfoundry/token-contracts/contracts/TokenControllerI.sol

/// @title Interface for token controllers. The controller specifies whether a transfer can be done.
contract TokenControllerI {

    /// @dev Specifies whether a transfer is allowed or not.
    /// @return True if the transfer is allowed
    function transferAllowed(address _from, address _to) external view returns (bool);
}

// File: zeppelin-solidity/contracts/token/ERC20/BasicToken.sol

/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  uint256 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(_to != address(0));
    require(_value <= balances[msg.sender]);

    // SafeMath.sub will throw if there is not enough balance.
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    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 balance) {
    return balances[_owner];
  }

}

// File: zeppelin-solidity/contracts/token/ERC20/StandardToken.sol

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * @dev https://github.com/ethereum/EIPs/issues/20
 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
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(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    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;
    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, uint _addedValue) public returns (bool) {
    allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
    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, uint _subtractedValue) public returns (bool) {
    uint oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}

// File: @tokenfoundry/token-contracts/contracts/ControllableToken.sol

/**
 * @title Controllable ERC20 token
 *
 * @dev Token that queries a token controller contract to check if a transfer is allowed.
 * @dev controller state var is going to be set with the address of a TokenControllerI contract that has 
 * implemented transferAllowed() function.
 */
contract ControllableToken is Ownable, StandardToken {
    TokenControllerI public controller;

    /// @dev Executes transferAllowed() function from the Controller. 
    modifier isAllowed(address _from, address _to) {
        require(controller.transferAllowed(_from, _to));
        _;
    }

    /// @dev Sets the controller that is going to be used by isAllowed modifier
    function setController(TokenControllerI _controller) onlyOwner public {
        require(_controller != address(0));
        controller = _controller;
    }

    /// @dev It calls parent BasicToken.transfer() function. It will transfer an amount of tokens to an specific address
    /// @return True if the token is transfered with success
    function transfer(address _to, uint256 _value) isAllowed(msg.sender, _to) public returns (bool) {        
        return super.transfer(_to, _value);
    }

    /// @dev It calls parent StandardToken.transferFrom() function. It will transfer from an address a certain amount of tokens to another address 
    /// @return True if the token is transfered with success 
    function transferFrom(address _from, address _to, uint256 _value) isAllowed(_from, _to) public returns (bool) {
        return super.transferFrom(_from, _to, _value);
    }
}

// File: zeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol

contract DetailedERC20 is ERC20 {
  string public name;
  string public symbol;
  uint8 public decimals;

  function DetailedERC20(string _name, string _symbol, uint8 _decimals) public {
    name = _name;
    symbol = _symbol;
    decimals = _decimals;
  }
}

// File: @tokenfoundry/token-contracts/contracts/Token.sol

/**
 * @title Token base contract - Defines basic structure for a token
 *
 * @dev ControllableToken is a StandardToken, an OpenZeppelin ERC20 implementation library. DetailedERC20 is also an OpenZeppelin contract.
 * More info about them is available here: https://github.com/OpenZeppelin/zeppelin-solidity/tree/master/contracts/token/ERC20
 */
contract Token is ControllableToken, DetailedERC20 {

	/**
	* @dev Transfer is an event inherited from ERC20Basic.sol interface (OpenZeppelin).
	* @param _supply Total supply of tokens.
    * @param _name Is the long name by which the token contract should be known
    * @param _symbol The set of capital letters used to represent the token e.g. DTH.
    * @param _decimals The number of decimal places the tokens can be split up into. This should be between 0 and 18.
	*/
    function Token(
        uint256 _supply,
        string _name,
        string _symbol,
        uint8 _decimals
    ) DetailedERC20(_name, _symbol, _decimals) public {
        require(_supply != 0);
        totalSupply_ = _supply;
        balances[msg.sender] = _supply;
        Transfer(address(0), msg.sender, _supply);  //event
    }
}

// File: @tokenfoundry/sale-contracts/contracts/Sale.sol

/// @title Sale base contract
contract Sale is Ownable, Whitelistable, TimedStateMachine, TokenControllerI {
    using SafeMath for uint256;

    // State machine states
    bytes32 private constant SETUP = 'setup';
    bytes32 private constant FREEZE = 'freeze';
    bytes32 private constant SALE_IN_PROGRESS = 'saleInProgress';
    bytes32 private constant SALE_ENDED = 'saleEnded';
    bytes32[] public states = [SETUP, FREEZE, SALE_IN_PROGRESS, SALE_ENDED];

    // Stores the contribution for each user
    mapping(address => uint256) public contributions;
    // Records which users have contributed throughout the sale
    mapping(address => bool) public hasContributed;

    DisbursementHandler public disbursementHandler;

    uint256 public weiContributed = 0;
    uint256 public totalSaleCap;
    uint256 public minContribution;
    uint256 public minThreshold;

    // How many tokens a user will receive per each wei contributed
    uint256 public tokensPerWei;
    uint256 public tokensForSale;

    Token public trustedToken;
    Vault public trustedVault;

    event LogContribution(address indexed contributor, uint256 value, uint256 excess);
    event LogTokensAllocated(address indexed contributor, uint256 amount);

    function Sale(
        uint256 _totalSaleCap,
        uint256 _minContribution,
        uint256 _minThreshold,
        uint256 _maxTokens,
        address _whitelistAdmin,
        address _wallet,
        uint256 _closingDuration,
        uint256 _vaultInitialAmount,
        uint256 _vaultDisbursementAmount,
        uint256 _startTime,
        string _tokenName,
        string _tokenSymbol,
        uint8 _tokenDecimals
    ) 
        Whitelistable(_whitelistAdmin)
        public 
    {
        require(_totalSaleCap != 0);
        require(_maxTokens != 0);
        require(_wallet != 0);
        require(_minThreshold <= _totalSaleCap);
        require(_vaultInitialAmount <= _minThreshold);
        require(now < _startTime);

        totalSaleCap = _totalSaleCap;
        minContribution = _minContribution;
        minThreshold = _minThreshold;

        // Setup the necessary contracts
        trustedToken = new Token(_maxTokens, _tokenName, _tokenSymbol, _tokenDecimals);
        disbursementHandler = new DisbursementHandler(trustedToken);

        trustedToken.setController(this);

        trustedVault = new Vault(
            _wallet,
            _vaultInitialAmount,
            _vaultDisbursementAmount, // disbursement amount
            _closingDuration
        );

        // Set the states
        setStates(states);

        allowFunction(SETUP, this.setup.selector);
        allowFunction(FREEZE, this.setEndTime.selector);
        allowFunction(SALE_IN_PROGRESS, this.setEndTime.selector);
        allowFunction(SALE_IN_PROGRESS, this.contribute.selector);
        allowFunction(SALE_IN_PROGRESS, this.endSale.selector);
        allowFunction(SALE_ENDED, this.allocateTokens.selector);

        // End the sale when the cap is reached
        addStartCondition(SALE_ENDED, wasCapReached);

        // Set the onSaleEnded callback (will be called when the sale ends)
        addCallback(SALE_ENDED, onSaleEnded);

        // Set the start and end times for the sale
        setStateStartTime(SALE_IN_PROGRESS, _startTime);
    }

    /// @dev Setup the disbursements and tokens for sale.
    /// @dev This needs to be outside the constructor because the token needs to query the sale for allowed transfers.
    function setup() public onlyOwner checkAllowed {
        require(trustedToken.transfer(disbursementHandler, disbursementHandler.totalAmount()));
        tokensForSale = trustedToken.balanceOf(this);       
        require(tokensForSale >= totalSaleCap);

        // Go to freeze state
        goToNextState();
    }

    /// @dev Called by users to contribute ETH to the sale.
    function contribute(uint256 contributionLimit, uint256 currentSaleCap, uint8 v, bytes32 r, bytes32 s) 
        external 
        payable
        checkAllowed 
    {
        // Check that the signature is valid
        require(currentSaleCap <= totalSaleCap);
        require(weiContributed < currentSaleCap);
        require(checkWhitelisted(msg.sender, contributionLimit, currentSaleCap, v, r, s));

        uint256 current = contributions[msg.sender];
        require(current < contributionLimit);

        // Get the max amount that the user can contribute
        uint256 remaining = Math.min256(contributionLimit.sub(current), currentSaleCap.sub(weiContributed));

        // Check if it goes over the contribution limit of the user or the eth cap. 
        uint256 contribution = Math.min256(msg.value, remaining);

        // Get the total contribution for the contributor after the previous checks
        uint256 totalContribution = current.add(contribution);
        require(totalContribution >= minContribution);

        contributions[msg.sender] = totalContribution;
        hasContributed[msg.sender] = true;

        weiContributed = weiContributed.add(contribution);

        trustedVault.deposit.value(contribution)(msg.sender);

        if (weiContributed >= minThreshold && trustedVault.state() != Vault.State.Success) trustedVault.saleSuccessful();

        // If there is an excess, return it to the user
        uint256 excess = msg.value.sub(contribution);
        if (excess > 0) msg.sender.transfer(excess);

        LogContribution(msg.sender, contribution, excess);

        assert(totalContribution <= contributionLimit);
    }

    /// @dev Sets the end time for the sale
    /// @param _endTime The timestamp at which the sale will end.
    function setEndTime(uint256 _endTime) external onlyOwner checkAllowed {
        require(now < _endTime);
        require(getStateStartTime(SALE_ENDED) == 0);
        setStateStartTime(SALE_ENDED, _endTime);
    }

    /// @dev Called to allocate the tokens depending on eth contributed by the end of the sale.
    /// @param _contributor The address of the contributor.
    function allocateTokens(address _contributor) external checkAllowed {
        require(contributions[_contributor] != 0);

        // Transfer the respective tokens to the contributor
        uint256 amount = contributions[_contributor].mul(tokensPerWei);

        // Set contributions to 0
        contributions[_contributor] = 0;

        require(trustedToken.transfer(_contributor, amount));

        LogTokensAllocated(_contributor, amount);
    }

    /// @dev Called to end the sale by the owner. Can only be called in SALE_IN_PROGRESS state
    function endSale() external onlyOwner checkAllowed {
        goToNextState();
    }

    /// @dev Since Sale is TokenControllerI, it has to implement transferAllowed() function
    /// @notice only the Sale and DisbursementHandler can disburse the initial tokens to their future owners
    function transferAllowed(address _from, address) external view returns (bool) {
        return _from == address(this) || _from == address(disbursementHandler);
    }

    /// @dev Called internally by the sale to setup a disbursement (it has to be called in the constructor of child sales)
    /// param _beneficiary Tokens will be disbursed to this address.
    /// param _amount Number of tokens to be disbursed.
    /// param _duration Tokens will be locked for this long.
    function setupDisbursement(address _beneficiary, uint256 _amount, uint256 _duration) internal {
        require(tokensForSale == 0);
        disbursementHandler.setupDisbursement(_beneficiary, _amount, now.add(_duration));
    }
   
    /// @dev Returns true if the cap was reached.
    function wasCapReached(bytes32) internal returns (bool) {
        return totalSaleCap <= weiContributed;
    }

    /// @dev Callback that gets called when entering the SALE_ENDED state.
    function onSaleEnded() internal {
        // If the minimum threshold wasn't reached, enable refunds
        if (weiContributed < minThreshold) {
            trustedVault.enableRefunds();
        } else {
            trustedVault.beginClosingPeriod();
            tokensPerWei = tokensForSale.div(weiContributed);
        }

        trustedToken.transferOwnership(owner); 
        trustedVault.transferOwnership(owner);
    }

}

// File: contracts/VirtuePokerSale.sol

contract VirtuePokerSale is Sale {

    function VirtuePokerSale() 
        Sale(
            25000 ether, // Total sale cap
            1 ether, // Min contribution
            12000 ether, // Min threshold
            500000000 * (10 ** 18), // Max tokens
            0x13ebf15f2e32d05ea944927ef5e6a3cad8187440, // Whitelist Admin
            0xaa0aE3459F9f3472d1237015CaFC1aAfc6F03C63, // Wallet
            28 days, // Closing duration
            12000 ether, // Vault initial amount
            25000 ether, // Vault disbursement amount
            1524218400, // Start time
            "Virtue Player Points", // Token name
            "VPP", // Token symbol
            18 // Token decimals
        )
        public 
    {
        // Team Wallet (50,000,000 VPP, 25% per year)
        setupDisbursement(0x2e286dA6Ee6E8e0Afb2c1CfADb1B74669a3cD642, 12500000 * (10 ** 18), 1 years);
        setupDisbursement(0x2e286dA6Ee6E8e0Afb2c1CfADb1B74669a3cD642, 12500000 * (10 ** 18), 2 years);
        setupDisbursement(0x2e286dA6Ee6E8e0Afb2c1CfADb1B74669a3cD642, 12500000 * (10 ** 18), 3 years);
        setupDisbursement(0x2e286dA6Ee6E8e0Afb2c1CfADb1B74669a3cD642, 12500000 * (10 ** 18), 4 years);

        // Company Wallet (250,000,000 VPP, no lock-up)
        setupDisbursement(0xaa0aE3459F9f3472d1237015CaFC1aAfc6F03C63, 250000000 * (10 ** 18), 1 days);

        // Founder Allocations (total 100,000,000, 12.5% per 6 months)
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 0.5 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 1 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 1.5 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 2 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 2.5 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 3 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 3.5 years);
        setupDisbursement(0x5ca71f050865092468CF8184D09e087F3DC58e31, 8000000 * (10 ** 18), 4 years);

        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 0.5 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 1 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 1.5 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 2 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 2.5 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 3 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 3.5 years);
        setupDisbursement(0x35fc8cA81E1b5992a0727c6Aa87DbeB8cca42094, 2250000 * (10 ** 18), 4 years);

        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 0.5 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 1 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 1.5 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 2 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 2.5 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 3 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 3.5 years);
        setupDisbursement(0xce3EFA6763e23DF21aF74DA46C6489736F96d4B6, 2250000 * (10 ** 18), 4 years);
    }
}

Contract Security Audit

Contract ABI

[{"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":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":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","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":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","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":"_controller","type":"address"}],"name":"setController","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","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":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":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"controller","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_supply","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"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"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

6060604052341561000f57600080fd5b604051610d7f380380610d7f833981016040528080519190602001805182019190602001805182019190602001805160008054600160a060020a03191633600160a060020a0316179055915083905082826005838051610073929160200190610107565b506006828051610087929160200190610107565b506007805460ff191660ff9290921691909117905550508315156100aa57600080fd5b6002849055600160a060020a0333166000818152600160205260408082208790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9087905190815260200160405180910390a3505050506101a2565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061014857805160ff1916838001178555610175565b82800160010185558215610175579182015b8281111561017557825182559160200191906001019061015a565b50610181929150610185565b5090565b61019f91905b80821115610181576000815560010161018b565b90565b610bce806101b16000396000f3006060604052600436106100c15763ffffffff60e060020a60003504166306fdde0381146100c6578063095ea7b31461015057806318160ddd1461018657806323b872dd146101ab578063313ce567146101d357806366188463146101fc57806370a082311461021e5780638da5cb5b1461023d57806392eefe9b1461026c57806395d89b411461028d578063a9059cbb146102a0578063d73dd623146102c2578063dd62ed3e146102e4578063f2fde38b14610309578063f77c479114610328575b600080fd5b34156100d157600080fd5b6100d961033b565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156101155780820151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015b57600080fd5b610172600160a060020a03600435166024356103d9565b604051901515815260200160405180910390f35b341561019157600080fd5b610199610445565b60405190815260200160405180910390f35b34156101b657600080fd5b610172600160a060020a036004358116906024351660443561044b565b34156101de57600080fd5b6101e66104ed565b60405160ff909116815260200160405180910390f35b341561020757600080fd5b610172600160a060020a03600435166024356104f6565b341561022957600080fd5b610199600160a060020a03600435166105f0565b341561024857600080fd5b61025061060b565b604051600160a060020a03909116815260200160405180910390f35b341561027757600080fd5b61028b600160a060020a036004351661061a565b005b341561029857600080fd5b6100d9610679565b34156102ab57600080fd5b610172600160a060020a03600435166024356106e4565b34156102cd57600080fd5b610172600160a060020a0360043516602435610784565b34156102ef57600080fd5b610199600160a060020a0360043581169060243516610828565b341561031457600080fd5b61028b600160a060020a0360043516610853565b341561033357600080fd5b6102506108ee565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b820191906000526020600020905b8154815290600101906020018083116103b457829003601f168201915b505050505081565b600160a060020a03338116600081815260036020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b60025490565b60045460009084908490600160a060020a031663214e52ca8383866040516020015260405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b15156104b257600080fd5b6102c65a03f115156104c357600080fd5b5050506040518051905015156104d857600080fd5b6104e38686866108fd565b9695505050505050565b60075460ff1681565b600160a060020a0333811660009081526003602090815260408083209386168352929052908120548083111561055357600160a060020a03338116600090815260036020908152604080832093881683529290529081205561058a565b610563818463ffffffff610a7f16565b600160a060020a033381166000908152600360209081526040808320938916835292905220555b600160a060020a0333811660008181526003602090815260408083209489168084529490915290819020547f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925915190815260200160405180910390a35060019392505050565b600160a060020a031660009081526001602052604090205490565b600054600160a060020a031681565b60005433600160a060020a0390811691161461063557600080fd5b600160a060020a038116151561064a57600080fd5b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b60045460009033908490600160a060020a031663214e52ca8383866040516020015260405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561074b57600080fd5b6102c65a03f1151561075c57600080fd5b50505060405180519050151561077157600080fd5b61077b8585610a91565b95945050505050565b600160a060020a0333811660009081526003602090815260408083209386168352929052908120546107bc908363ffffffff610b8c16565b600160a060020a0333811660008181526003602090815260408083209489168084529490915290819020849055919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591905190815260200160405180910390a350600192915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b60005433600160a060020a0390811691161461086e57600080fd5b600160a060020a038116151561088357600080fd5b600054600160a060020a0380831691167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600454600160a060020a031681565b6000600160a060020a038316151561091457600080fd5b600160a060020a03841660009081526001602052604090205482111561093957600080fd5b600160a060020a038085166000908152600360209081526040808320339094168352929052205482111561096c57600080fd5b600160a060020a038416600090815260016020526040902054610995908363ffffffff610a7f16565b600160a060020a0380861660009081526001602052604080822093909355908516815220546109ca908363ffffffff610b8c16565b600160a060020a03808516600090815260016020908152604080832094909455878316825260038152838220339093168252919091522054610a12908363ffffffff610a7f16565b600160a060020a03808616600081815260036020908152604080832033861684529091529081902093909355908516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b600082821115610a8b57fe5b50900390565b6000600160a060020a0383161515610aa857600080fd5b600160a060020a033316600090815260016020526040902054821115610acd57600080fd5b600160a060020a033316600090815260016020526040902054610af6908363ffffffff610a7f16565b600160a060020a033381166000908152600160205260408082209390935590851681522054610b2b908363ffffffff610b8c16565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b600082820183811015610b9b57fe5b93925050505600a165627a7a72305820b8c87ee973e0c1f7ba5d0646c429316821ea8f0d8cc6a7c13de230301ead2ff800290000000000000000000000000000000000000000019d971e4fe8401e74000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001456697274756520506c6179657220506f696e747300000000000000000000000000000000000000000000000000000000000000000000000000000000000000035650500000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6060604052600436106100c15763ffffffff60e060020a60003504166306fdde0381146100c6578063095ea7b31461015057806318160ddd1461018657806323b872dd146101ab578063313ce567146101d357806366188463146101fc57806370a082311461021e5780638da5cb5b1461023d57806392eefe9b1461026c57806395d89b411461028d578063a9059cbb146102a0578063d73dd623146102c2578063dd62ed3e146102e4578063f2fde38b14610309578063f77c479114610328575b600080fd5b34156100d157600080fd5b6100d961033b565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156101155780820151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015b57600080fd5b610172600160a060020a03600435166024356103d9565b604051901515815260200160405180910390f35b341561019157600080fd5b610199610445565b60405190815260200160405180910390f35b34156101b657600080fd5b610172600160a060020a036004358116906024351660443561044b565b34156101de57600080fd5b6101e66104ed565b60405160ff909116815260200160405180910390f35b341561020757600080fd5b610172600160a060020a03600435166024356104f6565b341561022957600080fd5b610199600160a060020a03600435166105f0565b341561024857600080fd5b61025061060b565b604051600160a060020a03909116815260200160405180910390f35b341561027757600080fd5b61028b600160a060020a036004351661061a565b005b341561029857600080fd5b6100d9610679565b34156102ab57600080fd5b610172600160a060020a03600435166024356106e4565b34156102cd57600080fd5b610172600160a060020a0360043516602435610784565b34156102ef57600080fd5b610199600160a060020a0360043581169060243516610828565b341561031457600080fd5b61028b600160a060020a0360043516610853565b341561033357600080fd5b6102506108ee565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b820191906000526020600020905b8154815290600101906020018083116103b457829003601f168201915b505050505081565b600160a060020a03338116600081815260036020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b60025490565b60045460009084908490600160a060020a031663214e52ca8383866040516020015260405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b15156104b257600080fd5b6102c65a03f115156104c357600080fd5b5050506040518051905015156104d857600080fd5b6104e38686866108fd565b9695505050505050565b60075460ff1681565b600160a060020a0333811660009081526003602090815260408083209386168352929052908120548083111561055357600160a060020a03338116600090815260036020908152604080832093881683529290529081205561058a565b610563818463ffffffff610a7f16565b600160a060020a033381166000908152600360209081526040808320938916835292905220555b600160a060020a0333811660008181526003602090815260408083209489168084529490915290819020547f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925915190815260200160405180910390a35060019392505050565b600160a060020a031660009081526001602052604090205490565b600054600160a060020a031681565b60005433600160a060020a0390811691161461063557600080fd5b600160a060020a038116151561064a57600080fd5b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103d15780601f106103a6576101008083540402835291602001916103d1565b60045460009033908490600160a060020a031663214e52ca8383866040516020015260405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561074b57600080fd5b6102c65a03f1151561075c57600080fd5b50505060405180519050151561077157600080fd5b61077b8585610a91565b95945050505050565b600160a060020a0333811660009081526003602090815260408083209386168352929052908120546107bc908363ffffffff610b8c16565b600160a060020a0333811660008181526003602090815260408083209489168084529490915290819020849055919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591905190815260200160405180910390a350600192915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b60005433600160a060020a0390811691161461086e57600080fd5b600160a060020a038116151561088357600080fd5b600054600160a060020a0380831691167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600454600160a060020a031681565b6000600160a060020a038316151561091457600080fd5b600160a060020a03841660009081526001602052604090205482111561093957600080fd5b600160a060020a038085166000908152600360209081526040808320339094168352929052205482111561096c57600080fd5b600160a060020a038416600090815260016020526040902054610995908363ffffffff610a7f16565b600160a060020a0380861660009081526001602052604080822093909355908516815220546109ca908363ffffffff610b8c16565b600160a060020a03808516600090815260016020908152604080832094909455878316825260038152838220339093168252919091522054610a12908363ffffffff610a7f16565b600160a060020a03808616600081815260036020908152604080832033861684529091529081902093909355908516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b600082821115610a8b57fe5b50900390565b6000600160a060020a0383161515610aa857600080fd5b600160a060020a033316600090815260016020526040902054821115610acd57600080fd5b600160a060020a033316600090815260016020526040902054610af6908363ffffffff610a7f16565b600160a060020a033381166000908152600160205260408082209390935590851681522054610b2b908363ffffffff610b8c16565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b600082820183811015610b9b57fe5b93925050505600a165627a7a72305820b8c87ee973e0c1f7ba5d0646c429316821ea8f0d8cc6a7c13de230301ead2ff80029

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

0000000000000000000000000000000000000000019d971e4fe8401e74000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001456697274756520506c6179657220506f696e747300000000000000000000000000000000000000000000000000000000000000000000000000000000000000035650500000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _supply (uint256): 500000000000000000000000000
Arg [1] : _name (string): Virtue Player Points
Arg [2] : _symbol (string): VPP
Arg [3] : _decimals (uint8): 18

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000019d971e4fe8401e74000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [5] : 56697274756520506c6179657220506f696e7473000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 5650500000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

27641:835:0:-;;;;;;;;;-1:-1:-1;;;27641:835:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26992:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;71:3;;;64:6;52:2;45:3;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22960:187:0;;;;;;;;;;-1:-1:-1;;;;;22960:187:0;;;;;;;;;;;;;;;;;;;;;;;;20168:85;;;;;;;;;;;;;;;;;;;;;;;;;;;26704:174;;;;;;;;;;-1:-1:-1;;;;;26704:174:0;;;;;;;;;;;;27040:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24806:407;;;;;;;;;;-1:-1:-1;;;;;24806:407:0;;;;;;;21011:109;;;;;;;;;;-1:-1:-1;;;;;21011:109:0;;;;;1595:20;;;;;;;;;;;;;;;-1:-1:-1;;;;;1595:20:0;;;;;;;;;;;;;;;25977:158;;;;;;;;;;-1:-1:-1;;;;;25977:158:0;;;;;;;27015:20;;;;;;;;;;;;26327:157;;;;;;;;;;-1:-1:-1;;;;;26327:157:0;;;;;;;24071:261;;;;;;;;;;-1:-1:-1;;;;;24071:261:0;;;;;;;23474:128;;;;;;;;;;-1:-1:-1;;;;;23474:128:0;;;;;;;;;;2215:173;;;;;;;;;;-1:-1:-1;;;;;2215:173:0;;;;;25648:34;;;;;;;;;;;;26992:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;22960:187::-;-1:-1:-1;;;;;23048:10:0;23040:19;;23027:4;23040:19;;;:7;:19;;;;;;;;:29;;;;;;;;;;;;;:38;;;23027:4;;23040:29;:19;23085:38;;23040;;23085;;;;;;;;;;;;;-1:-1:-1;23137:4:0;22960:187;;;;:::o;20168:85::-;20235:12;;20168:85;:::o;26704:174::-;25829:10;;26808:4;;26780:5;;26787:3;;-1:-1:-1;;;;;25829:10:0;:26;26780:5;26787:3;26808:4;25829:38;;;;;;;-1:-1:-1;;;25829:38:0;;;;;;-1:-1:-1;;;;;25829:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25821:47;;;;;;;;26832:38;26851:5;26858:3;26863:6;26832:18;:38::i;:::-;26825:45;26704:174;-1:-1:-1;;;;;;26704:174:0:o;27040:21::-;;;;;;:::o;24806:407::-;-1:-1:-1;;;;;24926:10:0;24918:19;;24889:4;24918:19;;;:7;:19;;;;;;;;:29;;;;;;;;;;;;24958:27;;;24954:168;;;-1:-1:-1;;;;;25004:10:0;24996:19;;25028:1;24996:19;;;:7;:19;;;;;;;;:29;;;;;;;;;;;:33;24954:168;;;25084:30;:8;25097:16;25084:30;:12;:30;:::i;:::-;-1:-1:-1;;;;;25060:10:0;25052:19;;;;;;:7;:19;;;;;;;;:29;;;;;;;;;:62;24954:168;-1:-1:-1;;;;;25137:10:0;25128:61;;25159:19;;;;:7;:19;;;;;;;;25128:61;;;25159:29;;;;;;;;;;;;25128:61;;;;;;;;;;;;;;;-1:-1:-1;25203:4:0;;24806:407;-1:-1:-1;;;24806:407:0:o;21011:109::-;-1:-1:-1;;;;;21098:16:0;21067:15;21098:16;;;-1:-1:-1;21098:16:0;;;;;;;21011:109::o;1595:20::-;;;-1:-1:-1;;;;;1595:20:0;;:::o;25977:158::-;2028:5;;2014:10;-1:-1:-1;;;;;2014:19:0;;;2028:5;;2014:19;2006:28;;;;;;-1:-1:-1;;;;;26066:25:0;;;;26058:34;;;;;;26103:10;:24;;-1:-1:-1;;26103:24:0;-1:-1:-1;;;;;26103:24:0;;;;;;;;;;25977:158::o;27015:20::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26327:157;25829:10;;26417:4;;26384:10;;26396:3;;-1:-1:-1;;;;;25829:10:0;:26;26384:10;26396:3;26417:4;25829:38;;;;;;;-1:-1:-1;;;25829:38:0;;;;;;-1:-1:-1;;;;;25829:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25821:47;;;;;;;;26449:27;26464:3;26469:6;26449:14;:27::i;:::-;26442:34;26327:157;-1:-1:-1;;;;;26327:157:0:o;24071:261::-;-1:-1:-1;;;;;24202:10:0;24194:19;;24149:4;24194:19;;;:7;:19;;;;;;;;:29;;;;;;;;;;;;:46;;24228:11;24194:33;:46::i;:::-;-1:-1:-1;;;;;24170:10:0;24162:19;;;;;;:7;:19;;;;;;;;:29;;;;;;;;;;;;;;:78;;;:29;;:19;;24247:61;;24162:78;24247:61;;;;;;;;;;;;;-1:-1:-1;24322:4:0;24071:261;;;;:::o;23474:128::-;-1:-1:-1;;;;;23571:15:0;;;23548:7;23571:15;;;:7;:15;;;;;;;;:25;;;;;;;;;;;;;23474:128::o;2215:173::-;2028:5;;2014:10;-1:-1:-1;;;;;2014:19:0;;;2028:5;;2014:19;2006:28;;;;;;-1:-1:-1;;;;;2292:22:0;;;;2284:31;;;;;;2343:5;;-1:-1:-1;;;;;2322:37:0;;;;2343:5;2322:37;;;;;;;;;;2366:5;:16;;-1:-1:-1;;2366:16:0;-1:-1:-1;;;;;2366:16:0;;;;;;;;;;2215:173::o;25648:34::-;;;-1:-1:-1;;;;;25648:34:0;;:::o;21876:449::-;21958:4;-1:-1:-1;;;;;21979:17:0;;;;21971:26;;;;;;-1:-1:-1;;;;;22022:15:0;;;;;;-1:-1:-1;22022:15:0;;;;;;22012:25;;;22004:34;;;;;;-1:-1:-1;;;;;22063:14:0;;;;;;;:7;:14;;;;;;;;22078:10;22063:26;;;;;;;;;;22053:36;;;22045:45;;;;;;-1:-1:-1;;;;;22117:15:0;;;;;;-1:-1:-1;22117:15:0;;;;;;:27;;22137:6;22117:19;:27::i;:::-;-1:-1:-1;;;;;22099:15:0;;;;;;;-1:-1:-1;22099:15:0;;;;;;:45;;;;22167:13;;;;;;;:25;;22185:6;22167:17;:25::i;:::-;-1:-1:-1;;;;;22151:13:0;;;;;;;-1:-1:-1;22151:13:0;;;;;;;;:41;;;;22228:14;;;;;:7;:14;;;;;22243:10;22228:26;;;;;;;;;;;:38;;22259:6;22228:30;:38::i;:::-;-1:-1:-1;;;;;22199:14:0;;;;;;;:7;:14;;;;;;;;22214:10;22199:26;;;;;;;;;;;:67;;;;22273:28;;;;;;22294:6;;22273:28;;;;;;;;;;;;;-1:-1:-1;22315:4:0;21876:449;;;;;:::o;996:113::-;1054:7;1077:6;;;;1070:14;;;;-1:-1:-1;1098:5:0;;;996:113::o;20414:388::-;20477:4;-1:-1:-1;;;;;20498:17:0;;;;20490:26;;;;;;-1:-1:-1;;;;;20550:10:0;20541:20;;;;;-1:-1:-1;20541:20:0;;;;;;20531:30;;;20523:39;;;;;;-1:-1:-1;;;;;20667:10:0;20658:20;;;;;-1:-1:-1;20658:20:0;;;;;;:32;;20683:6;20658:24;:32::i;:::-;-1:-1:-1;;;;;20644:10:0;20635:20;;;;;;-1:-1:-1;20635:20:0;;;;;;:55;;;;20713:13;;;;;;;:25;;20731:6;20713:17;:25::i;:::-;-1:-1:-1;;;;;20697:13:0;;;;;;;-1:-1:-1;20697:13:0;;;;;;;:41;;;;:13;20754:10;20745:33;;;;;;20771:6;;20745:33;;;;;;;;;;;;;-1:-1:-1;20792:4:0;20414:388;;;;:::o;1176:133::-;1234:7;1262:5;;;1281:6;;;;1274:14;;;;1302:1;1176:133;-1:-1:-1;;;1176:133:0:o

Swarm Source

bzzr://b8c87ee973e0c1f7ba5d0646c429316821ea8f0d8cc6a7c13de230301ead2ff8

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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