If you take a look at the UniswapV2Pair swap function, you will see the following:

The most important line in the whole function is this:

require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');

The pair itself does not automatically calculate how much tokens you will receive for the corresponding input amount. Instead, you must provide the desired output amount as well. Based on this output amount (and the input amount), the k check is executed.

**But what is the k check?**

The formula which is used to describe the bonding curve is x*y = k (constant product formula).

x = the quantity of tokenX in the pool

y = the quantity of tokenY B in the pool

k = a constant value representing the product of the quantities of the two tokens, which must remain unchanged for every swap

This means if we have supplyX and supplyY in the pool, the result of supplyX*supplyY (after a swap) must be >= k

Illustrated Example (ignoring fee):

Assume a liquidity pool has 100 ETH (x) and 10,000 USDC (y). The product k is:

100*10,000 = 1,000,000

If someone wants to swap 1 ETH for USDC, they add 1 ETH to the pool, increasing the ETH reserve to 101 ETH.

To maintain the constant product:

101 * y = 1,000,000

Solving for y:

y = 1,000,000 / 101

y = 9,900.99

Which means at most, one can determine 99,01 USDC as output amount without violating the k check. If you would set a higher output amount, the requirement will simply revert.

*Important sidenote:*Whenever liquidity is added/removed the k variable is updated to reflect the new product.