what approve and allowance methods are really doing in ERC20 Standard?
Asked Answered
M

2

22

The problem is what allowance and approve are really doing?

And what is _spender and what is it doing?

Is there anybody who can explain it to me?

contract Token {
    uint256 public totalSupply;
    function balanceOf(address _owner) constant returns (uint256 balance);
    function transfer(address _to, uint256 value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
Moulin answered 7/2, 2018 at 13:4 Comment(0)
C
57

what allowance and approve are doing really?

Let's assume we have user A and user B. A has 1000 tokens and want to give permission to B to spend 100 of them.

  • A will call approve(address(B), 100, {"from": address(A)})
  • B will check how many tokens A gave him permission to use by calling: allowance(address(A), address(B))
  • B will send to his account these tokens by calling: transferFrom(address(A), address(B), 100, {"from": address(B)})
Chaps answered 7/2, 2018 at 13:19 Comment(2)
In transferFrom, can B send this money to someone else like C?Audreyaudri
Yes, B can send token to C in that case. @EresDevGarotte
E
10
  • Allowance means that we can grant approval to another contract or address to be able to transfer our ERC20 tokens. And this requirement is common in distributed applications, such as escrows, games, auctions, etc. Hence, we need a way to approve other addresses to spend our tokens. Let's say you have tether contract and you want a DEX(Decentralized Exchange) or any other entity transfer coins from the tether contract. So you keep track of which entity how much can transfer from tether contract in a mapping.

     // my address is allowing your address for this much token
     mapping(address=>mapping(address=>uint)) public allowance;
    
  • In the ERC20 standard, we have a global variable allowed in which we keep the mapping from an "owner's address" to an "approved spender’s" address and then to the amount of tokens. Calling approve() function can add an approval to its desired _spender and _value. The amount of token is not checked here and it will be checked in transfer().

  • Once the approval is granted, the "approved spender" can use transferFrom() to transfer tokens. _from is the owner address and _to is the receiver’s address and _value is the required number of tokens to be sent. First, we check if the owner actually possesses the required number of tokens.

Let's say you want to deposit some ether to a DEFI platform. Interacting with a DEFI platform is actually interacting with the smart contract of that platform. Before you deposit money, you first approve the transaction. You are telling that this contract address can take some money from my account. Then you call the deposit function of DEFI smart contract and deposit the money. This how transfer occurs in order:

1- Inside Defi, defi contract has deposit to get coin from tether

function depositTokens(uint _amount) public{
  require(_amount>0,'amount cannot be zero');
  // transfer tether to this contract address for staking
  tether.transferFrom(msg.sender,address(this), _amount);
 // update the state inside Defi, like staked tokens, amount etc
}

2- Inside tether we have transferFrom

mapping(address=>mapping(address=>uint)) public allowance;

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
        // check the allowance
        require(_value <=allowance[_from][msg.sender]);
        balanceOf[_to]+=_value;
        balanceOf[_from]-=_value;
        allowance[_from][msg.sender]-=_value;
        emit Transfer(_from,_to,_value);
        return true;
    }

The first requirement is checking the allowance. mapping(address=>mapping(address=>uint)) public allowance. So actually before calling this, tether contract has to update its allowance mapping so this transferFrom will run smoothly

3- Update the allowance with approve:

function approve(address _spender, uint _value)public returns (bool success){
        allowance[msg.sender][_spender]=_value;
        // This event must trigger when a successful call is made to the approve function.
        emit Approval(msg.sender,_spender,_value);
        return true;
    }
Erastian answered 17/8, 2021 at 16:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.