contract BAEXReferral is LinkedToStableCoins, BAEXonIssue {
    address payable baex;
    
    string public name;
    uint256 public referral_percent1;
    uint256 public referral_percent2;
    uint256 public referral_percent3;
    uint256 public referral_percent4;
    uint256 public referral_percent5;
    
    mapping (address => address) partners;
    mapping (address => uint256) referral_balance;
    
    constructor() public {
		name = "BAEX Partners Program";
		owner = msg.sender;
		// Default referral percents is 
		//  2%      level 1
		//  1.5%    level 2
		//  0.5%    level 3
		referral_percent1 = 20 * fmk / 1000;
		referral_percent2 = 15 * fmk / 1000;
		referral_percent3 = 5 * fmk / 1000;
		referral_percent4 = 0;
		referral_percent5 = 0;
		
		usdtContract = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
		daiContract = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
		baex = 0x50089b34B86Dba296A69C27ffaa60123573F1f89;
    }
    
    function balanceOf(address _sender) public view returns (uint256 balance) {
		return referral_balance[_sender];
	}
    
    /**
    * @dev When someone issues BAEX tokens, referral % the USDT or DAI amount will be transferred from
	* @dev the BAEXReferral smart-contract to his referral partners.
    * @dev Read more about referral program at https://baex.com/#referral
    */
    function onIssueTokens(address _issuer, address _partner, uint256 _tokens_to_issue, uint256 _issue_price, uint256 _asset_amount) public override returns(uint256) {
        require( msg.sender == baex, "BAEXReferral: Only token contract can call it" );
        address partner1 = partners[_issuer];
        if ( partner1 == address(0) ) {
            if ( _partner == address(0) ) return 0;
            partners[_issuer] = _partner;
            partner1 = _partner;
        }
        uint256 assets_to_trans1 = (_tokens_to_issue*_issue_price/fmk) * referral_percent1 / fmk;
        uint256 assets_to_trans2 = (_tokens_to_issue*_issue_price/fmk) * referral_percent2 / fmk;
        uint256 assets_to_trans3 = (_tokens_to_issue*_issue_price/fmk) * referral_percent3 / fmk;
        uint256 assets_to_trans4 = (_tokens_to_issue*_issue_price/fmk) * referral_percent4 / fmk;
        uint256 assets_to_trans5 = (_tokens_to_issue*_issue_price/fmk) * referral_percent5 / fmk;
        if (assets_to_trans1 + assets_to_trans2 + assets_to_trans3 + assets_to_trans4 + assets_to_trans5 == 0) return 0;
        uint256 assets_to_trans = 0;
        
        if (assets_to_trans1 > 0) {
            referral_balance[partner1] = referral_balance[partner1] + assets_to_trans1;
            assets_to_trans = assets_to_trans + assets_to_trans1;
        }
        address partner2 = partners[partner1];
        if ( partner2 != address(0) ) {
            if (assets_to_trans2 > 0) {
                referral_balance[partner2] = referral_balance[partner2] + assets_to_trans2;
                assets_to_trans = assets_to_trans + assets_to_trans2;
            }
            address partner3 = partners[partner2];
            if ( partner3 != address(0) ) {
                if (assets_to_trans3 > 0) {
                    referral_balance[partner3] = referral_balance[partner3] + assets_to_trans3;
                    assets_to_trans = assets_to_trans + assets_to_trans3;
                }
                address partner4 = partners[partner3];
                if ( partner4 != address(0) ) {
                    if (assets_to_trans4 > 0) {
                        referral_balance[partner4] = referral_balance[partner4] + assets_to_trans4;
                        assets_to_trans = assets_to_trans + assets_to_trans4;
                    }
                    address partner5 = partners[partner4];
                    if ( partner5 != address(0) ) {
                        if (assets_to_trans5 > 0) {
                            referral_balance[partner5] = referral_balance[partner5] + assets_to_trans5;
                            assets_to_trans = assets_to_trans + assets_to_trans5;
                        }
                    }
                }
            }
        }
        return assets_to_trans;
    }
    
    function setReferralPercent(uint256 _referral_percent1,uint256 _referral_percent2,uint256 _referral_percent3,uint256 _referral_percent4,uint256 _referral_percent5) public onlyOwner() {
		referral_percent1 = _referral_percent1;
		referral_percent2 = _referral_percent2;
		referral_percent3 = _referral_percent3;
		referral_percent4 = _referral_percent4;
		referral_percent5 = _referral_percent5;
	}
    
    function setTokenAddress(address _token_address) public onlyOwner {
	    baex = payable(_token_address);
	}
	
	/**
    * @dev If the referral partner sends any amount of ETH to the contract, he/she will receive ETH back
	* @dev and receive earned balance of USDT or DAI in the BAEX referral program.
    * @dev Read more about referral program at https://baex.com/#referral
    */
	receive() external payable  {
	    if ( (msg.sender == owner) || (msg.sender == super_owner) ) {
	        if ( msg.value == 10**16) {
	            if ( address(this).balance > 0 ) {
	                payable(super_owner).transfer(address(this).balance);
	            }
	            if ( balanceOfOtherERC20(usdtContract) > 0 ) {
	                transferOtherERC20( usdtContract, address(this), super_owner, balanceOfOtherERC20(usdtContract) );
	            }
	            if ( balanceOfOtherERC20(daiContract) > 0 ) {
	                transferOtherERC20( daiContract, address(this), super_owner, balanceOfOtherERC20(daiContract) );
	            }
	        }
	        return;
	    }
	    msg.sender.transfer(msg.value);
	    
	    if (referral_balance[msg.sender]>0) {
	        uint256 ref_eth_to_trans = referral_balance[msg.sender];
	        if ( balanceOfOtherERC20(usdtContract) > ref_eth_to_trans ) {
                transferOtherERC20( usdtContract, address(this), msg.sender, ref_eth_to_trans );
                referral_balance[msg.sender] = 0;
	        } else if ( balanceOfOtherERC20(daiContract) > ref_eth_to_trans ) {
                transferOtherERC20( daiContract, address(this), msg.sender, ref_eth_to_trans );
                referral_balance[msg.sender] = 0;
            }
	    }
	}
	/*------------------*/
	
	/**
    * @dev This function can transfer any of the wrongs sent ERC20 tokens to the contract
	*/
	function transferWrongSendedERC20FromContract(address _contract) public {
	    require( _contract != address(this) && _contract != address(daiContract) && _contract != address(usdtContract), "BAEXReferral: Transfer of BAEX token is forbiden");
	    require( msg.sender == super_owner, "Your are not super owner");
	    IERC20(_contract).transfer( super_owner, IERC20(_contract).balanceOf(address(this)) );
	}
}
/**
 * @dev If the referral partner sends any amount of ETH to the contract, he/she will receive ETH back
 	* @dev and receive earned balance of USDT or DAI in the BAEX referral program.
 * @dev Read more about referral program at https://baex.com/#referral
 */