Created
January 12, 2018 11:53
-
-
Save abdul/cd6f5aca050ad6ec72bacfe420f985be to your computer and use it in GitHub Desktop.
Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.19+commit.c4cbbb05.js&optimize=false&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import './ERC20Basic.sol'; | |
import './SafeMath.sol'; | |
/** | |
* @title Basic token | |
* @dev Basic version of StandardToken, with no allowances. | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract BasicToken is ERC20Basic { | |
using SafeMath for uint256; | |
mapping(address => uint256) balances; | |
/** | |
* @dev transfer token for a specified address | |
* @param _to The address to transfer to. | |
* @param _value The amount to be transferred. | |
*/ | |
function transfer(address _to, uint256 _value) public returns (bool) { | |
require(_to != address(0)); | |
require(_value <= balances[msg.sender]); | |
// SafeMath.sub will throw if there is not enough balance. | |
balances[msg.sender] = balances[msg.sender].sub(_value); | |
balances[_to] = balances[_to].add(_value); | |
Transfer(msg.sender, _to, _value); | |
return true; | |
} | |
/** | |
* @dev Gets the balance of the specified address. | |
* @param _owner The address to query the the balance of. | |
* @return An uint256 representing the amount owned by the passed address. | |
*/ | |
function balanceOf(address _owner) public view returns (uint256 balance) { | |
return balances[_owner]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import "./Ownable.sol"; | |
import "./ERC20Basic.sol"; | |
import "./SafeERC20.sol"; | |
/** | |
* @title Contracts that should be able to recover tokens | |
* @author SylTi | |
* @dev This allow a contract to recover any ERC20 token received in a contract by transferring the balance to the contract owner. | |
* This will prevent any accidental loss of tokens. | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract CanReclaimToken is Ownable { | |
using SafeERC20 for ERC20Basic; | |
/** | |
* @dev Reclaim all ERC20Basic compatible tokens | |
* @param token ERC20Basic The address of the token contract | |
*/ | |
function reclaimToken(ERC20Basic token) external onlyOwner { | |
uint256 balance = token.balanceOf(this); | |
token.safeTransfer(owner, balance); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.13; | |
/** | |
* @title DayLimit | |
* @dev Base contract that enables methods to be protected by placing a linear limit (specifiable) | |
* on a particular resource per calendar day. Is multiowned to allow the limit to be altered. | |
*/ | |
contract DayLimit { | |
uint256 public dailyLimit; | |
uint256 public spentToday; | |
uint256 public lastDay; | |
/** | |
* @dev Constructor that sets the passed value as a dailyLimit. | |
* @param _limit uint256 to represent the daily limit. | |
*/ | |
function DayLimit(uint256 _limit) { | |
dailyLimit = _limit; | |
lastDay = today(); | |
} | |
/** | |
* @dev sets the daily limit. Does not alter the amount already spent today. | |
* @param _newLimit uint256 to represent the new limit. | |
*/ | |
function _setDailyLimit(uint256 _newLimit) internal { | |
dailyLimit = _newLimit; | |
} | |
/** | |
* @dev Resets the amount already spent today. | |
*/ | |
function _resetSpentToday() internal { | |
spentToday = 0; | |
} | |
/** | |
* @dev Checks to see if there is enough resource to spend today. If true, the resource may be expended. | |
* @param _value uint256 representing the amount of resource to spend. | |
* @return A boolean that is True if the resource was spended and false otherwise. | |
*/ | |
function underLimit(uint256 _value) internal returns (bool) { | |
// reset the spend limit if we're on a different day to last time. | |
if (today() > lastDay) { | |
spentToday = 0; | |
lastDay = today(); | |
} | |
// check to see if there's enough left - if so, subtract and return true. | |
// overflow protection // dailyLimit check | |
if (spentToday + _value >= spentToday && spentToday + _value <= dailyLimit) { | |
spentToday += _value; | |
return true; | |
} | |
return false; | |
} | |
/** | |
* @dev Private function to determine today's index | |
* @return uint256 of today's index. | |
*/ | |
function today() private constant returns (uint256) { | |
return now / 1 days; | |
} | |
/** | |
* @dev Simple modifier for daily limit. | |
*/ | |
modifier limitedDaily(uint256 _value) { | |
require(underLimit(_value)); | |
_; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import './ERC20Basic.sol'; | |
/** | |
* @title ERC20 interface | |
* @dev see https://github.com/ethereum/EIPs/issues/20 | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract ERC20 is ERC20Basic { | |
function allowance(address owner, address spender) public view returns (uint256); | |
function transferFrom(address from, address to, uint256 value) public returns (bool); | |
function approve(address spender, uint256 value) public returns (bool); | |
event Approval(address indexed owner, address indexed spender, uint256 value); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
/** | |
* @title ERC20Basic | |
* @dev Simpler version of ERC20 interface | |
* @dev see https://github.com/ethereum/EIPs/issues/179 | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract ERC20Basic { | |
uint256 public totalSupply; | |
function balanceOf(address who) public view returns (uint256); | |
function transfer(address to, uint256 value) public returns (bool); | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import "./CanReclaimToken.sol"; | |
/** | |
* @title Contracts that should not own Tokens | |
* @author Remco Bloemen <remco@2π.com> | |
* @dev This blocks incoming ERC23 tokens to prevent accidental loss of tokens. | |
* Should tokens (any ERC20Basic compatible) end up in the contract, it allows the | |
* owner to reclaim the tokens. | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract HasNoTokens is CanReclaimToken { | |
/** | |
* @dev Reject all ERC23 compatible tokens | |
* @param from_ address The address that is transferring the tokens | |
* @param value_ uint256 the amount of the specified token | |
* @param data_ Bytes The data passed from the caller. | |
*/ | |
function tokenFallback(address from_, uint256 value_, bytes data_) pure external { | |
from_; | |
value_; | |
data_; | |
revert(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.2; | |
contract Migrations { | |
address public owner; | |
uint public last_completed_migration; | |
modifier restricted() { | |
if (msg.sender == owner) { | |
_; | |
} | |
} | |
function Migrations() public { | |
owner = msg.sender; | |
} | |
function setCompleted(uint completed) public restricted { | |
last_completed_migration = completed; | |
} | |
function upgrade(address new_address) public restricted { | |
Migrations upgraded = Migrations(new_address); | |
upgraded.setCompleted(last_completed_migration); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.13; | |
/** | |
* @title Multisig | |
* @dev Interface contract for multisig proxy contracts; see below for docs. | |
*/ | |
contract Multisig { | |
// EVENTS | |
// logged events: | |
// Funds has arrived into the wallet (record how much). | |
event Deposit(address _from, uint256 value); | |
// Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going). | |
event SingleTransact(address owner, uint256 value, address to, bytes data); | |
// Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going). | |
event MultiTransact(address owner, bytes32 operation, uint256 value, address to, bytes data); | |
// Confirmation still needed for a transaction. | |
event ConfirmationNeeded(bytes32 operation, address initiator, uint256 value, address to, bytes data); | |
// FUNCTIONS | |
// TODO: document | |
function changeOwner(address _from, address _to) external; | |
function execute(address _to, uint256 _value, bytes _data) external returns (bytes32); | |
function confirm(bytes32 _h) returns (bool); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.13; | |
import "./Multisig.sol"; | |
import "./Shareable.sol"; | |
import "./DayLimit.sol"; | |
/** | |
* MultisigWallet | |
* Usage: | |
* bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data); | |
* Wallet(w).from(anotherOwner).confirm(h); | |
*/ | |
contract MultisigWallet is Multisig, Shareable, DayLimit { | |
struct Transaction { | |
address to; | |
uint256 value; | |
bytes data; | |
} | |
/** | |
* Constructor, sets the owners addresses, number of approvals required, and daily spending limit | |
* @param _owners A list of owners. | |
* @param _required The amount required for a transaction to be approved. | |
*/ | |
function MultisigWallet(address[] _owners, uint256 _required, uint256 _daylimit) | |
Shareable(_owners, _required) | |
DayLimit(_daylimit) { } | |
/** | |
* @dev destroys the contract sending everything to `_to`. | |
*/ | |
function destroy(address _to) onlymanyowners(keccak256(msg.data)) external { | |
selfdestruct(_to); | |
} | |
/** | |
* @dev Fallback function, receives value and emits a deposit event. | |
*/ | |
function() payable { | |
// just being sent some cash? | |
if (msg.value > 0) | |
Deposit(msg.sender, msg.value); | |
} | |
/** | |
* @dev Outside-visible transaction entry point. Executes transaction immediately if below daily | |
* spending limit. If not, goes into multisig process. We provide a hash on return to allow the | |
* sender to provide shortcuts for the other confirmations (allowing them to avoid replicating | |
* the _to, _value, and _data arguments). They still get the option of using them if they want, | |
* anyways. | |
* @param _to The receiver address | |
* @param _value The value to send | |
* @param _data The data part of the transaction | |
*/ | |
function execute(address _to, uint256 _value, bytes _data) external onlyOwner returns (bytes32 _r) { | |
// first, take the opportunity to check that we're under the daily limit. | |
if (underLimit(_value)) { | |
SingleTransact(msg.sender, _value, _to, _data); | |
// yes - just execute the call. | |
if (!_to.call.value(_value)(_data)) { | |
revert(); | |
} | |
return 0; | |
} | |
// determine our operation hash. | |
_r = keccak256(msg.data, block.number); | |
if (!confirm(_r) && txs[_r].to == 0) { | |
txs[_r].to = _to; | |
txs[_r].value = _value; | |
txs[_r].data = _data; | |
ConfirmationNeeded(_r, msg.sender, _value, _to, _data); | |
} | |
} | |
/** | |
* @dev Confirm a transaction by providing just the hash. We use the previous transactions map, | |
* txs, in order to determine the body of the transaction from the hash provided. | |
* @param _h The transaction hash to approve. | |
*/ | |
function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) { | |
if (txs[_h].to != 0) { | |
assert(txs[_h].to.call.value(txs[_h].value)(txs[_h].data)); | |
MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data); | |
delete txs[_h]; | |
return true; | |
} | |
} | |
/** | |
* @dev Updates the daily limit value. | |
* @param _newLimit uint256 to represent the new limit. | |
*/ | |
function setDailyLimit(uint256 _newLimit) onlymanyowners(keccak256(msg.data)) external { | |
_setDailyLimit(_newLimit); | |
} | |
/** | |
* @dev Resets the value spent to enable more spending | |
*/ | |
function resetSpentToday() onlymanyowners(keccak256(msg.data)) external { | |
_resetSpentToday(); | |
} | |
// INTERNAL METHODS | |
/** | |
* @dev Clears the list of transactions pending approval. | |
*/ | |
function clearPending() internal { | |
uint256 length = pendingsIndex.length; | |
for (uint256 i = 0; i < length; ++i) { | |
delete txs[pendingsIndex[i]]; | |
} | |
super.clearPending(); | |
} | |
// FIELDS | |
// pending transactions we have at present. | |
mapping (bytes32 => Transaction) txs; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
/** | |
* @title Ownable | |
* @dev The Ownable contract has an owner address, and provides basic authorization control | |
* functions, this simplifies the implementation of "user permissions". | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract Ownable { | |
address public owner; // Operational owner. | |
address public masterOwner = 0x6b116eB37e76730Afafb73D8a157D1b17c4dc0d6; // for ownership transfer segregation of duty, hard coded to wallet account | |
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); | |
/** | |
* @dev The Ownable constructor sets the original `owner` of the contract to the sender | |
* account. | |
*/ | |
function Ownable() public { | |
owner = msg.sender; | |
} | |
/** | |
* @dev Throws if called by any account other than the owner. | |
*/ | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
/** | |
* @dev Allows the current owner to transfer control of the contract to a newOwner. | |
* @param newOwner The address to transfer ownership to. | |
*/ | |
function transferOwnership(address newOwner) public { | |
require(newOwner != address(0)); | |
require(masterOwner == msg.sender); // only master owner can initiate change to ownershipe | |
OwnershipTransferred(owner, newOwner); | |
owner = newOwner; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import "./Ownable.sol"; | |
/** | |
* @title Pausable | |
* @dev Base contract which allows children to implement an emergency stop mechanism. | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract Pausable is Ownable { | |
event Pause(); | |
event Unpause(); | |
bool public paused = false; | |
/** | |
* @dev Modifier to make a function callable only when the contract is not paused. | |
*/ | |
modifier whenNotPaused() { | |
require(!paused); | |
_; | |
} | |
/** | |
* @dev Modifier to make a function callable only when the contract is paused. | |
*/ | |
modifier whenPaused() { | |
require(paused); | |
_; | |
} | |
/** | |
* @dev called by the owner to pause, triggers stopped state | |
*/ | |
function pause() onlyOwner whenNotPaused public { | |
paused = true; | |
Pause(); | |
} | |
/** | |
* @dev called by the owner to unpause, returns to normal state | |
*/ | |
function unpause() onlyOwner whenPaused public { | |
paused = false; | |
Unpause(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import './ERC20Basic.sol'; | |
import './ERC20.sol'; | |
/** | |
* @title SafeERC20 | |
* @dev Wrappers around ERC20 operations that throw on failure. | |
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, | |
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc. | |
*/ | |
library SafeERC20 { | |
function safeTransfer(ERC20Basic token, address to, uint256 value) internal { | |
assert(token.transfer(to, value)); | |
} | |
function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal { | |
assert(token.transferFrom(from, to, value)); | |
} | |
function safeApprove(ERC20 token, address spender, uint256 value) internal { | |
assert(token.approve(spender, value)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
/** | |
* @title SafeMath | |
* @dev Math operations with safety checks that throw on error | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
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; | |
} | |
function cei(uint256 a, uint256 b) internal pure returns (uint256) { | |
return ((a + b - 1) / b) * b; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import './BasicToken.sol'; | |
import './ERC20.sol'; | |
/** | |
* @title Standard ERC20 token | |
* | |
* @dev Implementation of the basic standard token. | |
* @dev https://github.com/ethereum/EIPs/issues/20 | |
* @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol | |
* https://github.com/OpenZeppelin/zeppelin-solidity/ | |
*/ | |
contract StandardToken is ERC20, BasicToken { | |
mapping (address => mapping (address => uint256)) internal allowed; | |
/** | |
* @dev Transfer tokens from one address to another | |
* @param _from address The address which you want to send tokens from | |
* @param _to address The address which you want to transfer to | |
* @param _value uint256 the amount of tokens to be transferred | |
*/ | |
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { | |
require(_to != address(0)); | |
require(_value <= balances[_from]); | |
require(_value <= allowed[_from][msg.sender]); | |
balances[_from] = balances[_from].sub(_value); | |
balances[_to] = balances[_to].add(_value); | |
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); | |
Transfer(_from, _to, _value); | |
return true; | |
} | |
/** | |
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. | |
* | |
* Beware that changing an allowance with this method brings the risk that someone may use both the old | |
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this | |
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: | |
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 | |
* @param _spender The address which will spend the funds. | |
* @param _value The amount of tokens to be spent. | |
*/ | |
function approve(address _spender, uint256 _value) public returns (bool) { | |
allowed[msg.sender][_spender] = _value; | |
Approval(msg.sender, _spender, _value); | |
return true; | |
} | |
/** | |
* @dev Function to check the amount of tokens that an owner allowed to a spender. | |
* @param _owner address The address which owns the funds. | |
* @param _spender address The address which will spend the funds. | |
* @return A uint256 specifying the amount of tokens still available for the spender. | |
*/ | |
function allowance(address _owner, address _spender) public view returns (uint256) { | |
return allowed[_owner][_spender]; | |
} | |
/** | |
* approve should be called when allowed[_spender] == 0. To increment | |
* allowed value is better to use this function to avoid 2 calls (and wait until | |
* the first transaction is mined) | |
* From MonolithDAO Token.sol | |
*/ | |
function increaseApproval (address _spender, uint _addedValue) public returns (bool) { | |
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue); | |
Approval(msg.sender, _spender, allowed[msg.sender][_spender]); | |
return true; | |
} | |
function decreaseApproval (address _spender, uint _subtractedValue) public returns (bool) { | |
uint oldValue = allowed[msg.sender][_spender]; | |
if (_subtractedValue > oldValue) { | |
allowed[msg.sender][_spender] = 0; | |
} else { | |
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); | |
} | |
Approval(msg.sender, _spender, allowed[msg.sender][_spender]); | |
return true; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import "./StandardToken.sol"; | |
import "./Ownable.sol"; | |
contract VZToken is StandardToken, Ownable { | |
/* metadata */ | |
string public constant NAME = "VectorZilla Token"; | |
string public constant SYMBOL = "VZT"; | |
string public constant VERSION = "0.5"; | |
uint8 public constant DECIMALS = 18; | |
/* all accounts in wei */ | |
uint256 public constant INITIAL_SUPPLY = 10000 * 10**18; //100000000 * 10**18; | |
uint256 public constant VECTORZILLA_RESERVE_VZT = 2500 * 10**18; //25000000 * 10**18; | |
// these three multi-sig addresses will be replaced on production: | |
address public constant VECTORZILLA_RESERVE = 0x76f458A8aBe327D79040931AC97f74662EF3CaD0; | |
// minimum VZT token to be transferred to make the gas worthwhile (avoid micro transfer), cannot be higher than minimal subscribed amount in crowd sale. | |
uint256 public token4Gas = 1*10**18; | |
// gas in wei to reimburse must be the lowest minimum 0.6Gwei * 80000 gas limit. | |
uint256 public gas4Token = 80000*0.6*10**9; | |
// minimum wei required in an account to perform an action (avg gas price 4Gwei * avg gas limit 80000). | |
uint256 public minGas4Accts = 80000*4*10**9; | |
// list of addresses that has transfer restriction. | |
mapping (address => bool) public accreditedList; | |
uint256 public NumOfAccredited = 0; | |
uint256 public accreditedDate = 1703543589; // Assume many years | |
event Withdraw(address indexed from, address indexed to, uint256 value); | |
event GasRebateFailed(address indexed to, uint256 value); | |
/** | |
* @dev Contructor that gives msg.sender all existing tokens. | |
*/ | |
function VZToken(address _owner) public { | |
require(_owner != address(0)); | |
totalSupply = INITIAL_SUPPLY; | |
balances[_owner] = INITIAL_SUPPLY - VECTORZILLA_RESERVE_VZT; | |
balances[VECTORZILLA_RESERVE] = VECTORZILLA_RESERVE_VZT; | |
owner = _owner; | |
} | |
/** | |
* @dev transfer token for a specified address | |
* @param _to The address to transfer to. | |
* @param _value The amount to be transferred. | |
*/ | |
function transfer(address _to, uint256 _value) public returns (bool) { | |
require(canTransferTokens()); // Team tokens lock 1 year | |
require(_value > 0 && _value >= token4Gas); // do nothing if less than allowed minimum but do not fail | |
balances[msg.sender] = balances[msg.sender].sub(_value); // insufficient token balance would revert here inside safemath | |
balances[_to] = balances[_to].add(_value); | |
Transfer(msg.sender, _to, _value); | |
// Keep a minimum balance of gas in all sender accounts. It would not be executed if the account has enough ETH for next action. | |
if (this.balance > gas4Token && msg.sender.balance < minGas4Accts) { | |
// reimburse gas in ETH to keep a minimal balance for next transaction, use send instead of transfer thus ignore failed rebate(not enough ether to rebate etc.). | |
if (!msg.sender.send(gas4Token)) { | |
GasRebateFailed(msg.sender,gas4Token); | |
} | |
} | |
return true; | |
} | |
/* | |
Allow changes to accredited date. | |
*/ | |
function setAccreditedDate(uint256 newAccreditedDate) public onlyOwner { | |
accreditedDate = newAccreditedDate; | |
} | |
/* | |
add the ether address to accredited list to put in transfer restrction. | |
*/ | |
function addToAccreditedList(address _addr) external onlyOwner { | |
require(_addr != address(0)); | |
require(!accreditedList[_addr]); | |
accreditedList[_addr] = true; | |
NumOfAccredited += 1; | |
} | |
/* | |
remove the ether address from accredited list to remove transfer restriction. | |
*/ | |
function delFrAccreditedList(address _addr) external onlyOwner { | |
require(accreditedList[_addr]); | |
delete accreditedList[_addr]; | |
NumOfAccredited -= 1; | |
} | |
// return true if buyer is an accredited | |
function isAccreditedlisted(address buyer) public view returns (bool) { | |
return accreditedList[buyer]; | |
} | |
/* When necessary, adjust minimum VZT to transfer to make the gas worthwhile */ | |
function setToken4Gas(uint newVZTAmount) public onlyOwner { | |
require(newVZTAmount > 0); // Upper bound is not necessary. | |
token4Gas = newVZTAmount; | |
} | |
/* Only when necessary such as gas price change, adjust the gas to be reimbursed on every transfer when sender account below minimum */ | |
function setGas4Token(uint newGasInWei) public onlyOwner { | |
require(newGasInWei > 0 && newGasInWei <= 840000*10**9); // must be less than a reasonable gas value | |
gas4Token = newGasInWei; | |
} | |
/* When necessary, adjust the minimum wei required in an account before an reimibusement of fee is triggerred */ | |
function setMinGas4Accts(uint minBalanceInWei) public onlyOwner { | |
require(minBalanceInWei > 0 && minBalanceInWei <= 840000*10**9); // must be less than a reasonable gas value | |
minGas4Accts = minBalanceInWei; | |
} | |
/* This unnamed function is called whenever the owner send Ether to fund the gas fees and gas reimbursement */ | |
function() payable public onlyOwner { | |
} | |
/* Owner withdrawal for excessive gas fees deposited */ | |
function withdrawToOwner (uint256 weiAmt) public onlyOwner { | |
require(weiAmt > 0); // do not allow zero transfer | |
msg.sender.transfer(weiAmt); | |
Withdraw(this, msg.sender, weiAmt); // signal the event for communication only it is meaningful | |
} | |
/* below are internal functions */ | |
/* | |
VectorZilla and Accredited folks can only transfer tokens after accredited date. | |
*/ | |
function canTransferTokens() internal view returns (bool) { | |
if (accreditedList[msg.sender]) { | |
return now >= accreditedDate; | |
} else { | |
return true; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import "./SafeMath.sol"; | |
import "./VZToken.sol"; | |
import "./Ownable.sol"; | |
import "./Pausable.sol"; | |
import "./HasNoTokens.sol"; | |
contract VZTPresale is Ownable, Pausable, HasNoTokens { | |
using SafeMath for uint256; | |
string public constant NAME = "VectorZilla Public Presale"; | |
string public constant VERSION = "0.5"; | |
VZToken token; | |
// this multi-sig address will be replaced on production: | |
address public constant VZT_WALLET = 0x4D9B157E1c2ed052560304ce10E81ec67AEAbbdF; | |
uint256 public startDate = 1514764800; //1515974400; // January 15, 2018 5:30 AM UTC | |
uint256 public endDate = 1517788800; // Febuary 5, 2018 5:30 AM UTC | |
uint256 public weiRaised = 0; // total amount of Ether raised in wei | |
uint256 public purchaserCount = 0; // total number of purchasers purchased VZT | |
uint256 public tokensSold = 0; // total number of VZT tokens sold | |
uint256 public numWhitelisted = 0; // total number whitelisted | |
/* if the minimum funding goal in wei is not reached, purchasers may withdraw their funds */ | |
uint256 public constant MIN_FUNDING_GOAL = 2 * 10 ** 18; //200 * 10 ** 18; | |
uint256 public constant PRESALE_TOKEN_SOFT_CAP = 2500 * 10**18; //1875000 * 10 ** 18; // presale ends 48 hours after soft cap of 1,875,000 VZT is reached | |
uint256 public constant PRESALE_RATE = 1250; // presale price is 1 ETH to 1,250 VZT | |
uint256 public constant SOFTCAP_RATE = 1150; // presale price becomes 1 ETH to 1,150 VZT after softcap is reached | |
uint256 public constant PRESALE_TOKEN_HARD_CAP = 5000 * 10**18; //5900000 * 10 ** 18; // presale token hardcap | |
uint256 public constant MIN_PURCHASE = 0.25 * 10 ** 17; // minimum purchase is 0.25 ETH to make the gas worthwhile | |
uint256 public constant MIN_VZT_PURCHASE = 1150 * 10 ** 18; // minimum token purchase is 100 or 0.1 ETH | |
bool public isFinalized = false; // it becomes true when token sale is completed | |
bool public publicSoftCapReached = false; // it becomes true when public softcap is reached | |
/** the amount of ETH in wei each address has purchased in this crowdsale */ | |
mapping(address => uint256) public purchasedAmountOf; | |
/** the amount of tokens this crowdsale has credited for each purchaser address */ | |
mapping(address => uint256) public tokenAmountOf; | |
/** this becomes true when crowdsale has distributed purchased tokens with bonus for each purchaser address */ | |
mapping(address => bool) public tokenDistributed; | |
/** the amount of leftover tokens this crowdsale has distributed for each purchaser address */ | |
mapping(address => uint256) public leftoverAmountOf; | |
/** this becomes true when crowdsale has distributed leftover tokens for each purchaser address */ | |
mapping(address => bool) public leftoverDistributed; | |
// purchaser wallets | |
address[] public purchasers; | |
// list of addresses that can purchase | |
mapping(address => bool) public whitelist; | |
/** | |
* event for token purchase logging | |
* @param purchaser who paid for the tokens | |
* @param beneficiary who got the tokens | |
* @param value weis paid for purchase | |
* @param amount amount of tokens purchased | |
*/ | |
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); | |
// event logging for token sale finalized | |
event Finalized(); | |
// event logging for softcap reached | |
event SoftCapReached(); | |
// event logging for funds transfered to VectorZilla multi-sig wallet | |
event FundsTransferred(); | |
// event logging for each individual refunded amount | |
event Refunded(address indexed beneficiary, uint256 weiAmount); | |
// event logging for each individual distributed token + bonus | |
event TokenDistributed(address indexed purchaser, uint256 tokenAmt); | |
// event logging for each individual distributed leftover | |
event LeftoverTokenDistributed(address indexed purchaser, uint256 tokenAmt); | |
/* | |
Constructor to initialize everything. | |
*/ | |
function VZTPresale(address _token, address _owner) public { | |
require(_token != address(0)); | |
require(_owner != address(0)); | |
token = VZToken(_token); | |
owner = _owner; | |
// default owner | |
tokenAmountOf[owner] = PRESALE_TOKEN_HARD_CAP; | |
// maximum tokens to be sold in presale | |
} | |
/* | |
default function to buy tokens. | |
*/ | |
function() payable public whenNotPaused { | |
// stop if no more token is allocated for sale | |
require(isPresale()); | |
// stop if address not valid | |
require(!hasSoldOut()); | |
// stop if the purchase is too small | |
require(msg.sender != address(0)); | |
// no purchase unless whitelisted | |
require(msg.value >= MIN_PURCHASE); | |
// do public presale | |
require(isWhitelisted(msg.sender)); | |
purchasePresale(msg.sender, msg.value); | |
} | |
function setDates(uint256 newStartDate, uint256 newEndDate) public onlyOwner { | |
startDate = newStartDate; | |
endDate = newEndDate; | |
} | |
function setTokenContract(address _token) external onlyOwner { | |
require(token != address(0)); | |
token = VZToken(_token); | |
} | |
/* | |
add the ether address to whitelist to enable purchase of token. | |
*/ | |
function addToWhitelist(address buyer) external onlyOwner { | |
require(buyer != address(0)); | |
if (!isWhitelisted(buyer)) { | |
whitelist[buyer] = true; | |
numWhitelisted += 1; | |
} | |
} | |
/* | |
remove the ether address from whitelist in case a mistake was made. | |
*/ | |
function delFrWhitelist(address buyer) public onlyOwner { | |
// Valid address | |
require(buyer != address(0)); | |
// No purchase yet. | |
require(purchasedAmountOf[buyer] <= 0); | |
if (isWhitelisted(buyer)) { | |
delete whitelist[buyer]; | |
numWhitelisted -= 1; | |
} | |
} | |
// return true if buyer is whitelisted | |
function isWhitelisted(address buyer) public view returns (bool) { | |
return whitelist[buyer]; | |
} | |
function purchasePresale(address buyer, uint256 value) internal { | |
uint256 tokens = 0; | |
// still under soft cap | |
if (!publicSoftCapReached) { | |
// 1 ETH for 1,250 VZT | |
tokens = value * PRESALE_RATE; | |
// get less if over softcap | |
if (tokensSold + tokens > PRESALE_TOKEN_SOFT_CAP) { | |
uint256 availablePresaleTokens = PRESALE_TOKEN_SOFT_CAP - tokensSold; | |
uint256 softCapTokens = (value - (availablePresaleTokens / PRESALE_RATE)) * SOFTCAP_RATE; | |
tokens = availablePresaleTokens + softCapTokens; | |
// process presale at 1 ETH to 1,150 VZT | |
processSale(buyer, value, tokens, SOFTCAP_RATE); | |
// public soft cap has been reached | |
publicSoftCapReached = true; | |
// signal the event for communication | |
SoftCapReached(); | |
} else { | |
// process presale @PRESALE_RATE | |
processSale(buyer, value, tokens, PRESALE_RATE); | |
} | |
} else { | |
// 1 ETH to 1,150 VZT | |
tokens = value * SOFTCAP_RATE; | |
// process presale at 1 ETH to 1,150 VZT | |
processSale(buyer, value, tokens, SOFTCAP_RATE); | |
} | |
} | |
/* | |
process sale at determined price. | |
*/ | |
function processSale(address buyer, uint256 value, uint256 vzt, uint256 vztRate) internal { | |
uint256 vztOver = 0; | |
uint256 excessEthInWei = 0; | |
uint256 paidValue = value; | |
uint256 purchasedVzt = vzt; | |
if (tokensSold + purchasedVzt > PRESALE_TOKEN_HARD_CAP) {// if maximum is exceeded | |
// find overage | |
vztOver = tokensSold + purchasedVzt - PRESALE_TOKEN_HARD_CAP; | |
// overage ETH to refund | |
excessEthInWei = vztOver / vztRate; | |
// adjust tokens purchased | |
purchasedVzt = purchasedVzt - vztOver; | |
// adjust Ether paid | |
paidValue = paidValue - excessEthInWei; | |
} | |
if (tokenAmountOf[buyer] == 0) { | |
// count new purchasers | |
purchaserCount++; | |
purchasers.push(buyer); | |
} | |
// deduct VZT from Vectorzilla account | |
tokenAmountOf[owner] = tokenAmountOf[owner].sub(purchasedVzt); | |
// record VZT on purchaser account | |
tokenAmountOf[buyer] = tokenAmountOf[buyer].add(purchasedVzt); | |
// record ETH paid | |
purchasedAmountOf[buyer] = purchasedAmountOf[buyer].add(paidValue); | |
// total ETH raised | |
weiRaised += paidValue; | |
// total VZT sold | |
tokensSold += purchasedVzt; | |
// signal the event for communication | |
TokenPurchase(buyer, buyer, paidValue, purchasedVzt); | |
// transfer must be done at the end after all states are updated to prevent reentrancy attack. | |
if (excessEthInWei > 0) { | |
// refund overage ETH | |
buyer.transfer(excessEthInWei); | |
// signal the event for communication | |
Refunded(buyer, excessEthInWei); | |
} | |
} | |
/* | |
default function to buy tokens. | |
*/ | |
function payableInFiatEth(address buyer, uint256 value) external onlyOwner { | |
require(isPresale()); | |
// stop if no more token is allocated for sale | |
require(!hasSoldOut()); | |
// stop if address not valid | |
require(buyer != address(0)); | |
// stop if the purchase is too small | |
require(value >= MIN_PURCHASE); | |
// no purchase unless whitelisted | |
require(isWhitelisted(buyer)); | |
// do public presale | |
purchasePresale(buyer, value); | |
} | |
/* | |
Check to see if this is public presale. | |
*/ | |
function isPresale() public view returns (bool) { | |
return !isFinalized && now >= startDate && now <= endDate; | |
} | |
/* | |
check if allocated has sold out. | |
*/ | |
function hasSoldOut() public view returns (bool) { | |
return PRESALE_TOKEN_HARD_CAP - tokensSold < MIN_VZT_PURCHASE; | |
} | |
/* | |
Check to see if the crowdsale end date has passed or if all tokens allocated for sale has been purchased. | |
*/ | |
function hasEnded() public view returns (bool) { | |
return now > endDate || (PRESALE_TOKEN_HARD_CAP - tokensSold < MIN_VZT_PURCHASE); | |
} | |
/* | |
Determine if the minimum goal in wei has been reached. | |
*/ | |
function isMinimumGoalReached() public view returns (bool) { | |
return weiRaised >= MIN_FUNDING_GOAL; | |
} | |
/* | |
Called after crowdsale ends, to do some extra finalization work. | |
*/ | |
function finalize() public onlyOwner { | |
require(!isFinalized); | |
// do nothing if finalized | |
require(hasEnded()); | |
// crowdsale must have ended | |
if (isMinimumGoalReached()) { | |
VZT_WALLET.transfer(this.balance); | |
// transfer to VectorZilla multisig wallet | |
FundsTransferred(); | |
// signal the event for communication | |
} | |
isFinalized = true; | |
// mark as finalized | |
Finalized(); | |
// signal the event for communication | |
} | |
/* | |
purchaser requesting a refund if minimum goal not reached. | |
*/ | |
function claimRefund() external { | |
require(isFinalized && !isMinimumGoalReached()); | |
// cannot refund unless authorized | |
uint256 depositedValue = purchasedAmountOf[msg.sender]; | |
// ETH to refund | |
purchasedAmountOf[msg.sender] = 0; | |
// assume all refunded | |
// transfer must be called only after purchasedAmountOf is updated to prevent reentrancy attack. | |
msg.sender.transfer(depositedValue); | |
// refund all ETH | |
Refunded(msg.sender, depositedValue); | |
// signal the event for communication | |
} | |
/* | |
send refund to purchaser if minimum goal not reached. | |
*/ | |
function sendRefund(address buyer) external onlyOwner { | |
// cannot refund unless authorized | |
require(isFinalized && !isMinimumGoalReached()); | |
// ETH to refund | |
uint256 depositedValue = purchasedAmountOf[buyer]; | |
// assume all refunded | |
purchasedAmountOf[buyer] = 0; | |
// transfer must be called only after purchasedAmountOf is updated to prevent reentrancy attack. | |
// refund all ETH | |
buyer.transfer(depositedValue); | |
// signal the event for communication | |
Refunded(buyer, depositedValue); | |
} | |
/* | |
For the convenience of crowdsale interface to find current discount tier. | |
*/ | |
function getTier() public view returns (uint256) { | |
// Assume presale top tier discount | |
uint256 tier = 1; | |
if (now >= startDate && now < endDate && getSoftCapReached()) { | |
// tier 2 discount | |
tier = 2; | |
} | |
return tier; | |
} | |
/* | |
For the convenience of crowdsale interface to present status info. | |
*/ | |
function getSoftCapReached() public view returns (bool) { | |
return publicSoftCapReached; | |
} | |
/* | |
For the convenience of crowdsale interface to present status info. | |
*/ | |
function getPresaleStatus() public view returns (uint256[3]) { | |
// 0 - presale not started | |
// 1 - presale started | |
// 2 - presale ended | |
if (now < startDate) | |
return ([0, startDate, endDate]); | |
else if (now <= endDate && !hasEnded()) | |
return ([1, startDate, endDate]); | |
else | |
return ([2, startDate, endDate]); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.18; | |
import './SafeMath.sol'; | |
import "./VZToken.sol"; | |
import "./Ownable.sol"; | |
import "./HasNoTokens.sol"; | |
import "./VZTPresale.sol"; | |
contract VZTPresaleDist is Ownable, HasNoTokens { | |
using SafeMath for uint256; | |
string public constant NAME = "VectorZilla token distribution"; | |
string public constant VERSION = "0.3"; | |
VZToken token; | |
VZTPresale preSale; | |
uint256 public purchaserCount = 0; // total number of purchasers purchased VZT | |
uint256 public purchaserDistCount = 0; // total number of purchasers received purchased VZT + bonus | |
uint256 public tokensSold = 0; | |
uint256 public minVztPurchase = 0; | |
uint256 public tokenHardCap = 0; | |
/** this becomes true when crowdsale has distributed purchased tokens with bonus for each purchaser address */ | |
mapping (address => bool) public tokenDistributed; | |
event TokenDistributed(address indexed purchaser, uint256 tokenAmt); // event logging for each individual distributed token + bonus | |
/* | |
Constructor to initialize everything. | |
*/ | |
function VZTPresaleDist (address _presale, address _token, address _owner) public { | |
if (_owner == address(0)) { | |
_owner = msg.sender; | |
} | |
require(_presale != address(0)); | |
require(_owner != address(0)); | |
token = VZToken(_token); | |
owner = _owner; // default owner | |
preSale = VZTPresale(_presale); | |
purchaserCount = preSale.purchaserCount(); // initialize to all purchaser count | |
tokensSold = preSale.tokensSold(); // initialize token sold from crowd sale | |
minVztPurchase = preSale.MIN_VZT_PURCHASE(); | |
tokenHardCap = preSale.PRESALE_TOKEN_HARD_CAP(); | |
} | |
function setTokenContract(address _token) external onlyOwner { | |
require(token != address(0)); | |
token = VZToken(_token); | |
} | |
/* | |
Distribute tokens purchased with bonus. | |
*/ | |
function distributeTokensFor(address purchaser) external onlyOwner { | |
require(token != address(0)); | |
require(preSale.isFinalized()); | |
require(preSale.isMinimumGoalReached()); | |
require(preSale.tokenAmountOf(purchaser) > 0); | |
require(!tokenDistributed[purchaser]); | |
tokenDistributed[purchaser] = true; // token + bonus distributed | |
uint256 tokenPurchased = preSale.tokenAmountOf(purchaser); | |
purchaserDistCount++; // one more purchaser received token + bonus | |
// transfer the purchased tokens + bonus | |
token.transfer(purchaser, tokenPurchased); | |
// signal the event for communication | |
TokenDistributed(purchaser, tokenPurchased); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment