Pair

The pair is a smart contract pool for the tokens. The users can swap the tokens directly using swap function here.

Function initialize

This function does not have a direct counterpart in the UniswapV2 code, with the closest match being the contract constructor. It is invoked by the factory contract to initialize the contract ERC-20 LP token, the factory address, reentrancy lock state, and the Upgradeable contract administrator address.

It is functionally equivalent to the UniswapV2 initialize function, with the only changes being due to storage access, replacing Uniswap references with references to Facet, and initializing the reentrancy lock and the Upgradeable contract from which the Pair contract inherits from.

Function init

This function is used by the factory contract to initialize the addresses of the tokens the pool operates with.

It is functionally equivalent to the UniswapV2 initialize function, with trivial changes to access storage while supporting the upgradability pattern and to replace Uniswap references with references to Facet. The function was also renamed from initialize to init.

Function getReserves

This function is used to get the cached reserve values for the pair as well as the timestamp when they were last cached.

It is functionally equivalent to UniswapV2, with the only changes being due to storage access.

Function _safeTransfer

This function is not equivalent to the version used by the Uniswap contracts. The Uniswap version of the function is as follows:

function _safeTransfer(address token, address to, uint value) private {
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
    require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
}

While the Facet version is as follows:

function _safeTransfer(address token, address to, uint value) private {
    bool result = ERC20(token).transfer(to, value);
    require(result, "FacetSwapV1: TRANSFER_FAILED");
}

The Facet version is less compatible with nonstandard ERC-20 implementations where the transfer function does not return a boolean value, such as the ERC-20 deployed for USDT on Ethereum.

This modification is not necessarily problematic, provided that all tokens used on Facet Swap correctly implement the ERC-20 standard.

This observation was addressed in commit , which switched the _safeTransfer implementation to the following code, which behaves like Uniswap:

function _safeTransferFrom(
    address token,
    address from,
    address to,
    uint256 value
) internal {
    // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
    require(
        success && (data.length == 0 || abi.decode(data, (bool))),
        'TransferHelper::transferFrom: transferFrom failed'
    );
}

Function _update

This function is used to update the cached reserve values and cumulative price.

It is mostly functionally equivalent to UniswapV2, with the only changes being due to storage access, replacing UQ112x112 fixed-point math usages with built-in checked arithmetic, and replacing Uniswap references with references to Facet. An additional event is also emitted, containing the cached reserve values before they are updated.

The Uniswap code explicitly states that some arithmetic overflows present in the code were intended and desired; the Facet Swap code targets a modern version of Solidity, which uses checked arithmetic operations and does not allow silent overflows. Without allowing overflows, the contract is destined to break, since the price0CumulativeLast and price1CumulativeLast variables increase for each block. When the attempt to update them causes an overflow, all functions of the contract that directly or indirectly invoke _update will revert.

Function encode

This function is used to encode a number into the encoding used by the UQ112x112 fixed-point library (effectively multiplying the number by ).

This function was inlined from the UQ112x112 fixed-point library and behaves identically to the original version.

Function uqdiv

This function was inlined from the UQ112x112 fixed-point library and behaves identically to the original version. However, we note that the function is unused and could be removed.

Function _mintFee

This function is used to mint an optional protocol fee (charged when minting or burning liquidity) in the form of LP tokens, which are transferred to a configurable fee recipient. The minted LP tokens dilute the other LP tokens, essentially granting a share of the pool liquidity to the fee recipient.

It is functionally equivalent to UniswapV2, with the only changes being due to storage access, replacing SafeMath usages with built-in checked arithmetic, and replacing Uniswap references with references to Facet.

Function mint

This function is used to provide liquidity to the pool by transferring assets to it in exchange for LP tokens.

It is functionally equivalent to UniswapV2, with the only changes being due to storage access, replacing SafeMath usages with built-in checked arithmetic, and replacing Uniswap references with references to Facet.

Function burn

This function is used to burn LP tokens in exchange for a corresponding amount of assets.

It is functionally equivalent to UniswapV2. Changes were made to allow access to contract storage while being compatible with the chosen upgradability pattern used in the Facet version of the contracts. Usages of SafeMath were removed in favor of built-in Solidity 0.8.0+ safe math. References to Uniswap were replaced with references to Facet.

Function swap

This function is used to perform a swap. It is functionally equivalent to UniswapV2, with one notable exception; instead of supporting a fixed 30-base-point fee, Facet supports dynamic fees retrieved from the factory contract. Notably, the k-invariant assertion has not been modified.

Additionally, changes were made to allow access to contract storage while being compatible with the chosen upgradability pattern used in the Facet version of the contracts. Usages of SafeMath were removed in favor of built-in Solidity 0.8.0+ safe math. References to Uniswap were replaced with references to Facet.

Function skim

This function is used to take away excess balances owned by the contract, meaning the difference between the current balance of the contract and the cached reserve values.

It is functionally equivalent to UniswapV2; changes were made to access contract storage due to use of the chosen upgradability pattern in the Facet version of the contracts. Additionally, usages of SafeMath were removed in favor of built-in Solidity 0.8.0+ safe math.

Function sync

This function is used to update the cached reserve values stored by the contract.

It is functionally equivalent to UniswapV2; the only changes are related to storage access due to use of the chosen upgradability pattern in the Facet version of the contracts.

Function sqrt

This function does not exist in the original UniswapV2Pair contract; it invokes the floating-point square-root precompile introduced for backwards compatibility with the legacy Rubidity language used in the development stage of Facet.

Function min

This function does not exist in the original UniswapV2Pair contract; it trivially returns the minimum between the two input numbers.

Zellic © 2025Back to top ↑