// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// ODIN token contract
// ----------------------------------------------------------------------------
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) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
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;
}
}
// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
contract ERC20Interface {
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
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);
event Burn(uint tokens);
}
// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
address public owner;
address private newOwner;
event OwnershipTransferred(address indexed _from, address indexed _to);
modifier onlyOwner {
require(msg.sender == owner);
_;
}
function transferOwnership(address _newOwner) onlyOwner public onlyOwner {
owner = _newOwner;
emit OwnershipTransferred(msg.sender, _newOwner);
}
}
// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and assisted
// token transfers
// ----------------------------------------------------------------------------
contract OdinToken is ERC20Interface, Owned {
using SafeMath for uint256;
string public symbol;
string public name;
uint8 public decimals;
uint private _totalSupply;
bool private _whitelistAll;
struct balanceData {
bool locked;
uint balance;
uint airDropQty;
}
mapping(address => balanceData) balances;
mapping(address => mapping(address => uint)) allowed;
/**
* @dev Constructor for Odin creation
* @dev Initially assigns the totalSupply to the contract creator
*/
function OdinToken() public {
// owner of this contract
owner = msg.sender;
symbol = "ODIN";
name = "ODIN Token";
decimals = 18;
_whitelistAll=false;
_totalSupply = 100000000000000000000000;
balances[owner].balance = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
function totalSupply() constant public returns (uint256 totalSupply) {
return _totalSupply;
}
// ------------------------------------------------------------------------
// whitelist an address
// ------------------------------------------------------------------------
function whitelistAddress(address to) onlyOwner public returns (bool) {
balances[to].airDropQty = 0;
return true;
}
/**
* @dev Whitelist all addresses early
* @return An bool showing if the function succeeded.
*/
function whitelistAllAddresses() onlyOwner public returns (bool) {
_whitelistAll = true;
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param tokenOwner The address to query the the balance of.
* @return An uint representing the amount owned by the passed address.
*/
function balanceOf(address tokenOwner) public constant returns (uint balance) {
return balances[tokenOwner].balance;
}
/**
* @dev transfer token for a specified address
* @param to The address to transfer to.
* @param tokens The amount to be transferred.
*/
function transfer(address to, uint tokens) public returns (bool success) {
require (msg.sender != to); // cannot send to yourself
require(to != address(0)); // cannot send to address(0)
require(tokens <= balances[msg.sender].balance); // do you have enough to send?
if (!_whitelistAll) {
// do not allow transfering air dropped tokens prior to Sep 1 2018
if (msg.sender != owner && block.timestamp < 1535760000 && balances[msg.sender].airDropQty>0) {
require(tokens < 0);
}
// after Sep 1 2018 and before Dec 31, 2018, do not allow transfering more than 10% of air dropped tokens
if (msg.sender != owner && block.timestamp < 1546214400 && balances[msg.sender].airDropQty>0) {
require((balances[msg.sender].balance - tokens) >= (balances[msg.sender].airDropQty / 10 * 9));
}
// after Dec 31 2018 and before March 31, 2019, do not allow transfering more than 25% of air dropped tokens
if (msg.sender != owner && block.timestamp < 1553990400 && balances[msg.sender].airDropQty>0) {
require((balances[msg.sender].balance - tokens) >= balances[msg.sender].airDropQty / 4 * 3);
}
// after March 31, 2019 and before Jun 30, 2019, do not allow transfering more than 50% of air dropped tokens
if (msg.sender != owner && block.timestamp < 1561852800 && balances[msg.sender].airDropQty>0) {
require((balances[msg.sender].balance - tokens) >= balances[msg.sender].airDropQty / 2);
}
// after Jun 30, 2019 and before Oct 2, 2019, do not allow transfering more than 75% of air dropped tokens
if (msg.sender != owner && block.timestamp < 1569974400 && balances[msg.sender].airDropQty>0) {
require((balances[msg.sender].balance - tokens) >= balances[msg.sender].airDropQty / 4);
}
// otherwise, no transfer restrictions
}
balances[msg.sender].balance = balances[msg.sender].balance.sub(tokens);
balances[to].balance = balances[to].balance.add(tokens);
if (msg.sender == owner) {
balances[to].airDropQty = balances[to].airDropQty.add(tokens);
}
emit Transfer(msg.sender, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// not implemented
// ------------------------------------------------------------------------
function approve(address spender, uint tokens) public returns (bool success) {
return false;
}
// ------------------------------------------------------------------------
// not implemented
// ------------------------------------------------------------------------
function transferFrom(address from, address to, uint tokens) public returns (bool success) {
return false;
}
// ------------------------------------------------------------------------
// not implemented
// ------------------------------------------------------------------------
function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
return 0;
}
// ------------------------------------------------------------------------
// not implemented
// ------------------------------------------------------------------------
function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
return false;
}
// ------------------------------------------------------------------------
// Used to burn unspent tokens in the contract
// ------------------------------------------------------------------------
function burn(uint256 tokens) onlyOwner public returns (bool) {
require((balances[owner].balance - tokens) >= 0);
balances[owner].balance = balances[owner].balance.sub(tokens);
_totalSupply = _totalSupply.sub(tokens);
emit Burn(tokens);
return true;
}
function () {
//if ether is sent to this address, send it back.
throw;
}
}
{
"compilationTarget": {
"OdinToken.sol": "OdinToken"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[],"name":"whitelistAllAddresses","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"totalSupply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"}],"name":"whitelistAddress","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"uint256"}],"name":"burn","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"},{"name":"data","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenOwner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Burn","type":"event"}]