YUL call transferFrom inline assembly run out of gas

When i test it it pass but in a big contract it fail with run out of gas. I use hardhat to test

uint256 private constant ERC20_transferFrom_signature = (
    0x23b872dd00000000000000000000000000000000000000000000000000000000
);
function assemblyTransferErc20(address token, address from, address to, uint256 amount) internal {
    assembly {
      if iszero(extcodesize(token)) {
        revert(0,0)
      }
      let ptr := mload(0x40)
      mstore(0, ERC20_transferFrom_signature)
      mstore(0x04, from)
      mstore(0x24, to)
      mstore(0x44, amount)

      let callStatus := call(
        gas(),
        token,
        0,
        0, // ptr to the signature
        0x64, // length of the signature
        0, // ptr to store the output
        0x20 // length of the output
      )
      if iszero(returndatasize()) {
        revert(0,0)
      }
      if iszero(callStatus) {
        returndatacopy(ptr, 0, returndatasize())
        revert(ptr, returndatasize())
      }
    }
  }

This capture it when it fail


the second one its when i test just the transferFrom and it pass

That's probably how you are using memory. The call data doesn't fit in the scratch area and you are overwriting the free memory pointer (at pos 0x40):

mstore(0x24, to)
mstore(0x44, amount)

Probably the call data should start at `mload(0x40)' instead of 0x00. You can read about solidity memory management here

ok ty it pass when i change the code

function assemblyTransferErc20(address token, address from, address to, uint256 amount) internal {
    assembly {
      if iszero(extcodesize(token)) {
        revert(0,0)
      }
      let ptr := mload(0x40)
      mstore(ptr, ERC20_transferFrom_signature)
      mstore(add(ptr, 0x04), from)
      mstore(add(ptr, 0x24), to)
      mstore(add(ptr, 0x44), amount)

      let callStatus := call(
        gas(),
        token,
        0,
        ptr, // ptr to the signature
        0x64, // length of the signature
        ptr, // ptr to store the output
        0x20 // length of the output
      )
      if iszero(returndatasize()) {
        revert(0,0)
      }
      if iszero(callStatus) {
        returndatacopy(ptr, 0, returndatasize())
        revert(ptr, returndatasize())
      }
    }
  }