pragma solidity 0.4.19;
contract BaseContract {
modifier greaterThanZero(uint256 _amount) {
require(_amount > 0);
_;
}
modifier isZero(uint256 _amount) {
require(_amount == 0);
_;
}
modifier nonZero(uint256 _amount) {
require(_amount != 0);
_;
}
modifier notThis(address _address) {
require(_address != address(this));
_;
}
modifier onlyIf(bool condition) {
require(condition);
_;
}
modifier validIndex(uint256 arrayLength, uint256 index) {
requireValidIndex(arrayLength, index);
_;
}
modifier validAddress(address _address) {
require(_address != 0x0);
_;
}
modifier validString(string value) {
require(bytes(value).length > 0);
_;
}
// mitigate short address attack
// http://vessenes.com/the-erc20-short-address-attack-explained/
modifier validParamData(uint256 numParams) {
uint256 expectedDataLength = (numParams * 32) + 4;
assert(msg.data.length >= expectedDataLength);
_;
}
function requireValidIndex(uint256 arrayLength, uint256 index)
internal
pure
{
require(index >= 0 && index < arrayLength);
}
}
contract Owned is BaseContract {
address public owner;
address public newOwner;
event OwnerUpdate(address indexed _prevOwner, address indexed _newOwner);
function Owned()
internal
{
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
/// @dev allows transferring the contract ownership
/// the new owner still needs to accept the transfer
/// can only be called by the contract owner
/// @param _newOwner new contract owner
function transferOwnership(address _newOwner)
public
validParamData(1)
onlyOwner
onlyIf(_newOwner != owner)
{
newOwner = _newOwner;
}
/// @dev used by a new owner to accept an ownership transfer
function acceptOwnership()
public
onlyIf(msg.sender == newOwner)
{
OwnerUpdate(owner, newOwner);
owner = newOwner;
newOwner = 0x0;
}
}
contract IToken {
function totalSupply()
public view
returns (uint256);
function balanceOf(address _owner)
public view
returns (uint256);
function transfer(address _to, uint256 _value)
public
returns (bool);
function transferFrom(address _from, address _to, uint256 _value)
public
returns (bool);
function approve(address _spender, uint256 _value)
public
returns (bool);
function allowance(address _owner, address _spender)
public view
returns (uint256);
}
contract TokenRetriever is Owned {
function TokenRetriever()
internal
{
}
/// @dev Failsafe mechanism - Allows owner to retrieve tokens from the contract
/// @param _token The address of ERC20 compatible token
function retrieveTokens(IToken _token)
public
onlyOwner
{
uint256 tokenBalance = _token.balanceOf(this);
if (tokenBalance > 0) {
_token.transfer(owner, tokenBalance);
}
}
}
/// @title Math operations with safety checks
library SafeMath {
function mul(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
uint256 c = a * b;
require(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
require(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)
{
require(b <= a);
return a - b;
}
function add(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
uint256 c = a + b;
require(c >= a);
return c;
}
function min256(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
return a < b ? a : b;
}
}
// solhint-disable no-simple-event-func-name
// ERC20 Standard Token implementation
contract ERC20Token is BaseContract {
using SafeMath for uint256;
string public name = "";
string public symbol = "";
uint8 public decimals = 0;
uint256 public totalSupply = 0;
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
/// @dev constructor
/// @param _name token name
/// @param _symbol token symbol
/// @param _decimals decimal points, for display purposes
function ERC20Token(string _name, string _symbol, uint8 _decimals)
internal
validString(_name)
validString(_symbol)
{
name = _name;
symbol = _symbol;
decimals = _decimals;
}
/// @dev send coins
/// throws on any error rather then return a false flag to minimize user errors
/// @param _to target address
/// @param _value transfer amount
/// @return true if the transfer was successful, false if it wasn't
function transfer(address _to, uint256 _value)
public
validParamData(2)
validAddress(_to)
notThis(_to)
returns (bool success)
{
balanceOf[msg.sender] = balanceOf[msg.sender].sub(_value);
balanceOf[_to] = balanceOf[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
/// @dev an account/contract attempts to get the coins
/// throws on any error rather then return a false flag to minimize user errors
/// @param _from source address
/// @param _to target address
/// @param _value transfer amount
/// @return true if the transfer was successful, false if it wasn't
function transferFrom(address _from, address _to, uint256 _value)
public
validParamData(3)
validAddress(_from)
validAddress(_to)
notThis(_to)
returns (bool success)
{
allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value);
balanceOf[_from] = balanceOf[_from].sub(_value);
balanceOf[_to] = balanceOf[_to].add(_value);
Transfer(_from, _to, _value);
return true;
}
/// @dev allow another account/contract to spend some tokens on your behalf
/// throws on any error rather then return a false flag to minimize user errors
/// also, to minimize the risk of the approve/transferFrom attack vector
/// (see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/)
/// approve has to be called twice in 2 separate transactions
/// once to change the allowance to 0 and secondly to change it to the new allowance value
/// @param _spender approved address
/// @param _value allowance amount
/// @return true if the approval was successful, false if it wasn't
function approve(address _spender, uint256 _value)
public
validParamData(2)
validAddress(_spender)
onlyIf(_value == 0 || allowance[msg.sender][_spender] == 0)
returns (bool success)
{
uint256 currentAllowance = allowance[msg.sender][_spender];
return changeApprovalCore(_spender, currentAllowance, _value);
}
/// @dev Allow another account/contract to spend some tokens on your behalf
/// Note: This method is protected against the approve/transferFrom attack vector
/// (see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/)
/// because the previous value and new value must both be specified.
function changeApproval(address _spender, uint256 _previousValue, uint256 _value)
public
validParamData(3)
validAddress(_spender)
returns (bool success)
{
return changeApprovalCore(_spender, _previousValue, _value);
}
function changeApprovalCore(address _spender, uint256 _previousValue, uint256 _value)
private
onlyIf(allowance[msg.sender][_spender] == _previousValue)
returns (bool success)
{
allowance[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
}
contract XBPToken is BaseContract, Owned, TokenRetriever, ERC20Token {
using SafeMath for uint256;
bool public issuanceEnabled = true;
event Issuance(uint256 _amount);
function XBPToken()
public
ERC20Token("BlitzPredict", "XBP", 18)
{
}
/// @dev disables/enables token issuance
/// can only be called by the contract owner
function disableIssuance()
public
onlyOwner
onlyIf(issuanceEnabled)
{
issuanceEnabled = false;
}
/// @dev increases the token supply and sends the new tokens to an account
/// can only be called by the contract owner
/// @param _to account to receive the new amount
/// @param _amount amount to increase the supply by
function issue(address _to, uint256 _amount)
public
onlyOwner
validParamData(2)
validAddress(_to)
onlyIf(issuanceEnabled)
notThis(_to)
{
totalSupply = totalSupply.add(_amount);
balanceOf[_to] = balanceOf[_to].add(_amount);
Issuance(_amount);
Transfer(this, _to, _amount);
}
}
{
"compilationTarget": {
"XBPToken.sol": "XBPToken"
},
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","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":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_previousValue","type":"uint256"},{"name":"_value","type":"uint256"}],"name":"changeApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issuanceEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"retrieveTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"disableIssuance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Issuance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_prevOwner","type":"address"},{"indexed":true,"name":"_newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"}]