```\\nfunction swap(\\n  address inputToken,\\n  address outputToken,\\n  uint256 inputAmount,\\n  uint256 minOutputAmount\\n)\\n  external\\n  payable\\n  onlyListedToken(inputToken)\\n  onlyListedToken(outputToken)\\n  override\\n  returns (uint256 outputAmount)\\n{\\n  // Check that the exchange is unlocked and thus open for business\\n  Config memory _config = DFPconfig;\\n  require(_config.unlocked, "DFP: Locked");\\n\\n  // Pull in input token and check the exchange balance for that token\\n  uint256 initialInputBalance;\\n  if (inputToken == address(0)) {\\n    require(msg.value == inputAmount, "DFP: bad ETH amount");\\n    initialInputBalance = address(this).balance - inputAmount;\\n  } else {\\n    initialInputBalance = IERC20(inputToken).balanceOf(address(this));\\n    IERC20(inputToken).safeTransferFrom(msg.sender, address(this), inputAmount);\\n  }\\n\\n  // Check dex balance of the output token\\n  uint256 initialOutputBalance;\\n  if (outputToken == address(0)) {\\n    initialOutputBalance = address(this).balance;\\n  } else {\\n    initialOutputBalance = IERC20(outputToken).balanceOf(address(this));\\n  }\\n\\n  // Calculate the output amount through the x*y=k invariant\\n  // Can skip overflow/underflow checks on this calculation as they will always work against an attacker anyway.\\n  uint256 netInputAmount = inputAmount * _config.oneMinusTradingFee;\\n  outputAmount = netInputAmount * initialOutputBalance / ((initialInputBalance << 64) + netInputAmount);\\n  require(outputAmount > minOutputAmount, "DFP: No deal");\\n\\n  // Send output tokens to whoever invoked the swap function\\n  if (outputToken == address(0)) {\\n    address payable sender = payable(msg.sender);\\n    sender.transfer(outputAmount);\\n  } else {\\n    IERC20(outputToken).safeTransfer(msg.sender, outputAmount);\\n  }\\n\\n  // Emit swap event to enable better governance decision making\\n  emit Swapped(msg.sender, inputToken, outputToken, inputAmount, outputAmount);\\n}\\n```\\n