Token-generator output that bolts a self-service sale onto an ERC-20: send ether to the contract and it moves tokens out of the creator's balance to you.
Historical Significance
Contracts like this are why 2018 produced tens of thousands of near-identical tokens. The template turns a launch into a constructor call, and the built-in faucet mode, a free allocation capped at one per address, made an airdrop possible without any off-chain infrastructure at all. The missing approve and transferFrom are the tell that it was written to be deployed and advertised rather than integrated.
Token Information
Key Facts
Description
Name, symbol, decimals, supply, sale window, rate and free-claim size are all constructor arguments, so one compiled artifact serves any number of launches. The whole supply is credited to the creator at construction; there is no minting.
The payable fallback is the sale. It refuses unless autoSend is on and the clock is inside the start and end window, then prices the buy as value times rate times ten to the decimals, divided by one ether, through SafeMath. A rate of zero switches the contract into giveaway mode: the buyer receives freeCount whole tokens and a per-address counter makes sure they can only claim once. Either way the tokens come out of the creator's balance, and the transfer is booked as an ordinary Transfer event so wallets see it.
transfer is the plain minimum: no allowances, no approve, no transferFrom, and no return value, so this is not a fully conformant ERC-20. getETH lets the creator withdraw the proceeds. Comments in the source are in Chinese.
This variant differs from the more common build of the same template by routing the sale arithmetic through SafeMath rather than doing it inline.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Byzantium Era
First Metropolis hard fork. Added zk-SNARK precompiles, REVERT opcode, and staticcall.
Bytecode Overview
Verified Source Available
This contract has verified source code.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
pragma solidity ^0.4.21;
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract Token {
string public name;
string public symbol;
uint256 public decimals;
uint256 public totalSupply;
address public creator;
bool public autoSend = false;
uint public start;
uint public end;
uint public rate;
uint public freeCount;
mapping (address => uint256) public balanceOf;
mapping (address => uint8) public buyCountOf;
event Transfer(address indexed from, address indexed to, uint256 value);
// buy token
function () public payable {
require(autoSend);
require(now >= start && now <= end);
uint256 weiAmount = msg.value;
uint256 tokens;
if (rate == 0)
tokens = freeCount * (10 ** decimals);
else
tokens = SafeMath.div(SafeMath.mul(SafeMath.mul(weiAmount, rate), 10 ** decimals), 1000000000000000000);
require(tokens > 0);
// 不要自己提到自己账户
require(creator != msg.sender);
// 首先检查发token的账户是否拥有对应数量的代币
require(balanceOf[creator] >= tokens);
// 当 rate 为 0 时,检查是否已经领取过
if (rate == 0)
require(buyCountOf[msg.sender] < 1);
// 开始转移代币
uint previousBalances = balanceOf[msg.sender] + balanceOf[creator];
balanceOf[msg.sender] += tokens;
balanceOf[creator] -= tokens;
// 这个是事件
emit Transfer(creator,msg.sender, tokens);
assert(balanceOf[msg.sender] + balanceOf[creator] == previousBalances);
if (rate == 0)
buyCountOf[msg.sender] += 1;
}
function getETH() public {
require(address(this).balance > 0 && msg.sender == creator);
creator.transfer(address(this).balance);
}
function Token(
uint256 initialSupply,
string tokenName,
string tokenSymbol,
uint8 tokenDecimals,
bool tokenAutoSend,
uint tokenStart,
uint tokenEnd,
uint tokenPrice,
uint tokenFreeCount
) public payable
{
name = tokenName;
symbol = tokenSymbol;
decimals = tokenDecimals;
creator = msg.sender;
totalSupply = initialSupply * ( 10 ** uint256(decimals) );
balanceOf[msg.sender] = totalSupply;
autoSend = tokenAutoSend;
start = tokenStart;
end = tokenEnd;
rate = tokenPrice;
freeCount = tokenFreeCount;
}
function transfer(address _to, uint256 _value) public {
// _value = _value * ( 10 ** uint256(decimals) );
require(_to != 0x0);
require(msg.sender != _to);
require(balanceOf[msg.sender] >= _value);
require(balanceOf[_to] + _value > balanceOf[_to]);
uint previousBalances = balanceOf[msg.sender] + balanceOf[_to];
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
// 这个是事件
emit Transfer(msg.sender, _to, _value);
assert(balanceOf[msg.sender] + balanceOf[_to] == previousBalances);
}
}External Links
Related contracts
Msg
Same eraMinimal contract that stores a single public string in state, exposed via the auto-generated m() getter. First of 281 identical siblings. Source verified by EthereumHistory.
0x2c8f58...37b173January 13, 2018Wallet
Same eraToken collection wallet that moves an entire token balance to a chosen address, without the ERC223 callback handler.
0x002204...531195January 19, 2018Wallet
Same eraOwner wallet that forwards ether to its owner, logs any call from a stranger with the full calldata, and lets the owner execute arbitrary calls.
0x001feb...9e7a4fJanuary 20, 2018Sweeper
Same eraMinimal ETH sweeper, first of 1,900 identical deployments in a 2-day burst in January 2018. All sweep to a single hardcoded destination. Source verified by EthereumHistory.
0xeb15f6...6cb3e1January 23, 2018Sweep
Same eraETH sweep-to-fixed-recipient — fallback forwards the contract's entire balance to `0xd293a88c…8d4` via `.send()` and reverts on failure. Massive cluster of 1899 identical deployments — likely deposit-address contracts for a single custodian.
0x00188b...b260a7January 23, 2018Forwarder
Same eraDeposit forwarder in the BitGo style, sending ether to a parent address and able to flush stranded tokens to the same place.
0x00d083...4d5405February 2, 2018