pragma solidity ^0.4.18;
// ----------------------------------------------------------------------------------------------
// Gifto Token by Gifto Limited.
// An ERC20 standard
//
// author: Gifto Team
// Contact: datwhnguyen@gmail.com
contract ERC20Interface {
// Get the total token supply
function totalSupply() public constant returns (uint256 _totalSupply);
// Get the account balance of another account with address _owner
function balanceOf(address _owner) public constant returns (uint256 balance);
// Send _value amount of tokens to address _to
function transfer(address _to, uint256 _value) public returns (bool success);
// transfer _value amount of token approved by address _from
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
// approve an address with _value amount of tokens
function approve(address _spender, uint256 _value) public returns (bool success);
// get remaining token approved by _owner to _spender
function allowance(address _owner, address _spender) public constant returns (uint256 remaining);
// Triggered when tokens are transferred.
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// Triggered whenever approve(address _spender, uint256 _value) is called.
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract Gifto is ERC20Interface {
uint256 public constant decimals = 5;
string public constant symbol = "GTO";
string public constant name = "Gifto";
bool public _selling = true;//initial selling
uint256 public _totalSupply = 10 ** 14; // total supply is 10^14 unit, equivalent to 10^9 Gifto
uint256 public _originalBuyPrice = 43 * 10**7; // original buy 1ETH = 4300 Gifto = 43 * 10**7 unit
// Owner of this contract
address public owner;
// Balances Gifto for each account
mapping(address => uint256) private balances;
// Owner of account approves the transfer of an amount to another account
mapping(address => mapping (address => uint256)) private allowed;
// List of approved investors
mapping(address => bool) private approvedInvestorList;
// deposit
mapping(address => uint256) private deposit;
// icoPercent
uint256 public _icoPercent = 10;
// _icoSupply is the avalable unit. Initially, it is _totalSupply
uint256 public _icoSupply = _totalSupply * _icoPercent / 100;
// minimum buy 0.3 ETH
uint256 public _minimumBuy = 3 * 10 ** 17;
// maximum buy 25 ETH
uint256 public _maximumBuy = 25 * 10 ** 18;
// totalTokenSold
uint256 public totalTokenSold = 0;
// tradable
bool public tradable = false;
/**
* Functions with this modifier can only be executed by the owner
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* Functions with this modifier check on sale status
* Only allow sale if _selling is on
*/
modifier onSale() {
require(_selling);
_;
}
/**
* Functions with this modifier check the validity of address is investor
*/
modifier validInvestor() {
require(approvedInvestorList[msg.sender]);
_;
}
/**
* Functions with this modifier check the validity of msg value
* value must greater than equal minimumBuyPrice
* total deposit must less than equal maximumBuyPrice
*/
modifier validValue(){
// require value >= _minimumBuy AND total deposit of msg.sender <= maximumBuyPrice
require ( (msg.value >= _minimumBuy) &&
( (deposit[msg.sender] + msg.value) <= _maximumBuy) );
_;
}
/**
*
*/
modifier isTradable(){
require(tradable == true || msg.sender == owner);
_;
}
/// @dev Fallback function allows to buy ether.
function()
public
payable {
buyGifto();
}
/// @dev buy function allows to buy ether. for using optional data
function buyGifto()
public
payable
onSale
validValue
validInvestor {
uint256 requestedUnits = (msg.value * _originalBuyPrice) / 10**18;
require(balances[owner] >= requestedUnits);
// prepare transfer data
balances[owner] -= requestedUnits;
balances[msg.sender] += requestedUnits;
// increase total deposit amount
deposit[msg.sender] += msg.value;
// check total and auto turnOffSale
totalTokenSold += requestedUnits;
if (totalTokenSold >= _icoSupply){
_selling = false;
}
// submit transfer
Transfer(owner, msg.sender, requestedUnits);
owner.transfer(msg.value);
}
/// @dev Constructor
function Gifto()
public {
owner = msg.sender;
setBuyPrice(_originalBuyPrice);
balances[owner] = _totalSupply;
Transfer(0x0, owner, _totalSupply);
}
/// @dev Gets totalSupply
/// @return Total supply
function totalSupply()
public
constant
returns (uint256) {
return _totalSupply;
}
/// @dev Enables sale
function turnOnSale() onlyOwner
public {
_selling = true;
}
/// @dev Disables sale
function turnOffSale() onlyOwner
public {
_selling = false;
}
function turnOnTradable()
public
onlyOwner{
tradable = true;
}
/// @dev set new icoPercent
/// @param newIcoPercent new value of icoPercent
function setIcoPercent(uint256 newIcoPercent)
public
onlyOwner {
_icoPercent = newIcoPercent;
_icoSupply = _totalSupply * _icoPercent / 100;
}
/// @dev set new _maximumBuy
/// @param newMaximumBuy new value of _maximumBuy
function setMaximumBuy(uint256 newMaximumBuy)
public
onlyOwner {
_maximumBuy = newMaximumBuy;
}
/// @dev Updates buy price (owner ONLY)
/// @param newBuyPrice New buy price (in unit)
function setBuyPrice(uint256 newBuyPrice)
onlyOwner
public {
require(newBuyPrice>0);
_originalBuyPrice = newBuyPrice; // 3000 Gifto = 3000 00000 unit
// control _maximumBuy_USD = 10,000 USD, Gifto price is 0.1USD
// maximumBuy_Gifto = 100,000 Gifto = 100,000,00000 unit
// 3000 Gifto = 1ETH => maximumETH = 100,000,00000 / _originalBuyPrice
// 100,000,00000/3000 0000 ~ 33ETH => change to wei
_maximumBuy = 10**18 * 10000000000 /_originalBuyPrice;
}
/// @dev Gets account's balance
/// @param _addr Address of the account
/// @return Account balance
function balanceOf(address _addr)
public
constant
returns (uint256) {
return balances[_addr];
}
/// @dev check address is approved investor
/// @param _addr address
function isApprovedInvestor(address _addr)
public
constant
returns (bool) {
return approvedInvestorList[_addr];
}
/// @dev get ETH deposit
/// @param _addr address get deposit
/// @return amount deposit of an buyer
function getDeposit(address _addr)
public
constant
returns(uint256){
return deposit[_addr];
}
/// @dev Adds list of new investors to the investors list and approve all
/// @param newInvestorList Array of new investors addresses to be added
function addInvestorList(address[] newInvestorList)
onlyOwner
public {
for (uint256 i = 0; i < newInvestorList.length; i++){
approvedInvestorList[newInvestorList[i]] = true;
}
}
/// @dev Removes list of investors from list
/// @param investorList Array of addresses of investors to be removed
function removeInvestorList(address[] investorList)
onlyOwner
public {
for (uint256 i = 0; i < investorList.length; i++){
approvedInvestorList[investorList[i]] = false;
}
}
/// @dev Transfers the balance from msg.sender to an account
/// @param _to Recipient address
/// @param _amount Transfered amount in unit
/// @return Transfer status
function transfer(address _to, uint256 _amount)
public
isTradable
returns (bool) {
// if sender's balance has enough unit and amount >= 0,
// and the sum is not overflow,
// then do transfer
if ( (balances[msg.sender] >= _amount) &&
(_amount >= 0) &&
(balances[_to] + _amount > balances[_to]) ) {
balances[msg.sender] -= _amount;
balances[_to] += _amount;
Transfer(msg.sender, _to, _amount);
return true;
} else {
return false;
}
}
// Send _value amount of tokens from address _from to address _to
// The transferFrom method is used for a withdraw workflow, allowing contracts to send
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge
// fees in sub-currencies; the command should fail unless the _from account has
// deliberately authorized the sender of the message via some mechanism; we propose
// these standardized APIs for approval:
function transferFrom(
address _from,
address _to,
uint256 _amount
)
public
isTradable
returns (bool success) {
if (balances[_from] >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[_from] -= _amount;
allowed[_from][msg.sender] -= _amount;
balances[_to] += _amount;
Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
}
// Allow _spender to withdraw from your account, multiple times, up to the _value amount.
// If this function is called again it overwrites the current allowance with _value.
function approve(address _spender, uint256 _amount)
public
isTradable
returns (bool success) {
allowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}
// get allowance
function allowance(address _owner, address _spender)
public
constant
returns (uint256 remaining) {
return allowed[_owner][_spender];
}
/// @dev Withdraws Ether in contract (Owner only)
/// @return Status of withdrawal
function withdraw() onlyOwner
public
returns (bool) {
return owner.send(this.balance);
}
}
{
"compilationTarget": {
"Gifto.sol": "Gifto"
},
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[{"name":"newMaximumBuy","type":"uint256"}],"name":"setMaximumBuy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","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":"turnOffSale","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"turnOnTradable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newIcoPercent","type":"uint256"}],"name":"setIcoPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_icoSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[{"name":"","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":"buyGifto","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"_icoPercent","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tradable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newBuyPrice","type":"uint256"}],"name":"setBuyPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_minimumBuy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_originalBuyPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_maximumBuy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isApprovedInvestor","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"investorList","type":"address[]"}],"name":"removeInvestorList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalTokenSold","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newInvestorList","type":"address[]"}],"name":"addInvestorList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"getDeposit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"turnOnSale","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_selling","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"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"}]