Skip to content

Instantly share code, notes, and snippets.

@yuriy77k
Created November 7, 2018 13:30
Show Gist options
  • Save yuriy77k/3f3d4a78958004e452a7c16e30322270 to your computer and use it in GitHub Desktop.
Save yuriy77k/3f3d4a78958004e452a7c16e30322270 to your computer and use it in GitHub Desktop.
CryptosoulToken
pragma solidity ^0.4.24;
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 result = a * b;
assert(a == 0 || result / a == b);
return result;
}
function div(uint256 a, uint256 b)internal pure returns (uint256) {
uint256 result = a / b;
return result;
}
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 result = a + b;
assert(result >= a);
return result;
}
}
contract ERC20Basic {
uint256 public totalSupply;
event Transfer(address indexed from, address indexed to, uint256 value);
function balanceOf(address who) public view returns(uint256);
function transfer(address to, uint256 value) public returns(bool);
}
contract ERC20 is ERC20Basic {
event Approval(address indexed owner, address indexed spender, uint256 value);
function allowance(address owner, address spender) public view returns (uint256);
function approve(address spender, uint256 value) public returns (bool);
function transferFrom(address from, address to, uint256 value) public returns (bool);
}
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
struct WalletData {
uint256 tokensAmount; //Tokens amount on wallet
uint256 freezedAmount; //Freezed tokens amount on wallet.
bool canFreezeTokens; //Is wallet can freeze tokens or not.
uint unfreezeDate; // Date when we can unfreeze tokens on wallet.
}
mapping(address => WalletData) wallets;
function transfer(address _to, uint256 _value) public notSender(_to) returns(bool) {
require(_to != address(0)
&& wallets[msg.sender].tokensAmount >= _value
&& checkIfCanUseTokens(msg.sender, _value));
uint256 amount = wallets[msg.sender].tokensAmount.sub(_value);
wallets[msg.sender].tokensAmount = amount;
wallets[_to].tokensAmount = wallets[_to].tokensAmount.add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
function balanceOf(address _owner) public view returns(uint256 balance) {
return wallets[_owner].tokensAmount;
}
// Check wallet on unfreeze tokens amount
function checkIfCanUseTokens(address _owner, uint256 _amount) internal view returns(bool) {
uint256 unfreezedAmount = wallets[_owner].tokensAmount - wallets[_owner].freezedAmount;
return _amount <= unfreezedAmount;
}
// Prevents user to send transaction on his own address
modifier notSender(address _owner) {
require(msg.sender != _owner);
_;
}
}
contract StandartToken is ERC20, BasicToken{
mapping (address => mapping (address => uint256)) allowed;
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
return allowed[_owner][_spender];
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0) &&
checkIfCanUseTokens(_from, _value) &&
_value <= wallets[_from].tokensAmount &&
_value <= allowed[_from][msg.sender]);
wallets[_from].tokensAmount = wallets[_from].tokensAmount.sub(_value);
wallets[_to].tokensAmount = wallets[_to].tokensAmount.add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
}
contract Ownable {
constructor() public {
owner = msg.sender;
}
event TransferOwnership(address indexed _previousOwner, address indexed _newOwner);
address public owner = 0x0;
//wallet that can change owner
address internal masterKey = 0x4977A392d8D207B49c7fDE8A6B91C23bCebE7291;
function transferOwnership(address _newOwner) public returns(bool);
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
}
contract FreezableToken is StandartToken, Ownable {
event ChangeFreezePermission(address indexed _owner, bool _permission);
event FreezeTokens(address indexed _owner, uint256 _freezeAmount);
event UnfreezeTokens(address indexed _owner, uint256 _unfreezeAmount);
// Give\deprive permission to a wallet for freeze tokens.
function giveFreezePermission(address[] _owners, bool _permission) public onlyOwner returns(bool) {
for (uint i = 0; i < _owners.length; i++) {
wallets[_owners[i]].canFreezeTokens = _permission;
emit ChangeFreezePermission(_owners[i], _permission);
}
return true;
}
function freezeAllowance(address _owner) public view returns(bool) {
return wallets[_owner].canFreezeTokens;
}
// Freeze tokens on sender wallet if have permission.
function freezeTokens(uint256 _amount, uint _unfreezeDate) public isFreezeAllowed returns(bool) {
//We can freeze tokens only if there are no frozen tokens on the wallet.
require(wallets[msg.sender].freezedAmount == 0
&& wallets[msg.sender].tokensAmount >= _amount);
wallets[msg.sender].freezedAmount = _amount;
wallets[msg.sender].unfreezeDate = _unfreezeDate;
emit FreezeTokens(msg.sender, _amount);
return true;
}
function showFreezedTokensAmount(address _owner) public view returns(uint256) {
return wallets[_owner].freezedAmount;
}
function unfreezeTokens() public returns(bool) {
require(wallets[msg.sender].freezedAmount > 0
&& now >= wallets[msg.sender].unfreezeDate);
emit UnfreezeTokens(msg.sender, wallets[msg.sender].freezedAmount);
wallets[msg.sender].freezedAmount = 0; // Unfreeze all tokens.
wallets[msg.sender].unfreezeDate = 0;
return true;
}
//Show date in UNIX time format.
function showTokensUnfreezeDate(address _owner) public view returns(uint) {
//If wallet don't have freezed tokens - function will return 0.
return wallets[_owner].unfreezeDate;
}
function getUnfreezedTokens(address _owner) internal view returns(uint256) {
return wallets[_owner].tokensAmount - wallets[_owner].freezedAmount;
}
modifier isFreezeAllowed() {
require(freezeAllowance(msg.sender));
_;
}
}
contract MultisendableToken is FreezableToken {
function massTransfer(address[] _addresses, uint[] _values) public onlyOwner returns(bool) {
for (uint i = 0; i < _addresses.length; i++) {
transferFromOwner(_addresses[i], _values[i]);
}
return true;
}
function massApprove(address[] _spenders, uint256[] _values) public returns (bool succes) {
for(uint i = 0; i < _spenders.length; i++) {
approve(_spenders[i], _values[i]);
}
return true;
}
function transferFromOwner(address _to, uint256 _value) internal notSender(_to) onlyOwner {
require(_to != address(0)
&& wallets[owner].tokensAmount >= _value
&& checkIfCanUseTokens(owner, _value));
wallets[owner].tokensAmount = wallets[owner].tokensAmount.sub(_value);
wallets[_to].tokensAmount = wallets[_to].tokensAmount.add(_value);
emit Transfer(owner, _to, _value);
}
}
contract CryptosoulToken is MultisendableToken {
event AllowMinting();
event Burn(address indexed _from, uint256 _value);
event Mint(address indexed _to, uint256 _value);
string constant public name = "CryptoSoul";
string constant public symbol = "SOUL";
uint constant public decimals = 18;
uint256 constant public START_TOKENS = 500000000 * 10**decimals; //500M start
uint256 constant public MINT_AMOUNT = 1370000 * 10**decimals;
uint256 constant public MINT_INTERVAL = 1 days; // 24 hours
uint256 constant private MAX_BALANCE_VALUE = 10000000000 * 10**decimals;
uint256 public nextMintPossibleDate = 0;
bool public canMint = false;
constructor() public {
wallets[owner].tokensAmount = START_TOKENS;
wallets[owner].canFreezeTokens = true;
totalSupply = START_TOKENS;
nextMintPossibleDate = 1538352000; //01.10.2018 (DD, MM, YYYY)
emit Mint(owner, START_TOKENS);
}
function allowMinting() public onlyOwner {
// Can start minting token after 01.10.2018
require(!canMint
&& now >= nextMintPossibleDate);
nextMintPossibleDate = now;
canMint = true;
emit AllowMinting();
}
function mint() public onlyOwner returns(bool) {
require(canMint
&& now >= nextMintPossibleDate
&& totalSupply + MINT_AMOUNT <= MAX_BALANCE_VALUE);
nextMintPossibleDate = nextMintPossibleDate.add(MINT_INTERVAL);
wallets[owner].tokensAmount = wallets[owner].tokensAmount.
add(MINT_AMOUNT);
totalSupply = totalSupply.add(MINT_AMOUNT);
emit Mint(owner, MINT_AMOUNT);
return true;
}
function burn(uint256 value) public onlyOwner returns(bool) {
require(checkIfCanUseTokens(owner, value)
&& wallets[owner].tokensAmount >= value);
wallets[owner].tokensAmount = wallets[owner].
tokensAmount.sub(value);
totalSupply = totalSupply.sub(value);
emit Burn(owner, value);
return true;
}
function transferOwnership(address _newOwner) public notSender(_newOwner) returns(bool) {
require(msg.sender == masterKey
&& _newOwner != address(0));
emit TransferOwnership(owner, _newOwner);
owner = _newOwner;
return true;
}
function() public payable {
revert();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment