The following function in UniswapV2 is responsible to calculate the ratio for the addLiquidity function:
As you can see, it goes through several conditions:
Condition 1: First liquidity addition, here it simply allows to whatever ratio is provided
Condition 2: Calculate amountB based on provided amountA and the current reserve ratio
Condition 3: Calculate amountA based on provided amountB and the current reserve ratio
Now let’s take a look at the quote function, which is invoked in condition 2&3:
Now the exploit:
The pair is newly created and no liquidity has been added, naturally the liquidity addition would follow condition 1. However, a malicious user manually transfers 1 wei of the counter token to the pair and invokes sync, which results in reserveB = 1. This means, condition 1 is not fulfilled anymore and it will enter condition 2. As one can see the quote function is invoked in condition 2. The problem: the require statement is not fulfilled because reserveA = 0 and reserveB = 1.
Therefore, liquidity addition will be blocked until someone manually transfers tokenA to the pair and invokes sync.