pragma solidity ^0.4.18;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant 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 constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
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() {
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) onlyOwner public {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title Pausable
* @dev Base contract which allows children to implement an emergency stop mechanism.
*/
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();
}
}
contract QuantstampSale is Pausable {
using SafeMath for uint256;
// The beneficiary is the future recipient of the funds
address public beneficiary;
// The crowdsale has a funding goal, cap, deadline, and minimum contribution
uint public fundingCap;
uint public minContribution;
bool public fundingCapReached = false;
bool public saleClosed = false;
// Whitelist data
mapping(address => bool) public registry;
// For each user, specifies the cap (in wei) that can be contributed for each tier
// Tiers are filled in the order 3, 2, 1, 4
mapping(address => uint256) public cap1; // 100% bonus
mapping(address => uint256) public cap2; // 40% bonus
mapping(address => uint256) public cap3; // 20% bonus
mapping(address => uint256) public cap4; // 0% bonus
// Stores the amount contributed for each tier for a given address
mapping(address => uint256) public contributed1;
mapping(address => uint256) public contributed2;
mapping(address => uint256) public contributed3;
mapping(address => uint256) public contributed4;
// Conversion rate by tier (QSP : ETHER)
uint public rate1 = 10000;
uint public rate2 = 7000;
uint public rate3 = 6000;
uint public rate4 = 5000;
// Time period of sale (UNIX timestamps)
uint public startTime;
uint public endTime;
// Keeps track of the amount of wei raised
uint public amountRaised;
// prevent certain functions from being recursively called
bool private rentrancy_lock = false;
// The token being sold
// QuantstampToken public tokenReward;
// A map that tracks the amount of wei contributed by address
mapping(address => uint256) public balanceOf;
// A map that tracks the amount of QSP tokens that should be allocated to each address
mapping(address => uint256) public tokenBalanceOf;
// Events
event CapReached(address _beneficiary, uint _amountRaised);
event FundTransfer(address _backer, uint _amount, bool _isContribution);
event RegistrationStatusChanged(address target, bool isRegistered, uint c1, uint c2, uint c3, uint c4);
// Modifiers
modifier beforeDeadline() { require (currentTime() < endTime); _; }
// modifier afterDeadline() { require (currentTime() >= endTime); _; } no longer used without fundingGoal
modifier afterStartTime() { require (currentTime() >= startTime); _; }
modifier saleNotClosed() { require (!saleClosed); _; }
modifier nonReentrant() {
require(!rentrancy_lock);
rentrancy_lock = true;
_;
rentrancy_lock = false;
}
/**
* Constructor for a crowdsale of QuantstampToken tokens.
*
* @param ifSuccessfulSendTo the beneficiary of the fund
* @param fundingCapInEthers the cap (maximum) size of the fund
* @param minimumContributionInWei minimum contribution (in wei)
* @param start the start time (UNIX timestamp)
* @param durationInMinutes the duration of the crowdsale in minutes
*/
function QuantstampSale(
address ifSuccessfulSendTo,
uint fundingCapInEthers,
uint minimumContributionInWei,
uint start,
uint durationInMinutes
// address addressOfTokenUsedAsReward
) {
require(ifSuccessfulSendTo != address(0) && ifSuccessfulSendTo != address(this));
//require(addressOfTokenUsedAsReward != address(0) && addressOfTokenUsedAsReward != address(this));
require(durationInMinutes > 0);
beneficiary = ifSuccessfulSendTo;
fundingCap = fundingCapInEthers * 1 ether;
minContribution = minimumContributionInWei;
startTime = start;
endTime = start + (durationInMinutes * 1 minutes);
// tokenReward = QuantstampToken(addressOfTokenUsedAsReward);
}
/**
* This function is called whenever Ether is sent to the
* smart contract. It can only be executed when the crowdsale is
* not paused, not closed, and before the deadline has been reached.
*
* This function will update state variables for whether or not the
* funding goal or cap have been reached. It also ensures that the
* tokens are transferred to the sender, and that the correct
* number of tokens are sent according to the current rate.
*/
function () payable {
buy();
}
function buy ()
payable public
whenNotPaused
beforeDeadline
afterStartTime
saleNotClosed
nonReentrant
{
require(msg.value >= minContribution);
uint amount = msg.value;
// ensure that the user adheres to whitelist restrictions
require(registry[msg.sender]);
uint numTokens = computeTokenAmount(msg.sender, amount);
assert(numTokens > 0);
// update the total amount raised
amountRaised = amountRaised.add(amount);
require(amountRaised <= fundingCap);
// update the sender's balance of wei contributed
balanceOf[msg.sender] = balanceOf[msg.sender].add(amount);
// add to the token balance of the sender
tokenBalanceOf[msg.sender] = tokenBalanceOf[msg.sender].add(numTokens);
FundTransfer(msg.sender, amount, true);
updateFundingCap();
}
/**
* Computes the amount of QSP that should be issued for the given transaction.
* Contribution tiers are filled up in the order 3, 2, 1, 4.
* @param addr The wallet address of the contributor
* @param amount Amount of wei for payment
*/
function computeTokenAmount(address addr, uint amount) internal
returns (uint){
require(amount > 0);
uint r3 = cap3[addr].sub(contributed3[addr]);
uint r2 = cap2[addr].sub(contributed2[addr]);
uint r1 = cap1[addr].sub(contributed1[addr]);
uint r4 = cap4[addr].sub(contributed4[addr]);
uint numTokens = 0;
// cannot contribute more than the remaining sum
assert(amount <= r3.add(r2).add(r1).add(r4));
// Compute tokens for tier 3
if(r3 > 0){
if(amount <= r3){
contributed3[addr] = contributed3[addr].add(amount);
return rate3.mul(amount);
}
else{
numTokens = rate3.mul(r3);
amount = amount.sub(r3);
contributed3[addr] = cap3[addr];
}
}
// Compute tokens for tier 2
if(r2 > 0){
if(amount <= r2){
contributed2[addr] = contributed2[addr].add(amount);
return numTokens.add(rate2.mul(amount));
}
else{
numTokens = numTokens.add(rate2.mul(r2));
amount = amount.sub(r2);
contributed2[addr] = cap2[addr];
}
}
// Compute tokens for tier 1
if(r1 > 0){
if(amount <= r1){
contributed1[addr] = contributed1[addr].add(amount);
return numTokens.add(rate1.mul(amount));
}
else{
numTokens = numTokens.add(rate1.mul(r1));
amount = amount.sub(r1);
contributed1[addr] = cap1[addr];
}
}
// Compute tokens for tier 4 (overflow)
contributed4[addr] = contributed4[addr].add(amount);
return numTokens.add(rate4.mul(amount));
}
/**
* @dev Check if a contributor was at any point registered.
*
* @param contributor Address that will be checked.
*/
function hasPreviouslyRegistered(address contributor)
internal
constant
onlyOwner returns (bool)
{
// if caps for this customer exist, then the customer has previously been registered
return (cap1[contributor].add(cap2[contributor]).add(cap3[contributor]).add(cap4[contributor])) > 0;
}
/*
* If the user was already registered, ensure that the new caps do not conflict previous contributions
*
* NOTE: cannot use SafeMath here, because it exceeds the local variable stack limit.
* Should be ok since it is onlyOwner, and conditionals should guard the subtractions from underflow.
*/
function validateUpdatedRegistration(address addr, uint c1, uint c2, uint c3, uint c4)
internal
constant
onlyOwner returns(bool)
{
return (contributed3[addr] <= c3) && (contributed2[addr] <= c2)
&& (contributed1[addr] <= c1) && (contributed4[addr] <= c4);
}
/**
* @dev Sets registration status of an address for participation.
*
* @param contributor Address that will be registered/deregistered.
* @param c1 The maximum amount of wei that the user can contribute in tier 1.
* @param c2 The maximum amount of wei that the user can contribute in tier 2.
* @param c3 The maximum amount of wei that the user can contribute in tier 3.
* @param c4 The maximum amount of wei that the user can contribute in tier 4.
*/
function registerUser(address contributor, uint c1, uint c2, uint c3, uint c4)
public
onlyOwner
{
require(contributor != address(0));
// if the user was already registered ensure that the new caps do not contradict their current contributions
if(hasPreviouslyRegistered(contributor)){
require(validateUpdatedRegistration(contributor, c1, c2, c3, c4));
}
require(c1.add(c2).add(c3).add(c4) >= minContribution);
registry[contributor] = true;
cap1[contributor] = c1;
cap2[contributor] = c2;
cap3[contributor] = c3;
cap4[contributor] = c4;
RegistrationStatusChanged(contributor, true, c1, c2, c3, c4);
}
/**
* @dev Remove registration status of an address for participation.
*
* NOTE: if the user made initial contributions to the crowdsale,
* this will not return the previously allotted tokens.
*
* @param contributor Address to be unregistered.
*/
function deactivate(address contributor)
public
onlyOwner
{
require(registry[contributor]);
registry[contributor] = false;
RegistrationStatusChanged(contributor, false, cap1[contributor], cap2[contributor], cap3[contributor], cap4[contributor]);
}
/**
* @dev Re-registers an already existing contributor
*
* @param contributor Address to be unregistered.
*/
function reactivate(address contributor)
public
onlyOwner
{
require(hasPreviouslyRegistered(contributor));
registry[contributor] = true;
RegistrationStatusChanged(contributor, true, cap1[contributor], cap2[contributor], cap3[contributor], cap4[contributor]);
}
/**
* @dev Sets registration statuses of addresses for participation.
* @param contributors Addresses that will be registered/deregistered.
* @param caps1 The maximum amount of wei that each user can contribute to cap1, in the same order as the addresses.
* @param caps2 The maximum amount of wei that each user can contribute to cap2, in the same order as the addresses.
* @param caps3 The maximum amount of wei that each user can contribute to cap3, in the same order as the addresses.
* @param caps4 The maximum amount of wei that each user can contribute to cap4, in the same order as the addresses.
*/
function registerUsers(address[] contributors,
uint[] caps1,
uint[] caps2,
uint[] caps3,
uint[] caps4)
external
onlyOwner
{
// check that all arrays have the same length
require(contributors.length == caps1.length);
require(contributors.length == caps2.length);
require(contributors.length == caps3.length);
require(contributors.length == caps4.length);
for (uint i = 0; i < contributors.length; i++) {
registerUser(contributors[i], caps1[i], caps2[i], caps3[i], caps4[i]);
}
}
/**
* The owner can terminate the crowdsale at any time.
*/
function terminate() external onlyOwner {
saleClosed = true;
}
/**
* The owner can allocate the specified amount of tokens from the
* crowdsale allowance to the recipient addresses.
*
* NOTE: be extremely careful to get the amounts correct, which
* are in units of wei and mini-QSP. Every digit counts.
*
* @param addrs the recipient addresses
* @param weiAmounts the amounts contributed in wei
* @param miniQspAmounts the amounts of tokens transferred in mini-QSP
*/
function ownerAllocateTokensForList(address[] addrs, uint[] weiAmounts, uint[] miniQspAmounts)
external onlyOwner
{
require(addrs.length == weiAmounts.length);
require(addrs.length == miniQspAmounts.length);
for(uint i = 0; i < addrs.length; i++){
ownerAllocateTokens(addrs[i], weiAmounts[i], miniQspAmounts[i]);
}
}
/**
*
* The owner can allocate the specified amount of tokens from the
* crowdsale allowance to the recipient (_to).
*
*
*
* NOTE: be extremely careful to get the amounts correct, which
* are in units of wei and mini-QSP. Every digit counts.
*
* @param _to the recipient of the tokens
* @param amountWei the amount contributed in wei
* @param amountMiniQsp the amount of tokens transferred in mini-QSP
*/
function ownerAllocateTokens(address _to, uint amountWei, uint amountMiniQsp)
onlyOwner nonReentrant
{
// don't allocate tokens for the admin
// require(tokenReward.adminAddr() != _to);
amountRaised = amountRaised.add(amountWei);
require(amountRaised <= fundingCap);
tokenBalanceOf[_to] = tokenBalanceOf[_to].add(amountMiniQsp);
balanceOf[_to] = balanceOf[_to].add(amountWei);
FundTransfer(_to, amountWei, true);
updateFundingCap();
}
/**
* The owner can call this function to withdraw the funds that
* have been sent to this contract for the crowdsale subject to
* the funding goal having been reached. The funds will be sent
* to the beneficiary specified when the crowdsale was created.
*/
function ownerSafeWithdrawal() external onlyOwner nonReentrant {
uint balanceToSend = this.balance;
beneficiary.transfer(balanceToSend);
FundTransfer(beneficiary, balanceToSend, false);
}
/**
* Checks if the funding cap has been reached. If it has, then
* the CapReached event is triggered.
*/
function updateFundingCap() internal {
assert (amountRaised <= fundingCap);
if (amountRaised == fundingCap) {
// Check if the funding cap has been reached
fundingCapReached = true;
saleClosed = true;
CapReached(beneficiary, amountRaised);
}
}
/**
* Returns the current time.
* Useful to abstract calls to "now" for tests.
*/
function currentTime() constant returns (uint _currentTime) {
return now;
}
}
/**
* The ExtendedQuantstampSale smart contract is used for selling QuantstampToken
* tokens (QSP). It does so by converting ETH received into a quantity of
* tokens that are transferred to the contributor via the ERC20-compatible
* transferFrom() function.
*/
contract ExtendedQuantstampSale is Pausable {
using SafeMath for uint256;
address public beneficiary;
uint public fundingCap;
uint public minContribution;
bool public fundingCapReached = false;
bool public saleClosed = false;
// Whitelist data
mapping(address => bool) public registry;
mapping(address => uint256) public cap;
// Time period of sale (UNIX timestamps)
uint public startTime;
uint public endTime;
// Keeps track of the amount of wei raised
uint public amountRaised;
// prevent certain functions from being recursively called
bool private rentrancy_lock = false;
// A map that tracks the amount of wei contributed by address
mapping(address => uint256) public balanceOf;
// Previously created contract
QuantstampSale public previousContract;
// Events
event CapReached(address _beneficiary, uint _amountRaised);
event FundTransfer(address _backer, uint _amount, bool _isContribution);
event RegistrationStatusChanged(address target, bool isRegistered, uint c);
// Modifiers
modifier beforeDeadline() { require (currentTime() < endTime); _; }
modifier afterStartTime() { require (currentTime() >= startTime); _; }
modifier saleNotClosed() { require (!saleClosed); _; }
modifier nonReentrant() {
require(!rentrancy_lock);
rentrancy_lock = true;
_;
rentrancy_lock = false;
}
/**
* Constructor for a crowdsale of QuantstampToken tokens.
*
* @param ifSuccessfulSendTo the beneficiary of the fund
* @param fundingCapInEthers the cap (maximum) size of the fund
* @param minimumContributionInWei minimum contribution (in wei)
* @param start the start time (UNIX timestamp)
* @param durationInMinutes the duration of the crowdsale in minutes
*/
function ExtendedQuantstampSale(
address ifSuccessfulSendTo,
uint fundingCapInEthers,
uint minimumContributionInWei,
uint start,
uint durationInMinutes,
address previousContractAddress
) {
require(ifSuccessfulSendTo != address(0) && ifSuccessfulSendTo != address(this));
require(durationInMinutes > 0);
beneficiary = ifSuccessfulSendTo;
fundingCap = fundingCapInEthers * 1 ether;
minContribution = minimumContributionInWei;
startTime = start;
endTime = start + (durationInMinutes * 1 minutes);
previousContract = QuantstampSale(previousContractAddress);
}
/**
* Fallback function that is payable and calls "buy" to purchase tokens.
*/
function () payable {
buy();
}
/**
* Buy tokens, subject to the descriptive constraints specified by modifiers.
*/
function buy ()
payable public
whenNotPaused
beforeDeadline
afterStartTime
saleNotClosed
nonReentrant
{
uint amount = msg.value;
require(amount >= minContribution);
// ensure that the user adheres to whitelist restrictions
require(registry[msg.sender]);
// update the amount raised
amountRaised = amountRaised.add(amount);
require(getTotalAmountRaised() <= fundingCap);
// update the sender's balance of wei contributed
balanceOf[msg.sender] = balanceOf[msg.sender].add(amount);
require(getUserBalance(msg.sender) <= cap[msg.sender]);
FundTransfer(msg.sender, amount, true);
updateFundingCap();
}
function getTotalAmountRaised() public constant returns (uint) {
return amountRaised.add(previousContract.amountRaised());
}
function getUserBalance(address user) public constant returns (uint) {
return balanceOf[user].add(previousContract.balanceOf(user));
}
function setEndTime(uint timestamp) public onlyOwner {
endTime = timestamp;
}
/**
* @dev Check if a contributor was at any point registered.
*
* @param contributor Address that will be checked.
*/
function hasPreviouslyRegistered(address contributor)
internal
constant
returns (bool)
{
// if a cap for this customer exist, then the customer has previously been registered
// we skip the caps from the previous contract
return cap[contributor] > 0;
}
/*
* If the user was already registered, ensure that the new caps do not conflict previous contributions
*/
function validateUpdatedRegistration(address addr, uint _cap)
internal
constant
returns(bool)
{
return (getUserBalance(addr) <= _cap);
}
/**
* @dev Sets registration status of an address for participation.
*
* @param contributor Address that will be registered/deregistered.
* @param _cap The maximum amount of wei that the user can contribute
*/
function registerUser(address contributor, uint _cap)
public
onlyOwner
{
require(contributor != address(0));
// if the user was already registered ensure that the new caps do not contradict their current contributions
if(hasPreviouslyRegistered(contributor)){
require(validateUpdatedRegistration(contributor, _cap));
}
require(_cap >= minContribution);
registry[contributor] = true;
cap[contributor] = _cap;
RegistrationStatusChanged(contributor, true, _cap);
}
/**
* @dev Remove registration status of an address for participation.
*
* NOTE: if the user made initial contributions to the crowdsale,
* this will not return the previously allotted tokens.
*
* @param contributor Address to be unregistered.
*/
function deactivate(address contributor)
public
onlyOwner
{
require(registry[contributor]);
registry[contributor] = false;
RegistrationStatusChanged(contributor, false, cap[contributor]);
}
/**
* @dev Re-registers an already existing contributor
*
* @param contributor Address to be unregistered.
*/
function reactivate(address contributor)
public
onlyOwner
{
require(hasPreviouslyRegistered(contributor));
registry[contributor] = true;
RegistrationStatusChanged(contributor, true, cap[contributor]);
}
/**
* @dev Sets registration statuses of addresses for participation.
* @param contributors Addresses that will be registered/deregistered.
* @param caps The maximum amount of wei that each user can contribute to cap, in the same order as the addresses.
*/
function registerUsers(address[] contributors, uint[] caps) external
onlyOwner
{
// check that all arrays have the same length
require(contributors.length == caps.length);
for (uint i = 0; i < contributors.length; i++) {
registerUser(contributors[i], caps[i]);
}
}
/**
* The owner can terminate the crowdsale at any time.
*/
function terminate() external
onlyOwner
{
saleClosed = true;
}
/**
*
* The owner can allocate the specified amount.
*
* @param _to the recipient of the tokens
* @param amountWei the amount contributed in wei
*/
function ownerAllocate(address _to, uint amountWei) public
onlyOwner
nonReentrant
{
amountRaised = amountRaised.add(amountWei);
require(getTotalAmountRaised() <= fundingCap);
balanceOf[_to] = balanceOf[_to].add(amountWei);
FundTransfer(_to, amountWei, true);
updateFundingCap();
}
/**
* The owner can call this function to withdraw the funds that
* have been sent to this contract for the crowdsale subject to
* the funding goal having been reached. The funds will be sent
* to the beneficiary specified when the crowdsale was created.
*/
function ownerSafeWithdrawal() external
onlyOwner
nonReentrant
{
uint balanceToSend = this.balance;
beneficiary.transfer(balanceToSend);
FundTransfer(beneficiary, balanceToSend, false);
}
/**
* Checks if the funding cap has been reached. If it has, then
* the CapReached event is triggered.
*/
function updateFundingCap() internal
{
uint amount = getTotalAmountRaised();
assert (amount <= fundingCap);
if (amount == fundingCap) {
// Check if the funding cap has been reached
fundingCapReached = true;
saleClosed = true;
CapReached(beneficiary, amount);
}
}
/**
* Returns the current time.
* Useful to abstract calls to "now" for tests.
*/
function currentTime() public constant returns (uint _currentTime)
{
return now;
}
}
{
"compilationTarget": {
"ExtendedQuantstampSale.sol": "ExtendedQuantstampSale"
},
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"registry","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"terminate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"endTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"contributor","type":"address"}],"name":"deactivate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getUserBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"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":"ownerSafeWithdrawal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"previousContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"startTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fundingCapReached","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"contributors","type":"address[]"},{"name":"caps","type":"uint256[]"}],"name":"registerUsers","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"cap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"buy","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"minContribution","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"saleClosed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"setEndTime","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentTime","outputs":[{"name":"_currentTime","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalAmountRaised","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fundingCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"contributor","type":"address"}],"name":"reactivate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"amountWei","type":"uint256"}],"name":"ownerAllocate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"contributor","type":"address"},{"name":"_cap","type":"uint256"}],"name":"registerUser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingCapInEthers","type":"uint256"},{"name":"minimumContributionInWei","type":"uint256"},{"name":"start","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"previousContractAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_beneficiary","type":"address"},{"indexed":false,"name":"_amountRaised","type":"uint256"}],"name":"CapReached","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_backer","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_isContribution","type":"bool"}],"name":"FundTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"target","type":"address"},{"indexed":false,"name":"isRegistered","type":"bool"},{"indexed":false,"name":"c","type":"uint256"}],"name":"RegistrationStatusChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]