Why is ERC20Permit better than approve/transferFrom?

Hi there, glad to know the OZ team rolled out a draft version of ERC20Permit. As I was researching on pancakeswap, I found this permit function for their PancakeERC20 token. I then began doing research on EIP-191, 712 and 2612. I have to say, after spending hours, I am still only staying on the surface.

Could anyone please explain in layman terms what this permit function does and why it is a better solution than approve-transferFrom interplay. I read that anyone can call this function, but really who gets to call this function in a concrete example? Thanks.

function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
    require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
    bytes32 digest = keccak256(
        abi.encodePacked(
            '\x19\x01',
            DOMAIN_SEPARATOR,
            keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
        )
    );
    address recoveredAddress = ecrecover(digest, v, r, s);
    require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
    _approve(owner, spender, value);
}
1 Like

Hi @maxaero,

By not relying on IERC20.approve , the token holder account doesn’t need to send a transaction, and thus is not required to hold Ether at all.
From: https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Permit

Essentially a token holder doesn’t need to hold Ether or create transactions to spend tokens. Instead a token holder can sign to permit an allowance for a contract, so an application can create the transaction to perform an action requiring tokens.

The token holder needs to sign one message compared with creating two transactions requiring Ether. The application could pay for the transaction and charge the user in tokens.

1 Like