```\nfunction addMultiple(address[] calldata tokens, uint256[] calldata maxAmounts)\n  external\n  payable\n  override\n  returns (uint256 actualLP)\n{\n  // Perform basic checks\n  Config memory _config = DFPconfig;\n  require(_config.unlocked, "DFP: Locked");\n  require(tokens.length == 16, "DFP: Bad tokens array length");\n  require(maxAmounts.length == 16, "DFP: Bad maxAmount array length");\n\n  // Check ETH amount/ratio first\n  require(tokens[0] == address(0), "DFP: No ETH found");\n  require(maxAmounts[0] == msg.value, "DFP: Incorrect ETH amount");\n  uint256 dexBalance = address(this).balance - msg.value;\n  uint256 actualRatio = msg.value * (1<<128) / dexBalance;\n\n  // Check ERC20 amounts/ratios\n  uint256 currentRatio;\n  address previous;\n  address token;\n  for (uint256 i = 1; i < 16; i++) {\n    token = tokens[i];\n    require(token > previous, "DFP: Require ordered list");\n    require(\n      listedTokens[token].state > State.Delisting,\n      "DFP: Token not listed"\n    );\n    dexBalance = IERC20(token).balanceOf(address(this));\n    currentRatio = maxAmounts[i] * (1 << 128) / dexBalance;\n    if (currentRatio < actualRatio) {\n      actualRatio = currentRatio;\n    }\n    previous = token;\n  }\n\n  // Calculate how many LP will be generated\n  actualLP = (actualRatio * totalSupply() >> 64) * DFPconfig.oneMinusTradingFee >> 128;\n\n  // Collect ERC20 tokens\n  for (uint256 i = 1; i < 16; i++) {\n    token = tokens[i];\n    dexBalance = IERC20(token).balanceOf(address(this));\n    IERC20(token).safeTransferFrom(msg.sender, address(this), dexBalance * actualRatio >> 128);\n  }\n\n  // Mint the LP tokens\n  _mint(msg.sender, actualLP);\n  emit MultiLiquidityAdded(msg.sender, actualLP, totalSupply());\n\n  // Refund ETH change\n  dexBalance = address(this).balance - msg.value;\n  address payable sender = payable(msg.sender);\n  sender.transfer(msg.value - (dexBalance * actualRatio >> 128));\n}\n```\n