Для тех, кто знаком с кодом в UniswapV2Pair.sol, я не понимаю следующую строку:

uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0

Наблюдая за предыдущими строками, я понимаю, что количество пула «_reserve0» используется для извлечения количества «amount0Out», поэтому окончательный баланс token0 в парном пуле составляет,

balance0 = _reserve0 - amount0Out

Поэтому я не понимаю, почему balance0 будет больше, чем _reserve0 - amount0Out.

Я прикрепляю здесь предыдущие строки кода,

function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
    require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');

    uint balance0;
    uint balance1;
    { // scope for _token{0,1}, avoids stack too deep errors
    address _token0 = token0;
    address _token1 = token1;
    require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
    if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
    balance0 = IERC20(_token0).balanceOf(address(this));
    balance1 = IERC20(_token1).balanceOf(address(this));
    }
    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
...
0
bitcazador 25 Июл 2021 в 22:54
Я не понимаю, почему balance0 будет больше, чем, потому что вы не можете продать то, чего у вас нет
 – 
Nulik
25 Июл 2021 в 23:12
Точно так, как сказал Нулик, но вы также можете проверить этот пост и принять ответ. ethereum. stackexchange.com/questions/102355/…
 – 
Kaki Master Of Time
26 Июл 2021 в 12:34
Спасибо вам обоим за ответы, они помогают. Но, вероятно, я упускаю важную концепцию, потому что вижу следующий поток контракта: 1. получить остатки пула до свопа (резервы) 2. вывести сумму из пула (так что новый баланс = резерв- out) 3. запросите баланс пула после этого перевода через интерфейс IERC20, который будет: баланс = резерв - суммаВыход, поэтому я не знаю, зачем запрашивать 4. если вы рассчитываете отсюда приток, суммаIn = баланс - ( резерв-сумма) = (резерв - сумма на выходе) - (резерв - сумма на выходе) = 0 Итак... что я упускаю?
 – 
bitcazador
31 Июл 2021 в 20:37
Возможно, магия в том, что эта функция "своп" вызывается ПОСЛЕ перевода пользователя в суммуВ. Итак, пользователь переводит в пул «количество», которое он хочет продать, а затем вызывается функция «своп», так что теперь «баланс» и «резерв» не совпадают. баланс равен резерв + суммаВход и затем после перевода суммаВыход баланс равен = резерв + суммаВход - суммаВыход [1], так что теперь мы в состоянии вычислить суммуВнепосредственно находя из [1], то есть: суммаВход = баланс -reserve+amountOut = balance - (резерв - суммаOut)
 – 
bitcazador
31 Июл 2021 в 21:00
Хорошо, этот факт подтвержден при тестировании: UniswapV2Pair.spec.ts
 – 
bitcazador
31 Июл 2021 в 21:19

1 ответ

Найдя решение, которое подтверждается в тестовом файле UniswapV2Pair.spec.ts, я сам отвечаю на вопрос на тот случай, если он кого-то тоже заинтересует. Кажется, магия в том, что эта функция swap вызывается ПОСЛЕ перехода пользователя в amountIn. Итак, пользователь передает в пул amountIn, который хочет продать, а затем вызывается функция swap, так что теперь balance и reserve не одно и то же. (иначе окончательный расчет amountIn будет равен нулю, как объяснялось в предыдущих комментариях). Баланс после перевода составляет reserve + amountIn (и сборы), а затем после перевода amountOut баланс составляет = reserve + amountIn - amountOut [1] (и сборы), так что теперь мы в состоянии вычислить amountIn непосредственно из [1], то есть: amountIn = balance-reserve+amountOut = balance - (reserve - amountOut)

0
bitcazador 31 Июл 2021 в 21:25