Back to Home

Ether Token Proxy(ETH)

Token
0x89d64bc7e46b...67418cbad62e
HomesteadContract #15KSource VerifiedEdit this contract
Deployed April 25, 2016 (9 years ago)Block 1,397,553

The earliest fully compliant ERC-20 token contract on Ethereum mainnet, wrapping Ether 1:1 into a transferable token.

Token Information

Token Name
Ether Token Proxy
Symbol
ETH
Decimals
18

Key Facts

Deployment Block
1,397,553
Deployment Date
Apr 25, 2016, 01:30 AM
Code Size
1.9 KB
Gas at Deploy
568,044
Transactions by Year
201610
20211
20235

Description

Ether Token Proxy is a fully ERC-20 compliant smart contract that tokenizes Ether into a standard ERC-20 representation. Users deposit ETH to receive ERC-20 tokens and can redeem those tokens at any time to withdraw the underlying ETH.

The contract implements the complete ERC-20 interface:

  • totalSupply()
  • balanceOf(address)
  • transfer(address,uint256)
  • transferFrom(address,address,uint256)
  • approve(address,uint256)
  • allowance(address,address)

It emits properly structured Transfer and Approval events in accordance with the ERC-20 specification.

Supply is dynamic and equals the contract’s ETH balance. Deposits mint tokens, withdrawals burn them, maintaining full collateralization at all times.

Source Verified

Etherscan verified

Heuristic Analysis

The following characteristics were detected through bytecode analysis and may not be accurate.

Detected Type: Token
Has ERC-20-like patterns

Homestead Era

The first planned hard fork. Removed the canary contract, adjusted gas costs.

Block span: 1,150,0001,919,999
March 14, 2016July 20, 2016

Bytecode Overview

Opcodes1,937
Unique Opcodes184
Jump Instructions93
Storage Operations31

Verified Source Available

Source verified on Etherscan.

Show source code (Solidity)
/*
  live: 0x89d64bc7e46bdc49a89652ae9bb167418cbad62e
morden: 0xe379e36671acbcc87ec7b760c07e6e45a1294944
  solc: v0.3.1-2016-04-12-3ad5e82 (optimization)
*/

contract tokenRecipient {
    function receiveApproval(address _from, uint256 _value, address _token);
}

contract Token {
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function totalSupply() constant returns (uint256 supply);
    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 approveAndCall(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
}

contract SafeAddSub {
    function safeToAdd(uint a, uint b) internal returns (bool) {
        return (a + b > a);
    }

    function safeToSubtract(uint a, uint b) internal returns (bool) {
        return (a >= b);
    }

    function safeAdd(uint a, uint b) internal returns (uint256) {
        if (!safeToAdd(a, b)) throw;
        return a + b;
    }

    function safeSubtract(uint a, uint b) internal returns (uint256) {
        if (!safeToSubtract(a, b)) throw;
        return a - b;
    }
}

contract EthToken is Token, SafeAddSub {
    string public constant name = "Ether Token Proxy";
    string public constant symbol = "ETH";
    uint8   public constant decimals = 18;
    uint256 public constant baseUnit = 10**18;
    
    mapping (address => uint256) _balanceOf;
    mapping (address => mapping (address => uint256)) _allowance;

    event Deposit(address indexed owner, uint256 amount);
    event Withdrawal(address indexed owner, uint256 amount);

    function totalSupply() constant returns (uint256 supply) {
        return this.balance;
    }
    
    function () {
        deposit();
    }
    
    function deposit() {
        _balanceOf[msg.sender] = safeAdd(_balanceOf[msg.sender], msg.value);
        Deposit(msg.sender, msg.value);
    }
    
    function redeem() {
        withdraw(_balanceOf[msg.sender]);
    }
    
    function withdraw(uint256 _value) returns (bool success) {
        _balanceOf[msg.sender] = safeSubtract(_balanceOf[msg.sender], _value);
        if (!msg.sender.send(_value)) {
            if (!msg.sender.call.gas(msg.gas).value(_value)()) throw;
        }
        Withdrawal(msg.sender, _value);
        return true;
    }
    
    function balanceOf(address _owner) constant returns (uint256 balance) {
        return _balanceOf[_owner];
    }
    
    function transfer(address _to, uint256 _value) returns (bool success) {
        if (_to == address(this) || _to == 0) {
            return withdraw(_value);
        } else {
            _balanceOf[msg.sender] = safeSubtract(_balanceOf[msg.sender], _value);
            _balanceOf[_to] = safeAdd(_balanceOf[_to], _value);
            Transfer(msg.sender, _to, _value);
        }
        return true;
    }
    
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (!safeToSubtract(_allowance[_from][msg.sender], _value)) throw;
        if (_to == address(this) || _to == 0) {
            if (!transferFrom(_from, msg.sender, _value)) throw;
            withdraw(_value);
        } else {
            _balanceOf[_from] = safeSubtract(_balanceOf[_from], _value);
            _balanceOf[_to] = safeAdd(_balanceOf[_to], _value);
            _allowance[_from][msg.sender] = safeSubtract(_allowance[_from][msg.sender], _value);
            Transfer(_from, _to, _value);
        }
        return true;
    }
    
    function approve(address _spender, uint256 _value) returns (bool success) {
        _allowance[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }
    
    function approveAndCall(address _spender, uint256 _value) returns (bool success) {
        if (approve(_spender, _value)) {
            tokenRecipient(_spender).receiveApproval(msg.sender, _value, this);
            return true;
        }
        throw;
    }
    
    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
        return _allowance[_owner][_spender];
    }
}

External Links