Error adding liquidity to UniswapV2Pair during construction

Hello, I'm concerning about why I'm getting an error trying to add liquidity using the addLiquidityETH to a UniswapV2Pair during construction. It seems that it reverts when the router calls the IUniswapV2Pair(pair).mint(to); method.

If I, instead, call the addLiquidityETH in a second transaction after token deployment it works.

The following calls the _addLiquidity method in constructor but the transaction fails (trx)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";

contract SwappableLiquidityInDeploy is ERC20 {
    IUniswapV2Router02 private immutable _uniswapV2Router;
    address private immutable _uniswapV2Pair;
    
    constructor(address uniswapV2Router_) ERC20("Swappable", "SWAP") payable {
        uint256 initialBalance = 100000000 * 10 ** decimals();
    
        _mint(address(this), initialBalance);

        _uniswapV2Router = IUniswapV2Router02(uniswapV2Router_);

        _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(
            address(this),
            _uniswapV2Router.WETH()
        );

        _addLiquidity(msg.value, initialBalance);
    }

    function _addLiquidity(uint256 ethAmount, uint256 tokenAmount) internal {
        _approve(address(this), address(_uniswapV2Router), tokenAmount);

        _uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0,
            0,
            address(this),
            block.timestamp
        );
    }
}

This one, instead, creates the contract first (trx) and then calls the addLiquidityMock method to add liquidity without errors (trx).

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";

contract SwappableLiquidityInFunction is ERC20 {
    IUniswapV2Router02 private immutable _uniswapV2Router;
    address private immutable _uniswapV2Pair;
    
    constructor(address uniswapV2Router_) ERC20("Swappable", "SWAP") payable {
        uint256 initialBalance = 100000000 * 10 ** decimals();
    
        _mint(address(this), initialBalance);

        _uniswapV2Router = IUniswapV2Router02(uniswapV2Router_);

        _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(
            address(this),
            _uniswapV2Router.WETH()
        );
    }

    function addLiquidityMock() public payable {
        _addLiquidity(msg.value, totalSupply());
    }

    function _addLiquidity(uint256 ethAmount, uint256 tokenAmount) internal {
        _approve(address(this), address(_uniswapV2Router), tokenAmount);

        _uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0,
            0,
            address(this),
            block.timestamp
        );
    }
}

Calling addLiquidityETH using your externally-owned account, means that you are adding liquidity from your externally-owned account.

Calling _addLiquidity inside the contract's constructor, means that you are adding liquidity from the smart-contract account.

Subsequently (for each one of these cases), the preliminary approval should be executed via the same account which adds the liquidity right after that.

No, I do not add liquidity from EOA but from the token contract that is the 100% holder of the token supply. In both cases I call the internal _addLiquidity method that calls the addLiquidityETH from the token contract itself. In that function there is a previous approval from token contract to the router.

Well, my guess would be that address(this) is not a valid expression when evaluated from the context of the constructor, since the contract isn't really deployed until the end of the constructor execution.

Yes, maybe, I think something like this too. But analyzing the stack it seems that the transfer from token to pair goes and then it fails on pair.mint.

Have not any cases where deployer is able to create liquidity during construction?

Hello, Vittorio Minacori - can you please contact me? You deployed a token for me, and I wish to have it verified, please. DonaldtheGuru@gmail.com Thank you.
I wish to have 0xB6FDD8A5b6069De409288Bc30C69c5856Dc67aC8 ETHTC to be made public and verified please.

@Donald_Lewis Sorry, not related to me. I have not deployed that contract.
You should delete that comment as it is not related to the discussion.