Code can be seen here: https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol#L53
What I don't understand is that if you use the constant product formula, you arrive at a different formula:
- invariant formula: resIn * resOut = k
- therefore, (resIn+amountIn)*(resOut-amountOut)=k
- solving for amountIn, we get amountIn = (resIn*resOut) / (resOut-amountOut) - resIn
- But the contract has a version that's not equivalent, even after accounting for fees.
Note: the above doesn’t include fees
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint numerator = reserveIn.mul(amountOut).mul(1000);
uint denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}