contract NamiTrade{
    using SafeMath for uint256;
    
    uint public minNac = 0; // min NAC deposit
    uint public minWithdraw =  10 * 10**18;
    uint public maxWithdraw = 1000000 * 10**18; // max NAC withdraw one time
    
    constructor(address _escrow, address _namiMultiSigWallet, address _namiAddress) public {
        require(_namiMultiSigWallet != 0x0);
        escrow = _escrow;
        namiMultiSigWallet = _namiMultiSigWallet;
        NamiAddr = _namiAddress; 
    }
    
    
    // balance of pool
    uint public NetfBalance;
    /**
     * NetfRevenueBalance:      NetfRevenue[_roundIndex].currentNAC
     * NlfBalance:              NLFunds[currentRound].currentNAC
     * NlfRevenueBalance:       listSubRoundNLF[currentRound][_subRoundIndex].totalNacInSubRound
     */

    
    // escrow has exclusive priveleges to call administrative
    // functions on this contract.
    address public escrow;

    // Gathered funds can be withdraw only to namimultisigwallet's address.
    address public namiMultiSigWallet;
    
    /// address of Nami token
    address public NamiAddr;
    
    modifier onlyEscrow() {
        require(msg.sender == escrow);
        _;
    }
    
    modifier onlyNami {
        require(msg.sender == NamiAddr);
        _;
    }
    
    modifier onlyNamiMultisig {
        require(msg.sender == namiMultiSigWallet);
        _;
    }
    
    modifier onlyController {
        require(isController[msg.sender] == true);
        _;
    }
    
    
    /*
    *
    * list setting function
    */
    mapping(address => bool) public isController;
    
    
    
    // set controller address
    /**
     * make new controller
     * require input address is not a controller
     * execute any time in sc state
     */
    function setController(address _controller)
        public
        onlyEscrow
    {
        require(!isController[_controller]);
        isController[_controller] = true;
    }
    
    /**
     * remove controller
     * require input address is a controller
     * execute any time in sc state
     */
    function removeController(address _controller)
        public
        onlyEscrow
    {
        require(isController[_controller]);
        isController[_controller] = false;
    }
    
    
    // change minimum nac to deposit
    function changeMinNac(uint _minNAC) public
        onlyEscrow
    {
        require(_minNAC != 0);
        minNac = _minNAC;
    }
    
    // change escrow
    function changeEscrow(address _escrow) public
        onlyNamiMultisig
    {
        require(_escrow != 0x0);
        escrow = _escrow;
    }
    
    
    // min and max for withdraw nac
    function changeMinWithdraw(uint _minWithdraw) public
        onlyEscrow
    {
        require(_minWithdraw != 0);
        minWithdraw = _minWithdraw;
    }
    
    function changeMaxWithdraw(uint _maxNac) public
        onlyEscrow
    {
        require(_maxNac != 0);
        maxWithdraw = _maxNac;
    }
    
    /// @dev withdraw ether to nami multisignature wallet, only escrow can call
    /// @param _amount value ether in wei to withdraw
    function withdrawEther(uint _amount) public
        onlyEscrow
    {
        require(namiMultiSigWallet != 0x0);
        // Available at any phase.
        if (address(this).balance > 0) {
            namiMultiSigWallet.transfer(_amount);
        }
    }
    
    
    /// @dev withdraw NAC to nami multisignature wallet, only escrow can call
    /// @param _amount value NAC to withdraw
    function withdrawNac(uint _amount) public
        onlyEscrow
    {
        require(namiMultiSigWallet != 0x0);
        // Available at any phase.
        NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
        if (namiToken.balanceOf(address(this)) > 0) {
            namiToken.transfer(namiMultiSigWallet, _amount);
        }
    }
    
    /*
    *
    *
    * List event
    */
    event Deposit(address indexed user, uint amount, uint timeDeposit);
    event Withdraw(address indexed user, uint amount, uint timeWithdraw);
    
    event PlaceBuyFciOrder(address indexed investor, uint amount, uint timePlaceOrder);
    event PlaceSellFciOrder(address indexed investor, uint amount, uint timePlaceOrder);
    event InvestToNLF(address indexed investor, uint amount, uint timeInvest);
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////fci token function///////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    string public name = "Nami Trade";
    string public symbol = "FCI-Test";
    uint8 public decimals = 18;
    
    uint256 public totalSupply;
    
    //  paus phrase to compute ratio fci
    bool public isPause;
    
    // time expires of price fci
    uint256 public timeExpires;
    
    // price fci : if 1 fci = 2 nac => priceFci = 2000000
    uint public fciDecimals = 1000000;
    uint256 public priceFci;
    
    // This creates an array with all balances
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;

    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint256 value);

    // This notifies clients about the amount burnt
    event Burn(address indexed from, uint256 value);
    
    // This notifies someone buy fci by NAC
    event BuyFci(address investor, uint256 valueNac, uint256 valueFci, uint timeBuyFci);
    event SellFci(address investor, uint256 valueNac, uint256 valueFci, uint timeSellFci);
    
    modifier onlyRunning {
        require(isPause == false);
        _;
    }
    
    
    /**
     * controller update balance of Netf to smart contract
     */
    function addNacToNetf(uint _valueNac) public onlyController {
        NetfBalance = NetfBalance.add(_valueNac);
    }
    
    
    /**
     * controller update balance of Netf to smart contract
     */
    function removeNacFromNetf(uint _valueNac) public onlyController {
        NetfBalance = NetfBalance.sub(_valueNac);
    }
    
    //////////////////////////////////////////////////////buy and sell fci function//////////////////////////////////////////////////////////
    /**
    *  Setup pause phrase
    */
    function changePause() public onlyController {
        isPause = !isPause;
    }
    
    /**
     * 
     * 
     * update price fci daily
     */
     function updatePriceFci(uint _price, uint _timeExpires) onlyController public {
         require(now > timeExpires);
         priceFci = _price;
         timeExpires = _timeExpires;
     }
    
    /**
     * before buy users need to place buy Order
     * function buy fci
     * only controller can execute in phrase running
     */
    function buyFci(address _buyer, uint _valueNac) onlyController public {
        // require fci is Running
        require(isPause == false && now < timeExpires);
        // require buyer not is 0x0 address
        require(_buyer != 0x0);
        require( _valueNac * fciDecimals > priceFci);
        uint fciReceive = (_valueNac.mul(fciDecimals))/priceFci;
        
        // construct fci
        balanceOf[_buyer] = balanceOf[_buyer].add(fciReceive);
        totalSupply = totalSupply.add(fciReceive);
        NetfBalance = NetfBalance.add(_valueNac);
        
        emit Transfer(address(this), _buyer, fciReceive);
        emit BuyFci(_buyer, _valueNac, fciReceive, now);
    }
    
    
    /**
     * 
     * before controller buy fci for user
     * user nead to place sell order
     */
    function placeSellFciOrder(uint _valueFci) onlyRunning public {
        require(balanceOf[msg.sender] >= _valueFci && _valueFci > 0);
        _transfer(msg.sender, address(this), _valueFci);
        emit PlaceSellFciOrder(msg.sender, _valueFci, now);
    }
    
    /**
     * 
     * function sellFci
     * only controller can execute in phare running
     */
    function sellFci(address _seller, uint _valueFci) onlyController public {
        // require fci is Running
        require(isPause == false && now < timeExpires);
        // require buyer not is 0x0 address
        require(_seller != 0x0);
        require(_valueFci * priceFci > fciDecimals);
        uint nacReturn = (_valueFci.mul(priceFci))/fciDecimals;
        
        // destroy fci
        balanceOf[address(this)] = balanceOf[address(this)].sub(_valueFci);
        totalSupply = totalSupply.sub(_valueFci);
        
        // update NETF balance
        NetfBalance = NetfBalance.sub(nacReturn);
        
        // send NAC
        NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
        namiToken.transfer(_seller, nacReturn);
        
        emit Transfer(_seller, address(this), _valueFci);
        emit SellFci(_seller, nacReturn, _valueFci, now);
    }
    
    /////////////////////////////////////////////////////NETF Revenue function///////////////////////////////////////////////////////////////
    struct ShareHolderNETF {
        uint stake;
        bool isWithdrawn;
    }
    
    struct RoundNetfRevenue {
        bool isOpen;
        uint currentNAC;
        uint totalFci;
        bool withdrawable;
    }
    
    uint public currentNetfRound;
    
    mapping (uint => RoundNetfRevenue) public NetfRevenue;
    mapping (uint => mapping(address => ShareHolderNETF)) public usersNETF;
    
    // 1. open Netf round
    /**
     * first controller open one round for netf revenue
     */
    function openNetfRevenueRound(uint _roundIndex) onlyController public {
        require(NetfRevenue[_roundIndex].isOpen == false);
        currentNetfRound = _roundIndex;
        NetfRevenue[_roundIndex].isOpen = true;
    }
    
    /**
     * 
     * this function update balance of NETF revenue funds add NAC to funds
     * only executable if round open and round not withdraw yet
     */
    function depositNetfRevenue(uint _valueNac) onlyController public {
        require(NetfRevenue[currentNetfRound].isOpen == true && NetfRevenue[currentNetfRound].withdrawable == false);
        NetfRevenue[currentNetfRound].currentNAC = NetfRevenue[currentNetfRound].currentNAC.add(_valueNac);
    }
    
    /**
     * 
     * this function update balance of NETF Funds remove NAC from funds
     * only executable if round open and round not withdraw yet
     */
    function withdrawNetfRevenue(uint _valueNac) onlyController public {
        require(NetfRevenue[currentNetfRound].isOpen == true && NetfRevenue[currentNetfRound].withdrawable == false);
        NetfRevenue[currentNetfRound].currentNAC = NetfRevenue[currentNetfRound].currentNAC.sub(_valueNac);
    }
    
    // switch to pause phrase here
    
    /**
     * after pause all investor to buy, sell and exchange fci on the market
     * controller or investor latch final fci of current round
     */
     function latchTotalFci(uint _roundIndex) onlyController public {
         require(isPause == true && NetfRevenue[_roundIndex].isOpen == true);
         require(NetfRevenue[_roundIndex].withdrawable == false);
         NetfRevenue[_roundIndex].totalFci = totalSupply;
     }
     
     function latchFciUserController(uint _roundIndex, address _investor) onlyController public {
         require(isPause == true && NetfRevenue[_roundIndex].isOpen == true);
         require(NetfRevenue[_roundIndex].withdrawable == false);
         require(balanceOf[_investor] > 0);
         usersNETF[_roundIndex][_investor].stake = balanceOf[_investor];
     }
     
     /**
      * investor can latch Fci by themself
      */
     function latchFciUser(uint _roundIndex) public {
         require(isPause == true && NetfRevenue[_roundIndex].isOpen == true);
         require(NetfRevenue[_roundIndex].withdrawable == false);
         require(balanceOf[msg.sender] > 0);
         usersNETF[_roundIndex][msg.sender].stake = balanceOf[msg.sender];
     }
     
     /**
      * after all investor latch fci, controller change round state withdrawable
      * now investor can withdraw NAC from NetfRevenue funds of this round
      * and auto switch to unpause phrase
      */
     function changeWithdrawableNetfRe(uint _roundIndex) onlyController public {
         require(isPause == true && NetfRevenue[_roundIndex].isOpen == true);
         NetfRevenue[_roundIndex].withdrawable = true;
         isPause = false;
     }
     
     // after latch all investor, unpause here
     /**
      * withdraw NAC for 
      * run by controller
      */
     function withdrawNacNetfReController(uint _roundIndex, address _investor) onlyController public {
         require(NetfRevenue[_roundIndex].withdrawable == true && isPause == false && _investor != 0x0);
         require(usersNETF[_roundIndex][_investor].stake > 0 && usersNETF[_roundIndex][_investor].isWithdrawn == false);
         require(NetfRevenue[_roundIndex].totalFci > 0);
         // withdraw NAC
         uint nacReturn = ( NetfRevenue[_roundIndex].currentNAC.mul(usersNETF[_roundIndex][_investor].stake) ) / NetfRevenue[_roundIndex].totalFci;
         NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
         namiToken.transfer(_investor, nacReturn);
         
         usersNETF[_roundIndex][_investor].isWithdrawn = true;
     }
     
     /**
      * withdraw NAC for 
      * run by investor
      */
     function withdrawNacNetfRe(uint _roundIndex) public {
         require(NetfRevenue[_roundIndex].withdrawable == true && isPause == false);
         require(usersNETF[_roundIndex][msg.sender].stake > 0 && usersNETF[_roundIndex][msg.sender].isWithdrawn == false);
         require(NetfRevenue[_roundIndex].totalFci > 0);
         // withdraw NAC
         uint nacReturn = ( NetfRevenue[_roundIndex].currentNAC.mul(usersNETF[_roundIndex][msg.sender].stake) ) / NetfRevenue[_roundIndex].totalFci;
         NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
         namiToken.transfer(msg.sender, nacReturn);
         
         usersNETF[_roundIndex][msg.sender].isWithdrawn = true;
     }
    
    /////////////////////////////////////////////////////token fci function//////////////////////////////////////////////////////////////////
    /**
     * Internal transfer, only can be called by this contract
     */
    function _transfer(address _from, address _to, uint _value) internal {
        // Prevent transfer to 0x0 address. Use burn() instead
        require(_to != 0x0);
        // Check if the sender has enough
        require(balanceOf[_from] >= _value);
        // Check for overflows
        require(balanceOf[_to] + _value >= balanceOf[_to]);
        // Save this for an assertion in the future
        uint previousBalances = balanceOf[_from] + balanceOf[_to];
        // Subtract from the sender
        balanceOf[_from] -= _value;
        // Add the same to the recipient
        balanceOf[_to] += _value;
        emit Transfer(_from, _to, _value);
        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
    }

    /**
     * Transfer tokens
     *
     * Send `_value` tokens to `_to` from your account
     *
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transfer(address _to, uint256 _value) public onlyRunning {
        _transfer(msg.sender, _to, _value);
    }

    /**
     * Transfer tokens from other address
     *
     * Send `_value` tokens to `_to` on behalf of `_from`
     *
     * @param _from The address of the sender
     * @param _to The address of the recipient
     * @param _value the amount to send
     */
    function transferFrom(address _from, address _to, uint256 _value) public onlyRunning returns (bool success) {
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        allowance[_from][msg.sender] -= _value;
        _transfer(_from, _to, _value);
        return true;
    }

    /**
     * Set allowance for other address
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     */
    function approve(address _spender, uint256 _value) public onlyRunning
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    /**
     * Set allowance for other address and notify
     *
     * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
     *
     * @param _spender The address authorized to spend
     * @param _value the max amount they can spend
     * @param _extraData some extra information to send to the approved contract
     */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        public onlyRunning
        returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////end fci token function///////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////pool function////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    uint public currentRound = 1;
    uint public currentSubRound = 1;
    
    struct shareHolderNLF {
        uint fciNLF;
        bool isWithdrawnRound;
    }
    
    struct SubRound {
        uint totalNacInSubRound;
        bool isOpen;
        bool isCloseNacPool;
    }
    
    struct Round {
        bool isOpen;
        bool isActivePool;
        bool withdrawable;
        uint currentNAC;
        uint finalNAC;
    }
    
    // NLF Funds
    mapping(uint => Round) public NLFunds;
    mapping(uint => mapping(address => mapping(uint => bool))) public isWithdrawnSubRoundNLF;
    mapping(uint => mapping(uint => SubRound)) public listSubRoundNLF;
    mapping(uint => mapping(address => shareHolderNLF)) public membersNLF;
    
    
    event ActivateRound(uint RoundIndex, uint TimeActive);
    event ActivateSubRound(uint RoundIndex, uint TimeActive);
    // ------------------------------------------------ 
    /**
     * Admin function
     * Open and Close Round
     */
    function activateRound(uint _roundIndex)
        onlyEscrow
        public
    {
        // require round not open
        require(NLFunds[_roundIndex].isOpen == false);
        NLFunds[_roundIndex].isOpen = true;
        currentRound = _roundIndex;
        emit ActivateRound(_roundIndex, now);
    }
    
    ///////////////////////deposit to NLF funds in tokenFallbackExchange///////////////////////////////
    /**
     * after all user deposit to NLF pool
     */
    function deactivateRound(uint _roundIndex)
        onlyEscrow
        public
    {
        // require round id is openning
        require(NLFunds[_roundIndex].isOpen == true);
        NLFunds[_roundIndex].isActivePool = true;
        NLFunds[_roundIndex].isOpen = false;
        NLFunds[_roundIndex].finalNAC = NLFunds[_roundIndex].currentNAC;
    }
    
    /**
     * before send NAC to subround controller need active subround
     */
    function activateSubRound(uint _subRoundIndex)
        onlyController
        public
    {
        // require current round is not open and pool active
        require(NLFunds[currentRound].isOpen == false && NLFunds[currentRound].isActivePool == true);
        // require sub round not open
        require(listSubRoundNLF[currentRound][_subRoundIndex].isOpen == false);
        //
        currentSubRound = _subRoundIndex;
        require(listSubRoundNLF[currentRound][_subRoundIndex].isCloseNacPool == false);
        
        listSubRoundNLF[currentRound][_subRoundIndex].isOpen = true;
        emit ActivateSubRound(_subRoundIndex, now);
    }
    
    
    /**
     * every week controller deposit to subround to send NAC to all user have NLF fci
     */
    function depositToSubRound(uint _value)
        onlyController
        public
    {
        // require sub round is openning
        require(currentSubRound != 0);
        require(listSubRoundNLF[currentRound][currentSubRound].isOpen == true);
        require(listSubRoundNLF[currentRound][currentSubRound].isCloseNacPool == false);
        
        // modify total NAC in each subround
        listSubRoundNLF[currentRound][currentSubRound].totalNacInSubRound = listSubRoundNLF[currentRound][currentSubRound].totalNacInSubRound.add(_value);
    }
    
    
    /**
     * every week controller deposit to subround to send NAC to all user have NLF fci
     */
    function withdrawFromSubRound(uint _value)
        onlyController
        public
    {
        // require sub round is openning
        require(currentSubRound != 0);
        require(listSubRoundNLF[currentRound][currentSubRound].isOpen == true);
        require(listSubRoundNLF[currentRound][currentSubRound].isCloseNacPool == false);
        
        // modify total NAC in each subround
        listSubRoundNLF[currentRound][currentSubRound].totalNacInSubRound = listSubRoundNLF[currentRound][currentSubRound].totalNacInSubRound.sub(_value);
    }
    
    
    /**
     * controller close deposit subround phrase and user can withdraw NAC from subround
     */
    function closeDepositSubRound()
        onlyController
        public
    {
        require(listSubRoundNLF[currentRound][currentSubRound].isOpen == true);
        require(listSubRoundNLF[currentRound][currentSubRound].isCloseNacPool == false);
        
        listSubRoundNLF[currentRound][currentSubRound].isCloseNacPool = true;
    }
    
    
    /**
     * user withdraw NAC from each subround of NLF funds for investor
     */
    function withdrawSubRound(uint _subRoundIndex) public {
        // require close deposit to subround
        require(listSubRoundNLF[currentRound][_subRoundIndex].isCloseNacPool == true);
        
        // user not ever withdraw nac in this subround
        require(isWithdrawnSubRoundNLF[currentRound][msg.sender][_subRoundIndex] == false);
        
        // require user have fci
        require(membersNLF[currentRound][msg.sender].fciNLF > 0);
        
        // withdraw token
        NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
        
        uint nacReturn = (listSubRoundNLF[currentRound][_subRoundIndex].totalNacInSubRound.mul(membersNLF[currentRound][msg.sender].fciNLF)).div(NLFunds[currentRound].finalNAC);
        namiToken.transfer(msg.sender, nacReturn);
        
        isWithdrawnSubRoundNLF[currentRound][msg.sender][_subRoundIndex] = true;
    }
    
    
    /**
     * controller of NLF add NAC to update NLF balance
     * this NAC come from 10% trading revenue
     */
    function addNacToNLF(uint _value) public onlyController {
        require(NLFunds[currentRound].isActivePool == true);
        require(NLFunds[currentRound].withdrawable == false);
        
        NLFunds[currentRound].currentNAC = NLFunds[currentRound].currentNAC.add(_value);
    }
    
    /**
     * controller get NAC from NLF pool to send to trader
     */
    
    function removeNacFromNLF(uint _value) public onlyController {
        require(NLFunds[currentRound].isActivePool == true);
        require(NLFunds[currentRound].withdrawable == false);
        
        NLFunds[currentRound].currentNAC = NLFunds[currentRound].currentNAC.sub(_value);
    }
    
    /**
     * end of round escrow run this to allow user sell fci to receive NAC
     */
    function changeWithdrawableRound(uint _roundIndex)
        public
        onlyEscrow
    {
        require(NLFunds[currentRound].isActivePool == true);
        require(NLFunds[_roundIndex].withdrawable == false && NLFunds[_roundIndex].isOpen == false);
        
        NLFunds[_roundIndex].withdrawable = true;
    }
    
    
    /**
     * end of round user sell fci to receive NAC from NLF funds
     * function for investor
     */
    function withdrawRound(uint _roundIndex) public {
        require(NLFunds[_roundIndex].withdrawable == true);
        require(membersNLF[currentRound][msg.sender].isWithdrawnRound == false);
        require(membersNLF[currentRound][msg.sender].fciNLF > 0);
        
        NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
        uint nacReturn = NLFunds[currentRound].currentNAC.mul(membersNLF[currentRound][msg.sender].fciNLF).div(NLFunds[currentRound].finalNAC);
        namiToken.transfer(msg.sender, nacReturn);
        
        // update status round
        membersNLF[currentRound][msg.sender].isWithdrawnRound = true;
        membersNLF[currentRound][msg.sender].fciNLF = 0;
    }
    
    function withdrawRoundController(uint _roundIndex, address _investor) public onlyController {
        require(NLFunds[_roundIndex].withdrawable == true);
        require(membersNLF[currentRound][_investor].isWithdrawnRound == false);
        require(membersNLF[currentRound][_investor].fciNLF > 0);
        
        NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
        uint nacReturn = NLFunds[currentRound].currentNAC.mul(membersNLF[currentRound][_investor].fciNLF).div(NLFunds[currentRound].finalNAC);
        namiToken.transfer(msg.sender, nacReturn);
        
        // update status round
        membersNLF[currentRound][_investor].isWithdrawnRound = true;
        membersNLF[currentRound][_investor].fciNLF = 0;
    }
    
    
    
    /**
     * fall back function call from nami crawsale smart contract
     * deposit NAC to NAMI TRADE broker, invest to NETF and NLF funds
     */
    function tokenFallbackExchange(address _from, uint _value, uint _choose) onlyNami public returns (bool success) {
        require(_choose <= 2);
        if (_choose == 0) {
            // deposit NAC to nami trade broker
            require(_value >= minNac);
            emit Deposit(_from, _value, now);
        } else if(_choose == 1) {
            require(_value >= minNac && NLFunds[currentRound].isOpen == true);
            // invest to NLF funds
            membersNLF[currentRound][_from].fciNLF = membersNLF[currentRound][_from].fciNLF.add(_value);
            NLFunds[currentRound].currentNAC = NLFunds[currentRound].currentNAC.add(_value);
            
            emit InvestToNLF(_from, _value, now);
        } else if(_choose == 2) {
            // invest NAC to NETF Funds
            require(_value >= minNac); // msg.value >= 0.1 ether
            emit PlaceBuyFciOrder(_from, _value, now);
        }
        return true;
    }
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////end pool function///////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    // withdraw token
    function withdrawToken(address _account, uint _amount)
        public
        onlyController
    {
        require(_amount >= minWithdraw && _amount <= maxWithdraw);
        NamiCrowdSale namiToken = NamiCrowdSale(NamiAddr);
        
        uint previousBalances = namiToken.balanceOf(address(this));
        require(previousBalances >= _amount);
        
        // transfer token
        namiToken.transfer(_account, _amount);
        
        // emit event
        emit Withdraw(_account, _amount, now);
        assert(previousBalances >= namiToken.balanceOf(address(this)));
    }
    
    
}
function activateSubRound(uint _subRoundIndex)
    onlyController
    public
{
    // require current round is not open and pool active
    require(NLFunds[currentRound].isOpen == false && NLFunds[currentRound].isActivePool == true);
    // require sub round not open
    require(listSubRoundNLF[currentRound][_subRoundIndex].isOpen == false);
    //
    currentSubRound = _subRoundIndex;
    require(listSubRoundNLF[currentRound][_subRoundIndex].isCloseNacPool == false);
        
    listSubRoundNLF[currentRound][_subRoundIndex].isOpen = true;
    emit ActivateSubRound(_subRoundIndex, now);
}

/**
 * before send NAC to subround controller need active subround
 */