safeApprove vs safeIncreaseAllowance vs permit

Hi there,

I am slightly confused between the usage of safeApprove vs safeIncreaseAllowance vs permit. Say I have a staking contract that allows a user to deposit some tokens (maybe $UNI or $SUSHI, tokens that I did not implement) into it,

contract A {
  function deposit(address token, uint256 amount) {
    IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
  }
  
  function approveA(address token, uint256 amount) external {
    IERC20(token).safeIncreaseAllowance(address(this), amount);
  }

  function approveB(address token, uint256 amount) external {
    IERC20(token).approve(address(this), amount);
  }

  function approveC(address token, uint256 amount) external {
    // what should v, r, s be if the user should call this before they can call deposit()?
    IERC20Permit(token).permit(msg.sender, address(this), amount, deadline, v, r, s)
  }
}

the user has to "approve" the token before they can call the deposit() function. Which approve function should I include in my contract? I tried doing approveA() but I'm running into ERC20: insufficient allowance. I want to do approveC() but I do not know what are the v, r, s if I were to run tests on it.

What is the magic function to add to the contract such that users on the front end can call the function to approve and stake their tokens into the contract?