It seems[1] they do:
(0.997 * amountIn * reserveOut) / (reserveIn + 0.997 * amountIn)
From my understanding it should be amountIn * price, which with fee becomes ((1 - fee) * amountIn) * price.
Now, since price is given by reserveOut / reserveIn, and since fee = 0.003, the above becomes (0.997 * amountIn * reserveOut) / (reserveIn)
We're missing the whole second addendum at the denominator!
Where is that coming from?
References
[1]: Directly from the contract:
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}