Spaces:
Runtime error
Runtime error
pragma solidity ^0.4.13; | |
contract owned { | |
address public owner; | |
mapping (address => bool) public admins; | |
function owned() { | |
owner = msg.sender; | |
admins[msg.sender]=true; | |
} | |
modifier onlyOwner { | |
require(msg.sender == owner); | |
_; | |
} | |
modifier onlyAdmin { | |
require(admins[msg.sender] == true); | |
_; | |
} | |
function transferOwnership(address newOwner) onlyOwner { | |
owner = newOwner; | |
} | |
function makeAdmin(address newAdmin, bool isAdmin) onlyOwner { | |
admins[newAdmin] = isAdmin; | |
} | |
} | |
interface tokenRecipient { | |
function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); | |
} | |
contract GRX is owned { | |
// Public variables of the token | |
string public name; | |
string public symbol; | |
uint8 public decimals; | |
uint256 public totalSupply; | |
uint256 minBalanceForAccounts; | |
bool public usersCanTrade; | |
bool public usersCanUnfreeze; | |
bool public ico = true; //turn ico on and of | |
mapping (address => bool) public admin; | |
modifier notICO { | |
require(admin[msg.sender] || !ico); | |
_; | |
} | |
// This creates an array with all balances | |
mapping (address => uint256) public balanceOf; | |
mapping (address => mapping (address => uint256)) public allowance; | |
mapping (address => bool) public frozen; | |
mapping (address => bool) public canTrade; //user allowed to buy or sell | |
// This generates a public event on the blockchain that will notify clients | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
//This generates a public even on the blockhcain when an address is reward | |
event Reward(address from, address to, uint256 value, string data, uint256 time); | |
// This notifies clients about the amount burnt | |
event Burn(address indexed from, uint256 value); | |
// This generates a public event on the blockchain that will notify clients | |
event Frozen(address indexed addr, bool frozen); | |
// This generates a public event on the blockchain that will notify clients | |
event Unlock(address indexed addr, address from, uint256 val); | |
// This generates a public event on the blockchain that will notify clients | |
// This generates a public event on the blockchain that will notify clients | |
// event Unfreeze(address indexed addr); | |
/** | |
* Constrctor function | |
* | |
* Initializes contract with initial supply tokens to the creator of the contract | |
*/ | |
function GRX() { | |
uint256 initialSupply = 20000000000000000000000000; | |
balanceOf[msg.sender] = initialSupply ; // Give the creator all initial tokens | |
totalSupply = initialSupply; // Update total supply | |
name = "Gold Reward Token"; // Set the name for display purposes | |
symbol = "GRX"; // Set the symbol for display purposes | |
decimals = 18; // Amount of decimals for display purposes | |
minBalanceForAccounts = 1000000000000000; | |
usersCanTrade=false; | |
usersCanUnfreeze=false; | |
admin[msg.sender]=true; | |
canTrade[msg.sender]=true; | |
} | |
/** | |
* Increace Total Supply | |
* | |
* Increases the total coin supply | |
*/ | |
function increaseTotalSupply (address target, uint256 increaseBy ) onlyOwner { | |
balanceOf[target] += increaseBy; | |
totalSupply += increaseBy; | |
Transfer(0, owner, increaseBy); | |
Transfer(owner, target, increaseBy); | |
} | |
function usersCanUnFreeze(bool can) { | |
usersCanUnfreeze=can; | |
} | |
function setMinBalance(uint minimumBalanceInWei) onlyOwner { | |
minBalanceForAccounts = minimumBalanceInWei; | |
} | |
/** | |
* transferAndFreeze | |
* | |
* Function to transfer to and freeze and account at the same time | |
*/ | |
function transferAndFreeze (address target, uint256 amount ) onlyAdmin { | |
_transfer(msg.sender, target, amount); | |
freeze(target, true); | |
} | |
/** | |
* _freeze internal | |
* | |
* function to freeze an account | |
*/ | |
function _freeze (address target, bool froze ) internal { | |
frozen[target]=froze; | |
Frozen(target, froze); | |
} | |
/** | |
* freeze | |
* | |
* function to freeze an account | |
*/ | |
function freeze (address target, bool froze ) { | |
if(froze || (!froze && !usersCanUnfreeze)) { | |
require(admin[msg.sender]); | |
} | |
_freeze(target, froze); | |
} | |
/** | |
* Internal transfer, only can be called by this contract | |
*/ | |
function _transfer(address _from, address _to, uint _value) internal { | |
require(_to != 0x0); // Prevent transfer to 0x0 address. Use burn() instead | |
require(!frozen[_from]); //prevent transfer from frozen address | |
require(balanceOf[_from] >= _value); // Check if the sender has enough | |
require(balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows | |
balanceOf[_from] -= _value; // Subtract from the sender | |
balanceOf[_to] += _value; // Add the same to the recipient | |
Transfer(_from, _to, _value); | |
} | |
/** | |
* Transfer tokens | |
* | |
* Send `_value` tokens to `_to` from your account | |
* | |
* @param _to The address of the recipient | |
* @param _value the amount to send | |
*/ | |
function transfer(address _to, uint256 _value) notICO { | |
require(!frozen[msg.sender]); //prevent transfer from frozen address | |
if (msg.sender.balance < minBalanceForAccounts) { | |
sell((minBalanceForAccounts - msg.sender.balance) * sellPrice); | |
} | |
_transfer(msg.sender, _to, _value); | |
} | |
mapping (address => uint256) public totalLockedRewardsOf; | |
mapping (address => mapping (address => uint256)) public lockedRewardsOf; //balance of a locked reward | |
mapping (address => mapping (uint32 => address)) public userRewarders; //indexed list of rewardees rewarder | |
mapping (address => mapping (address => uint32)) public userRewardCount; //a list of number of times a customer has received reward from a given merchant | |
mapping (address => uint32) public userRewarderCount; //number of rewarders per customer | |
//merchant | |
mapping (address => uint256 ) public totalRewardIssuedOut; | |
/** | |
* Reward tokens - tokens go to | |
* | |
* Send `_value` tokens to `_to` from your account | |
* | |
* @param _to The address of the recipient | |
* @param _value the amount to send | |
*/ | |
function reward(address _to, uint256 _value, bool locked, string data) { | |
require(_to != 0x0); | |
require(!frozen[msg.sender]); //prevent transfer from frozen address | |
if (msg.sender.balance < minBalanceForAccounts) { | |
sell((minBalanceForAccounts - msg.sender.balance) * sellPrice); | |
} | |
if(!locked) { | |
_transfer(msg.sender, _to, _value); | |
}else{ | |
//prevent transfer from frozen address | |
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough | |
require(totalLockedRewardsOf[_to] + _value > totalLockedRewardsOf[_to]); // Check for overflows | |
balanceOf[msg.sender] -= _value; // Subtract from the sender | |
totalLockedRewardsOf[_to] += _value; // Add the same to the recipient | |
lockedRewardsOf[_to][msg.sender] += _value; | |
if(userRewardCount[_to][msg.sender]==0) { | |
userRewarderCount[_to] += 1; | |
userRewarders[_to][userRewarderCount[_to]]=msg.sender; | |
} | |
userRewardCount[_to][msg.sender]+=1; | |
totalRewardIssuedOut[msg.sender]+= _value; | |
Transfer(msg.sender, _to, _value); | |
} | |
Reward(msg.sender, _to, _value, data, now); | |
} | |
/** | |
* Transfer locked rewards | |
* | |
* Send `_value` tokens to `_to` merchant | |
* | |
* @param _to The address of the recipient | |
* @param _value the amount to send | |
*/ | |
function transferReward(address _to, uint256 _value) { | |
require(!frozen[msg.sender]); //prevent transfer from frozen address | |
require(lockedRewardsOf[msg.sender][_to] >= _value ); | |
require(totalLockedRewardsOf[msg.sender] >= _value); | |
if (msg.sender.balance < minBalanceForAccounts) { | |
sell((minBalanceForAccounts - msg.sender.balance) * sellPrice); | |
} | |
totalLockedRewardsOf[msg.sender] -= _value; // Add the same to the recipient | |
lockedRewardsOf[msg.sender][_to] -= _value; | |
balanceOf[_to] += _value; | |
Transfer(msg.sender, _to, _value); | |
} | |
/** | |
* Unlocked locked rewards by merchant | |
* | |
* Unlock `_value` tokens of `add` | |
* | |
* @param addr The address of the recipient | |
* @param _value the amount to unlock | |
*/ | |
function unlockReward(address addr, uint256 _value) { | |
require(totalLockedRewardsOf[addr] > _value); //prevent transfer from frozen address | |
require(lockedRewardsOf[addr][msg.sender] >= _value ); | |
if(_value==0) _value=lockedRewardsOf[addr][msg.sender]; | |
if (msg.sender.balance < minBalanceForAccounts) { | |
sell((minBalanceForAccounts - msg.sender.balance) * sellPrice); | |
} | |
totalLockedRewardsOf[addr] -= _value; // Add the same to the recipient | |
lockedRewardsOf[addr][msg.sender] -= _value; | |
balanceOf[addr] += _value; | |
Unlock(addr, msg.sender, _value); | |
} | |
/** | |
* Transfer tokens from other address | |
* | |
* Send `_value` tokens to `_to` in behalf of `_from` | |
* | |
* @param _from The address of the sender | |
* @param _to The address of the recipient | |
* @param _value the amount to send | |
*/ | |
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) { | |
require(!frozen[_from]); //prevent transfer from frozen address | |
require(_value <= allowance[_from][msg.sender]); // Check allowance | |
allowance[_from][msg.sender] -= _value; | |
_transfer(_from, _to, _value); | |
return true; | |
} | |
/** | |
* Set allowance for other address | |
* | |
* Allows `_spender` to spend no more than `_value` tokens in your behalf | |
* | |
* @param _spender The address authorized to spend | |
* @param _value the max amount they can spend | |
*/ | |
function approve(address _spender, uint256 _value) | |
returns (bool success) { | |
allowance[msg.sender][_spender] = _value; | |
return true; | |
} | |
/** | |
* Set allowance for other address and notify | |
* | |
* Allows `_spender` to spend no more than `_value` tokens in your behalf, and then ping the contract about it | |
* | |
* @param _spender The address authorized to spend | |
* @param _value the max amount they can spend | |
* @param _extraData some extra information to send to the approved contract | |
*/ | |
function approveAndCall(address _spender, uint256 _value, bytes _extraData) onlyOwner | |
returns (bool success) { | |
tokenRecipient spender = tokenRecipient(_spender); | |
if (approve(_spender, _value)) { | |
spender.receiveApproval(msg.sender, _value, this, _extraData); | |
return true; | |
} | |
} | |
/** | |
* Destroy tokens | |
* | |
* Remove `_value` tokens from the system irreversibly | |
* | |
* @param _value the amount of money to burn | |
*/ | |
function burn(uint256 _value) onlyOwner returns (bool success) { | |
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough | |
balanceOf[msg.sender] -= _value; // Subtract from the sender | |
totalSupply -= _value; // Updates totalSupply | |
Burn(msg.sender, _value); | |
return true; | |
} | |
/** | |
* Destroy tokens from other ccount | |
* | |
* Remove `_value` tokens from the system irreversibly on behalf of `_from`. | |
* | |
* @param _from the address of the sender | |
* @param _value the amount of money to burn | |
*/ | |
function burnFrom(address _from, uint256 _value) returns (bool success) { | |
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough | |
require(_value <= allowance[_from][msg.sender]); // Check allowance | |
balanceOf[_from] -= _value; // Subtract from the targeted balance | |
allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance | |
totalSupply -= _value; // Update totalSupply | |
Burn(_from, _value); | |
return true; | |
} | |
/* | |
function increaseSupply(address _from, uint256 _value) onlyOwner returns (bool success) { | |
balanceOf[_from] += _value; // Subtract from the targeted balance | |
totalSupply += _value; // Update totalSupply | |
// Burn(_from, _value); | |
return true; | |
} | |
*/ | |
uint256 public sellPrice = 608; | |
uint256 public buyPrice = 760; | |
function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner { | |
sellPrice = newSellPrice; | |
buyPrice = newBuyPrice; | |
} | |
function setUsersCanTrade(bool trade) onlyOwner { | |
usersCanTrade=trade; | |
} | |
function setCanTrade(address addr, bool trade) onlyOwner { | |
canTrade[addr]=trade; | |
} | |
//user is buying grx | |
function buy() payable returns (uint256 amount){ | |
if(!usersCanTrade && !canTrade[msg.sender]) revert(); | |
amount = msg.value * buyPrice; // calculates the amount | |
require(balanceOf[this] >= amount); // checks if it has enough to sell | |
balanceOf[msg.sender] += amount; // adds the amount to buyer's balance | |
balanceOf[this] -= amount; // subtracts amount from seller's balance | |
Transfer(this, msg.sender, amount); // execute an event reflecting the change | |
return amount; // ends function and returns | |
} | |
//user is selling us grx, we are selling eth to the user | |
function sell(uint256 amount) returns (uint revenue){ | |
require(!frozen[msg.sender]); | |
if(!usersCanTrade && !canTrade[msg.sender]) { | |
require(minBalanceForAccounts > amount/sellPrice); | |
} | |
require(balanceOf[msg.sender] >= amount); // checks if the sender has enough to sell | |
balanceOf[this] += amount; // adds the amount to owner's balance | |
balanceOf[msg.sender] -= amount; // subtracts the amount from seller's balance | |
revenue = amount / sellPrice; | |
require(msg.sender.send(revenue)); // sends ether to the seller: it's important to do this last to prevent recursion attacks | |
Transfer(msg.sender, this, amount); // executes an event reflecting on the change | |
return revenue; // ends function and returns | |
} | |
function() payable { | |
} | |
event Withdrawn(address indexed to, uint256 value); | |
function withdraw(address target, uint256 amount) onlyOwner { | |
target.transfer(amount); | |
Withdrawn(target, amount); | |
} | |
function setAdmin(address addr, bool enabled) onlyOwner { | |
admin[addr]=enabled; | |
} | |
function setICO(bool enabled) onlyOwner { | |
ico=enabled; | |
} | |
} |