contract ExchangeCUSE is SafeMath, Owned, CUSE {
    
    // Exercise End Time 1/1/2019 0:0:0
    uint public ExerciseEndTime = 1546272000;
    uint public exchangeRate = 13333 * 10**9 wei; //percentage times (1 ether)
    
    //mapping (address => uint) ustValue; //mapping of token addresses to mapping of account balances (token=0 means Ether)
    
    // UST address
    address public USEaddress = address(0xd9485499499d66B175Cf5ED54c0a19f1a6Bcb61A);
    
    // offical Address
    address public officialAddress = address(0x89Ead717c9DC15a222926221897c68F9486E7229);

    function execCUSEOption() public payable returns (bool) {
        require (now < ExerciseEndTime);
        
        // ETH user send
        uint _ether = msg.value;
        (uint _use, uint _refoundETH) = calcUSE(balances[msg.sender], _ether);
        
        // do exercise
        balances[msg.sender] = safeSub(balances[msg.sender], _use/(10**18));
        balances[officialAddress] = safeAdd(balances[officialAddress], _use/(10**18));
        require (CUSE(USEaddress).transferFrom(officialAddress, msg.sender, _use) == true);

        emit Transfer(msg.sender, officialAddress, _use/(10**18)); 
        
        // refound ETH
        needRefoundETH(_refoundETH);
        officialAddress.transfer(safeSub(_ether, _refoundETH));
    }
    
    // Calculate
    function calcUSE(uint _cuse, uint _ether) internal view returns (uint _use, uint _refoundETH) {
        uint _amount = _ether / exchangeRate;
        require (safeMul(_amount, exchangeRate) <= _ether);
        
        // Check Whether msg.sender Have Enough CUSE
        if (_amount <= _cuse) {
            _use = safeMul(_amount, 10**18);
            _refoundETH = 0;
            
        } else {
            _use = safeMul(_cuse, 10**18);
            _refoundETH = safeMul(safeSub(_amount, _cuse), exchangeRate);
        }
        
    }
    
    function needRefoundETH(uint _refoundETH) internal {
        if (_refoundETH > 0) {
            msg.sender.transfer(_refoundETH);
        }
    }
    
    function changeOfficialAddress(address _newAddress) public onlyOwner {
         officialAddress = _newAddress;
    }
}
function calcUSE(uint _cuse, uint _ether) internal view returns (uint _use, uint _refoundETH) {
    uint _amount = _ether / exchangeRate;
    require (safeMul(_amount, exchangeRate) <= _ether);
        
    // Check Whether msg.sender Have Enough CUSE
    if (_amount <= _cuse) {
        _use = safeMul(_amount, 10**18);
        _refoundETH = 0;
            
    } else {
        _use = safeMul(_cuse, 10**18);
        _refoundETH = safeMul(safeSub(_amount, _cuse), exchangeRate);
    }
        
}

// Calculate