ERC20 Token Smart Contract Function Fails, No Concrete Error Thrown

I know this is a noob question but I have this staking function but it fails when I tried to call function stake.
Deployed Contract: 0x25187f46197BB0e0d343968df5318F630d3f6992

:1234: Code to reproduce

CCAToken.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";


contract CCAToken is ERC20, AccessControlEnumerable {
  bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
  bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
  constructor() ERC20("CCA Token", "CCA") {}

  function mint(address to, uint256 amount) public virtual {
    require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
    _mint(to, amount);
  }
}

CCAFarm.sol


// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import "./CCAToken.sol";

contract CCAFarm is CCAToken, Ownable, ERC20Burnable, ERC20Pausable {
  IERC20 public stakingToken;
  CCAToken public ccaToken;

  event Stake(address indexed from, uint256 amount);
  event Unstake(address indexed from, uint256 amount);
  event YieldWithdraw(address indexed to, uint256 amount);

  mapping(address => uint256) public stakingBalance;
  mapping(address => bool) public isStaking;
  mapping(address => uint256) public startTime;
  mapping(address => uint256) public ccaBalance;

   constructor(
      IERC20 _stakingToken,
      CCAToken _ccaToken
      ) {
          stakingToken = _stakingToken;
          ccaToken = _ccaToken;

          _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
          _setupRole(MINTER_ROLE, _msgSender());
          _setupRole(PAUSER_ROLE, _msgSender());
      }

  function decimals() public view virtual override returns (uint8) {
      return 5;
  }

  function mint(address to, uint256 amount) public override virtual {
    require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
    _mint(to, amount);
  }
  /**
   * @dev Pauses all token transfers.
   *
   * See {ERC20Pausable} and {Pausable-_pause}.
   *
   * Requirements:
   *
   * - the caller must have the `PAUSER_ROLE`.
   */
  function pause() public virtual {
      require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause");
      _pause();
  }

  function unpause() public virtual {
      require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause");
      _unpause();
  }

  function _beforeTokenTransfer(
      address from,
      address to,
      uint256 amount
  ) internal virtual override(ERC20, ERC20Pausable) {
      super._beforeTokenTransfer(from, to, amount);
  }

  function stake(uint256 _amount) public {
      address from = msg.sender;
      address to = address(this);
      uint256 amount = _amount;

      if(isStaking[from] == true){
          uint256 toTransfer = calculateYieldTotal(from);
          ccaBalance[from] += toTransfer;
      }

      stakingToken.transferFrom(from, to, amount);
      stakingBalance[from] += amount;
      startTime[from] = block.timestamp;
      isStaking[from] = true;
      emit Stake(from, amount);
  }

  function unstake(uint256 amount) public {
      require(isStaking[msg.sender] = true && stakingBalance[msg.sender] >= amount, "Nothing to unstake");
      uint256 yieldTransfer = calculateYieldTotal(msg.sender);
      startTime[msg.sender] = block.timestamp;
      uint256 balTransfer = amount;
      amount = 0;
      stakingBalance[msg.sender] -= balTransfer;
      stakingToken.transfer(msg.sender, balTransfer);
      ccaBalance[msg.sender] += yieldTransfer;
      if(stakingBalance[msg.sender] == 0){
          isStaking[msg.sender] = false;
      }
      emit Unstake(msg.sender, balTransfer);
  }

  function calculateYieldTime(address user) public view returns(uint256){
      uint256 end = block.timestamp;
      uint256 totalTime = end - startTime[user];
      return totalTime;
  }

  function calculateYieldTotal(address user) public view returns(uint256) {
      uint256 time = calculateYieldTime(user) * 10**18;
      uint256 rate = 86400;
      uint256 timeRate = time / rate;
      uint256 rawYield = (stakingBalance[user] * timeRate) / 10**18;
      return rawYield;
  }

  function withdrawYield() public {
      uint256 toTransfer = calculateYieldTotal(msg.sender);
      require(toTransfer > 0 || ccaBalance[msg.sender] > 0, "Nothing to withdraw");

      if(ccaBalance[msg.sender] != 0){
          uint256 oldBalance = ccaBalance[msg.sender];
          ccaBalance[msg.sender] = 0;
          toTransfer += oldBalance;
      }

      startTime[msg.sender] = block.timestamp;
      ccaToken.mint(msg.sender, toTransfer);
      emit YieldWithdraw(msg.sender, toTransfer);
  }
}

I have problem on this part of function,

function stake(uint256 _amount) public {
      address from = msg.sender;
      address to = address(this);
      uint256 amount = _amount;

      if(isStaking[from] == true){
          uint256 toTransfer = calculateYieldTotal(from);
          ccaBalance[from] += toTransfer;
      }

      stakingToken.transferFrom(from, to, amount);
      stakingBalance[from] += amount;
      startTime[from] = block.timestamp;
      isStaking[from] = true;
      emit Stake(from, amount);
  }

Screen Shot 2021-12-08 at 12.45.28 PM

:computer: Environment

I tried the both options but still the same problem:

  • Remix version 0.8.4
  • Hardhat version 0.8.4