Using "new" keyword doesn't work with certain function counts?

All of this works locally on hardhat and compiles and has ran through all local tests.

I have tried on ropsten and rinkeby with the samee issues

I have a factory contract that uses:

  function initToken(address asset) public {
      GLDToken gLDToken = new GLDToken(address(_provider), asset);
  }

This works with:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IPool} from '../pool/IPool.sol';
import {IPoolAddressesProvider} from '../pool/IPoolAddressesProvider.sol';
import {IBridge} from '../anchor/interfaces/IBridge.sol';
import {WadRayMath} from '../libraries/WadRayMath.sol';
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

interface IGLDToken  {

  function mint(address account, uint256 amount, uint256 exchangeRate) external;

  function supply(
      address addi,
      uint256 amount
  ) external returns (bool);

}

// works with 

// mint(...) + onlyPool() + name() + supply(...)

contract GLDToken is ERC20, IGLDToken {
    using SafeMath for uint256;
    using WadRayMath for uint256;
    using SafeERC20 for IERC20;

    string private _name;
    string private _symbol;

    address internal _underlyingAsset;

    IPoolAddressesProvider public _provider;

    IPool private _pool;

    IERC20 private _conversionWrappedAsset;

    constructor(
        address provider,
        address underlyingAsset
    ) ERC20("", "") {
        _name = "Asdf";
        _symbol = "Asdf";
        _underlyingAsset = underlyingAsset;
        _provider = IPoolAddressesProvider(provider);
        _pool = IPool(_provider.getPool());
    }

    modifier onlyPool() {
      require(msg.sender == address(_pool), "Error: Only pool can be sender.");
      _;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function mint(address account, uint256 amount, uint256 exchangeRate) external override onlyPool {
        uint256 scaledAmount;
        uint256 currentTimestamp = block.timestamp;

        scaledAmount = amount.wadDiv(exchangeRate);
        uint256 simulatedDepositsSuppliedExchangeRate = _pool.simulateOverallExchangeRate(_underlyingAsset);

        _mint(account, scaledAmount);
        /* emit Mint(account, amount, exchangeRate); */
    }

    function supply(address addi, uint256 amount) external override onlyPool returns (bool) {
        IDeposit(addi).deposit(
            amount,
            0,
            address(this)
        );

        return true;
    }

}

If I add another function I get reason: 'transaction failed', with no real reason and on etherscan an "out of gas"

If i do this i get the above error:

interface IGLDToken  {

  function mint(address account, uint256 amount, uint256 exchangeRate) external;

  function burn(address account, uint256 amount, uint256 exchangeRate) external;

}

contract GLDToken is ERC20, IGLDToken {
    using SafeMath for uint256;
    using WadRayMath for uint256;
    using SafeERC20 for IERC20;

    string private _name;
    string private _symbol;

    address internal _underlyingAsset;

    IPoolAddressesProvider public _provider;

    IPool private _pool;

    IConversionPoolV3 private _conversion;
    uint256 private bridgeTotalScaledSupply;
    uint256 private depositsSupplyTotalScaledSupply; // amount trackd at a discount

    IERC20 private _conversionWrappedAsset;

    constructor(
        address provider,
        address underlyingAsset
    ) ERC20("", "") {
        _name = "Asdf";
        _symbol = "Asdf";
        _underlyingAsset = underlyingAsset;
        _provider = IPoolAddressesProvider(provider);
        _pool = IPool(_provider.getPool());
    }

    modifier onlyPool() {
      require(msg.sender == address(_pool), "Error: Only pool can be sender.");
      _;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function mint(address account, uint256 amount, uint256 exchangeRate) external override onlyPool {
        uint256 scaledAmount;
        uint256 currentTimestamp = block.timestamp;

        scaledAmount = amount.wadDiv(exchangeRate);
        uint256 simulatedDepositsSuppliedExchangeRate = _pool.simulateOverallExchangeRate(_underlyingAsset);

        _mint(account, scaledAmount);
        /* emit Mint(account, amount, exchangeRate); */
    }

    function burn(address account, uint256 amount, uint256 exchangeRate) external override onlyPool {
        uint256 amountScaled = amount.wadDiv(exchangeRate);
        require(amountScaled != 0, "Error: Invalid burn amount");
        _burn(account, amountScaled);
        IERC20(_underlyingAsset).safeTransfer(account, amount);
    }

}

Are there any known issues that are causing this?

I'm really not sure at all what is going on

Hello @bnwater

There is no known issue with the new keyword. It looks like this is an issue coming from the tooling you use. Either it doesn't manage to compute the right amount of gas to send the transaction, or it uses a hardcoded value that is not enough.