mirror of
https://github.com/fluencelabs/smartcontracts
synced 2025-04-25 03:02:18 +00:00
using revert()
This commit is contained in:
parent
423ae7fef2
commit
c779da5064
@ -4,21 +4,21 @@ pragma solidity ^0.4.13;
|
|||||||
/* taking ideas from FirstBlood token */
|
/* taking ideas from FirstBlood token */
|
||||||
contract SafeMath {
|
contract SafeMath {
|
||||||
|
|
||||||
function safeAdd(uint256 x, uint256 y) internal returns(uint256) {
|
function safeAdd(uint256 x, uint256 y) internal returns (uint256) {
|
||||||
uint256 z = x + y;
|
uint256 z = x + y;
|
||||||
assert((z >= x) && (z >= y));
|
assert((z >= x) && (z >= y));
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
function safeSubtract(uint256 x, uint256 y) internal returns(uint256) {
|
function safeSubtract(uint256 x, uint256 y) internal returns (uint256) {
|
||||||
assert(x >= y);
|
assert(x >= y);
|
||||||
uint256 z = x - y;
|
uint256 z = x - y;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
function safeMult(uint256 x, uint256 y) internal returns(uint256) {
|
function safeMult(uint256 x, uint256 y) internal returns (uint256) {
|
||||||
uint256 z = x * y;
|
uint256 z = x * y;
|
||||||
assert((x == 0)||(z/x == y));
|
assert((x == 0) || (z / x == y));
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,14 +111,17 @@ contract FluencePreSale is Haltable, SafeMath {
|
|||||||
|
|
||||||
// Basic price
|
// Basic price
|
||||||
uint256 public constant basicThreshold = 500 finney;
|
uint256 public constant basicThreshold = 500 finney;
|
||||||
|
|
||||||
uint public constant basicTokensPerEth = 1500;
|
uint public constant basicTokensPerEth = 1500;
|
||||||
|
|
||||||
// Advanced price
|
// Advanced price
|
||||||
uint256 public constant advancedThreshold = 5 ether;
|
uint256 public constant advancedThreshold = 5 ether;
|
||||||
|
|
||||||
uint public constant advancedTokensPerEth = 2250;
|
uint public constant advancedTokensPerEth = 2250;
|
||||||
|
|
||||||
// Expert price
|
// Expert price
|
||||||
uint256 public constant expertThreshold = 100 ether;
|
uint256 public constant expertThreshold = 100 ether;
|
||||||
|
|
||||||
uint public constant expertTokensPerEth = 3000;
|
uint public constant expertTokensPerEth = 3000;
|
||||||
|
|
||||||
// As we have different prices for different amounts,
|
// As we have different prices for different amounts,
|
||||||
@ -135,77 +138,111 @@ contract FluencePreSale is Haltable, SafeMath {
|
|||||||
|
|
||||||
uint public endAtBlock;
|
uint public endAtBlock;
|
||||||
|
|
||||||
|
// All tokens are sold
|
||||||
event GoalReached(uint amountRaised);
|
event GoalReached(uint amountRaised);
|
||||||
|
|
||||||
|
// Minimal ether cap collected
|
||||||
event SoftCapReached(uint softCap);
|
event SoftCapReached(uint softCap);
|
||||||
|
|
||||||
|
// New contribution received and tokens are issued
|
||||||
event NewContribution(address indexed holder, uint256 tokenAmount, uint256 etherAmount);
|
event NewContribution(address indexed holder, uint256 tokenAmount, uint256 etherAmount);
|
||||||
|
|
||||||
|
// Ether is taken back
|
||||||
event Refunded(address indexed holder, uint256 amount);
|
event Refunded(address indexed holder, uint256 amount);
|
||||||
|
|
||||||
// If soft cap is reached, withdraw should be available
|
// If soft cap is reached, withdraw should be available
|
||||||
modifier softCapReached {
|
modifier softCapReached {
|
||||||
require(etherCollected >= softCap);
|
if (etherCollected < softCap) {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
assert(etherCollected >= softCap);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow contribution only during presale
|
||||||
modifier duringPresale {
|
modifier duringPresale {
|
||||||
require(block.number >= startAtBlock && block.number <= endAtBlock && totalSupply < SUPPLY_LIMIT);
|
if (block.number < startAtBlock || block.number > endAtBlock || totalSupply >= SUPPLY_LIMIT) {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
assert(block.number >= startAtBlock && block.number <= endAtBlock && totalSupply < SUPPLY_LIMIT);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow withdraw only during refund
|
||||||
modifier duringRefund {
|
modifier duringRefund {
|
||||||
require(block.number > endAtBlock && etherCollected < softCap && this.balance > 0);
|
if(block.number <= endAtBlock || etherCollected >= softCap || this.balance == 0) {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
assert(block.number > endAtBlock && etherCollected < softCap && this.balance > 0);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
function FluencePreSale(uint _startAtBlock, uint _endAtBlock, uint softCapEther){
|
function FluencePreSale(uint _startAtBlock, uint _endAtBlock, uint softCapInEther){
|
||||||
require(_startAtBlock > 0 && _endAtBlock > 0);
|
require(_startAtBlock > 0 && _endAtBlock > 0);
|
||||||
beneficiary = msg.sender;
|
beneficiary = msg.sender;
|
||||||
startAtBlock = _startAtBlock;
|
startAtBlock = _startAtBlock;
|
||||||
endAtBlock = _endAtBlock;
|
endAtBlock = _endAtBlock;
|
||||||
softCap = softCapEther * 1 ether;
|
softCap = softCapInEther * 1 ether;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change beneficiary address
|
||||||
function setBeneficiary(address to) onlyOwner external {
|
function setBeneficiary(address to) onlyOwner external {
|
||||||
require(to != address(0));
|
require(to != address(0));
|
||||||
beneficiary = to;
|
beneficiary = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Withdraw contract's balance to beneficiary account
|
||||||
function withdraw() onlyOwner softCapReached external {
|
function withdraw() onlyOwner softCapReached external {
|
||||||
require(this.balance > 0);
|
require(this.balance > 0);
|
||||||
beneficiary.transfer(this.balance);
|
beneficiary.transfer(this.balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process contribution, issue tokens to user
|
||||||
function contribute(address _address) private stopInEmergency duringPresale {
|
function contribute(address _address) private stopInEmergency duringPresale {
|
||||||
require(msg.value >= basicThreshold || owner == _address); // Minimal contribution
|
if(msg.value < basicThreshold && owner != _address) {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
assert(msg.value >= basicThreshold || owner == _address);
|
||||||
|
// Minimal contribution
|
||||||
|
|
||||||
uint256 tokensToIssue;
|
uint256 tokensToIssue;
|
||||||
|
|
||||||
if(msg.value >= expertThreshold) {
|
if (msg.value >= expertThreshold) {
|
||||||
tokensToIssue = safeMult(msg.value, expertTokensPerEth);
|
tokensToIssue = safeMult(msg.value, expertTokensPerEth);
|
||||||
} else if(msg.value >= advancedThreshold) {
|
}
|
||||||
|
else if (msg.value >= advancedThreshold) {
|
||||||
tokensToIssue = safeMult(msg.value, advancedTokensPerEth);
|
tokensToIssue = safeMult(msg.value, advancedTokensPerEth);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
tokensToIssue = safeMult(msg.value, basicTokensPerEth);
|
tokensToIssue = safeMult(msg.value, basicTokensPerEth);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(tokensToIssue > 0);
|
assert(tokensToIssue > 0);
|
||||||
|
|
||||||
totalSupply = safeAdd(totalSupply, tokensToIssue);
|
totalSupply = safeAdd(totalSupply, tokensToIssue);
|
||||||
require(totalSupply <= SUPPLY_LIMIT);
|
|
||||||
|
|
||||||
|
// Goal is already reached, can't issue any more tokens
|
||||||
|
if(totalSupply > SUPPLY_LIMIT) {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
assert(totalSupply <= SUPPLY_LIMIT);
|
||||||
|
|
||||||
|
// Saving ether contributions for the case of refund
|
||||||
etherContributions[_address] = safeAdd(etherContributions[_address], msg.value);
|
etherContributions[_address] = safeAdd(etherContributions[_address], msg.value);
|
||||||
|
|
||||||
|
// Track ether before adding current contribution to notice the event of reaching soft cap
|
||||||
uint collectedBefore = etherCollected;
|
uint collectedBefore = etherCollected;
|
||||||
etherCollected = safeAdd(etherCollected, msg.value);
|
etherCollected = safeAdd(etherCollected, msg.value);
|
||||||
|
|
||||||
|
// Tokens are issued
|
||||||
balanceOf[_address] = safeAdd(balanceOf[_address], tokensToIssue);
|
balanceOf[_address] = safeAdd(balanceOf[_address], tokensToIssue);
|
||||||
|
|
||||||
NewContribution(_address, tokensToIssue, msg.value);
|
NewContribution(_address, tokensToIssue, msg.value);
|
||||||
|
|
||||||
if(totalSupply == SUPPLY_LIMIT) {
|
if (totalSupply == SUPPLY_LIMIT) {
|
||||||
GoalReached(etherCollected);
|
GoalReached(etherCollected);
|
||||||
}
|
}
|
||||||
if(etherCollected >= softCap && collectedBefore < softCap) {
|
if (etherCollected >= softCap && collectedBefore < softCap) {
|
||||||
SoftCapReached(etherCollected);
|
SoftCapReached(etherCollected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,20 +254,28 @@ contract FluencePreSale is Haltable, SafeMath {
|
|||||||
function refund() stopInEmergency duringRefund external {
|
function refund() stopInEmergency duringRefund external {
|
||||||
uint tokensToBurn = balanceOf[msg.sender];
|
uint tokensToBurn = balanceOf[msg.sender];
|
||||||
|
|
||||||
require(tokensToBurn > 0); // Sender must have tokens
|
|
||||||
balanceOf[msg.sender] = 0; // Burn
|
|
||||||
|
|
||||||
uint amount = etherContributions[msg.sender]; // User contribution amount
|
// Sender must have tokens
|
||||||
|
require(tokensToBurn > 0);
|
||||||
|
|
||||||
require(amount > 0); // Amount must be positive -- refund is not processed yet
|
// Burn
|
||||||
|
balanceOf[msg.sender] = 0;
|
||||||
|
|
||||||
etherContributions[msg.sender] = 0; // Clear state
|
// User contribution amount
|
||||||
|
uint amount = etherContributions[msg.sender];
|
||||||
|
|
||||||
|
// Amount must be positive -- refund is not processed yet
|
||||||
|
assert(amount > 0);
|
||||||
|
|
||||||
|
etherContributions[msg.sender] = 0;
|
||||||
|
// Clear state
|
||||||
|
|
||||||
// Reduce counters
|
// Reduce counters
|
||||||
etherCollected = safeSubtract(etherCollected, amount);
|
etherCollected = safeSubtract(etherCollected, amount);
|
||||||
totalSupply = safeSubtract(totalSupply, tokensToBurn);
|
totalSupply = safeSubtract(totalSupply, tokensToBurn);
|
||||||
|
|
||||||
msg.sender.transfer(amount); // Process refund. In case of error, it will be thrown
|
// Process refund. In case of error, it will be thrown
|
||||||
|
msg.sender.transfer(amount);
|
||||||
|
|
||||||
Refunded(msg.sender, amount);
|
Refunded(msg.sender, amount);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user