Assignment - ERC20

Thats a shorthanded to x = x - y. So instead of writing again the x, you can write x -= y. Same with the addition. So…, in resume.

balances[_from] -= value;  // eq. balances[_from] = balances[_from]  - value

// is different than
balances[_from] - value; // this one is not being assigned 
2 Likes

Thanks Eric.
Where I went wrong was thinking [(address => uint256) balances] is seen as a Number. Therefore Number - value.
But it’s Number [(address => uint256) balances] = Number [(address => uint256) balances] - value :crazy_face:

2 Likes
pragma solidity 0.8.0;

/**
 * @title ERC20 standard token implementation.
 * @dev Standard ERC20 token. This contract follows the implementation at https://goo.gl/mLbAPJ.
 */
contract Token is ERC20Interface {
  /*
   * Token name.
   */
  string internal tokenName;

  /*
   * Token symbol.
   */
  string internal tokenSymbol;

  /*
   * Number of decimals.
   */
  uint8 internal tokenDecimals;

  /*
   * Total supply of tokens.
   */
  uint256 internal tokenTotalSupply;

  /*
   * Balance information map.
   */
  mapping (address => uint256) internal balances;

  /*
   * Token allowance mapping.
   */
  mapping (address => mapping (address => uint256)) internal allowed;

  /*
   * @dev Trigger when tokens are transferred, including zero value transfers.
   */
  event Transfer(address indexed _from,address indexed _to,uint256 _value);

  /*
   * @dev Trigger on any successful call to approve(address _spender, uint256 _value).
   */
  event Approval(address indexed _owner,address indexed _spender,uint256 _value);
  
  constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _initialOwnerBalance) {
      tokenName = _name;
      tokenSymbol = _symbol;
      tokenDecimals = _decimals;
      tokenTotalSupply = _initialOwnerBalance;
      balances[msg.sender] = _initialOwnerBalance;
  }

  /*
   * @dev Returns the name of the token.
   */
  function name() external view returns (string memory _name){
    _name = tokenName;
  }

  /*
   * @dev Returns the symbol of the token.
   */
  function symbol() external view returns (string memory _symbol){
    _symbol = tokenSymbol;
  }

  /*
   * @dev Returns the number of decimals the token uses.
   */
  function decimals() external view returns (uint8 _decimals){
    _decimals = tokenDecimals;
  }

  /*
   * @dev Returns the total token supply.
   */
  function totalSupply()external view returns (uint256 _totalSupply){
    _totalSupply = tokenTotalSupply;
  }

  /*
   * @dev Returns the account balance of another account with address _owner.
   * @param _owner The address from which the balance will be retrieved.
   */
  function balanceOf(address _owner) external view returns (uint256 _balance){
    _balance = balances[_owner];
  }

  /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
    // balance check  
    require(balances[msg.sender] >= _value, "Insufficient funds for transfer source.");
    // transfer
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    // success
    emit Transfer(msg.sender, _to, _value); 
    return true;
  }

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   */
  function approve(address _spender,uint256 _value) public returns (bool _success) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value); 
    return true;

  }

  /*
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   */
  function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
    _remaining = allowed[_owner][_spender];
  }

  /*
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
    uint256 allowance = allowed[_from][msg.sender];
    require(balances[_from] >= _value && allowance >= _value,"Insufficient allowed funds for transfer source.");
    balances[_to] += _value;
    balances[_from] -= _value;

    if (allowance < MAX_UINT256) {
      allowed[_from][msg.sender] -= _value;
    }
    emit Transfer(_from, _to, _value); 
    return true;

  }

}
1 Like
// SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

/**
 * @title ERC20 standard token implementation.
 * @dev Standard ERC20 token. This contract follows the implementation at https://goo.gl/mLbAPJ.
 */
contract Token {
  /*
   * Token name.
   */
  string internal tokenName;

  /*
   * Token symbol.
   */
  string internal tokenSymbol;

  /*
   * Number of decimals.
   */
  uint8 internal tokenDecimals;

  /*
   * Total supply of tokens.
   */
  uint256 internal tokenTotalSupply;

  /*
   * Balance information map.
   */
  mapping (address => uint256) internal balances;

  /*
   * Token allowance mapping.
   */
  mapping (address => mapping (address => uint256)) internal allowed;

  /*
   * @dev Trigger when tokens are transferred, including zero value transfers.
   */
  event Transfer(address indexed _from,address indexed _to,uint256 _value);

  /*
   * @dev Trigger on any successful call to approve(address _spender, uint256 _value).
   */
  event Approval(address indexed _owner,address indexed _spender,uint256 _value);
  
  constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _initialOwnerBalance) {
      tokenName = _name;
      tokenSymbol = _symbol;
      tokenDecimals = _decimals;
      tokenTotalSupply = _initialOwnerBalance;
      balances[msg.sender] = _initialOwnerBalance;
  }

  /*
   * @dev Returns the name of the token.
   */
  function name() external view returns (string memory _name){
    _name = tokenName;
  }

  /*
   * @dev Returns the symbol of the token.
   */
  function symbol() external view returns (string memory _symbol){
    _symbol = tokenSymbol;
  }

  /*
   * @dev Returns the number of decimals the token uses.
   */
  function decimals() external view returns (uint8 _decimals){
    _decimals = tokenDecimals;
  }

  /*
   * @dev Returns the total token supply.
   */
  function totalSupply()external view returns (uint256 _totalSupply){
    _totalSupply = tokenTotalSupply;
  }

  /*
   * @dev Returns the account balance of another account with address _owner.
   * @param _owner The address from which the balance will be retrieved.
   */
  function balanceOf(address _owner) external view returns (uint256 _balance){
    _balance = balances[_owner];
  }

  /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
      require(balances[msg.sender] >= _value, "ERC20.transfer: Insufficient balance");

      balances[msg.sender] -= _value;
      balances[_to] += _value;
      _success = true;

      emit Transfer(msg.sender, _to, _value);
  }

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   */
  function approve(address _spender,uint256 _value) public returns (bool _success) {
      allowed[msg.sender][_spender] = _value;
      _success = true;

      emit Approval(msg.sender, _spender, _value);
  }

  /*
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   */
  function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
    _remaining = allowed[_owner][_spender];
  }

  /*
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
      require(allowed[_from][msg.sender] >= _value, "ERC20: Withdrawal amount excceds amount permitted");
      
      allowed[_from][msg.sender] -= _value;
      balances[_from] -= _value;
      balances[_to] += _value;
      _success = true;

      emit Transfer(_from, _to, _value);

  }

}
1 Like
pragma solidity 0.8.0;

/**
 * @title ERC20 standard token implementation.
 * @dev Standard ERC20 token. This contract follows the implementation at https://goo.gl/mLbAPJ.
 */
contract Token {
  /*
   * Token name.
   */
  string internal tokenName;

  /*
   * Token symbol.
   */
  string internal tokenSymbol;

  /*
   * Number of decimals.
   */
  uint8 internal tokenDecimals;

  /*
   * Total supply of tokens.
   */
  uint256 internal tokenTotalSupply;

  /*
   * Balance information map.
   */
  mapping (address => uint256) internal balances;

  /*
   * Token allowance mapping.
   */
  mapping (address => mapping (address => uint256)) internal allowed;

  /*
   * @dev Trigger when tokens are transferred, including zero value transfers.
   */
  event Transfer(address indexed _from,address indexed _to,uint256 _value);

  /*
   * @dev Trigger on any successful call to approve(address _spender, uint256 _value).
   */
  event Approval(address indexed _owner,address indexed _spender,uint256 _value);
  
  constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _initialOwnerBalance) {
      tokenName = _name;
      tokenSymbol = _symbol;
      tokenDecimals = _decimals;
      tokenTotalSupply = _initialOwnerBalance;
      balances[msg.sender] = _initialOwnerBalance;
  }

  /*
   * @dev Returns the name of the token.
   */
  function name() external view returns (string memory _name){
    _name = tokenName;
  }

  /*
   * @dev Returns the symbol of the token.
   */
  function symbol() external view returns (string memory _symbol){
    _symbol = tokenSymbol;
  }

  /*
   * @dev Returns the number of decimals the token uses.
   */
  function decimals() external view returns (uint8 _decimals){
    _decimals = tokenDecimals;
  }

  /*
   * @dev Returns the total token supply.
   */
  function totalSupply()external view returns (uint256 _totalSupply){
    _totalSupply = tokenTotalSupply;
  }

  /*
   * @dev Returns the account balance of another account with address _owner.
   * @param _owner The address from which the balance will be retrieved.
   */
  function balanceOf(address _owner) external view returns (uint256 _balance){
    _balance = balances[_owner];
  }

  /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
      require(balances[msg.sender] >= _value);
      balances[msg.sender] -= _value;
      balances[_to] += _value;
      emit Transfer(msg.sender, _to, _value);
      _success = true;
  }

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   */
  function approve(address _spender, uint256 _value) public returns (bool _success) {
      allowed[msg.sender][_spender] = _value;
      emit Approval(msg.sender, _spender, _value);
      _success = true;
  }

  /*
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   */
  function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
    _remaining = allowed[_owner][_spender];
  }

  /*
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
      require(allowed[_from][msg.sender] >= _value);
      require(balances[_from] >= _value);
      balances[_from] -= _value;
      balances[_to] += _value;
      allowed[_from][msg.sender] -= _value;
      emit Transfer(_from, _to, _value);
      _success = true;
  }

}
1 Like

Here’s the modified part of the code:

  /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){

    require(_to != address(0), "Transfer to the zero address is impossible");
    require(balances[msg.sender] >= _value, "Transfer amount exceeds balance");
        
    balances[msg.sender] -= _value;
    balances[_to] += _value;

    emit Transfer(msg.sender, _to, _value);

    _success = true;

  }

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   */
  function approve(address _spender,uint256 _value) public returns (bool _success) {
    
    require(_spender != address(0), "Approve to the zero address is impossible");

    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);

    _success = true;

  }

  /*
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   */
  function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
    _remaining = allowed[_owner][_spender];
  }

  /*
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){

    require(_to != address(0), "Transfer to the zero address is impossible");
    require(balances[_from] >= _value, "Transfer amount exceeds balance");
    require(allowed[_from][_to] >= _value,"Transfer amount exceeds authorization");

    balances[_from] -= _value;
    balances[_to] += _value;
    allowed[_from][_to] -= _value;

    emit Transfer(_from, _to, _value);

    _success = true;

  }

Thanks for your feed-back!

1 Like
pragma solidity 0.8.0;
import "./SafeMath.sol";

/**
 * @title ERC20 standard token implementation.
 * @dev Standard ERC20 token. This contract follows the implementation at https://goo.gl/mLbAPJ.
 */
contract Token {
    using SafeMath for uint256;
    /*
    * Token name.
    */
    string internal tokenName;

    /*
    * Token symbol.
    */
    string internal tokenSymbol;

    /*
    * Number of decimals.
    */
    uint8 internal tokenDecimals;

    /*
    * Total supply of tokens.
    */
    uint256 internal tokenTotalSupply;

    /*
    * Balance information map.
    */
    mapping (address => uint256) internal balances;

    /*
    * Token allowance mapping.
    */
    mapping (address => mapping (address => uint256)) internal allowed;

    /*
    * @dev Trigger when tokens are transferred, including zero value transfers.
    */
    event Transfer(address indexed _from,address indexed _to,uint256 _value);

    /*
    * @dev Trigger on any successful call to approve(address _spender, uint256 _value).
    */
    event Approval(address indexed _owner,address indexed _spender,uint256 _value);

    constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _initialOwnerBalance) {
        tokenName = _name;
        tokenSymbol = _symbol;
        tokenDecimals = _decimals;
        tokenTotalSupply = _initialOwnerBalance;
        balances[msg.sender] = _initialOwnerBalance;
    }

    /*
    * @dev Returns the name of the token.
    */
    function name() external view returns (string memory _name){
        _name = tokenName;
    }

    /*
    * @dev Returns the symbol of the token.
    */
    function symbol() external view returns (string memory _symbol){
        _symbol = tokenSymbol;
    }

    /*
    * @dev Returns the number of decimals the token uses.
    */
    function decimals() external view returns (uint8 _decimals){
        _decimals = tokenDecimals;
    }

    /*
    * @dev Returns the total token supply.
    */
    function totalSupply() external view returns (uint256 _totalSupply){
        _totalSupply = tokenTotalSupply;
    }

    /*
    * @dev Returns the account balance of another account with address _owner.
    * @param _owner The address from which the balance will be retrieved.
    */
    function balanceOf(address _owner) external view returns (uint256 _balance){
        _balance = balances[_owner];
    }

    /*
    * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
    * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
    * @param _to The address of the recipient.
    * @param _value The amount of token to be transferred.
    */
    function transfer(address payable _to, uint256 _value) public returns (bool _success){
        require(balances[msg.sender] >= _value, "insufficient balance");
        require(msg.sender != _to, "Don't transfer money to yourself");
        uint256 previousSenderBalance = balances[msg.sender];
        balances[msg.sender].sub(_value);
        balances[_to].add(_value);
        payable(msg.sender).transfer(_value);
        assert(balances[msg.sender] == previousSenderBalance - _value);
        return true;
    }

    /*
    * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
    * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
    * @param _spender The address of the account able to transfer the tokens.
    * @param _value The amount of tokens to be approved for transfer.
    */
    function approve(address _spender,uint256 _value) public returns (bool _success) {
        allowed[msg.sender][_spender] = _value;
        return true;
    }

    /*
    * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
    * @param _owner The address of the account owning tokens.
    * @param _spender The address of the account able to transfer the tokens.
    */
    function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
        _remaining = allowed[_owner][_spender];
    }

    /*
    * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
    * Transfer event.
    * @param _from The address of the sender.
    * @param _to The address of the recipient.
    * @param _value The amount of token to be transferred.
    */
    function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
        require(allowed[msg.sender][_from] >= _value, "insufficient allowance");
        require(balances[_from] >= _value, "insufficient balance");
        require(_from != _to, "Don't transfer money to yourself");
        uint256 previousSenderBalance = balances[_from];
        allowed[msg.sender][_from].sub(_value);
        balances[_from].sub(_value);
        balances[_to].add(_value);

        payable(msg.sender).transfer(_value);
        assert(balances[_from] == previousSenderBalance - _value);
        return true;
    }

}
1 Like
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
    require(balances[msg.sender] >= _value, "Balance not sufficient.");
    balances[msg.sender] -= _value;
    balances[_to] += _value;

    emit Transfer(msg.sender, _to, _value);
    _success = true;
    return _success;
  }
  function approve(address _spender,uint256 _value) public returns (bool _success) {
      allowed[msg.sender][_spender] = _value;
      emit Approval(msg.sender, _spender, _value);
      _success = true;
      return _success;
  }
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
      require(_value <= allowed[_from][msg.sender], "Amount to transfer exceeds allowed amount");
      require(balances[_from] >= _value, "Balance not sufficient in owner's account");

      allowed[_from][msg.sender] -= _value;
      balances[_from] -= _value;
      balances[_to] += _value;

      emit Transfer(_from, _to, _value);
      _success = true;
      return _success;
 }
1 Like

Hi there,
I was about to ask if we should check for under and over-flow but from what I read in the reply to the below post it seems that it is automatically check in new Solidity versions. Is this correct?
Thanks

function transfer(address payable _to, uint256 _value) public returns (bool _success){
    // Check if the sender has enough
    require(balances[msg.sender] >= _value, "Insufficient balance."); //CHECKS
    // Check for overflows ???
    // Subtract from the sender
    balances[msg.sender] -= _value; //EFFECTS 
    // Add the same to the recipient
    balances[_to] += _value;
    // Notify anyone listening that this transfer took place
    emit Transfer(msg.sender, _to, _value); //(no INTERACTION here)
    //return true if successful
    _success = true;
  }
function approve(address _spender,uint256 _value) public returns (bool _success) {
    //require spender is not the owner
    require(_spender != msg.sender, "Cannot approve self.");
    // Set allowance
    //the first key is the actual owner of the funds, the second key is the address of the spender
    allowed[msg.sender][_spender] = _value;  
    // Notify
    emit Approval(msg.sender, _spender, _value);
    //Return true if successful
    _success = true; 
  }
unction transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
    // Check if the sender has enough
    require(balances[_from] >= _value, "Insufficient balance.");
    // Check allowance
    require(allowed[_from][msg.sender] >= _value, "Insufficient allowance.");

    balances[_from] -= _value; // Subtract from the sender
    balances[_to] += _value; // Add the same to the recipient
    allowed[_from][msg.sender] -= _value;  // Update the allowance

    emit Transfer(_from, _to, _value); // Notify anyone listening that this transfer took place
    _success = true; //return true if successful
  }

HI @fsicard

You are referring to the erc20 balance adjusting between send and received right? In that case, it is only related to the transfer function from erc20 standard version rather than the solidity version.

1 Like

  /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
      require(balances[msg.sender] >= _value);
      balances[msg.sender] -= _value;
      balances[_to] += _value;
      emit Transfer(msg.sender, _to, _value);
      _success = true;
  }

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   */
  function approve(address _spender,uint256 _value) public returns (bool _success) {
      allowed[msg.sender][_spender] = _value;
      emit Approval(msg.sender, _spender, _value);
      _success = true;
  }

  /*
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   */
  function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
    _remaining = allowed[_owner][_spender];
  }

  /*
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
      require(balances[_from] >= _value);
      require(allowed[_from][msg.sender] >= _value);
      allowed[_from][msg.sender] -= _value;
      balances[_from] -= _value;
      balances[_to] += _value;
      emit Transfer(_from, _to, _value);
      _success = true;
  }
// SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

import "./safemath.sol";

/**
 * @title ERC20 standard token implementation.
 * @dev Standard ERC20 token. This contract follows the implementation at https://goo.gl/mLbAPJ.
 */
contract Token {
    using SafeMath for uint;
  /*
   * Token name.
   */
  string internal tokenName;

  /*
   * Token symbol.
   */
  string internal tokenSymbol;

  /*
   * Number of decimals.
   */
  uint8 internal tokenDecimals;

  /*
   * Total supply of tokens.
   */
  uint256 internal tokenTotalSupply;

  /*
   * Balance information map.
   */
  mapping (address => uint256) internal balances;

  /*
   * Token allowance mapping.
   */
  mapping (address => mapping (address => uint256)) internal allowed;

  /*
   * @dev Trigger when tokens are transferred, including zero value transfers.
   */
  event Transfer(address indexed _from,address indexed _to,uint256 _value);

  /*
   * @dev Trigger on any successful call to approve(address _spender, uint256 _value).
   */
  event Approval(address indexed _owner,address indexed _spender,uint256 _value);
  
  constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _initialOwnerBalance) {
      tokenName = _name;
      tokenSymbol = _symbol;
      tokenDecimals = _decimals;
      tokenTotalSupply = _initialOwnerBalance;
      balances[msg.sender] = _initialOwnerBalance;
  }

  /*
   * @dev Returns the name of the token.
   */
  function name() external view returns (string memory _name){
    _name = tokenName;
  }

  /*
   * @dev Returns the symbol of the token.
   */
  function symbol() external view returns (string memory _symbol){
    _symbol = tokenSymbol;
  }

  /*
   * @dev Returns the number of decimals the token uses.
   */
  function decimals() external view returns (uint8 _decimals){
    _decimals = tokenDecimals;
  }

  /*
   * @dev Returns the total token supply.
   */
  function totalSupply()external view returns (uint256 _totalSupply){
    _totalSupply = tokenTotalSupply;
  }

  /*
   * @dev Returns the account balance of another account with address _owner.
   * @param _owner The address from which the balance will be retrieved.
   */
  function balanceOf(address _owner) external view returns (uint256 _balance){
    _balance = balances[_owner];
  }

      /*
   * @dev Internal function used for all transfers
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function _transfer(address _from,address _to,uint256 _value) internal returns (bool _success){

        //We use require instead of throw as throw is depricated 
        require(balances[_from] >= _value, "Balance not sufficient");
        require(_from != _to, "Don't transfer money to yourself");

        uint previousSenderBalance = balances[_from];
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        
        emit Transfer(_from, _to, _value);
        assert(balances[_from] == previousSenderBalance.sub(_value));
        _success=true;
  }

  /*
   * @dev internal version of approve to capsule common logic
   * @param _spender The address of the account able to transfer the tokens.
   * @param _owner The address of the owner account 
   * @param _value The amount of tokens to be approved for transfer.
   */
  function _approve(address _owner, address _spender, uint256 _value) internal returns (bool _success) {
        allowed[_owner][_spender] = _value;
        emit Approval(_owner, _spender, _value);
        _success=true;
  }

    /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){                                        
        _success=_transfer(msg.sender, _to, _value);
  }

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   */
  function approve(address _spender,uint256 _value) public returns (bool _success) {                
        require(_spender != msg.sender, "Don't approve yourself");
        _success=_approve (msg.sender, _spender, _value);
  }

  /*
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   */
  function allowance(address _owner,address _spender) external view returns (uint256 _remaining){
    _remaining = allowed[_owner][_spender];
  }


  /*
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
        
        //We use require instead of throw as throw is depricated 
        require(allowed[_from][msg.sender] >= _value, "Allowance not sufficient");
        // Reduce the allowance        
        _approve(_from, msg.sender, allowed[_from][msg.sender].sub(_value));        
        // Do the transfer
        _success=_transfer(_from, _to, _value);
  }

}
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
    require(msg.sender != _to, "Do not try to transfer tokens to yourself please.");
    require(balances[msg.sender] >= _value, "You do not have enough tokens for this transfer.");
    uint256 previousFromBalance = balances[msg.sender];
    uint256 previousToBalance = balances[_to];
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    assert(balances[msg.sender] == previousFromBalance.sub(_value));
    assert(balances[_to] == previousToBalance.add(_value));
    return true;
  }
  
  function approve(address _spender,uint256 _value) public returns (bool _success) {
    require(balances[msg.sender] >= _value, "Do not try to approve spending by others of amounts greater than your current balance please.");
    require(msg.sender != _spender, "Do not try to approve yourself please.");
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }
  
  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
    require(_from != msg.sender, "This transfer function is only for approved third-party use.");
    require(_from != _to, "Do not try to transfer tokens from the owner to themselves please.");
    require(allowed[_from][msg.sender] >= _value, "You have not been authorized to transfer this amount of tokens from the owners account.");
    require(balances[_from] >= _value, "There are not enough tokens in the owners balance to complete this transfer.");
    uint256 previousAllowance = allowed[_from][msg.sender];
    uint256 previousFromBalance = balances[_from];
    uint256 previousToBalance = balances[_to];
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    assert(allowed[_from][msg.sender] == previousAllowance.sub(_value));
    assert(balances[_from] == previousFromBalance.sub(_value));
    assert(balances[_to] == previousToBalance.add(_value));
    emit Transfer(_from, _to, _value);
    return true;
  }
1 Like

transfer:

type or p  /*
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the "from" account balance does not have enough tokens to spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   */
  function transfer(address payable _to, uint256 _value) public returns (bool _success){
    require(balances[msg.sender]>=_value,"Insufficient balance");
    require(_to != address(0), "Null address");
    require(allowed[msg.sender][_to]>=_value," Address/value not approved yet");

        balances[msg.sender] -= _value;
        balances[_to] += _value;
    
    emit Transfer(msg.sender, _to,_value);
    return true;
  }aste code here

approve function:

  /*
   * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If
   * this function is called again it overwrites the current allowance with _value. SHOULD emit the Approval event.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   * // mapping (address => mapping (address => uint256)) internal allowed;
   */
  function approve(address _spender,uint256 _value) public returns (bool _success) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

function transferFrom:


  function transferFrom(address _from,address _to,uint256 _value) public returns (bool _success){
    
    require(_to != address(0));
    balances[_from] -= _value;
    balances[_to] += _value;

    emit Transfer(_from, _to, _value);
    return true;

  }

revokeAllowace, just to test the transfer function…

  function revokeAllowance(address _owner, address _spender) public returns (bool success){
    delete allowed[_owner][_spender];

    return true;
  }
1 Like