DAI/USDC/USDT Free Transfer?

Very easy case, you have 100 DAI/USDC/USDT. You wanna transfer some to your friend but you have no ETH in your wallet :(

Posted by Statemind on August 03, 2022 · 4 mins read


Very easy case, you have 100 DAI/USDC/USDT. You wanna transfer some to your friend but you have no ETH in your wallet :(

Okay, let’s find the solution starting with DAI

Simple Way

Of course, you can “just transfer some dust ETH to the account”

BUT: 01

So let’s find another way //

Another way

Let’s dive into the code

Scrolling it down… aand see that picture:

// --- Approve by signature ---
function permit(address holder, address spender, uint256 nonce, uint256 expiry,
               bool allowed, uint8 v, bytes32 r, bytes32 s) external
   bytes32 digest =
   require(holder != address(0), "Dai/invalid-address-0");
   require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit");
   require(expiry == 0 || now <= expiry, "Dai/permit-expired");
   require(nonce == nonces[holder]++, "Dai/invalid-nonce");
   uint wad = allowed ? uint(-1) : 0;
   allowance[holder][spender] = wad;
   emit Approval(holder, spender, wad);

There is a permit function(see reference).

Function designed to be callable from any account, so if you want to give allowance for transfer, you don’t need to make a transaction anymore. Rather, you can generate a permit signature off-chain and send it to your friend by any messanger, even WhatsApp :)

Deeper explanation


  • holder — address who gives allowance
  • spender — address who can spend allowance
  • nonce — sequence number of permit (used to avoid replay attack)
  • expiry — deadline timestamp, if you didn’t use permit till that timestamp it will be invalidated
  • allowed — boolean flag, if true you make infinite allowance, if false — revoke allowance
  • v, r, s — ethereum signature, more details

How that works:

The key idea is elementary, the user makes the signature of “allowance” using own private key, then the contract can verify that using built-in ecrecover function. “Allowance” is just the set of parameters of permit (like holder, spender, etc.) and service constants (see EIP for details).


  • User chooses parameters
  • User calculates keccak256 hash of paraments + service info
  • User signs hash from the previous step
  • User sends signature and parameters to friend off-chain
  • Friend sent a transaction with the permit and transfer tokens from the users’ account

What about USDC/USDT ?


Here is the contract source code, basically, there is similar mechanics with the permit. But for one-time transfers is better to use transferWithAuthorization function.


Here is the contract source code

02 USDT doesn’t have permit mechanics and it’s cannot be implemented since the contract is non-upgradable.