paint-brush
DAI/USDC/USDT Free Transfer?by@statemind
908 reads
908 reads

DAI/USDC/USDT Free Transfer?

by StatemindJuly 28th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Free stablecoin transactions. Ethereum smart contract hacks and audits.

Coins Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - DAI/USDC/USDT Free Transfer?
Statemind HackerNoon profile picture

Case

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:

So let’s find another way //

Another way

Let's dive into the code https://etherscan.io/toke /0x6b175474e89094c44da98b954eedeac495271d0f#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 =
       keccak256(abi.encodePacked(
           "\x19\x01",
           DOMAIN_SEPARATOR,
           keccak256(abi.encode(PERMIT_TYPEHASH,
                                 holder,
                                 spender,
                                 nonce,
                                 expiry,
                                 allowed))
   ));

   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 https://eips.ethereum.org/EIPS/eip-2612).


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

Arguments:

  • 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).


Algorithm:

  • 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 ?

USDC

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.

USDT

Here is the contract souce code

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