ETH Price: $3,159.11 (+1.28%)
Gas: 2 Gwei

Token

Gilgamesh Token (GIL)
 

Overview

Max Total Supply

5,964,920.153244582296418264 GIL

Holders

1,354

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
354 GIL

Value
$0.00
0xca63a1eae2face6eb858d30554da0363716489c9
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
GilgameshToken

Compiler Version
v0.4.19+commit.c4cbbb05

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-01-13
*/

pragma solidity ^0.4.19;


contract SafeMath {

	function safeAdd(uint256 a, uint256 b) internal pure returns (uint256) {
		uint256 c = a + b;
		assert(c >= a && c >= b);
		return c;
	}

	function safeSub(uint256 a, uint256 b) internal pure returns (uint256) {
		assert(b <= a);
		return a - b;
	}

	function safeMul(uint256 a, uint256 b) internal pure returns (uint256) {
		uint256 c = a * b;
		assert(a == 0 || c / a == b);
		return c;
	}

	function safeDiv(uint256 a, uint256 b) internal pure returns (uint256) {
		assert(b > 0);
		uint256 c = a / b;
		assert(a == b * c + a % b);
		return c;
	}
}


contract ERC20Token {

	// --------
	//	Events
	// ---------

	// publicize actions to external listeners.
	/// @notice Triggered when tokens are transferred.
	event Transfer(address indexed _from, address indexed _to, uint256 _value);

	/// @notice Triggered whenever approve(address _spender, uint256 _value) is called.
	event Approval(address indexed _owner, address indexed _spender, uint256 _value);

	// --------
	//	Getters
	// ---------

	/// @notice Get the total amount of token supply
	function totalSupply() public constant returns (uint256 _totalSupply);

	/// @notice Get the account balance of address _owner
	/// @param _owner The address from which the balance will be retrieved
	/// @return The balance
	function balanceOf(address _owner) public constant returns (uint256 balance);

	/// @param _owner The address of the account owning tokens
	/// @param _spender The address of the account able to transfer the tokens
	/// @return Amount of remaining tokens allowed to spent by the _spender from _owner account
	function allowance(address _owner, address _spender) public constant returns (uint256 remaining);

	// --------
	//	Actions
	// ---------

	/// @notice send _value amount of tokens to _to address from msg.sender address
	/// @param _to The address of the recipient
	/// @param _value The amount of token to be transferred
	/// @return a boolean - whether the transfer was successful or not
	function transfer(address _to, uint256 _value) public returns (bool success);

	/// @notice send _value amount of tokens to _to address from _from address, on the condition it is approved by _from
	/// @param _from The address of the sender
	/// @param _to The address of the recipient
	/// @param _value The amount of token to be transferred
	/// @return a boolean - whether the transfer was successful or not
	function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);

	/// @notice msg.sender approves _spender to spend multiple times up to _value amount of tokens
	/// If this function is called again it overwrites the current allowance with _value.
	/// @param _spender The address of the account able to transfer the tokens
	/// @param _value The amount of tokens to be approved for transfer
	/// @return a boolean - whether the approval was successful or not
	function approve(address _spender, uint256 _value) public returns (bool success);
}


contract SecureERC20Token is ERC20Token {

	// State variables

	// balances dictionary that maps addresses to balances
	mapping (address => uint256) private balances;

	// locked account dictionary that maps addresses to boolean
	mapping (address => bool) private lockedAccounts;

	 // allowed dictionary that allow transfer rights to other addresses.
	mapping (address => mapping(address => uint256)) private allowed;

	// The Token's name: e.g. 'Gilgamesh Tokens'
	string public name;

	// Symbol of the token: e.q 'GIL'
	string public symbol;

	// Number of decimals of the smallest unit: e.g '18'
	uint8 public decimals;

	// Number of total tokens: e,g: '1000000000'
	uint256 public totalSupply;

	// token version
	uint8 public version = 1;

	// address of the contract admin
	address public admin;

	// address of the contract minter
	address public minter;

	// creationBlock is the block number that the Token was created
	uint256 public creationBlock;

	// Flag that determines if the token is transferable or not
	// disable actionable ERC20 token methods
	bool public isTransferEnabled;

	event AdminOwnershipTransferred(address indexed previousAdmin, address indexed newAdmin);
	event MinterOwnershipTransferred(address indexed previousMinter, address indexed newMinter);
	event TransferStatus(address indexed sender, bool status);

	// @notice Constructor to create Gilgamesh ERC20 Token
	function SecureERC20Token(
		uint256 initialSupply,
		string _name,
		string _symbol,
		uint8 _decimals,
		bool _isTransferEnabled
	) public {
		// assign all tokens to the deployer
		balances[msg.sender] = initialSupply;

		totalSupply = initialSupply; // set initial supply of Tokens
		name = _name;				 // set token name
		decimals = _decimals;		 // set the decimals
		symbol = _symbol;			 // set the token symbol
		isTransferEnabled = _isTransferEnabled;
		creationBlock = block.number;
		minter = msg.sender;		// by default the contract deployer is the minter
		admin = msg.sender;			// by default the contract deployer is the admin
	}

	// --------------
	// ERC20 Methods
	// --------------

	/// @notice Get the total amount of token supply
	function totalSupply() public constant returns (uint256 _totalSupply) {
		return totalSupply;
	}

	/// @notice Get the account balance of address _owner
	/// @param _owner The address from which the balance will be retrieved
	/// @return The balance
	function balanceOf(address _owner) public constant returns (uint256 balance) {
		return balances[_owner];
	}

	/// @notice send _value amount of tokens to _to address from msg.sender address
	/// @param _to The address of the recipient
	/// @param _value The amount of token to be transferred
	/// @return a boolean - whether the transfer was successful or not
	function transfer(address _to, uint256 _value) public returns (bool success) {
		// if transfer is not enabled throw an error and stop execution.
		require(isTransferEnabled);

		// continue with transfer
		return doTransfer(msg.sender, _to, _value);
	}

	/// @notice send _value amount of tokens to _to address from _from address, on the condition it is approved by _from
	/// @param _from The address of the sender
	/// @param _to The address of the recipient
	/// @param _value The amount of token to be transferred
	/// @return a boolean - whether the transfer was successful or not
	function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
		// if transfer is not enabled throw an error and stop execution.
		require(isTransferEnabled);

		// if from allowed transferrable rights to sender for amount _value
		if (allowed[_from][msg.sender] < _value) revert();

		// subtreact allowance
		allowed[_from][msg.sender] -= _value;

		// continue with transfer
		return doTransfer(_from, _to, _value);
	}

	/// @notice msg.sender approves _spender to spend _value tokens
	/// @param _spender The address of the account able to transfer the tokens
	/// @param _value The amount of tokens to be approved for transfer
	/// @return a boolean - whether the approval was successful or not
	function approve(address _spender, uint256 _value)
	public
	is_not_locked(_spender)
	returns (bool success) {
		// if transfer is not enabled throw an error and stop execution.
		require(isTransferEnabled);

		// user can only reassign an allowance of 0 if value is greater than 0
		// sender should first change the allowance to zero by calling approve(_spender, 0)
		// race condition is explained below:
		// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
		if(_value != 0 && allowed[msg.sender][_spender] != 0) revert();

		if (
			// if sender balance is less than _value return false;
			balances[msg.sender] < _value
		) {
			// transaction failure
			return false;
		}

		// allow transfer rights from msg.sender to _spender for _value token amount
		allowed[msg.sender][_spender] = _value;

		// log approval event
		Approval(msg.sender, _spender, _value);

		// transaction successful
		return true;
	}

	/// @param _owner The address of the account owning tokens
	/// @param _spender The address of the account able to transfer the tokens
	/// @return Amount of remaining tokens allowed to spent by the _spender from _owner account
	function allowance(address _owner, address _spender)
	public
	constant
	returns (uint256 remaining) {
		return allowed[_owner][_spender];
	}

	// --------------
	// Contract Custom Methods - Non ERC20
	// --------------

	/* Public Methods */

	/// @notice only the admin is allowed to lock accounts.
	/// @param _owner the address of the account to be locked
	function lockAccount(address _owner)
	public
	is_not_locked(_owner)
	validate_address(_owner)
	onlyAdmin {
		lockedAccounts[_owner] = true;
	}

	/// @notice only the admin is allowed to unlock accounts.
	/// @param _owner the address of the account to be unlocked
	function unlockAccount(address _owner)
	public
	is_locked(_owner)
	validate_address(_owner)
	onlyAdmin {
		lockedAccounts[_owner] = false;
	}

	/// @notice only the admin is allowed to burn tokens - in case if the user haven't verified identity or performed fraud
	/// @param _owner the address of the account that their tokens needs to be burnt
	function burnUserTokens(address _owner)
	public
	validate_address(_owner)
	onlyAdmin {
		// if user balance is 0 ignore
		if (balances[_owner] == 0) revert();

		// should never happen but just in case
		if (balances[_owner] > totalSupply) revert();

		// decrease the total supply
		totalSupply -= balances[_owner];

		// burn it all
		balances[_owner] = 0;
	}

	/// @notice only the admin is allowed to change the minter.
	/// @param newMinter the address of the minter
	function changeMinter(address newMinter)
	public
	validate_address(newMinter)
	onlyAdmin {
		if (minter == newMinter) revert();
		MinterOwnershipTransferred(minter, newMinter);
		minter = newMinter;
	}

	/// @notice only the admin is allowed to change the admin.
	/// @param newAdmin the address of the new admin
	function changeAdmin(address newAdmin)
	public
	validate_address(newAdmin)
	onlyAdmin {
		if (admin == newAdmin) revert();
		AdminOwnershipTransferred(admin, newAdmin);
		admin = newAdmin;
	}

	/// @notice mint new tokens by the minter
	/// @param _owner the owner of the newly tokens
	/// @param _amount the amount of new token to be minted
	function mint(address _owner, uint256 _amount)
	public
	onlyMinter
	validate_address(_owner)
	returns (bool success) {
		// preventing overflow on the totalSupply
		if (totalSupply + _amount < totalSupply) revert();

		// preventing overflow on the receiver account
		if (balances[_owner] + _amount < balances[_owner]) revert();

		// increase the total supply
		totalSupply += _amount;

		// assign the additional supply to the target account.
		balances[_owner] += _amount;

		// contract has minted new token by the minter
		Transfer(0x0, msg.sender, _amount);

		// minter has transferred token to the target account
		Transfer(msg.sender, _owner, _amount);

		return true;
	}

	/// @notice Enables token holders to transfer their tokens freely if true
	/// after the crowdsale is finished it will be true
	/// for security reasons can be switched to false
	/// @param _isTransferEnabled boolean
	function enableTransfers(bool _isTransferEnabled) public onlyAdmin {
		isTransferEnabled = _isTransferEnabled;
		TransferStatus(msg.sender, isTransferEnabled);
	}

	/* Internal Methods */

	///	@dev this is the actual transfer function and it can only be called internally
	/// @notice send _value amount of tokens to _to address from _from address
	/// @param _to The address of the recipient
	/// @param _value The amount of token to be transferred
	/// @return a boolean - whether the transfer was successful or not
	function doTransfer(address _from, address _to, uint256 _value)
	validate_address(_to)
	is_not_locked(_from)
	internal
	returns (bool success) {
		if (
			// if the value is not more than 0 fail
			_value <= 0 ||
			// if the sender doesn't have enough balance fail
			balances[_from] < _value ||
			// if token supply overflows (total supply exceeds 2^256 - 1) fail
			balances[_to] + _value < balances[_to]
		) {
			// transaction failed
			return false;
		}

		// decrease the number of tokens from sender address.
		balances[_from] -= _value;

		// increase the number of tokens for _to address
		balances[_to] += _value;

		// log transfer event
		Transfer(_from, _to, _value);

		// transaction successful
		return true;
	}

	// --------------
	// Modifiers
	// --------------
	modifier onlyMinter() {
		// if sender is not the minter stop the execution
		if (msg.sender != minter) revert();
		// if the sender is the minter continue
		_;
	}

	modifier onlyAdmin() {
		// if sender is not the admin stop the execution
		if (msg.sender != admin) revert();
		// if the sender is the admin continue
		_;
	}

	modifier validate_address(address _address) {
		if (_address == address(0)) revert();
		_;
	}

	modifier is_not_locked(address _address) {
		if (lockedAccounts[_address] == true) revert();
		_;
	}

	modifier is_locked(address _address) {
		if (lockedAccounts[_address] != true) revert();
		_;
	}
}


contract GilgameshToken is SecureERC20Token {
	// @notice Constructor to create Gilgamesh ERC20 Token
	function GilgameshToken()
	public
	SecureERC20Token(
		0, // no token in the begning
		"Gilgamesh Token", // Token Name
		"GIL", // Token Symbol
		18, // Decimals
		false // Enable token transfer
	) {}

}


/*
	Copyright 2017, Skiral Inc
*/
contract GilgameshTokenSale is SafeMath{

	// creationBlock is the block number that the Token was created
	uint256 public creationBlock;

	// startBlock token sale starting block
	uint256 public startBlock;

	// endBlock token sale ending block
	// end block is not a valid block for crowdfunding. endBlock - 1 is the last valid block
	uint256 public endBlock;

	// total Wei rasised
	uint256 public totalRaised = 0;

	// Has Gilgamesh stopped the sale
	bool public saleStopped = false;

	// Has Gilgamesh finalized the sale
	bool public saleFinalized = false;

	// Minimum purchase - 0.1 Ether
	uint256 constant public minimumInvestment = 100 finney;

	// Maximum hard Cap
	uint256 public hardCap = 50000 ether;

	// number of wei GIL tokens for sale - 60 Million GIL Tokens
	uint256 public tokenCap = 60000000 * 10**18;

	// Minimum cap
	uint256 public minimumCap = 1250 ether;

	/* Contract Info */

	// the deposit address for the Eth that is raised.
	address public fundOwnerWallet;

	// the deposit address for the tokens that is minted for the dev team.
	address public tokenOwnerWallet;

	// owner the address of the contract depoloyer
	address public owner;

	// List of stage bonus percentages in every stage
	// this will get generated in the constructor
	uint[] public stageBonusPercentage;

	// number of participants
	uint256 public totalParticipants;

	// a map of userId to wei
	mapping(uint256 => uint256) public paymentsByUserId;

	// a map of user address to wei
	mapping(address => uint256) public paymentsByAddress;

	// total number of bonus stages.
	uint8 public totalStages;

	// max bonus percentage on first stage
	uint8 public stageMaxBonusPercentage;

	// number of wei-GIL tokens for 1 wei (18 decimals)
	uint256 public tokenPrice;

	// the team owns 25% of the tokens - 3 times more than token purchasers.
	uint8 public teamTokenRatio = 3;

	// GIL token address
	GilgameshToken public token;

	// if Ether or Token cap has been reached
	bool public isCapReached = false;

	// log when token sale has been initialized
	event LogTokenSaleInitialized(
		address indexed owner,
		address indexed fundOwnerWallet,
		uint256 startBlock,
		uint256 endBlock,
		uint256 creationBlock
	);

	// log each contribution
	event LogContribution(
		address indexed contributorAddress,
		address indexed invokerAddress,
		uint256 amount,
		uint256 totalRaised,
		uint256 userAssignedTokens,
		uint256 indexed userId
	);

	// log when crowd fund is finalized
	event LogFinalized(address owner, uint256 teamTokens);

	// Constructor
	function GilgameshTokenSale(
		uint256 _startBlock, // starting block number
		uint256 _endBlock, // ending block number
		address _fundOwnerWallet, // fund owner wallet address - transfer ether to this address during and after fund has been closed
		address _tokenOwnerWallet, // token fund owner wallet address - transfer GIL tokens to this address after fund is finalized
		uint8 _totalStages, // total number of bonus stages
		uint8 _stageMaxBonusPercentage, // maximum percentage for bonus in the first stage
		uint256 _tokenPrice, // price of each GIL token in wei
		address _gilgameshToken, // address of the gilgamesh ERC20 token contract
		uint256 _minimumCap, // minimum cap, minimum amount of wei to be raised
		uint256 _tokenCap // tokenCap
	)
	public
	validate_address(_fundOwnerWallet) {

		if (
			_gilgameshToken == 0x0 ||
			_tokenOwnerWallet == 0x0 ||
			// start block needs to be in the future
			_startBlock < getBlockNumber()  ||
			// start block should be less than ending block
			_startBlock >= _endBlock  ||
			// minimum number of stages is 2
			_totalStages < 2 ||
			// verify stage max bonus
			_stageMaxBonusPercentage < 0  ||
			_stageMaxBonusPercentage > 100 ||
			// stage bonus percentage needs to be devisible by number of stages
			_stageMaxBonusPercentage % (_totalStages - 1) != 0 ||
			// total number of blocks needs to be devisible by the total stages
			(_endBlock - _startBlock) % _totalStages != 0
		) revert();

		owner = msg.sender; // make the contract creator the `owner`
		token = GilgameshToken(_gilgameshToken);
		endBlock = _endBlock;
		startBlock = _startBlock;
		creationBlock = getBlockNumber();
		fundOwnerWallet = _fundOwnerWallet;
		tokenOwnerWallet = _tokenOwnerWallet;
		tokenPrice = _tokenPrice;
		totalStages = _totalStages;
		minimumCap = _minimumCap;
		stageMaxBonusPercentage = _stageMaxBonusPercentage;
		totalRaised = 0; //	total number of wei raised
		tokenCap = _tokenCap;

		// spread bonuses evenly between stages - e.g 27 / 9 = 3%
		uint spread = stageMaxBonusPercentage / (totalStages - 1);

		// loop through [10 to 1] => ( 9 to 0) * 3% = [27%, 24%, 21%, 18%, 15%, 12%, 9%, 6%, 3%, 0%]
		for (uint stageNumber = totalStages; stageNumber > 0; stageNumber--) {
			stageBonusPercentage.push((stageNumber - 1) * spread);
		}

		LogTokenSaleInitialized(
			owner,
			fundOwnerWallet,
			startBlock,
			endBlock,
			creationBlock
		);
	}

	// --------------
	// Public Funtions
	// --------------

	/// @notice Function to stop sale for an emergency.
	/// @dev Only Gilgamesh Dev can do it after it has been activated.
	function emergencyStopSale()
	public
	only_sale_active
	onlyOwner {
		saleStopped = true;
	}

	/// @notice Function to restart stopped sale.
	/// @dev Only Gilgamesh Dev can do it after it has been disabled and sale has stopped.
	/// can it's in a valid time range for sale
	function restartSale()
	public
	only_during_sale_period
	only_sale_stopped
	onlyOwner {
		// if sale is finalized fail
		if (saleFinalized) revert();
		saleStopped = false;
	}

	/// @notice Function to change the fund owner wallet address
	/// @dev Only Gilgamesh Dev can trigger this function
	function changeFundOwnerWalletAddress(address _fundOwnerWallet)
	public
	validate_address(_fundOwnerWallet)
	onlyOwner {
		fundOwnerWallet = _fundOwnerWallet;
	}

	/// @notice Function to change the token fund owner wallet address
	/// @dev Only Gilgamesh Dev can trigger this function
	function changeTokenOwnerWalletAddress(address _tokenOwnerWallet)
	public
	validate_address(_tokenOwnerWallet)
	onlyOwner {
		tokenOwnerWallet = _tokenOwnerWallet;
	}

	/// @notice finalize the sale
	/// @dev Only Gilgamesh Dev can trigger this function
	function finalizeSale()
	public
	onlyOwner {
		doFinalizeSale();
	}

	/// @notice change hard cap and if it reaches hard cap finalize sale
	function changeCap(uint256 _cap)
	public
	onlyOwner {
		if (_cap < minimumCap) revert();
		if (_cap <= totalRaised) revert();

		hardCap = _cap;

		if (totalRaised + minimumInvestment >= hardCap) {
			isCapReached = true;
			doFinalizeSale();
		}
	}

	/// @notice change minimum cap, in case Ether price fluctuates.
	function changeMinimumCap(uint256 _cap)
	public
	onlyOwner {
		if (minimumCap < _cap) revert();
		minimumCap = _cap;
	}

	/// @notice remove conttact only when sale has been finalized
	/// transfer all the fund to the contract owner
	/// @dev only Gilgamesh Dev can trigger this function
	function removeContract()
	public
	onlyOwner {
		if (!saleFinalized) revert();
		selfdestruct(msg.sender);
	}

	/// @notice only the owner is allowed to change the owner.
	/// @param _newOwner the address of the new owner
	function changeOwner(address _newOwner)
	public
	validate_address(_newOwner)
	onlyOwner {
		require(_newOwner != owner);
		owner = _newOwner;
	}

	/// @dev The fallback function is called when ether is sent to the contract
	/// Payable is a required solidity modifier to receive ether
	/// every contract only has one unnamed function
	/// 2300 gas available for this function
	/*function () public payable {
		return deposit();
	}*/

	/**
	* Pay on a behalf of the sender.
	*
	* @param customerId Identifier in the central database, UUID v4
	*
	*/
	/// @dev allow purchasers to deposit ETH for GIL Tokens.
	function depositForMySelf(uint256 userId)
	public
	only_sale_active
	minimum_contribution()
	payable {
		deposit(userId, msg.sender);
	}

	///	@dev deposit() is an public function that accepts a userId and userAddress
	///	contract receives ETH in return of GIL tokens
	function deposit(uint256 userId, address userAddress)
	public
	payable
	only_sale_active
	minimum_contribution()
	validate_address(userAddress) {
		// if it passes hard cap throw
		if (totalRaised + msg.value > hardCap) revert();

		uint256 userAssignedTokens = calculateTokens(msg.value);

		// if user tokens are 0 throw
		if (userAssignedTokens <= 0) revert();

		// if number of tokens exceed the token cap stop execution
		if (token.totalSupply() + userAssignedTokens > tokenCap) revert();

		// send funds to fund owner wallet
		if (!fundOwnerWallet.send(msg.value)) revert();

		// mint tokens for the user
		if (!token.mint(userAddress, userAssignedTokens)) revert();

		// save total number wei raised
		totalRaised = safeAdd(totalRaised, msg.value);

		// if cap is reached mark it
		if (totalRaised >= hardCap) {
			isCapReached = true;
		}

		// if token supply has exceeded or reached the token cap stop
		if (token.totalSupply() >= tokenCap) {
			isCapReached = true;
		}

		// increase the number of participants for the first transaction
		if (paymentsByUserId[userId] == 0) {
			totalParticipants++;
		}

		// increase the amount that the user has payed
		paymentsByUserId[userId] += msg.value;

		// total wei based on address
		paymentsByAddress[userAddress] += msg.value;

		// log contribution event
		LogContribution(
			userAddress,
			msg.sender,
			msg.value,
			totalRaised,
			userAssignedTokens,
			userId
		);
	}

	/// @notice calculate number of tokens need to be issued based on the amount received
	/// @param amount number of wei received
	function calculateTokens(uint256 amount)
	public
	view
	returns (uint256) {
		// return 0 if the crowd fund has ended or it hasn't started
		if (!isDuringSalePeriod(getBlockNumber())) return 0;

		// get the current stage number by block number
		uint8 currentStage = getStageByBlockNumber(getBlockNumber());

		// if current stage is more than the total stage return 0 - something is wrong
		if (currentStage > totalStages) return 0;

		// calculate number of tokens that needs to be issued for the purchaser
		uint256 purchasedTokens = safeMul(amount, tokenPrice);
		// calculate number of tokens that needs to be rewraded to the purchaser
		uint256 rewardedTokens = calculateRewardTokens(purchasedTokens, currentStage);
		// add purchasedTokens and rewardedTokens
		return safeAdd(purchasedTokens, rewardedTokens);
	}

	/// @notice calculate reward based on amount of tokens that will be issued to the purchaser
	/// @param amount number tokens that will be minted for the purchaser
	/// @param stageNumber number of current stage in the crowd fund process
	function calculateRewardTokens(uint256 amount, uint8 stageNumber)
	public
	view
	returns (uint256 rewardAmount) {
		// throw if it's invalid stage number
		if (
			stageNumber < 1 ||
			stageNumber > totalStages
		) revert();

		// get stage index for the array
		uint8 stageIndex = stageNumber - 1;

		// calculate reward - e.q 100 token creates 100 * 20 /100 = 20 tokens for reward
		return safeDiv(safeMul(amount, stageBonusPercentage[stageIndex]), 100);
	}

	/// @notice get crowd fund stage by block number
	/// @param _blockNumber block number
	function getStageByBlockNumber(uint256 _blockNumber)
	public
	view
	returns (uint8) {
		// throw error, if block number is out of range
		if (!isDuringSalePeriod(_blockNumber)) revert();

		uint256 totalBlocks = safeSub(endBlock, startBlock);
		uint256 numOfBlockPassed = safeSub(_blockNumber, startBlock);

		// since numbers round down we need to add one to number of stage
		return uint8(safeDiv(safeMul(totalStages, numOfBlockPassed), totalBlocks) + 1);
	}

	// --------------
	// Internal Funtions
	// --------------

	/// @notice check if the block number is during the sale period
	/// @param _blockNumber block number
	function isDuringSalePeriod(uint256 _blockNumber)
	view
	internal
	returns (bool) {
		return (_blockNumber >= startBlock && _blockNumber < endBlock);
	}

	/// @notice finalize the crowdfun sale
	/// @dev Only Gilgamesh Dev can trigger this function
	function doFinalizeSale()
	internal
	onlyOwner {

		if (saleFinalized) revert();

		// calculate the number of tokens that needs to be assigned to Gilgamesh team
		uint256 teamTokens = safeMul(token.totalSupply(), teamTokenRatio);

		if (teamTokens > 0){
			// mint tokens for the team
			if (!token.mint(tokenOwnerWallet, teamTokens)) revert();
		}

		// if there is any fund drain it
		if(this.balance > 0) {
			// send ether funds to fund owner wallet
			if (!fundOwnerWallet.send(this.balance)) revert();
		}

		// finalize sale flag
		saleFinalized = true;

		// stop sale flag
		saleStopped = true;

		// log finalized
		LogFinalized(tokenOwnerWallet, teamTokens);
	}

	/// @notice returns block.number
	function getBlockNumber() constant internal returns (uint) {
		return block.number;
	}

	// --------------
	// Modifiers
	// --------------

	/// continue only when sale has stopped
	modifier only_sale_stopped {
		if (!saleStopped) revert();
		_;
	}


	/// validates an address - currently only checks that it isn't null
	modifier validate_address(address _address) {
		if (_address == 0x0) revert();
		_;
	}

	/// continue only during the sale period
	modifier only_during_sale_period {
		// if block number is less than starting block fail
		if (getBlockNumber() < startBlock) revert();
		// if block number has reach to the end block fail
		if (getBlockNumber() >= endBlock) revert();
		// otherwise safe to continue
		_;
	}

	/// continue when sale is active and valid
	modifier only_sale_active {
		// if sale is finalized fail
		if (saleFinalized) revert();
		// if sale is stopped fail
		if (saleStopped) revert();
		// if cap is reached
		if (isCapReached) revert();
		// if block number is less than starting block fail
		if (getBlockNumber() < startBlock) revert();
		// if block number has reach to the end block fail
		if (getBlockNumber() >= endBlock) revert();
		// otherwise safe to continue
		_;
	}

	/// continue if minimum contribution has reached
	modifier minimum_contribution() {
		if (msg.value < minimumInvestment) revert();
		_;
	}

	/// continue when the invoker is the owner
	modifier onlyOwner() {
		if (msg.sender != owner) revert();
		_;
	}
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minter","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"creationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"_totalSupply","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":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newMinter","type":"address"}],"name":"changeMinter","outputs":[],"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":"_owner","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"lockAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"unlockAccount","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":"_owner","type":"address"}],"name":"burnUserTokens","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":"isTransferEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_isTransferEnabled","type":"bool"}],"name":"enableTransfers","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousAdmin","type":"address"},{"indexed":true,"name":"newAdmin","type":"address"}],"name":"AdminOwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousMinter","type":"address"},{"indexed":true,"name":"newMinter","type":"address"}],"name":"MinterOwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"status","type":"bool"}],"name":"TransferStatus","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":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]

60606040526007805460ff19166001179055341561001c57600080fd5b6000604080519081016040908152600f82527f47696c67616d65736820546f6b656e000000000000000000000000000000000060208301528051908101604090815260038083527f47494c0000000000000000000000000000000000000000000000000000000000602080850191909152600160a060020a0333166000908152908190529182208590556006859055601291908480516100c092916020019061013b565b506005805460ff191660ff841617905560048380516100e392916020019061013b565b50600a805460ff1916911515919091179055505043600955505060088054600160a060020a03191633600160a060020a03169081179091556007805461010060a860020a0319166101009092029190911790556101d6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017c57805160ff19168380011785556101a9565b828001600101855582156101a9579182015b828111156101a957825182559160200191906001019061018e565b506101b59291506101b9565b5090565b6101d391905b808211156101b557600081556001016101bf565b90565b610d99806101e56000396000f30060606040526004361061011c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461012157806307546172146101ab578063095ea7b3146101da578063176345141461021057806318160ddd1461023557806323b872dd146102485780632c4d4d1814610270578063313ce5671461029157806340c10f19146102ba57806347a64f44146102dc57806354fd4d50146102fb57806370a082311461030e5780638f2839701461032d578063905295e31461034c57806395d89b411461036b5780639bc853021461037e578063a9059cbb1461039d578063cca5dcb6146103bf578063dd62ed3e146103d2578063f41e60c5146103f7578063f851a4401461040f575b600080fd5b341561012c57600080fd5b610134610422565b60405160208082528190810183818151815260200191508051906020019080838360005b83811015610170578082015183820152602001610158565b50505050905090810190601f16801561019d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101b657600080fd5b6101be6104c0565b604051600160a060020a03909116815260200160405180910390f35b34156101e557600080fd5b6101fc600160a060020a03600435166024356104cf565b604051901515815260200160405180910390f35b341561021b57600080fd5b6102236105e2565b60405190815260200160405180910390f35b341561024057600080fd5b6102236105e8565b341561025357600080fd5b6101fc600160a060020a03600435811690602435166044356105ee565b341561027b57600080fd5b61028f600160a060020a0360043516610676565b005b341561029c57600080fd5b6102a4610733565b60405160ff909116815260200160405180910390f35b34156102c557600080fd5b6101fc600160a060020a036004351660243561073c565b34156102e757600080fd5b61028f600160a060020a0360043516610859565b341561030657600080fd5b6102a46108e8565b341561031957600080fd5b610223600160a060020a03600435166108f1565b341561033857600080fd5b61028f600160a060020a036004351661090c565b341561035757600080fd5b61028f600160a060020a03600435166109d9565b341561037657600080fd5b610134610a61565b341561038957600080fd5b61028f600160a060020a0360043516610acc565b34156103a857600080fd5b6101fc600160a060020a0360043516602435610b74565b34156103ca57600080fd5b6101fc610b9a565b34156103dd57600080fd5b610223600160a060020a0360043581169060243516610ba3565b341561040257600080fd5b61028f6004351515610bce565b341561041a57600080fd5b6101be610c44565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b505050505081565b600854600160a060020a031681565b600160a060020a0382166000908152600160208190526040822054849160ff909116151514156104fe57600080fd5b600a5460ff16151561050f57600080fd5b82158015906105425750600160a060020a0333811660009081526002602090815260408083209388168352929052205415155b1561054c57600080fd5b600160a060020a0333166000908152602081905260409020548390101561057657600091506105db565b600160a060020a03338116600081815260026020908152604080832094891680845294909152908190208690557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259086905190815260200160405180910390a3600191505b5092915050565b60095481565b60065490565b600a5460009060ff16151561060257600080fd5b600160a060020a03808516600090815260026020908152604080832033909416835292905220548290101561063657600080fd5b600160a060020a038085166000908152600260209081526040808320339094168352929052208054839003905561066e848484610c58565b949350505050565b80600160a060020a038116151561068c57600080fd5b60075433600160a060020a0390811661010090920416146106ac57600080fd5b600854600160a060020a03838116911614156106c757600080fd5b600854600160a060020a0380841691167fde77229fa00b529105f0b70b944b5ec6e7967121b91074f4ab65f9907bbf976b60405160405180910390a3506008805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60055460ff1681565b60085460009033600160a060020a0390811691161461075a57600080fd5b82600160a060020a038116151561077057600080fd5b600654838101101561078157600080fd5b600160a060020a03841660009081526020819052604090205483810110156107a857600080fd5b6006805484019055600160a060020a0380851660009081526020819052604080822080548701905533909216917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a383600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405190815260200160405180910390a35060019392505050565b600160a060020a038116600090815260016020819052604090912054829160ff9091161515141561088957600080fd5b81600160a060020a038116151561089f57600080fd5b60075433600160a060020a0390811661010090920416146108bf57600080fd5b5050600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b60075460ff1681565b600160a060020a031660009081526020819052604090205490565b80600160a060020a038116151561092257600080fd5b60075433600160a060020a03908116610100909204161461094257600080fd5b600754600160a060020a0383811661010090920416141561096257600080fd5b600754600160a060020a03808416916101009004167f1747af0dff66eb7165b467825c51774199b063a569a06cdea4565bac5d1be8cf60405160405180910390a35060078054600160a060020a039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b600160a060020a038116600090815260016020819052604090912054829160ff909116151514610a0857600080fd5b81600160a060020a0381161515610a1e57600080fd5b60075433600160a060020a039081166101009092041614610a3e57600080fd5b5050600160a060020a03166000908152600160205260409020805460ff19169055565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104b85780601f1061048d576101008083540402835291602001916104b8565b80600160a060020a0381161515610ae257600080fd5b60075433600160a060020a039081166101009092041614610b0257600080fd5b600160a060020a0382166000908152602081905260409020541515610b2657600080fd5b600654600160a060020a0383166000908152602081905260409020541115610b4d57600080fd5b50600160a060020a0316600090815260208190526040812080546006805491909103905555565b600a5460009060ff161515610b8857600080fd5b610b93338484610c58565b9392505050565b600a5460ff1681565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b60075433600160a060020a039081166101009092041614610bee57600080fd5b600a805460ff1916821515179081905533600160a060020a0316907f175c6709b75b0374a000960e3efe2fd0b15e523b8eff9f8afaf504b988157c939060ff16604051901515815260200160405180910390a250565b6007546101009004600160a060020a031681565b600082600160a060020a0381161515610c7057600080fd5b600160a060020a038516600090815260016020819052604090912054869160ff90911615151415610ca057600080fd5b600084111580610cc85750600160a060020a0386166000908152602081905260409020548490105b80610cec5750600160a060020a038516600090815260208190526040902054848101105b15610cfa5760009250610d64565b600160a060020a038087166000818152602081905260408082208054899003905592881680825290839020805488019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9087905190815260200160405180910390a3600192505b505093925050505600a165627a7a72305820d2fdbd80f95bb096fc491e347574331b8c4f6e3ede658747dba8032d852880cf0029

Deployed Bytecode

0x60606040526004361061011c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461012157806307546172146101ab578063095ea7b3146101da578063176345141461021057806318160ddd1461023557806323b872dd146102485780632c4d4d1814610270578063313ce5671461029157806340c10f19146102ba57806347a64f44146102dc57806354fd4d50146102fb57806370a082311461030e5780638f2839701461032d578063905295e31461034c57806395d89b411461036b5780639bc853021461037e578063a9059cbb1461039d578063cca5dcb6146103bf578063dd62ed3e146103d2578063f41e60c5146103f7578063f851a4401461040f575b600080fd5b341561012c57600080fd5b610134610422565b60405160208082528190810183818151815260200191508051906020019080838360005b83811015610170578082015183820152602001610158565b50505050905090810190601f16801561019d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101b657600080fd5b6101be6104c0565b604051600160a060020a03909116815260200160405180910390f35b34156101e557600080fd5b6101fc600160a060020a03600435166024356104cf565b604051901515815260200160405180910390f35b341561021b57600080fd5b6102236105e2565b60405190815260200160405180910390f35b341561024057600080fd5b6102236105e8565b341561025357600080fd5b6101fc600160a060020a03600435811690602435166044356105ee565b341561027b57600080fd5b61028f600160a060020a0360043516610676565b005b341561029c57600080fd5b6102a4610733565b60405160ff909116815260200160405180910390f35b34156102c557600080fd5b6101fc600160a060020a036004351660243561073c565b34156102e757600080fd5b61028f600160a060020a0360043516610859565b341561030657600080fd5b6102a46108e8565b341561031957600080fd5b610223600160a060020a03600435166108f1565b341561033857600080fd5b61028f600160a060020a036004351661090c565b341561035757600080fd5b61028f600160a060020a03600435166109d9565b341561037657600080fd5b610134610a61565b341561038957600080fd5b61028f600160a060020a0360043516610acc565b34156103a857600080fd5b6101fc600160a060020a0360043516602435610b74565b34156103ca57600080fd5b6101fc610b9a565b34156103dd57600080fd5b610223600160a060020a0360043581169060243516610ba3565b341561040257600080fd5b61028f6004351515610bce565b341561041a57600080fd5b6101be610c44565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b505050505081565b600854600160a060020a031681565b600160a060020a0382166000908152600160208190526040822054849160ff909116151514156104fe57600080fd5b600a5460ff16151561050f57600080fd5b82158015906105425750600160a060020a0333811660009081526002602090815260408083209388168352929052205415155b1561054c57600080fd5b600160a060020a0333166000908152602081905260409020548390101561057657600091506105db565b600160a060020a03338116600081815260026020908152604080832094891680845294909152908190208690557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259086905190815260200160405180910390a3600191505b5092915050565b60095481565b60065490565b600a5460009060ff16151561060257600080fd5b600160a060020a03808516600090815260026020908152604080832033909416835292905220548290101561063657600080fd5b600160a060020a038085166000908152600260209081526040808320339094168352929052208054839003905561066e848484610c58565b949350505050565b80600160a060020a038116151561068c57600080fd5b60075433600160a060020a0390811661010090920416146106ac57600080fd5b600854600160a060020a03838116911614156106c757600080fd5b600854600160a060020a0380841691167fde77229fa00b529105f0b70b944b5ec6e7967121b91074f4ab65f9907bbf976b60405160405180910390a3506008805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60055460ff1681565b60085460009033600160a060020a0390811691161461075a57600080fd5b82600160a060020a038116151561077057600080fd5b600654838101101561078157600080fd5b600160a060020a03841660009081526020819052604090205483810110156107a857600080fd5b6006805484019055600160a060020a0380851660009081526020819052604080822080548701905533909216917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a383600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405190815260200160405180910390a35060019392505050565b600160a060020a038116600090815260016020819052604090912054829160ff9091161515141561088957600080fd5b81600160a060020a038116151561089f57600080fd5b60075433600160a060020a0390811661010090920416146108bf57600080fd5b5050600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b60075460ff1681565b600160a060020a031660009081526020819052604090205490565b80600160a060020a038116151561092257600080fd5b60075433600160a060020a03908116610100909204161461094257600080fd5b600754600160a060020a0383811661010090920416141561096257600080fd5b600754600160a060020a03808416916101009004167f1747af0dff66eb7165b467825c51774199b063a569a06cdea4565bac5d1be8cf60405160405180910390a35060078054600160a060020a039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b600160a060020a038116600090815260016020819052604090912054829160ff909116151514610a0857600080fd5b81600160a060020a0381161515610a1e57600080fd5b60075433600160a060020a039081166101009092041614610a3e57600080fd5b5050600160a060020a03166000908152600160205260409020805460ff19169055565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104b85780601f1061048d576101008083540402835291602001916104b8565b80600160a060020a0381161515610ae257600080fd5b60075433600160a060020a039081166101009092041614610b0257600080fd5b600160a060020a0382166000908152602081905260409020541515610b2657600080fd5b600654600160a060020a0383166000908152602081905260409020541115610b4d57600080fd5b50600160a060020a0316600090815260208190526040812080546006805491909103905555565b600a5460009060ff161515610b8857600080fd5b610b93338484610c58565b9392505050565b600a5460ff1681565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b60075433600160a060020a039081166101009092041614610bee57600080fd5b600a805460ff1916821515179081905533600160a060020a0316907f175c6709b75b0374a000960e3efe2fd0b15e523b8eff9f8afaf504b988157c939060ff16604051901515815260200160405180910390a250565b6007546101009004600160a060020a031681565b600082600160a060020a0381161515610c7057600080fd5b600160a060020a038516600090815260016020819052604090912054869160ff90911615151415610ca057600080fd5b600084111580610cc85750600160a060020a0386166000908152602081905260409020548490105b80610cec5750600160a060020a038516600090815260208190526040902054848101105b15610cfa5760009250610d64565b600160a060020a038087166000818152602081905260408082208054899003905592881680825290839020805488019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9087905190815260200160405180910390a3600192505b505093925050505600a165627a7a72305820d2fdbd80f95bb096fc491e347574331b8c4f6e3ede658747dba8032d852880cf0029

Swarm Source

bzzr://d2fdbd80f95bb096fc491e347574331b8c4f6e3ede658747dba8032d852880cf
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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.