Indentation code. Add new methods to access products.

pragma solidity ^0.4.4;

contract Shop {

	struct Product {
		uint price;
		string name;
		uint stockBalance;
	}

    uint ownerWithdrawals;

	mapping (uint => Product) stock;

	uint[] products;

	address administrator;

	address owner;

	event AddProductEvent(uint id, uint price, string name);

	event DeleteProductEvent(uint id, uint price, string name);

	event BuyProductEvent(uint id);

    event LogWithdrawEvent(address main, uint quantity);

	function Shop(address administratorAddress)
		public
	{
		administrator = administratorAddress;
		owner = msg.sender;
	}

    modifier isOwner
    {
        require(msg.sender == owner);
        _;
    }

    modifier isAdministrator
    {
        require(msg.sender == administrator);
        _;
    }

	function getProductCount()
		constant
		returns (uint length)
	{
		return products.length;
	}

	function getProductIdAt(uint index)
		constant
		returns (uint id)
	{
		return products[index];
	}

	function getProduct(uint id)
		constant
		returns (string name, uint price, uint stockBalance)
	{
		Product product = stock[id];
		return (product.name,
			product.price,
			product.stockBalance);
	}

    function addProduct(uint id, uint price, string name)
   		public
   		isAdministrator
   	{
        stock[id].price = price;
        stock[id].stockBalance += 1;
        stock[id].name = name;
        products.push(id);
        AddProductEvent(id, price, name);

    }

    function deleteProduct(uint id)
    	public
    	isAdministrator
    {
        stock[id].price = 0;
        stock[id].stockBalance = 0;
        stock[id].name = "";
    }

    function buyProduct(uint id)
    	payable
    	public
    {
        require(stock[id].price > 0);
        require(stock[id].price <= msg.value);
        require(stock[id].stockBalance > 0);
        stock[id].stockBalance--;
        ownerWithdrawals += stock[id].price;
        BuyProductEvent(id);
    }

    function withdraw()
    	public
    	isOwner
    {

        if (ownerWithdrawals<=0) revert();

        ownerWithdrawals = 0;
        msg.sender.transfer(ownerWithdrawals);
        LogWithdrawEvent(msg.sender, ownerWithdrawals);

    }
}

pragma solidity ^0.4.4;

contract Shop {

	struct Product {
		uint price;
		string name;
		uint stockBalance;
	}

    uint ownerWithdrawals;

	mapping (uint => Product) public stock;

	uint[] public products;

	address administrator;

	address owner;

	event AddProductEvent(uint id, uint price, string name);

	event DeleteProductEvent(uint id, uint price, string name);

	event BuyProductEvent(uint id);

    event LogWithdrawEvent(address main, uint quantity);

	function Shop(address administratorAddress) public {
		administrator = administratorAddress;
		owner = msg.sender;
	}

    modifier isOwner {
        require(msg.sender == owner);
        _;
    }

    modifier isAdministrator {
        require(msg.sender == administrator);
        _;
    }

    function addProduct(uint id, uint price, string name) public isAdministrator{

        stock[id].price = price;
        stock[id].stockBalance += 1;
        stock[id].name = name;
        products.push(id);
        AddProductEvent(id, price, name);

    }

    function deleteProduct(uint id) public isAdministrator {
        stock[id].price = 0;
        stock[id].stockBalance = 0;
        stock[id].name = "";
    }

    function buyProduct(uint id) payable public{

        require(stock[id].price > 0);
        require(stock[id].price <= msg.value);
        require(stock[id].stockBalance > 0);
        stock[id].stockBalance--;
        ownerWithdrawals += stock[id].price;
        BuyProductEvent(id);
    }

    function withdraw() public isOwner {

        if (ownerWithdrawals<=0) revert();

        ownerWithdrawals = 0;
        msg.sender.transfer(ownerWithdrawals);
        LogWithdrawEvent(msg.sender, ownerWithdrawals);

    }
}


Delete Owned.sol

Delete Owned.sol

pragma solidity ^0.4.4;

// 所有者管理用コントラクト
contract Owned {
    address public owner; // オーナーアドレス

    // オーナー移転時のイベント
    event TransferOwnership(address old_addr, address new_addr);

    // オーナー限定メソッド用の修飾子
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    /**
     * コンストラクタ
     */
    function Owned() {
        owner = msg.sender; // コントラクト作成アドレスをオーナーとする
    }

    /**
     * オーナーを移転
     * @param new_addr 移転先のアドレス
     */
    function transferOwnership(address new_addr) onlyOwner {
        address old_addr = owner;
        owner = new_addr;
        TransferOwnership(old_addr, owner);
    }
}


AccountingLib updates

AccountingLib updates

// Accounting v0.1 (not the same as the 0.1 release of this library)

/// @title Accounting Lib - Accounting utilities
/// @author Piper Merriam - <pipermerriam@gmail.com>
library AccountingLib {
        /*
         *  Address: 0x947aaa72162d32135d2af1ed0c6d610d541829c3
         */
        struct Bank {
            mapping (address => uint) accountBalances;
        }

        /// @dev Low level method for adding funds to an account.  Protects against overflow.
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be added to.
        /// @param value The amount that should be added to the account.
        function addFunds(Bank storage self, address accountAddress, uint value) public {
                if (self.accountBalances[accountAddress] + value < self.accountBalances[accountAddress]) {
                        // Prevent Overflow.
                        throw;
                }
                self.accountBalances[accountAddress] += value;
        }

        event _Deposit(address indexed _from, address indexed accountAddress, uint value);
        /// @dev Function wrapper around the _Deposit event so that it can be used by contracts.  Can be used to log a deposit to an account.
        /// @param _from The address that deposited the funds.
        /// @param accountAddress The address of the account the funds were added to.
        /// @param value The amount that was added to the account.
        function Deposit(address _from, address accountAddress, uint value) public {
            _Deposit(_from, accountAddress, value);
        }

        /// @dev Safe function for depositing funds.  Returns boolean for whether the deposit was successful
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be added to.
        /// @param value The amount that should be added to the account.
        function deposit(Bank storage self, address accountAddress, uint value) public returns (bool) {
                addFunds(self, accountAddress, value);
                return true;
        }

        event _Withdrawal(address indexed accountAddress, uint value);

        /// @dev Function wrapper around the _Withdrawal event so that it can be used by contracts.  Can be used to log a withdrawl from an account.
        /// @param accountAddress The address of the account the funds were withdrawn from.
        /// @param value The amount that was withdrawn to the account.
        function Withdrawal(address accountAddress, uint value) public {
            _Withdrawal(accountAddress, value);
        }

        event _InsufficientFunds(address indexed accountAddress, uint value, uint balance);

        /// @dev Function wrapper around the _InsufficientFunds event so that it can be used by contracts.  Can be used to log a failed withdrawl from an account.
        /// @param accountAddress The address of the account the funds were to be withdrawn from.
        /// @param value The amount that was attempted to be withdrawn from the account.
        /// @param balance The current balance of the account.
        function InsufficientFunds(address accountAddress, uint value, uint balance) public {
            _InsufficientFunds(accountAddress, value, balance);
        }

        /// @dev Low level method for removing funds from an account.  Protects against underflow.
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be deducted from.
        /// @param value The amount that should be deducted from the account.
        function deductFunds(Bank storage self, address accountAddress, uint value) public {
                /*
                 *  Helper function that should be used for any reduction of
                 *  account funds.  It has error checking to prevent
                 *  underflowing the account balance which would be REALLY bad.
                 */
                if (value > self.accountBalances[accountAddress]) {
                        // Prevent Underflow.
                        throw;
                }
                self.accountBalances[accountAddress] -= value;
        }

        /// @dev Safe function for withdrawing funds.  Returns boolean for whether the deposit was successful as well as sending the amount in ether to the account address.
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be withdrawn from.
        /// @param value The amount that should be withdrawn from the account.
        function withdraw(Bank storage self, address accountAddress, uint value) public returns (bool) {
                /*
                 *  Public API for withdrawing funds.
                 */
                if (self.accountBalances[accountAddress] >= value) {
                        deductFunds(self, accountAddress, value);
                        if (!accountAddress.send(value)) {
                                // Potentially sending money to a contract that
                                // has a fallback function.  So instead, try
                                // tranferring the funds with the call api.
                                if (!accountAddress.call.value(value)()) {
                                        // Revert the entire transaction.  No
                                        // need to destroy the funds.
                                        throw;
                                }
                        }
                        return true;
                }
                return false;
        }

        uint constant DEFAULT_SEND_GAS = 100000;

        function sendRobust(address toAddress, uint value) public returns (bool) {
                sendRobust(toAddress, value, DEFAULT_SEND_GAS);
        }

        function sendRobust(address toAddress, uint value, uint maxGas) public returns (bool) {
                if (value > 0 && !toAddress.send(value)) {
                        // Potentially sending money to a contract that
                        // has a fallback function.  So instead, try
                        // tranferring the funds with the call api.
                        if (!toAddress.call.gas(maxGas).value(value)()) {
                                return false;
                        }
                }
                return true;
        }
}

// Accounting v0.1 (not the same as the 0.1 release of this library)

/// @title Accounting Lib - Accounting utilities
/// @author Piper Merriam - <pipermerriam@gmail.com>
library AccountingLib {
        /*
         *  Address: 0x947aaa72162d32135d2af1ed0c6d610d541829c3
         */
        struct Bank {
            mapping (address => uint) accountBalances;
        }

        /// @dev Low level method for adding funds to an account.  Protects against overflow.
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be added to.
        /// @param value The amount that should be added to the account.
        function addFunds(Bank storage self, address accountAddress, uint value) public {
                if (self.accountBalances[accountAddress] + value < self.accountBalances[accountAddress]) {
                        // Prevent Overflow.
                        throw;
                }
                self.accountBalances[accountAddress] += value;
        }

        event _Deposit(address indexed _from, address indexed accountAddress, uint value);
        /// @dev Function wrapper around the _Deposit event so that it can be used by contracts.  Can be used to log a deposit to an account.
        /// @param _from The address that deposited the funds.
        /// @param accountAddress The address of the account the funds were added to.
        /// @param value The amount that was added to the account.
        function Deposit(address _from, address accountAddress, uint value) public {
            _Deposit(_from, accountAddress, value);
        }

        /// @dev Safe function for depositing funds.  Returns boolean for whether the deposit was successful
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be added to.
        /// @param value The amount that should be added to the account.
        function deposit(Bank storage self, address accountAddress, uint value) public returns (bool) {
                addFunds(self, accountAddress, value);
                return true;
        }

        event _Withdrawal(address indexed accountAddress, uint value);

        /// @dev Function wrapper around the _Withdrawal event so that it can be used by contracts.  Can be used to log a withdrawl from an account.
        /// @param accountAddress The address of the account the funds were withdrawn from.
        /// @param value The amount that was withdrawn to the account.
        function Withdrawal(address accountAddress, uint value) public {
            _Withdrawal(accountAddress, value);
        }

        event _InsufficientFunds(address indexed accountAddress, uint value, uint balance);

        /// @dev Function wrapper around the _InsufficientFunds event so that it can be used by contracts.  Can be used to log a failed withdrawl from an account.
        /// @param accountAddress The address of the account the funds were to be withdrawn from.
        /// @param value The amount that was attempted to be withdrawn from the account.
        /// @param balance The current balance of the account.
        function InsufficientFunds(address accountAddress, uint value, uint balance) public {
            _InsufficientFunds(accountAddress, value, balance);
        }

        /// @dev Low level method for removing funds from an account.  Protects against underflow.
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be deducted from.
        /// @param value The amount that should be deducted from the account.
        function deductFunds(Bank storage self, address accountAddress, uint value) public {
                /*
                 *  Helper function that should be used for any reduction of
                 *  account funds.  It has error checking to prevent
                 *  underflowing the account balance which would be REALLY bad.
                 */
                if (value > self.accountBalances[accountAddress]) {
                        // Prevent Underflow.
                        throw;
                }
                self.accountBalances[accountAddress] -= value;
        }

        /// @dev Safe function for withdrawing funds.  Returns boolean for whether the deposit was successful as well as sending the amount in ether to the account address.
        /// @param self The Bank instance to operate on.
        /// @param accountAddress The address of the account the funds should be withdrawn from.
        /// @param value The amount that should be withdrawn from the account.
        function withdraw(Bank storage self, address accountAddress, uint value) public returns (bool) {
                /*
                 *  Public API for withdrawing funds.
                 */
                if (self.accountBalances[accountAddress] >= value) {
                        deductFunds(self, accountAddress, value);
                        if (!accountAddress.send(value)) {
                                // Potentially sending money to a contract that
                                // has a fallback function.  So instead, try
                                // tranferring the funds with the call api.
                                if (!accountAddress.call.value(value)()) {
                                        // Revert the entire transaction.  No
                                        // need to destroy the funds.
                                        throw;
                                }
                        }
                        return true;
                }
                return false;
        }

        function sendRobust(address toAddress, uint value) public returns (bool) {
                if (value > 0 && !toAddress.send(value)) {
                        // Potentially sending money to a contract that
                        // has a fallback function.  So instead, try
                        // tranferring the funds with the call api.
                        if (!toAddress.call.value(value)()) {
                                return false;
                        }
                }
                return true;
        }
}


contracts: correct hasSaleEnded to correct for paused, but not yet ended sale

pragma solidity ^0.4.17;

// ----------------------------------------------------------------------------
// Token Sale Implementation
//
// Copyright (c) 2017 OpenST Ltd.
// https://simpletoken.org/
//
// The MIT Licence.
// ----------------------------------------------------------------------------

import "./SimpleToken.sol";
import "./Trustee.sol";
import "./TokenSaleConfig.sol";
import "./OpsManaged.sol";
import "./Pausable.sol";
import "./SafeMath.sol";

//
// Implementation of the 1st token sale for Simple Token
//
// * Lifecycle *
// Initialization sequence should be as follow:
//    1. Deploy SimpleToken contract
//    2. Deploy Trustee contract
//    3. Deploy TokenSale contract
//    4. Set operationsAddress of SimpleToken contract to TokenSale contract
//    5. Set operationsAddress of Trustee contract to TokenSale contract
//    6. Set operationsAddress of TokenSale contract to some address
//    7. Transfer tokens from owner to TokenSale contract
//    8. Transfer tokens from owner to Trustee contract
//    9. Initialize TokenSale contract
//
// Pre-sale sequence:
//    - Set tokensPerKEther
//    - Set phase1AccountTokensMax
//    - Add presales
//    - Add allocations for founders, advisors, etc.
//    - Update whitelist
//
// After-sale sequence:
//    1. Finalize the TokenSale contract
//    2. Finalize the SimpleToken contract
//    3. Set operationsAddress of TokenSale contract to 0
//    4. Set operationsAddress of SimpleToken contract to 0
//    5. Set operationsAddress of Trustee contract to some address
//
// Anytime
//    - Add/Remove allocations
//

//
// Permissions, according to the ST key management specification.
//
//                                Owner    Admin   Ops
// initialize                       x
// changeWallet                              x
// updateWhitelist                                  x
// setTokensPerKEther                        x
// setPhase1AccountTokensMax                 x
// addPresale                                x
// pause / unpause                           x
// reclaimTokens                             x
// finalize                                  x
//

contract TokenSale is OpsManaged, Pausable, TokenSaleConfig { // Pausable is also Owned

    using SafeMath for uint256;

    // We keep track of whether the sale has been finalized, at which point
    // no additional contributions will be permitted.
    bool public finalized;

    // The sale end time is initially defined by the END_TIME constant but it
    // may get extended if the sale is paused.
    uint256 public endTime;
    uint256 public pausedTime;

    // Number of tokens per 1000 ETH. See TokenSaleConfig for details.
    uint256 public tokensPerKEther;

    // Keeps track of the maximum amount of tokens that an account is allowed to purchase in phase 1.
    uint256 public phase1AccountTokensMax;

    // Address where the funds collected during the sale will be forwarded.
    address public wallet;

    // Token contract that the sale contract will interact with.
    SimpleToken public tokenContract;

    // Trustee contract to hold on token balances. The following token pools will be held by trustee:
    //    - Founders
    //    - Advisors
    //    - Early investors
    //    - Presales
    Trustee public trusteeContract;

    // Total amount of tokens sold during presale + public sale. Excludes pre-sale bonuses.
    uint256 public totalTokensSold;

    // Total amount of tokens given as bonus during presale. Will influence accelerator token balance.
    uint256 public totalPresaleBase;
    uint256 public totalPresaleBonus;

    // Map of addresses that have been whitelisted in advance (and passed KYC).
    // The whitelist value indicates what phase (1 or 2) the address has been whitelisted for.
    // Addresses whitelisted for phase 1 can also contribute during phase 2.
    mapping(address => uint8) public whitelist;

    //
    // EVENTS
    //
    event Initialized();
    event PresaleAdded(address indexed _account, uint256 _baseTokens, uint256 _bonusTokens);
    event WhitelistUpdated(address indexed _account, uint8 _phase);
    event TokensPurchased(address indexed _beneficiary, uint256 _cost, uint256 _tokens);
    event TokensPerKEtherUpdated(uint256 _amount);
    event Phase1AccountTokensMaxUpdated(uint256 _tokens);
    event WalletChanged(address _newWallet);
    event TokensReclaimed(uint256 _amount);
    event Finalized();

    function TokenSale(SimpleToken _tokenContract, Trustee _trusteeContract, address _wallet) public
        OpsManaged()
    {
        require(address(_tokenContract) != address(0));
        require(address(_trusteeContract) != address(0));
        require(_wallet != address(0));

        require(PHASE1_START_TIME >= currentTime());
        require(PHASE2_START_TIME > PHASE1_START_TIME);
        require(END_TIME > PHASE2_START_TIME);
        require(TOKENS_PER_KETHER > 0);
        require(PHASE1_ACCOUNT_TOKENS_MAX > 0);

        // Basic check that the constants add up to TOKENS_MAX
        uint256 partialAllocations = TOKENS_FOUNDERS.add(TOKENS_ADVISORS).add(TOKENS_EARLY_INVESTORS);
        require(partialAllocations.add(TOKENS_SALE).add(TOKENS_ACCELERATOR_MAX).add(TOKENS_FUTURE) == TOKENS_MAX);

        wallet                 = _wallet;
        pausedTime             = 0;
        endTime                = END_TIME;
        finalized              = false;
        tokensPerKEther        = TOKENS_PER_KETHER;
        phase1AccountTokensMax = PHASE1_ACCOUNT_TOKENS_MAX;

        tokenContract   = _tokenContract;
        trusteeContract = _trusteeContract;
    }

    // Initialize is called to check some configuration parameters.
    // It expects that a certain amount of tokens have already been assigned to the sale contract address.
    function initialize() external onlyOwner returns (bool) {
        require(totalTokensSold == 0);
        require(totalPresaleBase == 0);
        require(totalPresaleBonus == 0);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(ownBalance == TOKENS_SALE);

        // Simple check to confirm that tokens are present
        uint256 trusteeBalance = tokenContract.balanceOf(address(trusteeContract));
        require(trusteeBalance >= TOKENS_FUTURE);

        Initialized();

        return true;
    }

    // Allows the admin to change the wallet where ETH contributions are sent.
    function changeWallet(address _wallet) external onlyAdmin returns (bool) {
        require(_wallet != address(0));
        require(_wallet != address(this));
        require(_wallet != address(trusteeContract));
        require(_wallet != address(tokenContract));

        wallet = _wallet;

        WalletChanged(wallet);

        return true;
    }

    //
    // TIME
    //

    function currentTime() public view returns (uint256 _currentTime) {
        return now;
    }

    modifier onlyBeforeSale() {
        require(hasSaleEnded() == false);
        require(currentTime() < PHASE1_START_TIME);
       _;
    }

    modifier onlyDuringSale() {
        require(hasSaleEnded() == false && currentTime() >= PHASE1_START_TIME);
        _;
    }

    function hasSaleEnded() private view returns (bool) {
        // if sold out or finalized, sale has ended
        if (totalTokensSold >= TOKENS_SALE || finalized) {
            return true;
        // else if sale is not paused (pausedTime = 0)
        // and endtime has past, then sale has ended
        } else if (pausedTime == 0 && currentTime() >= endTime) {
            return true;
        // otherwise it not past and not paused; or paused
        // and as such not ended
        } else {
            return false;
        }
    }

    //
    // WHITELIST
    //

    // Allows ops to add accounts to the whitelist.
    // Only those accounts will be allowed to contribute during the sale.
    // _phase = 1: Can contribute during phases 1 and 2 of the sale.
    // _phase = 2: Can contribute during phase 2 of the sale only.
    // _phase = 0: Cannot contribute at all (not whitelisted).
    function updateWhitelist(address _account, uint8 _phase) external onlyOps returns (bool) {
        require(_account != address(0));
        require(_phase <= 2);
        require(!finalized);

        whitelist[_account] = _phase;

        WhitelistUpdated(_account, _phase);

        return true;
    }

    //
    // PURCHASES / CONTRIBUTIONS
    //

    // Allows the admin to set the price for tokens sold during phases 1 and 2 of the sale.
    function setTokensPerKEther(uint256 _tokensPerKEther) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokensPerKEther > 0);

        tokensPerKEther = _tokensPerKEther;

        TokensPerKEtherUpdated(_tokensPerKEther);

        return true;
    }

    // Allows the admin to set the maximum amount of tokens that an account can buy during phase 1 of the sale.
    function setPhase1AccountTokensMax(uint256 _tokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokens > 0);

        phase1AccountTokensMax = _tokens;

        Phase1AccountTokensMaxUpdated(_tokens);

        return true;
    }

    function () external payable whenNotPaused onlyDuringSale {
        buyTokens();
    }

    // This is the main function to process incoming ETH contributions.
    function buyTokens() public payable whenNotPaused onlyDuringSale returns (bool) {
        require(msg.value >= CONTRIBUTION_MIN);
        require(msg.value <= CONTRIBUTION_MAX);
        require(totalTokensSold < TOKENS_SALE);

        // All accounts need to be whitelisted to purchase.
        uint8 whitelistedPhase = whitelist[msg.sender];
        require(whitelistedPhase > 0);

        uint256 tokensMax = TOKENS_SALE.sub(totalTokensSold);

        if (currentTime() < PHASE2_START_TIME) {
            // We are in phase 1 of the sale
            require(whitelistedPhase == 1);

            uint256 accountBalance = tokenContract.balanceOf(msg.sender);

            // Can only purchase up to a maximum per account.
            // Calculate how much of that amount is still available.
            uint256 phase1Balance = phase1AccountTokensMax.sub(accountBalance);

            if (phase1Balance < tokensMax) {
                tokensMax = phase1Balance;
            }
        }

        require(tokensMax > 0);

        uint256 tokensBought = msg.value.mul(tokensPerKEther).div(PURCHASE_DIVIDER);
        require(tokensBought > 0);

        uint256 cost = msg.value;
        uint256 refund = 0;

        if (tokensBought > tokensMax) {
            // Not enough tokens available for full contribution, we will do partial.
            tokensBought = tokensMax;

            // Calculate actual cost for partial amount of tokens.
            cost = tokensBought.mul(PURCHASE_DIVIDER).div(tokensPerKEther);

            // Calculate refund for contributor.
            refund = msg.value.sub(cost);
        }

        totalTokensSold = totalTokensSold.add(tokensBought);

        // Transfer tokens to the account
        require(tokenContract.transfer(msg.sender, tokensBought));

        // Issue a ETH refund for any unused portion of the funds.
        if (refund > 0) {
            msg.sender.transfer(refund);
        }

        // Transfer the contribution to the wallet
        wallet.transfer(msg.value.sub(refund));

        TokensPurchased(msg.sender, cost, tokensBought);

        // If all tokens available for sale have been sold out, finalize the sale automatically.
        if (totalTokensSold == TOKENS_SALE) {
            finalizeInternal();
        }

        return true;
    }

    //
    // PRESALES
    //

    // Allows the admin to record pre-sales, before the public sale starts. Presale base tokens come out of the
    // main sale pool (the 30% allocation) while bonus tokens come from the remaining token pool.
    function addPresale(address _account, uint256 _baseTokens, uint256 _bonusTokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_account != address(0));

        // Presales may have 0 bonus tokens but need to have a base amount of tokens sold.
        require(_baseTokens > 0);
        require(_bonusTokens < _baseTokens);

        // We do not count bonus tokens as part of the sale cap.
        totalTokensSold = totalTokensSold.add(_baseTokens);
        require(totalTokensSold <= TOKENS_SALE);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(_baseTokens <= ownBalance);

        totalPresaleBase  = totalPresaleBase.add(_baseTokens);
        totalPresaleBonus = totalPresaleBonus.add(_bonusTokens);

        // Move base tokens to the trustee
        require(tokenContract.transfer(address(trusteeContract), _baseTokens));

        // Presale allocations are marked as locked, they cannot be removed by the owner.
        uint256 tokens = _baseTokens.add(_bonusTokens);
        require(trusteeContract.grantAllocation(_account, tokens, false /* revokable */));

        PresaleAdded(_account, _baseTokens, _bonusTokens);

        return true;
    }

    //
    // PAUSE / UNPAUSE
    //

    // Allows the owner or admin to pause the sale for any reason.
    function pause() public onlyAdmin whenNotPaused {
        require(hasSaleEnded() == false);

        pausedTime = currentTime();

        return super.pause();
    }

    // Unpause may extend the end time of the public sale.
    // Note that we do not extend the start time of each phase.
    // Currently does not extend phase 1 end time, only final end time.
    function unpause() public onlyAdmin whenPaused {

        // If owner unpauses before sale starts, no impact on end time.
        uint256 current = currentTime();

        // If owner unpauses after sale starts, calculate how to extend end.
        if (current > PHASE1_START_TIME) {
            uint256 timeDelta;

            if (pausedTime < PHASE1_START_TIME) {
                // Pause was triggered before the start time, extend by time that
                // passed from proposed start time until now.
                timeDelta = current.sub(PHASE1_START_TIME);
            } else {
                // Pause was triggered while the sale was already started.
                // Extend end time by amount of time since pause.
                timeDelta = current.sub(pausedTime);
            }

            endTime = endTime.add(timeDelta);
        }

        pausedTime = 0;

        return super.unpause();
    }

    // Allows the admin to reclaim all tokens assigned to the sale contract.
    // This should only be used in case of emergency.
    function reclaimTokens() external onlyAdmin returns (bool) {
        uint256 ownBalance = tokenContract.balanceOf(address(this));

        address tokenOwner = tokenContract.owner();
        require(tokenOwner != address(0));

        require(tokenContract.transfer(tokenOwner, ownBalance));

        TokensReclaimed(ownBalance);

        return true;
    }

    // Allows the admin to finalize the sale and complete allocations.
    // The SimpleToken.admin also needs to finalize the token contract
    // so that token transfers are enabled.
    function finalize() external onlyAdmin returns (bool) {
        return finalizeInternal();
    }

    // The internal one will be called if tokens are sold out or
    // the end time for the sale is reached, in addition to being called
    // from the public version of finalize().
    function finalizeInternal() private returns (bool) {
        require(!finalized);

        finalized = true;

        Finalized();

        return true;
    }
}

pragma solidity ^0.4.17;

// ----------------------------------------------------------------------------
// Token Sale Implementation
//
// Copyright (c) 2017 OpenST Ltd.
// https://simpletoken.org/
//
// The MIT Licence.
// ----------------------------------------------------------------------------

import "./SimpleToken.sol";
import "./Trustee.sol";
import "./TokenSaleConfig.sol";
import "./OpsManaged.sol";
import "./Pausable.sol";
import "./SafeMath.sol";

//
// Implementation of the 1st token sale for Simple Token
//
// * Lifecycle *
// Initialization sequence should be as follow:
//    1. Deploy SimpleToken contract
//    2. Deploy Trustee contract
//    3. Deploy TokenSale contract
//    4. Set operationsAddress of SimpleToken contract to TokenSale contract
//    5. Set operationsAddress of Trustee contract to TokenSale contract
//    6. Set operationsAddress of TokenSale contract to some address
//    7. Transfer tokens from owner to TokenSale contract
//    8. Transfer tokens from owner to Trustee contract
//    9. Initialize TokenSale contract
//
// Pre-sale sequence:
//    - Set tokensPerKEther
//    - Set phase1AccountTokensMax
//    - Add presales
//    - Add allocations for founders, advisors, etc.
//    - Update whitelist
//
// After-sale sequence:
//    1. Finalize the TokenSale contract
//    2. Finalize the SimpleToken contract
//    3. Set operationsAddress of TokenSale contract to 0
//    4. Set operationsAddress of SimpleToken contract to 0
//    5. Set operationsAddress of Trustee contract to some address
//
// Anytime
//    - Add/Remove allocations
//

//
// Permissions, according to the ST key management specification.
//
//                                Owner    Admin   Ops
// initialize                       x
// changeWallet                              x
// updateWhitelist                                  x
// setTokensPerKEther                        x
// setPhase1AccountTokensMax                 x
// addPresale                                x
// pause / unpause                           x
// reclaimTokens                             x
// finalize                                  x
//

contract TokenSale is OpsManaged, Pausable, TokenSaleConfig { // Pausable is also Owned

    using SafeMath for uint256;

    // We keep track of whether the sale has been finalized, at which point
    // no additional contributions will be permitted.
    bool public finalized;

    // The sale end time is initially defined by the END_TIME constant but it
    // may get extended if the sale is paused.
    uint256 public endTime;
    uint256 public pausedTime;

    // Number of tokens per 1000 ETH. See TokenSaleConfig for details.
    uint256 public tokensPerKEther;

    // Keeps track of the maximum amount of tokens that an account is allowed to purchase in phase 1.
    uint256 public phase1AccountTokensMax;

    // Address where the funds collected during the sale will be forwarded.
    address public wallet;

    // Token contract that the sale contract will interact with.
    SimpleToken public tokenContract;

    // Trustee contract to hold on token balances. The following token pools will be held by trustee:
    //    - Founders
    //    - Advisors
    //    - Early investors
    //    - Presales
    Trustee public trusteeContract;

    // Total amount of tokens sold during presale + public sale. Excludes pre-sale bonuses.
    uint256 public totalTokensSold;

    // Total amount of tokens given as bonus during presale. Will influence accelerator token balance.
    uint256 public totalPresaleBase;
    uint256 public totalPresaleBonus;

    // Map of addresses that have been whitelisted in advance (and passed KYC).
    // The whitelist value indicates what phase (1 or 2) the address has been whitelisted for.
    // Addresses whitelisted for phase 1 can also contribute during phase 2.
    mapping(address => uint8) public whitelist;

    //
    // EVENTS
    //
    event Initialized();
    event PresaleAdded(address indexed _account, uint256 _baseTokens, uint256 _bonusTokens);
    event WhitelistUpdated(address indexed _account, uint8 _phase);
    event TokensPurchased(address indexed _beneficiary, uint256 _cost, uint256 _tokens);
    event TokensPerKEtherUpdated(uint256 _amount);
    event Phase1AccountTokensMaxUpdated(uint256 _tokens);
    event WalletChanged(address _newWallet);
    event TokensReclaimed(uint256 _amount);
    event Finalized();

    function TokenSale(SimpleToken _tokenContract, Trustee _trusteeContract, address _wallet) public
        OpsManaged()
    {
        require(address(_tokenContract) != address(0));
        require(address(_trusteeContract) != address(0));
        require(_wallet != address(0));

        require(PHASE1_START_TIME >= currentTime());
        require(PHASE2_START_TIME > PHASE1_START_TIME);
        require(END_TIME > PHASE2_START_TIME);
        require(TOKENS_PER_KETHER > 0);
        require(PHASE1_ACCOUNT_TOKENS_MAX > 0);

        // Basic check that the constants add up to TOKENS_MAX
        uint256 partialAllocations = TOKENS_FOUNDERS.add(TOKENS_ADVISORS).add(TOKENS_EARLY_INVESTORS);
        require(partialAllocations.add(TOKENS_SALE).add(TOKENS_ACCELERATOR_MAX).add(TOKENS_FUTURE) == TOKENS_MAX);

        wallet                 = _wallet;
        pausedTime             = 0;
        endTime                = END_TIME;
        finalized              = false;
        tokensPerKEther        = TOKENS_PER_KETHER;
        phase1AccountTokensMax = PHASE1_ACCOUNT_TOKENS_MAX;

        tokenContract   = _tokenContract;
        trusteeContract = _trusteeContract;
    }

    // Initialize is called to check some configuration parameters.
    // It expects that a certain amount of tokens have already been assigned to the sale contract address.
    function initialize() external onlyOwner returns (bool) {
        require(totalTokensSold == 0);
        require(totalPresaleBase == 0);
        require(totalPresaleBonus == 0);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(ownBalance == TOKENS_SALE);

        // Simple check to confirm that tokens are present
        uint256 trusteeBalance = tokenContract.balanceOf(address(trusteeContract));
        require(trusteeBalance >= TOKENS_FUTURE);

        Initialized();

        return true;
    }

    // Allows the admin to change the wallet where ETH contributions are sent.
    function changeWallet(address _wallet) external onlyAdmin returns (bool) {
        require(_wallet != address(0));
        require(_wallet != address(this));
        require(_wallet != address(trusteeContract));
        require(_wallet != address(tokenContract));

        wallet = _wallet;

        WalletChanged(wallet);

        return true;
    }

    //
    // TIME
    //

    function currentTime() public view returns (uint256 _currentTime) {
        return now;
    }

    modifier onlyBeforeSale() {
        require(hasSaleEnded() == false);
        require(currentTime() < PHASE1_START_TIME);
       _;
    }

    modifier onlyDuringSale() {
        require(hasSaleEnded() == false && currentTime() >= PHASE1_START_TIME);
        _;
    }

    function hasSaleEnded() private view returns (bool) {
        if (totalTokensSold >= TOKENS_SALE || currentTime() >= endTime || finalized) {
            return true;
        }

        return false;
    }

    //
    // WHITELIST
    //

    // Allows ops to add accounts to the whitelist.
    // Only those accounts will be allowed to contribute during the sale.
    // _phase = 1: Can contribute during phases 1 and 2 of the sale.
    // _phase = 2: Can contribute during phase 2 of the sale only.
    // _phase = 0: Cannot contribute at all (not whitelisted).
    function updateWhitelist(address _account, uint8 _phase) external onlyOps returns (bool) {
        require(_account != address(0));
        require(_phase <= 2);
        require(!finalized);

        whitelist[_account] = _phase;

        WhitelistUpdated(_account, _phase);

        return true;
    }

    //
    // PURCHASES / CONTRIBUTIONS
    //

    // Allows the admin to set the price for tokens sold during phases 1 and 2 of the sale.
    function setTokensPerKEther(uint256 _tokensPerKEther) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokensPerKEther > 0);

        tokensPerKEther = _tokensPerKEther;

        TokensPerKEtherUpdated(_tokensPerKEther);

        return true;
    }

    // Allows the admin to set the maximum amount of tokens that an account can buy during phase 1 of the sale.
    function setPhase1AccountTokensMax(uint256 _tokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokens > 0);

        phase1AccountTokensMax = _tokens;

        Phase1AccountTokensMaxUpdated(_tokens);

        return true;
    }

    function () external payable whenNotPaused onlyDuringSale {
        buyTokens();
    }

    // This is the main function to process incoming ETH contributions.
    function buyTokens() public payable whenNotPaused onlyDuringSale returns (bool) {
        require(msg.value >= CONTRIBUTION_MIN);
        require(msg.value <= CONTRIBUTION_MAX);
        require(totalTokensSold < TOKENS_SALE);

        // All accounts need to be whitelisted to purchase.
        uint8 whitelistedPhase = whitelist[msg.sender];
        require(whitelistedPhase > 0);

        uint256 tokensMax = TOKENS_SALE.sub(totalTokensSold);

        if (currentTime() < PHASE2_START_TIME) {
            // We are in phase 1 of the sale
            require(whitelistedPhase == 1);

            uint256 accountBalance = tokenContract.balanceOf(msg.sender);

            // Can only purchase up to a maximum per account.
            // Calculate how much of that amount is still available.
            uint256 phase1Balance = phase1AccountTokensMax.sub(accountBalance);

            if (phase1Balance < tokensMax) {
                tokensMax = phase1Balance;
            }
        }

        require(tokensMax > 0);

        uint256 tokensBought = msg.value.mul(tokensPerKEther).div(PURCHASE_DIVIDER);
        require(tokensBought > 0);

        uint256 cost = msg.value;
        uint256 refund = 0;

        if (tokensBought > tokensMax) {
            // Not enough tokens available for full contribution, we will do partial.
            tokensBought = tokensMax;

            // Calculate actual cost for partial amount of tokens.
            cost = tokensBought.mul(PURCHASE_DIVIDER).div(tokensPerKEther);

            // Calculate refund for contributor.
            refund = msg.value.sub(cost);
        }

        totalTokensSold = totalTokensSold.add(tokensBought);

        // Transfer tokens to the account
        require(tokenContract.transfer(msg.sender, tokensBought));

        // Issue a ETH refund for any unused portion of the funds.
        if (refund > 0) {
            msg.sender.transfer(refund);
        }

        // Transfer the contribution to the wallet
        wallet.transfer(msg.value.sub(refund));

        TokensPurchased(msg.sender, cost, tokensBought);

        // If all tokens available for sale have been sold out, finalize the sale automatically.
        if (totalTokensSold == TOKENS_SALE) {
            finalizeInternal();
        }

        return true;
    }

    //
    // PRESALES
    //

    // Allows the admin to record pre-sales, before the public sale starts. Presale base tokens come out of the
    // main sale pool (the 30% allocation) while bonus tokens come from the remaining token pool.
    function addPresale(address _account, uint256 _baseTokens, uint256 _bonusTokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_account != address(0));

        // Presales may have 0 bonus tokens but need to have a base amount of tokens sold.
        require(_baseTokens > 0);
        require(_bonusTokens < _baseTokens);

        // We do not count bonus tokens as part of the sale cap.
        totalTokensSold = totalTokensSold.add(_baseTokens);
        require(totalTokensSold <= TOKENS_SALE);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(_baseTokens <= ownBalance);

        totalPresaleBase  = totalPresaleBase.add(_baseTokens);
        totalPresaleBonus = totalPresaleBonus.add(_bonusTokens);

        // Move base tokens to the trustee
        require(tokenContract.transfer(address(trusteeContract), _baseTokens));

        // Presale allocations are marked as locked, they cannot be removed by the owner.
        uint256 tokens = _baseTokens.add(_bonusTokens);
        require(trusteeContract.grantAllocation(_account, tokens, false /* revokable */));

        PresaleAdded(_account, _baseTokens, _bonusTokens);

        return true;
    }

    //
    // PAUSE / UNPAUSE
    //

    // Allows the owner or admin to pause the sale for any reason.
    function pause() public onlyAdmin whenNotPaused {
        require(hasSaleEnded() == false);

        pausedTime = currentTime();

        return super.pause();
    }

    // Unpause may extend the end time of the public sale.
    // Note that we do not extend the start time of each phase.
    // Currently does not extend phase 1 end time, only final end time.
    function unpause() public onlyAdmin whenPaused {

        // If owner unpauses before sale starts, no impact on end time.
        uint256 current = currentTime();

        // If owner unpauses after sale starts, calculate how to extend end.
        if (current > PHASE1_START_TIME) {
            uint256 timeDelta;

            if (pausedTime < PHASE1_START_TIME) {
                // Pause was triggered before the start time, extend by time that
                // passed from proposed start time until now.
                timeDelta = current.sub(PHASE1_START_TIME);
            } else {
                // Pause was triggered while the sale was already started.
                // Extend end time by amount of time since pause.
                timeDelta = current.sub(pausedTime);
            }

            endTime = endTime.add(timeDelta);
        }

        pausedTime = 0;

        return super.unpause();
    }

    // Allows the admin to reclaim all tokens assigned to the sale contract.
    // This should only be used in case of emergency.
    function reclaimTokens() external onlyAdmin returns (bool) {
        uint256 ownBalance = tokenContract.balanceOf(address(this));

        address tokenOwner = tokenContract.owner();
        require(tokenOwner != address(0));

        require(tokenContract.transfer(tokenOwner, ownBalance));

        TokensReclaimed(ownBalance);

        return true;
    }

    // Allows the admin to finalize the sale and complete allocations.
    // The SimpleToken.admin also needs to finalize the token contract
    // so that token transfers are enabled.
    function finalize() external onlyAdmin returns (bool) {
        return finalizeInternal();
    }

    // The internal one will be called if tokens are sold out or
    // the end time for the sale is reached, in addition to being called
    // from the public version of finalize().
    function finalizeInternal() private returns (bool) {
        require(!finalized);

        finalized = true;

        Finalized();

        return true;
    }
}


Improved checks for ICO starting and ending blocks; Added an event when tokens are claimed; Now many token variables are constant;

pragma solidity ^0.4.13;

interface TokenERC20 {

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    function balanceOf(address _owner) constant returns (uint256 balance);
}

interface TokenNotifier {

    function receiveApproval(address from, uint256 _amount, address _token, bytes _data);
}

/**
 * @title SafeMath (from https://github.com/OpenZeppelin/zeppelin-solidity/blob/4d91118dd964618863395dcca25a50ff137bf5b6/contracts/math/SafeMath.sol)
 * @dev Math operations with safety checks that throw on error
 */
contract SafeMath {

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

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

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

contract Owned {

    address owner;

    function Owned() { owner = msg.sender; }

    modifier onlyOwner { require(msg.sender == owner); _; }
}

contract PersianToken is TokenERC20, Owned, SafeMath {

    // The actual total supply is not constant and it will be updated with the real redeemed tokens once the ICO is over
    uint256 public totalSupply = 0;
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    uint8 public constant decimals = 18;
    string public constant name = 'Persian';
    string public constant symbol = 'PRS';
    string public constant version = '1.0.0';

    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] < _value) return false;
        balances[msg.sender] = safeSub(balances[msg.sender], _value);
        balances[_to] = safeAdd(balances[_to], _value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if(balances[msg.sender] < _value || allowed[_from][msg.sender] < _value) return false;
        balances[_to] = safeAdd(balances[_to], _value);
        balances[_from] = safeSub(balances[_from], _value);
        allowed[_from][msg.sender] = safeSub(allowed[_from][msg.sender], _value);
        Transfer(_from, _to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
        if(!approve(_spender, _value)) return false;
        TokenNotifier(_spender).receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }
}

contract TokenICO is PersianToken {

    uint256 public icoStartBlock;
    uint256 public icoEndBlock;
    uint256 public totalContributions;
    mapping (address => uint256) public contributions;

    // At max 300.000 Persian (with 18 decimals) will be ever generated from this ICO
    uint256 public constant maxTotalSupply = 300000 * 10**18;

    event Contributed(address indexed _contributor, uint256 _value, uint256 _estimatedTotalTokenBalance);
    event Claimed(address indexed _contributor, uint256 _value);

    function contribute() onlyDuringICO payable external returns (bool success) {
        totalContributions = safeAdd(totalContributions, msg.value);
        contributions[msg.sender] = safeAdd(contributions[msg.sender], msg.value);
        Contributed(msg.sender, msg.value, estimateBalanceOf(msg.sender));
        return true;
    }

    function claimToken() onlyAfterICO external returns (bool success) {
        uint256 balance = estimateBalanceOf(msg.sender);
        contributions[msg.sender] = 0;
        balances[msg.sender] = balance;
        totalSupply = safeAdd(totalSupply, balance);
        require(totalSupply <= maxTotalSupply);
        Claimed(msg.sender, balance);
        return true;
    }

    function redeemEther() onlyAfterICO onlyOwner external  {
        owner.transfer(this.balance);
    }

    function estimateBalanceOf(address _owner) constant returns (uint256 estimatedTokens) {
        return contributions[_owner] > 0 ? safeMul( maxTotalSupply / totalContributions, contributions[_owner]) : 0;
    }

    // This check is an helper function for ÐApp to check the effect of the NEXT tx, NOT simply the current state of the contract
    function isICOOpen() constant returns (bool _open) {
        return block.number >= (icoStartBlock - 1) && !isICOEnded();
    }

    // This check is an helper function for ÐApp to check the effect of the NEXT tx, NOT simply the current state of the contract
    function isICOEnded() constant returns (bool _ended) {
        return block.number >= icoEndBlock;
    }

    modifier onlyDuringICO {
        require(block.number >= icoStartBlock && block.number <= icoEndBlock); _;
    }

    modifier onlyAfterICO {
        require(block.number > icoEndBlock); _;
    }
}

contract PersianTokenICO is TokenICO {

    function PersianTokenICO(uint256 _icoStartBlock, uint256 _icoEndBlock) {
        icoStartBlock = _icoStartBlock;
        icoEndBlock = _icoEndBlock;
    }

    function () onlyDuringICO payable {
        totalContributions = safeAdd(totalContributions, msg.value);
        contributions[msg.sender] = safeAdd(contributions[msg.sender], msg.value);
        Contributed(msg.sender, msg.value, estimateBalanceOf(msg.sender));
    }

}

pragma solidity ^0.4.13;

interface TokenERC20 {

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    function balanceOf(address _owner) constant returns (uint256 balance);
}

interface TokenNotifier {

    function receiveApproval(address from, uint256 _amount, address _token, bytes _data);
}

/**
 * @title SafeMath (from https://github.com/OpenZeppelin/zeppelin-solidity/blob/4d91118dd964618863395dcca25a50ff137bf5b6/contracts/math/SafeMath.sol)
 * @dev Math operations with safety checks that throw on error
 */
contract SafeMath {

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

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

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

contract Owned {

    address owner;

    function Owned() { owner = msg.sender; }

    modifier onlyOwner { require(msg.sender == owner); _; }
}

contract PersianToken is TokenERC20, Owned, SafeMath {

    uint8 public decimals;
    uint256 public totalSupply;
    uint256 public maxTotalSupply;
    string public name;
    string public symbol;
    string public version;
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] < _value) return false;
        balances[msg.sender] = safeSub(balances[msg.sender], _value);
        balances[_to] = safeAdd(balances[_to], _value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if(balances[msg.sender] < _value || allowed[_from][msg.sender] < _value) return false;
        balances[_to] = safeAdd(balances[_to], _value);
        balances[_from] = safeSub(balances[_from], _value);
        allowed[_from][msg.sender] = safeSub(allowed[_from][msg.sender], _value);
        Transfer(_from, _to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
        if(!approve(_spender, _value)) return false;
        TokenNotifier(_spender).receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }
}

contract TokenICO is PersianToken {

    uint256 public icoStartBlock;
    uint256 public icoEndBlock;
    uint256 public totalContributions;
    mapping (address => uint256) public contributions;

    event Contributed(address indexed _contributor, uint256 _value, uint256 _estimatedTotalTokenBalance);

    function contribute() onlyDuringICO payable external returns (bool success) {
        totalContributions = safeAdd(totalContributions, msg.value);
        contributions[msg.sender] = safeAdd(contributions[msg.sender], msg.value);
        Contributed(msg.sender, msg.value, estimateBalanceOf(msg.sender));
        return true;
    }

    function claimToken() onlyAfterICO external returns (bool success) {
        uint256 balance = estimateBalanceOf(msg.sender);
        contributions[msg.sender] = 0;
        balances[msg.sender] = balance;
        totalSupply = safeAdd(totalSupply, balance);
        require(totalSupply <= maxTotalSupply);
        return true;
    }

    function redeemEther() onlyAfterICO onlyOwner external  {
        owner.transfer(this.balance);
    }

    function estimateBalanceOf(address _owner) constant returns (uint256 estimatedTokens) {
        return contributions[_owner] > 0 ? safeMul( maxTotalSupply / totalContributions, contributions[_owner]) : 0;
    }

    function isICOEnded() constant returns (bool _ended) {
        return block.number > icoEndBlock;
    }

    function isICOOpen() constant returns (bool _open) {
        return block.number >= icoStartBlock && block.number <= icoEndBlock;
    }

    modifier onlyDuringICO {
        require(block.number >= icoStartBlock && block.number <= icoEndBlock); _;
    }

    modifier onlyAfterICO {
        require(block.number > icoEndBlock); _;
    }
}

contract PersianTokenICO is TokenICO {

    function PersianTokenICO(uint256 _icoStartBlock, uint256 _icoEndBlock) {
        decimals = 18;
        // At max 300.000 Persian will be generated from this ICO
        maxTotalSupply = 300000 * 10**18;
        // The actual total supply will be updated with the real redeemed tokens once the ICO is over
        totalSupply = 0;
        name = 'Persian';
        symbol = 'PRS';
        version = '1.0.0';
        icoStartBlock = _icoStartBlock;
        icoEndBlock = _icoEndBlock;
    }

    function () onlyDuringICO payable {
        totalContributions = safeAdd(totalContributions, msg.value);
        contributions[msg.sender] = safeAdd(contributions[msg.sender], msg.value);
        Contributed(msg.sender, msg.value, estimateBalanceOf(msg.sender));
    }

}


caution test _crowdsale param is not address 0

/*

  Contract to implement Rouge ERC20 tokens for the Rouge Project.
  They are based on StandardToken from (https://github.com/ConsenSys/Tokens).

*/

import "./EIP20.sol";

pragma solidity ^0.4.23;

contract RGEToken is EIP20 {

    /* ERC20 */
    string public name = 'Rouge';
    string public symbol = 'RGE';
    uint8 public decimals = 6;

    /* RGEToken */
    address owner;
    address public crowdsale;
    uint public endTGE;
    string public version = 'v0.2';
    uint256 public totalSupply = 1000000000 * 10**uint(decimals);
    uint256 public   reserveY1 =  300000000 * 10**uint(decimals);
    uint256 public   reserveY2 =  200000000 * 10**uint(decimals);

    modifier onlyBy(address _account) {
        require(msg.sender == _account);
        _;
    }

    constructor(uint _endTGE) EIP20 (totalSupply, name, decimals, symbol) public {
        owner = msg.sender;
        endTGE = _endTGE;
        crowdsale = address(0);
    }

    function startCrowdsaleY0(address _crowdsale) onlyBy(owner) public {
        require(_crowdsale != address(0));
        require(crowdsale == address(0));
        require(now < endTGE);
        crowdsale = _crowdsale;
        balances[crowdsale] = totalSupply - reserveY1 - reserveY2;
        emit Transfer(address(0), crowdsale, balances[crowdsale]);
    }

    function startCrowdsaleY1(address _crowdsale) onlyBy(owner) public {
        require(_crowdsale != address(0));
        require(crowdsale == address(0));
        require(reserveY1 > 0);
        require(now >= endTGE + 31536000); /* Y+1 crowdsale can only start after a year */
        crowdsale = _crowdsale;
        balances[crowdsale] = reserveY1;
        emit Transfer(address(0), crowdsale, reserveY1);
        reserveY1 = 0;
    }

    function startCrowdsaleY2(address _crowdsale) onlyBy(owner) public {
        require(_crowdsale != address(0));
        require(crowdsale == address(0));
        require(reserveY2 > 0);
        require(now >= endTGE + 63072000); /* Y+2 crowdsale can only start after 2 years */
        crowdsale = _crowdsale;
        balances[crowdsale] = reserveY2;
        emit Transfer(address(0), crowdsale, reserveY2);
        reserveY2 = 0;
    }

    // in practice later than end of TGE to let people withdraw
    function endCrowdsale() onlyBy(owner) public {
        require(crowdsale != address(0));
        require(now > endTGE);
        reserveY2 += balances[crowdsale];
        emit Transfer(crowdsale, address(0), balances[crowdsale]);
        balances[crowdsale] = 0;
        crowdsale = address(0);
    }

    event Burn(address indexed burner, uint256 value);

    function burn(uint256 _value) public returns (bool success) {
        require(_value > 0);
        require(balances[msg.sender] >= _value);
        balances[msg.sender] -= _value;
        totalSupply -= _value;
        emit Transfer(msg.sender, address(0), _value);
        emit Burn(msg.sender, _value);
        return true;
    }

}

/*

  Contract to implement Rouge ERC20 tokens for the Rouge Project.
  They are based on StandardToken from (https://github.com/ConsenSys/Tokens).

*/

import "./EIP20.sol";

pragma solidity ^0.4.23;

contract RGEToken is EIP20 {

    /* ERC20 */
    string public name = 'Rouge';
    string public symbol = 'RGE';
    uint8 public decimals = 6;

    /* RGEToken */
    address owner;
    address public crowdsale;
    uint public endTGE;
    string public version = 'v0.2';
    uint256 public totalSupply = 1000000000 * 10**uint(decimals);
    uint256 public   reserveY1 =  300000000 * 10**uint(decimals);
    uint256 public   reserveY2 =  200000000 * 10**uint(decimals);

    modifier onlyBy(address _account) {
        require(msg.sender == _account);
        _;
    }

    constructor(uint _endTGE) EIP20 (totalSupply, name, decimals, symbol) public {
        owner = msg.sender;
        endTGE = _endTGE;
        crowdsale = address(0);
    }

    function startCrowdsaleY0(address _crowdsale) onlyBy(owner) public {
        require(crowdsale == address(0));
        require(now < endTGE);
        crowdsale = _crowdsale;
        balances[crowdsale] = totalSupply - reserveY1 - reserveY2;
        emit Transfer(address(0), crowdsale, balances[crowdsale]);
    }

    function startCrowdsaleY1(address _crowdsale) onlyBy(owner) public {
        require(crowdsale == address(0));
        require(reserveY1 > 0);
        require(now >= endTGE + 31536000); /* Y+1 crowdsale can only start after a year */
        crowdsale = _crowdsale;
        balances[crowdsale] = reserveY1;
        emit Transfer(address(0), crowdsale, reserveY1);
        reserveY1 = 0;
    }

    function startCrowdsaleY2(address _crowdsale) onlyBy(owner) public {
        require(crowdsale == address(0));
        require(reserveY2 > 0);
        require(now >= endTGE + 63072000); /* Y+2 crowdsale can only start after 2 years */
        crowdsale = _crowdsale;
        balances[crowdsale] = reserveY2;
        emit Transfer(address(0), crowdsale, reserveY2);
        reserveY2 = 0;
    }

    // in practice later than end of TGE to let people withdraw
    function endCrowdsale() onlyBy(owner) public {
        require(crowdsale != address(0));
        require(now > endTGE);
        reserveY2 += balances[crowdsale];
        emit Transfer(crowdsale, address(0), balances[crowdsale]);
        balances[crowdsale] = 0;
        crowdsale = address(0);
    }

    event Burn(address indexed burner, uint256 value);

    function burn(uint256 _value) public returns (bool success) {
        require(_value > 0);
        require(balances[msg.sender] >= _value);
        balances[msg.sender] -= _value;
        totalSupply -= _value;
        emit Transfer(msg.sender, address(0), _value);
        emit Burn(msg.sender, _value);
        return true;
    }

}