Token Sparkster

 

Overview [ERC-20]

Max Total Supply:
435,000,000 SPRK

Holders:
3,981

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

OVERVIEW

Token migration announcement. Sparkster token contract has migrated to 0x80a740c8ffa28c8c2c3f1fc8b6c1a0a442212e71


 


# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SparksterToken

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-07-22
*/

pragma solidity 0.4.24;

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * 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);
}

/**
 * @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]);

    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];
  }

}


/**
 * @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
  );
}


/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/issues/20
 * 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);
    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;
  }

}


/**
 * @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 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;
  }
}


/**
 * @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 c) {
    // Gas optimization: this is cheaper than asserting '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;
    }

    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 a / b;
  }

  /**
  * @dev Subtracts 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 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}


contract SparksterToken is StandardToken, Ownable{
	using SafeMath for uint256;
	struct Member {
		mapping(uint256 => uint256) weiBalance; // How much wei has this member contributed for this group?
	}

	struct Group {
		bool distributed; // Whether or not tokens in this group have been distributed.
		bool distributing; // This flag is set when we first enter the distribute function and is there to prevent race conditions, since distribution might take a long time.
		bool unlocked; // Whether or not tokens in this group have been unlocked.
		mapping(address => bool) exists; // If exists[address] is true, this address has made a purchase on this group before.
		string name;
		uint256 ratio; // 1 eth:ratio tokens. This amount represents the decimal amount. ratio*10**decimal = ratio sparks.
		uint256 startTime; // Epoch of crowdsale start time.
		uint256 phase1endTime; // Epoch of phase1 end time.
		uint256 phase2endTime; // Epoch of phase2 end time.
		uint256 deadline; // No contributions allowed after this epoch.
		uint256 max2; // cap of phase2
		uint256 max3; // Total ether this group can collect in phase 3.
		uint256 weiTotal; // How much ether has this group collected?
		uint256 cap; // The hard ether cap.
		uint256 nextDistributionIndex; // The next index to start distributing at.
		address[] addresses; // List of addresses that have made a purchase on this group.
	}

	address oracleAddress;
	bool public transferLock = true; // A Global transfer lock. Set to lock down all tokens from all groups.
	bool public allowedToBuyBack = false;
	bool public allowedToPurchase = false;
	string public name;									 // name for display
	string public symbol;								 //An identifier
	uint8 public decimals;							//How many decimals to show.
	uint256 public penalty;
	uint256 public maxGasPrice; // The maximum allowed gas for the purchase function.
	uint256 internal nextGroupNumber;
	uint256 public sellPrice; // sellPrice wei:1 spark token; we won't allow to sell back parts of a token.
	mapping(address => Member) internal members;
	mapping(uint256 => Group) internal groups;
	uint256 public openGroupNumber;
	event WantsToPurchase(address walletAddress, uint256 weiAmount, uint256 groupNumber, bool inPhase1);
	event PurchasedCallbackOnAccept(uint256 groupNumber, address[] addresses);
	event WantsToDistribute(uint256 groupNumber);
	event NearingHardCap(uint256 groupNumber, uint256 remainder);
	event ReachedHardCap(uint256 groupNumber);
	event DistributeDone(uint256 groupNumber);
	event DistributedBatch(uint256 groupNumber, uint256 howMany);
	event AirdroppedBatch(address[] addresses);
	event RefundedBatch(address[] addresses);
	event AddToGroup(address walletAddress, uint256 groupNumber);
	event ChangedTransferLock(bool transferLock);
	event ChangedAllowedToPurchase(bool allowedToPurchase);
	event ChangedAllowedToBuyBack(bool allowedToBuyBack);
	event SetSellPrice(uint256 sellPrice);
	
	modifier onlyOwnerOrOracle() {
		require(msg.sender == owner || msg.sender == oracleAddress);
		_;
	}
	
	// Fix for the ERC20 short address attack http://vessenes.com/the-erc20-short-address-attack-explained/
	modifier onlyPayloadSize(uint size) {	 
		require(msg.data.length == size + 4);
		_;
	}

	modifier canTransfer() {
		if (msg.sender != owner) {
			require(!transferLock);
		}
		_;
	}

	modifier canPurchase() {
		require(allowedToPurchase);
		_;
	}

	modifier canSell() {
		require(allowedToBuyBack);
		_;
	}

	function() public payable {
		purchase();
	}

	constructor() public {
		name = "Sparkster";									// Set the name for display purposes
		decimals = 18;					 // Amount of decimals for display purposes
		symbol = "SPRK";							// Set the symbol for display purposes
		setMaximumGasPrice(40);
		mintTokens(435000000);
	}
	
	function setOracleAddress(address newAddress) public onlyOwner returns(bool success) {
		oracleAddress = newAddress;
		return true;
	}

	function removeOracleAddress() public onlyOwner {
		oracleAddress = address(0);
	}

	function setMaximumGasPrice(uint256 gweiPrice) public onlyOwner returns(bool success) {
		maxGasPrice = gweiPrice.mul(10**9); // Convert the gwei value to wei.
		return true;
	}

	function mintTokens(uint256 amount) public onlyOwner {
		// Here, we'll consider amount to be the full token amount, so we have to get its decimal value.
		uint256 decimalAmount = amount.mul(uint(10)**decimals);
		totalSupply_ = totalSupply_.add(decimalAmount);
		balances[msg.sender] = balances[msg.sender].add(decimalAmount);
		emit Transfer(address(0), msg.sender, decimalAmount); // Per erc20 standards-compliance.
	}

	function purchase() public canPurchase payable returns(bool success) {
		require(msg.sender != address(0)); // Don't allow the 0 address.
		Member storage memberRecord = members[msg.sender];
		Group storage openGroup = groups[openGroupNumber];
		require(openGroup.ratio > 0); // Group must be initialized.
		uint256 currentTimestamp = block.timestamp;
		require(currentTimestamp >= openGroup.startTime && currentTimestamp <= openGroup.deadline);																 //the timestamp must be greater than or equal to the start time and less than or equal to the deadline time
		require(!openGroup.distributing && !openGroup.distributed); // Don't allow to purchase if we're in the middle of distributing this group; Don't let someone buy tokens on the current group if that group is already distributed.
		require(tx.gasprice <= maxGasPrice); // Restrict maximum gas this transaction is allowed to consume.
		uint256 weiAmount = msg.value;																		// The amount purchased by the current member
		require(weiAmount >= 0.1 ether);
		uint256 weiTotal = openGroup.weiTotal.add(weiAmount); // Calculate total contribution of all members in this group.
		require(weiTotal <= openGroup.cap);														// Check to see if accepting these funds will put us above the hard ether cap.
		uint256 userWeiTotal = memberRecord.weiBalance[openGroupNumber].add(weiAmount);	// Calculate the total amount purchased by the current member
		if (!openGroup.exists[msg.sender]) { // Has this person not purchased on this group before?
			openGroup.addresses.push(msg.sender);
			openGroup.exists[msg.sender] = true;
		}
		if(currentTimestamp <= openGroup.phase1endTime){																			 // whether the current timestamp is in the first phase
			emit WantsToPurchase(msg.sender, weiAmount, openGroupNumber, true);
			return true;
		} else if (currentTimestamp <= openGroup.phase2endTime) { // Are we in phase 2?
			require(userWeiTotal <= openGroup.max2); // Allow to contribute no more than max2 in phase 2.
			emit WantsToPurchase(msg.sender, weiAmount, openGroupNumber, false);
			return true;
		} else { // We've passed both phases 1 and 2.
			require(userWeiTotal <= openGroup.max3); // Don't allow to contribute more than max3 in phase 3.
			emit WantsToPurchase(msg.sender, weiAmount, openGroupNumber, false);
			return true;
		}
	}
	
	function purchaseCallbackOnAccept(uint256 groupNumber, address[] addresses, uint256[] weiAmounts) public onlyOwnerOrOracle returns(bool success) {
		uint256 n = addresses.length;
		require(n == weiAmounts.length, "Array lengths mismatch");
		Group storage theGroup = groups[groupNumber];
		uint256 weiTotal = theGroup.weiTotal;
		for (uint256 i = 0; i < n; i++) {
			Member storage memberRecord = members[addresses[i]];
			uint256 weiAmount = weiAmounts[i];
			weiTotal = weiTotal.add(weiAmount);								 // Calculate the total amount purchased by all members in this group.
			memberRecord.weiBalance[groupNumber] = memberRecord.weiBalance[groupNumber].add(weiAmount);														 // Record the total amount purchased by the current member
		}
		theGroup.weiTotal = weiTotal;
		if (getHowMuchUntilHardCap_(groupNumber) <= 100 ether) {
			emit NearingHardCap(groupNumber, getHowMuchUntilHardCap_(groupNumber));
			if (weiTotal >= theGroup.cap) {
				emit ReachedHardCap(groupNumber);
			}
		}
		emit PurchasedCallbackOnAccept(groupNumber, addresses);
		return true;
	}

	function insertAndApprove(uint256 groupNumber, address[] addresses, uint256[] weiAmounts) public onlyOwnerOrOracle returns(bool success) {
		uint256 n = addresses.length;
		require(n == weiAmounts.length, "Array lengtsh mismatch");
		Group storage theGroup = groups[groupNumber];
		for (uint256 i = 0; i < n; i++) {
			address theAddress = addresses[i];
			if (!theGroup.exists[theAddress]) {
				theGroup.addresses.push(theAddress);
				theGroup.exists[theAddress] = true;
			}
		}
		return purchaseCallbackOnAccept(groupNumber, addresses, weiAmounts);
	}

	function callbackInsertApproveAndDistribute(uint256 groupNumber, address[] addresses, uint256[] weiAmounts) public onlyOwnerOrOracle returns(bool success) {
		uint256 n = addresses.length;
		require(n == weiAmounts.length, "Array lengths mismatch");
		Group storage theGroup = groups[groupNumber];
		if (!theGroup.distributing) {
			theGroup.distributing = true;
		}
		uint256 newOwnerSupply = balances[owner];
		for (uint256 i = 0; i < n; i++) {
			address theAddress = addresses[i];
			Member storage memberRecord = members[theAddress];
			uint256 weiAmount = weiAmounts[i];
			memberRecord.weiBalance[groupNumber] = memberRecord.weiBalance[groupNumber].add(weiAmount);														 // Record the total amount purchased by the current member
			uint256 additionalBalance = weiAmount.mul(theGroup.ratio); // Don't give cumulative tokens; one address can be distributed multiple times.
			if (additionalBalance > 0) { // No need to waste ticks if they have no tokens to distribute
				balances[theAddress] = balances[theAddress].add(additionalBalance);
				newOwnerSupply = newOwnerSupply.sub(additionalBalance); // Update the available number of tokens.
				emit Transfer(owner, theAddress, additionalBalance); // Notify exchanges of the distribution.
			}
		}
		balances[owner] = newOwnerSupply;
		emit PurchasedCallbackOnAccept(groupNumber, addresses);
		return true;
	}

	function refund(address[] addresses, uint256[] weiAmounts) public onlyOwnerOrOracle returns(bool success) {
		uint256 n = addresses.length;
		require (n == weiAmounts.length, "Array lengths mismatch");
		uint256 thePenalty = penalty;
		for(uint256 i = 0; i < n; i++) {
			uint256 weiAmount = weiAmounts[i];
			address theAddress = addresses[i];
			if (thePenalty <= weiAmount) {
				weiAmount = weiAmount.sub(thePenalty);
				require(address(this).balance >= weiAmount);
				theAddress.transfer(weiAmount);
			}
		}
		emit RefundedBatch(addresses);
		return true;
	}

	function signalDoneDistributing(uint256 groupNumber) public onlyOwnerOrOracle {
		Group storage theGroup = groups[groupNumber];
		theGroup.distributed = true;
		theGroup.distributing = false;
		emit DistributeDone(groupNumber);
	}
	
	function drain() public onlyOwner {
		owner.transfer(address(this).balance);
	}
	
	function setPenalty(uint256 newPenalty) public onlyOwner returns(bool success) {
		penalty = newPenalty;
		return true;
	}
	
	function buyback(uint256 amount) public canSell { // Can't sell unless owner has allowed it.
		uint256 decimalAmount = amount.mul(uint(10)**decimals); // convert the full token value to the smallest unit possible.
		require(balances[msg.sender].sub(decimalAmount) >= getLockedTokens_(msg.sender)); // Don't allow to sell locked tokens.
		balances[msg.sender] = balances[msg.sender].sub(decimalAmount); // Do this before transferring to avoid re-entrance attacks; will throw if result < 0.
		// Amount is considered to be how many full tokens the user wants to sell.
		uint256 totalCost = amount.mul(sellPrice); // sellPrice is the per-full-token value.
		require(address(this).balance >= totalCost); // The contract must have enough funds to cover the selling.
		balances[owner] = balances[owner].add(decimalAmount); // Put these tokens back into the available pile.
		msg.sender.transfer(totalCost); // Pay the seller for their tokens.
		emit Transfer(msg.sender, owner, decimalAmount); // Notify exchanges of the sell.
	}

	function fundContract() public onlyOwnerOrOracle payable { // For the owner to put funds into the contract.
	}

	function setSellPrice(uint256 thePrice) public onlyOwner {
		sellPrice = thePrice;
	}
	
	function setAllowedToBuyBack(bool value) public onlyOwner {
		allowedToBuyBack = value;
		emit ChangedAllowedToBuyBack(value);
	}

	function setAllowedToPurchase(bool value) public onlyOwner {
		allowedToPurchase = value;
		emit ChangedAllowedToPurchase(value);
	}
	
	function createGroup(string groupName, uint256 startEpoch, uint256 phase1endEpoch, uint256 phase2endEpoch, uint256 deadlineEpoch, uint256 phase2weiCap, uint256 phase3weiCap, uint256 hardWeiCap, uint256 ratio) public onlyOwner returns (bool success, uint256 createdGroupNumber) {
		createdGroupNumber = nextGroupNumber;
		Group storage theGroup = groups[createdGroupNumber];
		theGroup.name = groupName;
		theGroup.startTime = startEpoch;
		theGroup.phase1endTime = phase1endEpoch;
		theGroup.phase2endTime = phase2endEpoch;
		theGroup.deadline = deadlineEpoch;
		theGroup.max2 = phase2weiCap;
		theGroup.max3 = phase3weiCap;
		theGroup.cap = hardWeiCap;
		theGroup.ratio = ratio;
		nextGroupNumber++;
		success = true;
	}

	function getGroup(uint256 groupNumber) public view returns(string groupName, bool distributed, bool unlocked, uint256 phase2cap, uint256 phase3cap, uint256 cap, uint256 ratio, uint256 startTime, uint256 phase1endTime, uint256 phase2endTime, uint256 deadline, uint256 weiTotal) {
		require(groupNumber < nextGroupNumber);
		Group storage theGroup = groups[groupNumber];
		groupName = theGroup.name;
		distributed = theGroup.distributed;
		unlocked = theGroup.unlocked;
		phase2cap = theGroup.max2;
		phase3cap = theGroup.max3;
		cap = theGroup.cap;
		ratio = theGroup.ratio;
		startTime = theGroup.startTime;
		phase1endTime = theGroup.phase1endTime;
		phase2endTime = theGroup.phase2endTime;
		deadline = theGroup.deadline;
		weiTotal = theGroup.weiTotal;
	}
	
	function getHowMuchUntilHardCap_(uint256 groupNumber) internal view returns(uint256 remainder) {
		Group storage theGroup = groups[groupNumber];
		if (theGroup.weiTotal > theGroup.cap) { // calling .sub in this situation will throw.
			return 0;
		}
		return theGroup.cap.sub(theGroup.weiTotal);
	}
	
	function getHowMuchUntilHardCap() public view returns(uint256 remainder) {
		return getHowMuchUntilHardCap_(openGroupNumber);
	}

	function addMemberToGroup(address walletAddress, uint256 groupNumber) public onlyOwner returns(bool success) {
		emit AddToGroup(walletAddress, groupNumber);
		return true;
	}
	
	function instructOracleToDistribute(uint256 groupNumber) public onlyOwner {
		Group storage theGroup = groups[groupNumber];
		require(groupNumber < nextGroupNumber && !theGroup.distributed); // can't have already distributed
		emit WantsToDistribute(groupNumber);
	}
	
	function distributeCallback(uint256 groupNumber, uint256 howMany) public onlyOwnerOrOracle returns (bool success) {
		Group storage theGroup = groups[groupNumber];
		require(!theGroup.distributed);
		if (!theGroup.distributing) {
			theGroup.distributing = true;
		}
		uint256 n = theGroup.addresses.length;
		uint256 nextDistributionIndex = theGroup.nextDistributionIndex;
		uint256 exclusiveEndIndex = nextDistributionIndex + howMany;
		if (exclusiveEndIndex > n) {
			exclusiveEndIndex = n;
		}
		uint256 newOwnerSupply = balances[owner];
		for (uint256 i = nextDistributionIndex; i < exclusiveEndIndex; i++) {
			address theAddress = theGroup.addresses[i];
			uint256 balance = getUndistributedBalanceOf_(theAddress, groupNumber);
			if (balance > 0) { // No need to waste ticks if they have no tokens to distribute
				balances[theAddress] = balances[theAddress].add(balance);
				newOwnerSupply = newOwnerSupply.sub(balance); // Update the available number of tokens.
				emit Transfer(owner, theAddress, balance); // Notify exchanges of the distribution.
			}
		}
		balances[owner] = newOwnerSupply;
		if (exclusiveEndIndex < n) {
			emit DistributedBatch(groupNumber, howMany);
		} else { // We've finished distributing people
			signalDoneDistributing(groupNumber);
		}
		theGroup.nextDistributionIndex = exclusiveEndIndex; // Usually not necessary if we've finished distribution, but if we don't update this, getHowManyLeftToDistribute will never show 0.
		return true;
	}

	function getHowManyLeftToDistribute(uint256 groupNumber) public view returns(uint256 remainder) {
		Group storage theGroup = groups[groupNumber];
		return theGroup.addresses.length - theGroup.nextDistributionIndex;
	}

	function changeGroupInfo(uint256 groupNumber, uint256 startEpoch, uint256 phase1endEpoch, uint256 phase2endEpoch, uint256 deadlineEpoch, uint256 phase2weiCap, uint256 phase3weiCap, uint256 hardWeiCap, uint256 ratio) public onlyOwner returns (bool success) {
		Group storage theGroup = groups[groupNumber];
		if (startEpoch > 0) {
			theGroup.startTime = startEpoch;
		}
		if (phase1endEpoch > 0) {
			theGroup.phase1endTime = phase1endEpoch;
		}
		if (phase2endEpoch > 0) {
			theGroup.phase2endTime = phase2endEpoch;
		}
		if (deadlineEpoch > 0) {
			theGroup.deadline = deadlineEpoch;
		}
		if (phase2weiCap > 0) {
			theGroup.max2 = phase2weiCap;
		}
		if (phase3weiCap > 0) {
			theGroup.max3 = phase3weiCap;
		}
		if (hardWeiCap > 0) {
			theGroup.cap = hardWeiCap;
		}
		if (ratio > 0) {
			theGroup.ratio = ratio;
		}
		return true;
	}

	function relockGroup(uint256 groupNumber) public onlyOwner returns(bool success) {
		groups[groupNumber].unlocked = true;
		return true;
	}

	function resetGroupInfo(uint256 groupNumber) public onlyOwner returns (bool success) {
		Group storage theGroup = groups[groupNumber];
		theGroup.startTime = 0;
		theGroup.phase1endTime = 0;
		theGroup.phase2endTime = 0;
		theGroup.deadline = 0;
		theGroup.max2 = 0;
		theGroup.max3 = 0;
		theGroup.cap = 0;
		theGroup.ratio = 0;
		return true;
	}

	function unlock(uint256 groupNumber) public onlyOwner returns (bool success) {
		Group storage theGroup = groups[groupNumber];
		require(theGroup.distributed); // Distribution must have occurred first.
		theGroup.unlocked = true;
		return true;
	}
	
	function setGlobalLock(bool value) public onlyOwner {
		transferLock = value;
		emit ChangedTransferLock(transferLock);
	}
	
	function burn(uint256 amount) public onlyOwner {
		// Burns tokens from the owner's supply and doesn't touch allocated tokens.
		// Decrease totalSupply and leftOver by the amount to burn so we can decrease the circulation.
		balances[msg.sender] = balances[msg.sender].sub(amount); // Will throw if result < 0
		totalSupply_ = totalSupply_.sub(amount); // Will throw if result < 0
		emit Transfer(msg.sender, address(0), amount);
	}
	
	function splitTokensBeforeDistribution(uint256 splitFactor) public onlyOwner returns (bool success) {
		// SplitFactor is the multiplier per decimal of spark. splitFactor * 10**decimals = splitFactor sparks
		uint256 ownerBalance = balances[msg.sender];
		uint256 multiplier = ownerBalance.mul(splitFactor);
		uint256 increaseSupplyBy = multiplier.sub(ownerBalance); // We need to mint owner*splitFactor - owner additional tokens.
		balances[msg.sender] = multiplier;
		totalSupply_ = totalSupply_.mul(splitFactor);
		emit Transfer(address(0), msg.sender, increaseSupplyBy); // Notify exchange that we've minted tokens.
		// Next, increase group ratios by splitFactor, so users will receive ratio * splitFactor tokens per ether.
		uint256 n = nextGroupNumber;
		require(n > 0); // Must have at least one group.
		for (uint256 i = 0; i < n; i++) {
			Group storage currentGroup = groups[i];
			currentGroup.ratio = currentGroup.ratio.mul(splitFactor);
		}
		return true;
	}

	function reverseSplitTokensBeforeDistribution(uint256 splitFactor) public onlyOwner returns (bool success) {
		// SplitFactor is the multiplier per decimal of spark. splitFactor * 10**decimals = splitFactor sparks
		uint256 ownerBalance = balances[msg.sender];
		uint256 divier = ownerBalance.div(splitFactor);
		uint256 decreaseSupplyBy = ownerBalance.sub(divier);
		// We don't use burnTokens here since the amount to subtract might be more than what the owner currently holds in their unallocated supply which will cause the function to throw.
		totalSupply_ = totalSupply_.div(splitFactor);
		balances[msg.sender] = divier;
		// Notify the exchanges of how many tokens were burned.
		emit Transfer(msg.sender, address(0), decreaseSupplyBy);
		// Next, decrease group ratios by splitFactor, so users will receive ratio / splitFactor tokens per ether.
		uint256 n = nextGroupNumber;
		require(n > 0); // Must have at least one group. Groups are 0-indexed.
		for (uint256 i = 0; i < n; i++) {
			Group storage currentGroup = groups[i];
			currentGroup.ratio = currentGroup.ratio.div(splitFactor);
		}
		return true;
	}

	function airdrop( address[] addresses, uint256[] tokenDecimalAmounts) public onlyOwnerOrOracle returns (bool success) {
		uint256 n = addresses.length;
		require(n == tokenDecimalAmounts.length, "Array lengths mismatch");
		uint256 newOwnerBalance = balances[owner];
		for (uint256 i = 0; i < n; i++) {
			address theAddress = addresses[i];
			uint256 airdropAmount = tokenDecimalAmounts[i];
			if (airdropAmount > 0) {
				uint256 currentBalance = balances[theAddress];
				balances[theAddress] = currentBalance.add(airdropAmount);
				newOwnerBalance = newOwnerBalance.sub(airdropAmount);
				emit Transfer(owner, theAddress, airdropAmount);
			}
		}
		balances[owner] = newOwnerBalance;
		emit AirdroppedBatch(addresses);
		return true;
	}

	function transfer(address _to, uint256 _value) public onlyPayloadSize(2 * 32) canTransfer returns (bool success) {		
		// If the transferrer has purchased tokens, they must be unlocked before they can be used.
		if (msg.sender != owner) { // Owner can transfer anything to anyone.
			require(balances[msg.sender].sub(_value) >= getLockedTokens_(msg.sender));
		}
		return super.transfer(_to, _value);
	}

	function transferFrom(address _from, address _to, uint256 _value) public onlyPayloadSize(3 * 32) canTransfer returns (bool success) {
		// If the transferrer has purchased tokens, they must be unlocked before they can be used.
		if (msg.sender != owner) { // Owner not affected by locked tokens
			require(balances[_from].sub(_value) >= getLockedTokens_(_from));
		}
		return super.transferFrom(_from, _to, _value);
	}

	function setOpenGroup(uint256 groupNumber) public onlyOwner returns (bool success) {
		require(groupNumber < nextGroupNumber);
		openGroupNumber = groupNumber;
		return true;
	}

	function getLockedTokensInGroup_(address walletAddress, uint256 groupNumber) internal view returns (uint256 balance) {
		Member storage theMember = members[walletAddress];
		if (groups[groupNumber].unlocked) {
			return 0;
		}
		return theMember.weiBalance[groupNumber].mul(groups[groupNumber].ratio);
	}

	function getLockedTokens_(address walletAddress) internal view returns(uint256 balance) {
		uint256 n = nextGroupNumber;
		for (uint256 i = 0; i < n; i++) {
			balance = balance.add(getLockedTokensInGroup_(walletAddress, i));
		}
		return balance;
	}

	function getLockedTokens(address walletAddress) public view returns(uint256 balance) {
		return getLockedTokens_(walletAddress);
	}

	function getUndistributedBalanceOf_(address walletAddress, uint256 groupNumber) internal view returns (uint256 balance) {
		Member storage theMember = members[walletAddress];
		Group storage theGroup = groups[groupNumber];
		if (theGroup.distributed) {
			return 0;
		}
		return theMember.weiBalance[groupNumber].mul(theGroup.ratio);
	}

	function getUndistributedBalanceOf(address walletAddress, uint256 groupNumber) public view returns (uint256 balance) {
		return getUndistributedBalanceOf_(walletAddress, groupNumber);
	}

	function checkMyUndistributedBalance(uint256 groupNumber) public view returns (uint256 balance) {
		return getUndistributedBalanceOf_(msg.sender, groupNumber);
	}

	function transferRecovery(address _from, address _to, uint256 _value) public onlyOwner returns (bool success) {
		// Will be used if someone sends tokens to an incorrect address by accident. This way, we have the ability to recover the tokens. For example, sometimes there's a problem of lost tokens if someone sends tokens to a contract address that can't utilize the tokens.
		allowed[_from][msg.sender] = allowed[_from][msg.sender].add(_value); // Authorize the owner to spend on someone's behalf.
		return transferFrom(_from, _to, _value);
	}
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferRecovery","outputs":[{"name":"success","type":"bool"}],"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":"groupNumber","type":"uint256"}],"name":"signalDoneDistributing","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"penalty","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"},{"name":"addresses","type":"address[]"},{"name":"weiAmounts","type":"uint256[]"}],"name":"purchaseCallbackOnAccept","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"checkMyUndistributedBalance","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"setOpenGroup","outputs":[{"name":"success","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":"groupNumber","type":"uint256"}],"name":"resetGroupInfo","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"bool"}],"name":"setGlobalLock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxGasPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"instructOracleToDistribute","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"allowedToPurchase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newPenalty","type":"uint256"}],"name":"setPenalty","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"sellPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAddress","type":"address"}],"name":"setOracleAddress","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"walletAddress","type":"address"},{"name":"groupNumber","type":"uint256"}],"name":"getUndistributedBalanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"splitFactor","type":"uint256"}],"name":"reverseSplitTokensBeforeDistribution","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"walletAddress","type":"address"},{"name":"groupNumber","type":"uint256"}],"name":"addMemberToGroup","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"unlock","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getHowMuchUntilHardCap","outputs":[{"name":"remainder","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"purchase","outputs":[{"name":"success","type":"bool"}],"payable":true,"stateMutability":"payable","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":"addresses","type":"address[]"},{"name":"tokenDecimalAmounts","type":"uint256[]"}],"name":"airdrop","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"walletAddress","type":"address"}],"name":"getLockedTokens","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"openGroupNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":"transferLock","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"buyback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"gweiPrice","type":"uint256"}],"name":"setMaximumGasPrice","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"groupName","type":"string"},{"name":"startEpoch","type":"uint256"},{"name":"phase1endEpoch","type":"uint256"},{"name":"phase2endEpoch","type":"uint256"},{"name":"deadlineEpoch","type":"uint256"},{"name":"phase2weiCap","type":"uint256"},{"name":"phase3weiCap","type":"uint256"},{"name":"hardWeiCap","type":"uint256"},{"name":"ratio","type":"uint256"}],"name":"createGroup","outputs":[{"name":"success","type":"bool"},{"name":"createdGroupNumber","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"},{"name":"addresses","type":"address[]"},{"name":"weiAmounts","type":"uint256[]"}],"name":"insertAndApprove","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"allowedToBuyBack","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"bool"}],"name":"setAllowedToBuyBack","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"mintTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"getHowManyLeftToDistribute","outputs":[{"name":"remainder","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"fundContract","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addresses","type":"address[]"},{"name":"weiAmounts","type":"uint256[]"}],"name":"refund","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"getGroup","outputs":[{"name":"groupName","type":"string"},{"name":"distributed","type":"bool"},{"name":"unlocked","type":"bool"},{"name":"phase2cap","type":"uint256"},{"name":"phase3cap","type":"uint256"},{"name":"cap","type":"uint256"},{"name":"ratio","type":"uint256"},{"name":"startTime","type":"uint256"},{"name":"phase1endTime","type":"uint256"},{"name":"phase2endTime","type":"uint256"},{"name":"deadline","type":"uint256"},{"name":"weiTotal","type":"uint256"}],"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":false,"inputs":[],"name":"removeOracleAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"},{"name":"howMany","type":"uint256"}],"name":"distributeCallback","outputs":[{"name":"success","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":"groupNumber","type":"uint256"},{"name":"startEpoch","type":"uint256"},{"name":"phase1endEpoch","type":"uint256"},{"name":"phase2endEpoch","type":"uint256"},{"name":"deadlineEpoch","type":"uint256"},{"name":"phase2weiCap","type":"uint256"},{"name":"phase3weiCap","type":"uint256"},{"name":"hardWeiCap","type":"uint256"},{"name":"ratio","type":"uint256"}],"name":"changeGroupInfo","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"bool"}],"name":"setAllowedToPurchase","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"}],"name":"relockGroup","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"splitFactor","type":"uint256"}],"name":"splitTokensBeforeDistribution","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"thePrice","type":"uint256"}],"name":"setSellPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"groupNumber","type":"uint256"},{"name":"addresses","type":"address[]"},{"name":"weiAmounts","type":"uint256[]"}],"name":"callbackInsertApproveAndDistribute","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"walletAddress","type":"address"},{"indexed":false,"name":"weiAmount","type":"uint256"},{"indexed":false,"name":"groupNumber","type":"uint256"},{"indexed":false,"name":"inPhase1","type":"bool"}],"name":"WantsToPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"groupNumber","type":"uint256"},{"indexed":false,"name":"addresses","type":"address[]"}],"name":"PurchasedCallbackOnAccept","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"groupNumber","type":"uint256"}],"name":"WantsToDistribute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"groupNumber","type":"uint256"},{"indexed":false,"name":"remainder","type":"uint256"}],"name":"NearingHardCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"groupNumber","type":"uint256"}],"name":"ReachedHardCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"groupNumber","type":"uint256"}],"name":"DistributeDone","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"groupNumber","type":"uint256"},{"indexed":false,"name":"howMany","type":"uint256"}],"name":"DistributedBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addresses","type":"address[]"}],"name":"AirdroppedBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addresses","type":"address[]"}],"name":"RefundedBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"walletAddress","type":"address"},{"indexed":false,"name":"groupNumber","type":"uint256"}],"name":"AddToGroup","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"transferLock","type":"bool"}],"name":"ChangedTransferLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"allowedToPurchase","type":"bool"}],"name":"ChangedAllowedToPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"allowedToBuyBack","type":"bool"}],"name":"ChangedAllowedToBuyBack","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sellPrice","type":"uint256"}],"name":"SetSellPrice","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"}]

60806040526004805460a860020a61ffff021960a060020a60ff021990911674010000000000000000000000000000000000000000171690553480156200004557600080fd5b5060038054600160a060020a031916331790556040805180820190915260098082527f537061726b73746572000000000000000000000000000000000000000000000060209092019182526200009e9160059162000285565b506007805460ff191660121790556040805180820190915260048082527f5350524b000000000000000000000000000000000000000000000000000000006020909201918252620000f29160069162000285565b5062000108602864010000000062000127810204565b50620001216319ed92c06401000000006200016b810204565b6200032a565b600354600090600160a060020a031633146200014257600080fd5b6200016082633b9aca00640100000000620032cb6200024482021704565b600955506001919050565b600354600090600160a060020a031633146200018657600080fd5b600754620001aa90839060ff16600a0a640100000000620032cb6200024482021704565b600154909150620001ca9082640100000000620030516200027782021704565b60015533600090815260208190526040902054620001f79082640100000000620030516200027782021704565b336000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000821515620002575750600062000271565b508181028183828115156200026857fe5b04146200027157fe5b92915050565b818101828110156200027157fe5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002c857805160ff1916838001178555620002f8565b82800160010185558215620002f8579182015b82811115620002f8578251825591602001919060010190620002db565b50620003069291506200030a565b5090565b6200032791905b8082111562000306576000815560010162000311565b90565b6135ae806200033a6000396000f3006080604052600436106102be5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166303cd3e4781146102c957806306fdde0314610307578063095ea7b3146103915780630d4891ad146103b55780630edd2ffc146103cf57806318160ddd146103f6578063215b54111461040b57806323b872dd1461049e5780632caeb8fc146104c8578063304a87b7146104e0578063313ce567146104f8578063315ad5ce14610523578063319a93951461053b5780633de39c11146105555780633ebb2d6b1461056a57806342966c681461058257806348e4e2971461059a5780634a4b674a146105af5780634b750334146105c75780634c69c00f146105dc5780634fc28f68146105fd578063506a0aaa14610621578063530e3543146106395780636198e3391461065d57806361c2c9c01461067557806364edfbf01461068a578063661884631461069257806367243482146106b65780636b2d95d4146107445780636d991cce1461076557806370a082311461077a578063715018a61461079b57806373124ced146107b057806379a9fa1c146107c557806379c8fe30146107dd5780637fd169d6146107f557806381edc308146108925780638a4db4fa146109255780638c2a59381461093a5780638da5cb5b1461095457806395d89b411461098557806397304ced1461099a5780639890220b146109b2578063a9059cbb146109c7578063b499a26f146109eb578063bd097e2114610a03578063c091c43514610a0b578063ceb6065414610a99578063d73dd62314610b7e578063d98b43f714610ba2578063dbd2ac6014610bb7578063dd62ed3e14610bd2578063e4bf619514610bf9578063ed9ca4ff14610c2a578063f2fde38b14610c44578063f9dfea5414610c65578063fab8cbe414610c7d578063fc6634b914610c95578063fed8a53b14610cad575b6102c6610d40565b50005b3480156102d557600080fd5b506102f3600160a060020a0360043581169060243516604435610fb8565b604080519115158252519081900360200190f35b34801561031357600080fd5b5061031c61103d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561035657818101518382015260200161033e565b50505050905090810190601f1680156103835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561039d57600080fd5b506102f3600160a060020a03600435166024356110cb565b3480156103c157600080fd5b506103cd600435611132565b005b3480156103db57600080fd5b506103e46111be565b60408051918252519081900360200190f35b34801561040257600080fd5b506103e46111c4565b34801561041757600080fd5b506040805160206004602480358281013584810280870186019097528086526102f396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506111cb9650505050505050565b3480156104aa57600080fd5b506102f3600160a060020a0360043581169060243516604435611448565b3480156104d457600080fd5b506103e46004356114f6565b3480156104ec57600080fd5b506102f3600435611502565b34801561050457600080fd5b5061050d611533565b6040805160ff9092168252519081900360200190f35b34801561052f57600080fd5b506102f360043561153c565b34801561054757600080fd5b506103cd60043515156115ab565b34801561056157600080fd5b506103e4611642565b34801561057657600080fd5b506103cd600435611648565b34801561058e57600080fd5b506103cd6004356116c6565b3480156105a657600080fd5b506102f361174c565b3480156105bb57600080fd5b506102f360043561176f565b3480156105d357600080fd5b506103e4611792565b3480156105e857600080fd5b506102f3600160a060020a0360043516611798565b34801561060957600080fd5b506103e4600160a060020a03600435166024356117e4565b34801561062d57600080fd5b506102f36004356117f7565b34801561064557600080fd5b506102f3600160a060020a0360043516602435611901565b34801561066957600080fd5b506102f3600435611968565b34801561068157600080fd5b506103e46119bc565b6102f3610d40565b34801561069e57600080fd5b506102f3600160a060020a03600435166024356119ce565b3480156106c257600080fd5b50604080516020600480358082013583810280860185019096528085526102f395369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611ac09650505050505050565b34801561075057600080fd5b506103e4600160a060020a0360043516611ce1565b34801561077157600080fd5b506103e4611cec565b34801561078657600080fd5b506103e4600160a060020a0360043516611cf2565b3480156107a757600080fd5b506103cd611d0d565b3480156107bc57600080fd5b506102f3611d7b565b3480156107d157600080fd5b506103cd600435611d9c565b3480156107e957600080fd5b506102f3600435611f1c565b34801561080157600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261087794369492936024939284019190819084018382808284375094975050843595505050602083013592604081013592506060810135915060808101359060a08101359060c08101359060e00135611f55565b60408051921515835260208301919091528051918290030190f35b34801561089e57600080fd5b506040805160206004602480358281013584810280870186019097528086526102f396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611fed9650505050505050565b34801561093157600080fd5b506102f361215d565b34801561094657600080fd5b506103cd600435151561217f565b34801561096057600080fd5b5061096961220d565b60408051600160a060020a039092168252519081900360200190f35b34801561099157600080fd5b5061031c61221c565b3480156109a657600080fd5b506103cd600435612277565b3480156109be57600080fd5b506103cd61231f565b3480156109d357600080fd5b506102f3600160a060020a0360043516602435612373565b3480156109f757600080fd5b506103e460043561240e565b6103cd61242b565b348015610a1757600080fd5b50604080516020600480358082013583810280860185019096528085526102f395369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975061245b9650505050505050565b348015610aa557600080fd5b50610ab1600435612614565b60405180806020018d1515151581526020018c1515151581526020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528e818151815260200191508051906020019080838360005b83811015610b38578181015183820152602001610b20565b50505050905090810190601f168015610b655780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390f35b348015610b8a57600080fd5b506102f3600160a060020a036004351660243561274e565b348015610bae57600080fd5b506103cd6127e7565b348015610bc357600080fd5b506102f360043560243561281d565b348015610bde57600080fd5b506103e4600160a060020a0360043581169060243516612a53565b348015610c0557600080fd5b506102f360043560243560443560643560843560a43560c43560e43561010435612a7e565b348015610c3657600080fd5b506103cd6004351515612b41565b348015610c5057600080fd5b506103cd600160a060020a0360043516612bd1565b348015610c7157600080fd5b506102f3600435612bf1565b348015610c8957600080fd5b506102f3600435612c30565b348015610ca157600080fd5b506103cd600435612d2e565b348015610cb957600080fd5b506040805160206004602480358281013584810280870186019097528086526102f396843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750612d4a9650505050505050565b6000806000806000806000600460169054906101000a900460ff161515610d6657600080fd5b331515610d7257600080fd5b336000908152600c60209081526040808320600e548452600d90925282206003810154919850965011610da457600080fd5b42935084600401548410158015610dbf575084600701548411155b1515610dca57600080fd5b8454610100900460ff16158015610de35750845460ff16155b1515610dee57600080fd5b6009543a1115610dfd57600080fd5b34925067016345785d8a0000831015610e1557600080fd5b600a850154610e2a908463ffffffff61305116565b600b860154909250821115610e3e57600080fd5b600e54600090815260208790526040902054610e60908463ffffffff61305116565b33600090815260018701602052604090205490915060ff161515610ed157600d850180546001818101835560009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff19163390811790915583528088019091526040909120805460ff191690911790555b60058501548411610f2f57600e5460408051338152602081018690528082019290925260016060830152517fdd26f741705a89a641bf9670936db6583982b27ad123d2e52c16f52501e643149181900360800190a160019650610faf565b60068501548411610f9e576008850154811115610f4b57600080fd5b600e5460408051338152602081018690528082019290925260006060830152517fdd26f741705a89a641bf9670936db6583982b27ad123d2e52c16f52501e643149181900360800190a160019650610faf565b6009850154811115610f4b57600080fd5b50505050505090565b600354600090600160a060020a03163314610fd257600080fd5b600160a060020a0384166000908152600260209081526040808320338452909152902054611006908363ffffffff61305116565b600160a060020a0385166000908152600260209081526040808320338452909152902055611035848484611448565b949350505050565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156110c35780601f10611098576101008083540402835291602001916110c3565b820191906000526020600020905b8154815290600101906020018083116110a657829003601f168201915b505050505081565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b600354600090600160a060020a03163314806111585750600454600160a060020a031633145b151561116357600080fd5b506000818152600d6020908152604091829020805461ff001960ff199091166001171681558251848152925190927f29c357a5c8d0a88d3bec7f98eadbf69c499098b797af76665f424431f4dbf0e192908290030190a15050565b60085481565b6001545b90565b600354600090819081908190819081908190600160a060020a03163314806111fd5750600454600160a060020a031633145b151561120857600080fd5b885188519096508614611253576040805160e560020a62461bcd0281526020600482015260166024820152600080516020613543833981519152604482015290519081900360640190fd5b60008a8152600d60205260408120600a810154909650945092505b8583101561131a57600c60008a8581518110151561128857fe5b90602001906020020151600160a060020a0316600160a060020a03168152602001908152602001600020915087838151811015156112c257fe5b6020908102909101015190506112de848263ffffffff61305116565b60008b815260208490526040902054909450611300908263ffffffff61305116565b60008b81526020849052604090205560019092019161126e565b600a850184905568056bc75e2d631000006113348b61305e565b116113bb577f37230adc97de8473c3f7d8283beb37b23ba4f1237f08f8190a62b04e45218b708a6113648c61305e565b6040805192835260208301919091528051918290030190a1600b85015484106113bb57604080518b815290517f2097ed8c6ffdfed9e01ab18c5682eca607d3f4e1657d4abf32a51ea341782c699181900360200190a15b7f534eb4590ac348de6e66b31074d03cf96af9a0fab73aa98716c575e44f0b93db8a8a6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561142457818101518382015260200161140c565b50505050905001935050505060405180910390a15060019998505050505050505050565b600060603660641461145957600080fd5b600354600160a060020a031633146114935760045474010000000000000000000000000000000000000000900460ff161561149357600080fd5b600354600160a060020a031633146114e2576114ae8561309e565b600160a060020a0386166000908152602081905260409020546114d7908563ffffffff6130d916565b10156114e257600080fd5b6114ed8585856130eb565b95945050505050565b600061112c3383613250565b600354600090600160a060020a0316331461151c57600080fd5b600a54821061152a57600080fd5b50600e55600190565b60075460ff1681565b6003546000908190600160a060020a0316331461155857600080fd5b50506000818152600d60205260408120600481018290556005810182905560068101829055600781018290556008810182905560098101829055600b810182905560038101919091556001905b50919050565b600354600160a060020a031633146115c257600080fd5b600480548215157401000000000000000000000000000000000000000090810274ff0000000000000000000000000000000000000000199092169190911791829055604080519190920460ff161515815290517f7772b54b7aa3898aee10d476009b352b8b0542eaa2563ebd6a12d50d0edfacde9181900360200190a150565b60095481565b600354600090600160a060020a0316331461166257600080fd5b506000818152600d60205260409020600a54821080156116845750805460ff16155b151561168f57600080fd5b6040805183815290517f802eff881699fa025d411df3fd011f381e2a10e9e6ef38c35b8c76e146966fbe9181900360200190a15050565b600354600160a060020a031633146116dd57600080fd5b336000908152602081905260409020546116fd908263ffffffff6130d916565b33600090815260208190526040902055600154611720908263ffffffff6130d916565b60015560408051828152905160009133916000805160206135638339815191529181900360200190a350565b600454760100000000000000000000000000000000000000000000900460ff1681565b600354600090600160a060020a0316331461178957600080fd5b50600855600190565b600b5481565b600354600090600160a060020a031633146117b257600080fd5b5060048054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff199091161790556001919050565b60006117f08383613250565b9392505050565b600354600090819081908190819081908190600160a060020a0316331461181d57600080fd5b33600090815260208190526040902054955061183f868963ffffffff6132b616565b9450611851868663ffffffff6130d916565b600154909450611867908963ffffffff6132b616565b6001553360008181526020818152604080832089905580518881529051929392600080516020613563833981519152929181900390910190a3600a549250600083116118b257600080fd5b600091505b828210156118f357506000818152600d6020526040902060038101546118e3908963ffffffff6132b616565b60038201556001909101906118b7565b506001979650505050505050565b600354600090600160a060020a0316331461191b57600080fd5b60408051600160a060020a03851681526020810184905281517ff9951fbb46b09e4116221a0fdbd49ff3f8ec4ee8e893e45327e063235ad07183929181900390910190a150600192915050565b6003546000908190600160a060020a0316331461198457600080fd5b506000828152600d60205260409020805460ff1615156119a357600080fd5b805462ff00001916620100001781556001915050919050565b60006119c9600e5461305e565b905090565b336000908152600260209081526040808320600160a060020a038616845290915281205480831115611a2357336000908152600260209081526040808320600160a060020a0388168452909152812055611a58565b611a33818463ffffffff6130d916565b336000908152600260209081526040808320600160a060020a03891684529091529020555b336000818152600260209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a3600191505b5092915050565b600354600090819081908190819081908190600160a060020a0316331480611af25750600454600160a060020a031633145b1515611afd57600080fd5b885188519096508614611b48576040805160e560020a62461bcd0281526020600482015260166024820152600080516020613543833981519152604482015290519081900360640190fd5b600354600160a060020a0316600090815260208190526040812054955093505b85841015611c42578884815181101515611b7e57fe5b9060200190602002015192508784815181101515611b9857fe5b9060200190602002015191506000821115611c375750600160a060020a038216600090815260208190526040902054611bd7818363ffffffff61305116565b600160a060020a038416600090815260208190526040902055611c00858363ffffffff6130d916565b600354604080518581529051929750600160a060020a03808716939216916000805160206135638339815191529181900360200190a35b600190930192611b68565b600354600160a060020a031660009081526020818152604080832088905580518281528c51818401528c517f6bd09b018bf088558f7ca2a5f8ec81d0fa727ecf41a5eff5ca5420915509d374948e949293849390840192868201929102908190849084905b83811015611cbf578181015183820152602001611ca7565b505050509050019250505060405180910390a150600198975050505050505050565b600061112c8261309e565b600e5481565b600160a060020a031660009081526020819052604090205490565b600354600160a060020a03163314611d2457600080fd5b600354604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a26003805473ffffffffffffffffffffffffffffffffffffffff19169055565b60045474010000000000000000000000000000000000000000900460ff1681565b60045460009081907501000000000000000000000000000000000000000000900460ff161515611dcb57600080fd5b600754611de590849060ff16600a0a63ffffffff6132cb16565b9150611df03361309e565b33600090815260208190526040902054611e10908463ffffffff6130d916565b1015611e1b57600080fd5b33600090815260208190526040902054611e3b908363ffffffff6130d916565b33600090815260208190526040902055600b54611e5f90849063ffffffff6132cb16565b90503031811115611e6f57600080fd5b600354600160a060020a0316600090815260208190526040902054611e9a908363ffffffff61305116565b600354600160a060020a0316600090815260208190526040808220929092559051339183156108fc02918491818181858888f19350505050158015611ee3573d6000803e3d6000fd5b50600354604080518481529051600160a060020a03909216913391600080516020613563833981519152919081900360200190a3505050565b600354600090600160a060020a03163314611f3657600080fd5b611f4a82633b9aca0063ffffffff6132cb16565b600955506001919050565b60035460009081908190600160a060020a03163314611f7357600080fd5b5050600a546000818152600d602090815260409091208c519091611f9e9160028401918f01906134aa565b50600481019a909a5560058a0198909855506006880195909555600787019390935560088601919091556009850155600b840155600390920191909155600a8054600190810190915592909150565b6003546000908190819081908190600160a060020a031633148061201b5750600454600160a060020a031633145b151561202657600080fd5b865186519094508414612083576040805160e560020a62461bcd02815260206004820152601660248201527f4172726179206c656e67747368206d69736d6174636800000000000000000000604482015290519081900360640190fd5b6000888152600d60205260408120935091505b838210156121465786828151811015156120ac57fe5b6020908102909101810151600160a060020a03811660009081526001860190925260409091205490915060ff16151561213b57600d830180546001808201835560009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03861690811790915583528086019091526040909120805460ff191690911790555b600190910190612096565b6121518888886111cb565b98975050505050505050565b6004547501000000000000000000000000000000000000000000900460ff1681565b600354600160a060020a0316331461219657600080fd5b600480548215157501000000000000000000000000000000000000000000810275ff000000000000000000000000000000000000000000199092169190911790915560408051918252517f7005e1991959ce579ccf48eb6da4e420123f4f7bdfdb6c0796738d6c3f432f0b9181900360200190a150565b600354600160a060020a031681565b6006805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156110c35780601f10611098576101008083540402835291602001916110c3565b600354600090600160a060020a0316331461229157600080fd5b6007546122ab90839060ff16600a0a63ffffffff6132cb16565b6001549091506122c1908263ffffffff61305116565b600155336000908152602081905260409020546122e4908263ffffffff61305116565b336000818152602081815260408083209490945583518581529351929391926000805160206135638339815191529281900390910190a35050565b600354600160a060020a0316331461233657600080fd5b600354604051600160a060020a0390911690303180156108fc02916000818181858888f19350505050158015612370573d6000803e3d6000fd5b50565b600060403660441461238457600080fd5b600354600160a060020a031633146123be5760045474010000000000000000000000000000000000000000900460ff16156123be57600080fd5b600354600160a060020a03163314612404576123d93361309e565b336000908152602081905260409020546123f9908563ffffffff6130d916565b101561240457600080fd5b61103584846132f4565b6000908152600d60208190526040909120600c8101549101540390565b600354600160a060020a031633148061244e5750600454600160a060020a031633145b151561245957600080fd5b565b60035460009081908190819081908190600160a060020a031633148061248b5750600454600160a060020a031633145b151561249657600080fd5b8751875190955085146124e1576040805160e560020a62461bcd0281526020600482015260166024820152600080516020613543833981519152604482015290519081900360640190fd5b6008549350600092505b8483101561259157868381518110151561250157fe5b906020019060200201519150878381518110151561251b57fe5b6020908102909101015190508184116125865761253e828563ffffffff6130d916565b9150303182111561254e57600080fd5b604051600160a060020a0382169083156108fc029084906000818181858888f19350505050158015612584573d6000803e3d6000fd5b505b6001909201916124eb565b7f3953e3f71784c01be5e0ad95d36e2fa536d6d0cc98205ed234665f2efcf0812e886040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156125f35781810151838201526020016125db565b505050509050019250505060405180910390a1506001979650505050505050565b6060600080600080600080600080600080600080600a548e10151561263857600080fd5b5060008d8152600d60209081526040918290206002808201805485516001821615610100026000190190911692909204601f8101859004850283018501909552848252919390928301828280156126d05780601f106126a5576101008083540402835291602001916126d0565b820191906000526020600020905b8154815290600101906020018083116126b357829003601f168201915b50505050509c508060000160009054906101000a900460ff169b508060000160029054906101000a900460ff169a50806008015499508060090154985080600b01549750806003015496508060040154955080600501549450806006015493508060070154925080600a015491505091939597999b5091939597999b565b336000908152600260209081526040808320600160a060020a0386168452909152812054612782908363ffffffff61305116565b336000818152600260209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600354600160a060020a031633146127fe57600080fd5b6004805473ffffffffffffffffffffffffffffffffffffffff19169055565b6000806000806000806000806000600360009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316148061286a5750600454600160a060020a031633145b151561287557600080fd5b60008b8152600d60205260409020805490985060ff161561289557600080fd5b8754610100900460ff1615156128b357875461ff0019166101001788555b600d880154600c89015490975095508986019450868511156128d3578694505b600354600160a060020a031660009081526020819052604090205493508592505b848310156129cc57600d880180548490811061290c57fe5b600091825260209091200154600160a060020a0316915061292d828c613250565b905060008111156129c157600160a060020a038216600090815260208190526040902054612961908263ffffffff61305116565b600160a060020a03831660009081526020819052604090205561298a848263ffffffff6130d916565b600354604080518481529051929650600160a060020a03808616939216916000805160206135638339815191529181900360200190a35b6001909201916128f4565b600354600160a060020a0316600090815260208190526040902084905586851015612a3157604080518c8152602081018c905281517f49cfca8b5cce4cc1899d604dbced372d90766b107abaea147572edc4bfe22e4b929181900390910190a1612a3a565b612a3a8b611132565b600c880185905560019850505050505050505092915050565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b6003546000908190600160a060020a03163314612a9a57600080fd5b5060008a8152600d60205260408120908a1115612ab957600481018a90555b6000891115612aca57600581018990555b6000881115612adb57600681018890555b6000871115612aec57600781018790555b6000861115612afd57600881018690555b6000851115612b0e57600981018590555b6000841115612b1f57600b81018490555b6000831115612b3057600381018390555b5060019a9950505050505050505050565b600354600160a060020a03163314612b5857600080fd5b60048054821515760100000000000000000000000000000000000000000000810276ff00000000000000000000000000000000000000000000199092169190911790915560408051918252517faacaf402900fc42a1b9c12f73a8e872a8126b1559c6cc680d43e9c5e4053c3669181900360200190a150565b600354600160a060020a03163314612be857600080fd5b612370816133c3565b600354600090600160a060020a03163314612c0b57600080fd5b506000818152600d60205260409020805462ff00001916620100001790556001919050565b600354600090819081908190819081908190600160a060020a03163314612c5657600080fd5b336000908152602081905260409020549550612c78868963ffffffff6132cb16565b9450612c8a858763ffffffff6130d916565b336000908152602081905260409020869055600154909450612cb2908963ffffffff6132cb16565b60015560408051858152905133916000916000805160206135638339815191529181900360200190a3600a54925060008311612ced57600080fd5b600091505b828210156118f357506000818152600d602052604090206003810154612d1e908963ffffffff6132cb16565b6003820155600190910190612cf2565b600354600160a060020a03163314612d4557600080fd5b600b55565b6000806000806000806000806000600360009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a03161480612d975750600454600160a060020a031633145b1515612da257600080fd5b8a518a519098508814612ded576040805160e560020a62461bcd0281526020600482015260166024820152600080516020613543833981519152604482015290519081900360640190fd5b60008c8152600d602052604090208054909750610100900460ff161515612e1c57865461ff0019166101001787555b600354600160a060020a0316600090815260208190526040812054965094505b87851015612f84578a85815181101515612e5257fe5b906020019060200201519350600c600085600160a060020a0316600160a060020a0316815260200190815260200160002092508985815181101515612e9357fe5b602090810290910181015160008e815291859052604090912054909250612ec0908363ffffffff61305116565b60008d8152602085905260409020556003870154612ee590839063ffffffff6132cb16565b90506000811115612f7957600160a060020a038416600090815260208190526040902054612f19908263ffffffff61305116565b600160a060020a038516600090815260208190526040902055612f42868263ffffffff6130d916565b600354604080518481529051929850600160a060020a03808816939216916000805160206135638339815191529181900360200190a35b600190940193612e3c565b85600080600360009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a03168152602001908152602001600020819055507f534eb4590ac348de6e66b31074d03cf96af9a0fab73aa98716c575e44f0b93db8c8c6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561302b578181015183820152602001613013565b50505050905001935050505060405180910390a15060019b9a5050505050505050505050565b8181018281101561112c57fe5b6000818152600d60205260408120600b810154600a820154111561308557600091506115a5565b600a810154600b8201546117f09163ffffffff6130d916565b600a54600090815b818110156130d2576130c86130bb8583613441565b849063ffffffff61305116565b92506001016130a6565b5050919050565b6000828211156130e557fe5b50900390565b6000600160a060020a038316151561310257600080fd5b600160a060020a03841660009081526020819052604090205482111561312757600080fd5b600160a060020a038416600090815260026020908152604080832033845290915290205482111561315757600080fd5b600160a060020a038416600090815260208190526040902054613180908363ffffffff6130d916565b600160a060020a0380861660009081526020819052604080822093909355908516815220546131b5908363ffffffff61305116565b600160a060020a038085166000908152602081815260408083209490945591871681526002825282812033825290915220546131f7908363ffffffff6130d916565b600160a060020a0380861660008181526002602090815260408083203384528252918290209490945580518681529051928716939192600080516020613563833981519152929181900390910190a35060019392505050565b600160a060020a0382166000908152600c60209081526040808320848452600d9092528220805460ff161561328857600092506132ae565b60038101546000858152602084905260409020546132ab9163ffffffff6132cb16565b92505b505092915050565b600081838115156132c357fe5b049392505050565b60008215156132dc5750600061112c565b508181028183828115156132ec57fe5b041461112c57fe5b6000600160a060020a038316151561330b57600080fd5b3360009081526020819052604090205482111561332757600080fd5b33600090815260208190526040902054613347908363ffffffff6130d916565b3360009081526020819052604080822092909255600160a060020a03851681522054613379908363ffffffff61305116565b600160a060020a038416600081815260208181526040918290209390935580518581529051919233926000805160206135638339815191529281900390910190a350600192915050565b600160a060020a03811615156133d857600080fd5b600354604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a0382166000908152600c60209081526040808320848452600d90925282205462010000900460ff161561347e5760009150611ab9565b6000838152600d602090815260408083206003015491849052909120546110359163ffffffff6132cb16565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106134eb57805160ff1916838001178555613518565b82800160010185558215613518579182015b828111156135185782518255916020019190600101906134fd565b50613524929150613528565b5090565b6111c891905b80821115613524576000815560010161352e56004172726179206c656e67746873206d69736d6174636800000000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a72305820f5cf28df18ab1352f9c0c8aafb98cd6bfb20c77f2dfa86515ed36aeab6c93d3c0029

Swarm Source

bzzr://f5cf28df18ab1352f9c0c8aafb98cd6bfb20c77f2dfa86515ed36aeab6c93d3c

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.