contract ERC20SwappableOutput is ERC20, Ownable {
    using SafeMath for uint256;

    /**
     * @dev Emitted when funds have been successfully swapped from another token.
     */
    event SwapOutput(address indexed inputToken, address indexed payee, uint256 inputAmount, uint256 outputAmount);

    /**
     * @dev Transfer previously locked funds to a payee at or after the minimum unlock time.
     * @param payee The address whose previously locked funds will be unlocked and transferred to.
     * @param inputAmount The amount of input tokens to be burned.
     * @param outputAmount The amount of output tokens to be minted.
     */
    function finishSwap(address payee, uint256 inputAmount, uint256 outputAmount) external onlyInputSwapToken returns (bool) {
        _mint(payee, outputAmount);
        emit SwapOutput(msg.sender, payee, inputAmount, outputAmount);
        return true;
    }

    mapping(address => bool) private _inputSwapTokens;

    /**
     * @dev Registers an input swap token.
     * @param token The address of the token.
     */
    function addInputSwapToken(address token) external onlyOwner returns (bool) {
        _inputSwapTokens[token] = true;
        return true;
    }

    /**
     * @dev Unregisters an input swap token.
     * @param token The address of the token.
     */
    function removeInputSwapToken(address token) external onlyOwner returns (bool) {
        _inputSwapTokens[token] = false;
        return true;
    }

    /**
     * @dev Throws if called by any account other than a registered input swap token.
     */
    modifier onlyInputSwapToken() {
        require(isInputSwapToken(), "ERC20SwappableOutput: caller is not a registered input swap token");
        _;
    }

    /**
     * @dev Returns true if the caller is a registered input swap token.
     */
    function isInputSwapToken() public view returns (bool) {
        return _inputSwapTokens[msg.sender];
    }
}
/**
 * @title ERC20SwappableOutput
 * @dev ERC20 token that can be converted from another ERC20 token.
 */
function finishSwap(address payee, uint256 inputAmount, uint256 outputAmount) external onlyInputSwapToken returns (bool) {
        _mint(payee, outputAmount);
        emit SwapOutput(msg.sender, payee, inputAmount, outputAmount);
        return true;
    }
/**
 * @dev Transfer previously locked funds to a payee at or after the minimum unlock time.
 * @param payee The address whose previously locked funds will be unlocked and transferred to.
 * @param inputAmount The amount of input tokens to be burned.
 * @param outputAmount The amount of output tokens to be minted.
 */