Skip to content

Instantly share code, notes, and snippets.

@jtakalai
Last active September 18, 2018 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jtakalai/35ea6d7d449b92180172410b32c2826c to your computer and use it in GitHub Desktop.
Save jtakalai/35ea6d7d449b92180172410b32c2826c to your computer and use it in GitHub Desktop.
ERC20 compatible token with an added feature
pragma solidity ^0.4.24;
// Token standard interface
contract ERC20 {
// Basic token features: book of balances and transfer
uint public totalSupply = 0;
mapping (address => uint256) public balanceOf;
function transfer(address to, uint tokens) public returns (bool success);
// Advanced features: An account can approve another account to spend its funds
mapping(address => mapping (address => uint256)) public allowance;
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
// Universal Basic Income for all token holders! Join today!
contract UbiToken is ERC20 {
// metadata for wallets
string public constant name = "UBI Token";
string public constant symbol = "UBI";
uint8 public constant decimals = 18;
// token holders, also UBI recipients
address[] public holders;
// how much everyone gets every time tokens are transferred
uint256 DISTRIBUTION_AMOUNT = 1 ether;
uint256 WELCOME_AMOUNT = 100 ether;
// distribute UBI every time someone receives tokens
function _onReceive(address to) internal {
bool isNew = true;
// fresh tokens for everyone!
for (uint i = 0; i < holders.length; i++) {
if (to == holders[i]) { isNew = false; }
_mint(holders[i], DISTRIBUTION_AMOUNT);
}
// "new" addresses have an initial balance
if (isNew) {
holders.push(to);
_mint(to, WELCOME_AMOUNT);
}
}
address public owner;
constructor() public {
owner = msg.sender;
mint(msg.sender, 1);
}
function mint(address to, uint256 value) public {
require(msg.sender == owner, "Privileged operation");
_onReceive(to);
_mint(to, value);
}
function _mint(address to, uint256 value) internal {
require(totalSupply + value > totalSupply, "Overflow");
balanceOf[to] += value;
totalSupply += value;
emit Transfer(0, to, value);
}
function transfer(address to, uint256 value) public returns (bool success) {
require(balanceOf[msg.sender] >= value, "Not enough tokens");
require(value > 0, "Zero transfer");
require(balanceOf[to] + value > balanceOf[to], "Overflow");
_onReceive(to);
balanceOf[msg.sender] -= value;
balanceOf[to] += value;
emit Transfer(msg.sender, to, value);
return true;
}
function approve(address spender, uint tokens) public returns (bool success) {
allowance[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
return true;
}
function transferFrom(address from, address to, uint value) public returns (bool success) {
require(balanceOf[from] >= value, "Not enough tokens");
require(value > 0, "Zero transfer");
require(balanceOf[to] + value > balanceOf[to], "Overflow");
require(allowance[from][msg.sender] >= value, "Not enough allowance");
_onReceive(to);
balanceOf[from] -= value;
allowance[from][msg.sender] -= value;
balanceOf[to] += value;
emit Transfer(from, to, value);
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment