Created
November 23, 2018 04:36
-
-
Save gorbunovperm/f08ae6561b5584eb0bcfba0b4aaf2a94 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.24+commit.e67f0147.js&optimize=false&gist=
This file contains 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.22; | |
import "./ERC20Basic.sol"; | |
import "./SafeMath.sol"; | |
/** | |
* @title Basic token | |
* @dev Basic version of StandardToken, with no allowances. | |
*/ | |
contract BasicToken is ERC20Basic { | |
using SafeMath for uint256; | |
mapping(address => uint256) balances; | |
uint256 totalSupply_; | |
/** | |
* @dev total number of tokens in existence | |
*/ | |
function totalSupply() public view returns (uint256) { | |
return totalSupply_; | |
} | |
/** | |
* @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); | |
emit 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 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.22; | |
import "./BasicToken.sol"; | |
/** | |
* @title Burnable Token | |
* @dev Token that can be irreversibly burned (destroyed). | |
*/ | |
contract BurnableToken is BasicToken { | |
event Burn(address indexed burner, uint256 value); | |
/** | |
* @dev Burns a specific amount of tokens. | |
* @param _value The amount of token to be burned. | |
*/ | |
function burn(uint256 _value) public { | |
require(_value <= balances[msg.sender]); | |
// no need to require value <= totalSupply, since that would imply the | |
// sender's balance is greater than the totalSupply, which *should* be an assertion failure | |
address burner = msg.sender; | |
balances[burner] = balances[burner].sub(_value); | |
totalSupply_ = totalSupply_.sub(_value); | |
emit Burn(burner, _value); | |
emit Transfer(burner, address(0), _value); | |
} | |
} |
This file contains 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.22; | |
import "./ERC20Basic.sol"; | |
/** | |
* @title ERC20 interface | |
* @dev see https://github.com/ethereum/EIPs/issues/20 | |
*/ | |
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 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.22; | |
/** | |
* @title ERC20Basic | |
* @dev Simpler version of ERC20 interface | |
* @dev see https://github.com/ethereum/EIPs/issues/179 | |
*/ | |
contract ERC20Basic { | |
function totalSupply() public view returns (uint256); | |
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 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.24; | |
contract IBonus { | |
function getCurrentDayBonus(uint startSaleDate, bool saleState) public view returns(uint); | |
function _currentDay(uint startSaleDate, bool saleState) public view returns(uint); | |
function getBonusData() public view returns(string); | |
function getPreSaleBonusPercent() public view returns(uint); | |
function getMinReachUsdPayInCents() public view returns(uint); | |
} |
This file contains 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.24; | |
contract ICurrency { | |
function getUsdAbsRaisedInCents() external view returns(uint); | |
function getCoinRaisedBonusInWei() external view returns(uint); | |
function getCoinRaisedInWei() public view returns(uint); | |
function getUsdFromETH(uint ethWei) public view returns(uint); | |
function getTokenFromETH(uint ethWei) public view returns(uint); | |
function getCurrencyRate(string _ticker) public view returns(uint); | |
function addPay(string _ticker, uint value, uint usdAmount, uint coinRaised, uint coinRaisedBonus) public returns(bool); | |
function checkTickerExists(string ticker) public view returns(bool); | |
function getUsdFromCurrency(string ticker, uint value) public view returns(uint); | |
function getUsdFromCurrency(string ticker, uint value, uint usd) public view returns(uint); | |
function getUsdFromCurrency(bytes32 ticker, uint value) public view returns(uint); | |
function getUsdFromCurrency(bytes32 ticker, uint value, uint usd) public view returns(uint); | |
function getTokenWeiFromUSD(uint usdCents) public view returns(uint); | |
function editPay(bytes32 ticker, uint currencyValue, uint currencyUsdRaised, uint _usdAbsRaisedInCents, uint _coinRaisedInWei, uint _coinRaisedBonusInWei) public returns(bool); | |
function getCurrencyList(string ticker) public view returns(bool active, uint usd, uint devision, uint raised, uint usdRaised, uint usdRaisedExchangeRate, uint counter, uint lastUpdate); | |
function getCurrencyList(bytes32 ticker) public view returns(bool active, uint usd, uint devision, uint raised, uint usdRaised, uint usdRaisedExchangeRate, uint counter, uint lastUpdate); | |
function getTotalUsdRaisedInCents() public view returns(uint); | |
function getAllCurrencyTicker() public view returns(string); | |
function getCoinUSDRate() public view returns(uint); | |
function addPreSaleBonus(uint bonusToken) public returns(bool); | |
function editPreSaleBonus(uint beforeBonus, uint afterBonus) public returns(bool); | |
} |
This file contains 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.24; | |
contract IStorage { | |
function processPreSaleBonus(uint minTotalUsdAmountInCents, uint bonusPercent, uint _start, uint _limit) external returns(uint); | |
function checkNeedProcessPreSaleBonus(uint minTotalUsdAmountInCents) external view returns(bool); | |
function getCountNeedProcessPreSaleBonus(uint minTotalUsdAmountInCents, uint start, uint limit) external view returns(uint); | |
function reCountUserPreSaleBonus(uint uId, uint minTotalUsdAmountInCents, uint bonusPercent, uint maxPayTime) external returns(uint, uint); | |
function getContributorIndexes(uint index) external view returns(uint); | |
function checkNeedSendSHPC(bool proc) external view returns(bool); | |
function getCountNeedSendSHPC(uint start, uint limit) external view returns(uint); | |
function checkETHRefund(bool proc) external view returns(bool); | |
function getCountETHRefund(uint start, uint limit) external view returns(uint); | |
function addPayment(address _addr, string pType, uint _value, uint usdAmount, uint currencyUSD, uint tokenWithoutBonus, uint tokenBonus, uint bonusPercent, uint payId) public returns(bool); | |
function addPayment(uint uId, string pType, uint _value, uint usdAmount, uint currencyUSD, uint tokenWithoutBonus, uint tokenBonus, uint bonusPercent, uint payId) public returns(bool); | |
function checkUserIdExists(uint uId) public view returns(bool); | |
function getContributorAddressById(uint uId) public view returns(address); | |
function editPaymentByUserId(uint uId, uint payId, uint _payValue, uint _usdAmount, uint _currencyUSD, uint _totalToken, uint _tokenWithoutBonus, uint _tokenBonus, uint _bonusPercent) public returns(bool); | |
function getUserPaymentById(uint uId, uint payId) public view returns(uint time, bytes32 pType, uint currencyUSD, uint bonusPercent, uint payValue, uint totalToken, uint tokenBonus, uint tokenWithoutBonus, uint usdAbsRaisedInCents, bool refund); | |
function checkWalletExists(address addr) public view returns(bool result); | |
function checkReceivedCoins(address addr) public view returns(bool); | |
function getContributorId(address addr) public view returns(uint); | |
function getTotalCoin(address addr) public view returns(uint); | |
function setReceivedCoin(uint uId) public returns(bool); | |
function checkPreSaleReceivedBonus(address addr) public view returns(bool); | |
function checkRefund(address addr) public view returns(bool); | |
function setRefund(uint uId) public returns(bool); | |
function getEthPaymentContributor(address addr) public view returns(uint); | |
function refundPaymentByUserId(uint uId, uint payId) public returns(bool); | |
function changeSupportChangeMainWallet(bool support) public returns(bool); | |
} |
This file contains 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.24; | |
contract Migrations { | |
address public owner; | |
uint public last_completed_migration; | |
constructor() public { | |
owner = msg.sender; | |
} | |
modifier restricted() { | |
if (msg.sender == owner) _; | |
} | |
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 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.22; | |
import "./StandardToken.sol"; | |
import "./Ownable.sol"; | |
/** | |
* @title Mintable token | |
* @dev Simple ERC20 Token example, with mintable token creation | |
* @dev Issue: * https://github.com/OpenZeppelin/zeppelin-solidity/issues/120 | |
* Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol | |
*/ | |
contract MintableToken is StandardToken, Ownable { | |
event Mint(address indexed to, uint256 amount); | |
event MintFinished(); | |
bool public mintingFinished = false; | |
modifier canMint() { | |
require(!mintingFinished); | |
_; | |
} | |
/** | |
* @dev Function to mint tokens | |
* @param _to The address that will receive the minted tokens. | |
* @param _amount The amount of tokens to mint. | |
* @return A boolean that indicates if the operation was successful. | |
*/ | |
function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) { | |
totalSupply_ = totalSupply_.add(_amount); | |
balances[_to] = balances[_to].add(_amount); | |
emit Mint(_to, _amount); | |
emit Transfer(address(0), _to, _amount); | |
return true; | |
} | |
/** | |
* @dev Function to stop minting new tokens. | |
* @return True if the operation was successful. | |
*/ | |
function finishMinting() onlyOwner canMint public returns (bool) { | |
mintingFinished = true; | |
emit MintFinished(); | |
return true; | |
} | |
} |
This file contains 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.24; | |
import "./Ownable.sol"; | |
/** | |
* @title MultiOwnable | |
* @dev The MultiOwnable contract has an owner address[], and provides basic authorization control | |
*/ | |
contract MultiOwnable is Ownable { | |
struct Types { | |
mapping (address => bool) access; | |
} | |
mapping (uint => Types) private multiOwnersTypes; | |
event AddOwner(uint _type, address addr); | |
event AddOwner(uint[] types, address addr); | |
event RemoveOwner(uint _type, address addr); | |
modifier onlyMultiOwnersType(uint _type) { | |
require(multiOwnersTypes[_type].access[msg.sender] || msg.sender == owner, "403"); | |
_; | |
} | |
function onlyMultiOwnerType(uint _type, address _sender) public view returns(bool) { | |
if (multiOwnersTypes[_type].access[_sender] || _sender == owner) { | |
return true; | |
} | |
return false; | |
} | |
function addMultiOwnerType(uint _type, address _owner) public onlyOwner returns(bool) { | |
require(_owner != address(0)); | |
multiOwnersTypes[_type].access[_owner] = true; | |
emit AddOwner(_type, _owner); | |
return true; | |
} | |
function addMultiOwnerTypes(uint[] types, address _owner) public onlyOwner returns(bool) { | |
require(_owner != address(0)); | |
require(types.length > 0); | |
for (uint i = 0; i < types.length; i++) { | |
multiOwnersTypes[types[i]].access[_owner] = true; | |
} | |
emit AddOwner(types, _owner); | |
return true; | |
} | |
function removeMultiOwnerType(uint types, address _owner) public onlyOwner returns(bool) { | |
require(_owner != address(0)); | |
multiOwnersTypes[types].access[_owner] = false; | |
emit RemoveOwner(types, _owner); | |
return true; | |
} | |
} |
This file contains 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.24; | |
/** | |
* @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 OwnershipRenounced(address indexed previousOwner); | |
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); | |
/** | |
* @dev The Ownable constructor sets the original `owner` of the contract to the sender | |
* account. | |
*/ | |
constructor () 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 onlyOwner { | |
require(newOwner != address(0)); | |
emit OwnershipTransferred(owner, newOwner); | |
owner = newOwner; | |
} | |
/** | |
* @dev Allows the current owner to relinquish control of the contract. | |
*/ | |
function renounceOwnership() public onlyOwner { | |
emit OwnershipRenounced(owner); | |
owner = address(0); | |
} | |
} |
This file contains 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.24; | |
/** | |
* @title SafeMath | |
* @dev Math operations with safety checks that throw on error | |
*/ | |
library SafeMath { | |
/** | |
* @dev Multiplies two numbers, throws on overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
// Gas optimization: this is cheaper than asserting 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
c = a * b; | |
assert(c / a == b); | |
return c; | |
} | |
/** | |
* @dev Integer division of two numbers, truncating the quotient. | |
*/ | |
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 a / b; | |
} | |
/** | |
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
assert(b <= a); | |
return a - b; | |
} | |
/** | |
* @dev Adds two numbers, throws on overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} |
This file contains 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.22; | |
import "./StandardToken.sol"; | |
/** | |
* @title SimpleToken | |
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator. | |
* Note they can later distribute these tokens as they wish using `transfer` and other | |
* `StandardToken` functions. | |
*/ | |
contract ShipCoin is StandardToken { | |
string public constant name = "ShipCoin"; // solium-disable-line uppercase | |
string public constant symbol = "SHPC"; // solium-disable-line uppercase | |
uint8 public constant decimals = 18; // solium-disable-line uppercase | |
uint256 public constant INITIAL_SUPPLY = 1000000000 * (10 ** uint256(decimals)); | |
/** | |
* @dev Constructor that gives msg.sender all of existing tokens. | |
*/ | |
constructor () public { | |
totalSupply_ = INITIAL_SUPPLY; | |
balances[msg.sender] = INITIAL_SUPPLY; | |
emit Transfer(0x0, msg.sender, INITIAL_SUPPLY); | |
} | |
} |
This file contains 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.24; | |
import "./IBonus.sol"; | |
import "./SafeMath.sol"; | |
import "./MultiOwnable.sol"; | |
import "./String.sol"; | |
contract ShipCoinBonusSystem is IBonus, MultiOwnable, String { | |
using SafeMath for uint256; | |
struct Bonus { | |
uint startDay; | |
uint endDay; | |
uint percent; | |
} | |
Bonus[] public bonus; | |
uint256 private constant ONE_DAY = 86400; | |
uint private preSaleBonusPercent = 40; | |
uint private minReachUsdPayInCents = 1000000; | |
event AddBonus(uint startDay, uint endDay, uint percent); | |
event ChangeBonus(uint startDay, uint endDay, uint percentOld, uint percentNew); | |
event DeleteBonus(uint startDay, uint endDay, uint percent); | |
/** | |
* @dev constructor | |
*/ | |
constructor() public { | |
bonus.push(Bonus(0, 2, 20)); // 20% for the first 48 hours | 0 - 2 days | |
bonus.push(Bonus(3, 14, 15)); // 15% for weeks 1-2 starting from day 3 | 3 - 14 days | |
bonus.push(Bonus(15, 28, 10)); // 10% for weeks 3-4 | 15 - 28 days | |
bonus.push(Bonus(29, 42, 5));// 5% for weeks 5-6 | 29 - 42 days | |
} | |
/** | |
* @dev Add or change bonus data | |
* @param _startDay timestamp | |
* @param _endDay timestamp | |
* @param _percent uint | |
*/ | |
function addChangeBonus(uint _startDay, uint _endDay, uint _percent) public onlyMultiOwnersType(1) returns(bool) { | |
for (uint i = 0; i < bonus.length; i++) { | |
if (bonus[i].startDay == _startDay && bonus[i].endDay == _endDay) { | |
uint oldPercent = bonus[i].percent; | |
if (bonus[i].percent != _percent) { | |
bonus[i].percent = _percent; | |
emit ChangeBonus(_startDay, _endDay, oldPercent, _percent); | |
} | |
return true; | |
} | |
} | |
bonus.push(Bonus(_startDay, _endDay, _percent)); | |
emit AddBonus(_startDay, _endDay, _percent); | |
return true; | |
} | |
/** | |
* @dev Delete bonus data | |
* @param _startDay timestamp | |
* @param _endDay timestamp | |
* @param _percent uint | |
*/ | |
function delBonus(uint _startDay, uint _endDay, uint _percent) public onlyMultiOwnersType(2) returns(bool) { | |
for (uint i = 0; i < bonus.length; i++) { | |
if (bonus[i].startDay == _startDay && bonus[i].endDay == _endDay && bonus[i].percent == _percent) { | |
delete bonus[i]; | |
emit DeleteBonus(_startDay, _endDay, _percent); | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* @dev Get current day bonus percent. | |
* @param startSaleDate timestamp | |
* @param saleState bool | |
*/ | |
function getCurrentDayBonus(uint startSaleDate, bool saleState) public view returns(uint) { | |
if (saleState) { | |
for (uint i = 0; i < bonus.length; i++) { | |
if ((startSaleDate > 0 && block.timestamp >= startSaleDate) && (_currentDay(startSaleDate, saleState) >= bonus[i].startDay) && (_currentDay(startSaleDate, saleState) <= bonus[i].endDay)) { | |
if (bonus[i].percent > 0) { | |
return bonus[i].percent; | |
} | |
} | |
} | |
} | |
return 0; | |
} | |
/** | |
* @dev Change preSale bonus percent | |
* @param _bonus uint | |
*/ | |
function changePreSaleBonus(uint _bonus) public onlyOwner returns(bool) { | |
require(_bonus > 20); | |
preSaleBonusPercent = _bonus; | |
} | |
/** | |
* @dev Change the minimum required amount to participate in the PreSale. | |
* @param _minUsdInCents minReachUsdPayInCents | |
*/ | |
function changePreSaleMinUsd(uint _minUsdInCents) public onlyOwner returns(bool) { | |
require(_minUsdInCents > 100000); | |
minReachUsdPayInCents = _minUsdInCents; | |
} | |
/** | |
* @dev Сurrent day from the moment of start sale | |
* @param startSaleDate timestamp | |
* @param saleState bool | |
*/ | |
function _currentDay(uint startSaleDate, bool saleState) public view returns(uint) { | |
if (!saleState || startSaleDate == 0 || startSaleDate > block.timestamp) { | |
return 0; | |
} | |
return block.timestamp.sub(startSaleDate).div(ONE_DAY); | |
} | |
/** | |
* @dev get all bonus data in json format | |
*/ | |
function getBonusData() public view returns(string) { | |
string memory _array = "["; | |
for (uint i = 0; i < bonus.length; i++) { | |
_array = strConcat( | |
_array, | |
strConcat("{\"startDay\":", uint2str(bonus[i].startDay), ",\"endDay\":", uint2str(bonus[i].endDay), ",\"percent\":"), | |
uint2str(bonus[i].percent), | |
(i+1 == bonus.length) ? "}]" : "}," | |
); | |
} | |
return _array; | |
} | |
/** | |
* @dev get preSale bonus prcent | |
*/ | |
function getPreSaleBonusPercent() public view returns(uint) { | |
return preSaleBonusPercent; | |
} | |
/** | |
* @dev get minimum required amount to participate in the PreSale | |
*/ | |
function getMinReachUsdPayInCents() public view returns(uint) { | |
return minReachUsdPayInCents; | |
} | |
} |
This file contains 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.24; | |
import "./ERC20Basic.sol"; | |
import "./IStorage.sol"; | |
import "./ICurrency.sol"; | |
import "./IBonus.sol"; | |
import "./SafeMath.sol"; | |
import "./MultiOwnable.sol"; | |
/** | |
* @title ShipCoin Crowdsale | |
*/ | |
contract ShipCoinCrowdsale is MultiOwnable { | |
using SafeMath for uint256; | |
ERC20Basic public coinContract; | |
IStorage public storageContract; | |
ICurrency public currencyContract; | |
IBonus public bonusContract; | |
enum SaleState {NEW, PRESALE, CALCPSBONUS, SALE, END, REFUND} | |
uint256 private constant ONE_DAY = 86400; | |
SaleState public state; | |
bool public paused = false; | |
/** | |
* @dev Modifier to make a function callable only when the contract is not paused. | |
*/ | |
modifier whenNotPaused() { | |
require(!paused); | |
_; | |
} | |
// minimum goal USD | |
uint public softCapUSD = 500000000; // 5,000,000$ in cents | |
// maximum goal USD | |
uint public hardCapUSD = 6200000000; // 62,000,000$ in cents | |
// maximum available SHPC with a bonus | |
uint public maxDistributeCoin = 600000000 * 1 ether; //600,000,000 shpc (incl. bonus) | |
// minimal accept payment | |
uint public minimalContributionUSD = 100000; // 1000$ in cents | |
// start and end timestamps where investments are allowed in PreSale | |
uint public startPreSaleDate; | |
uint public endPreSaleDate; | |
uint public unfreezeRefundPreSale; | |
uint public unfreezeRefundAll; | |
// start and end timestamps where investments are allowed in sale | |
uint public startSaleDate; | |
uint public endSaleDate; | |
bool public softCapAchieved = false; | |
address public multiSig1; | |
address public multiSig2; | |
bool public multiSigReceivedSoftCap = false; | |
/* Events */ | |
event ChangeState(uint blockNumber, SaleState state); | |
event ChangeMinContribUSD(uint oldAmount, uint newAmount); | |
event ChangeStorageContract(address oldAddress, address newAddress); | |
event ChangeCurrencyContract(address oldAddress, address newAddress); | |
event ChangeCoinContract(address oldAddress, address newAddress); | |
event ChangeBonusContract(address oldAddress, address newAddress); | |
event AddPay(address contributor); | |
event EditPay(address contributor); | |
event SoftCapAchieved(uint amount); | |
event ManualChangeStartPreSaleDate(uint oldDate, uint newDate); | |
event ManualChangeEndPreSaleDate(uint oldDate, uint newDate); | |
event ManualChangeStartSaleDate(uint oldDate, uint newDate); | |
event ManualEndSaleDate(uint oldDate, uint newDate); | |
event SendSHPCtoContributor(address contributor); | |
event SoftCapChanged(); | |
event Refund(address contributor); | |
event RefundPay(address contributor); | |
struct PaymentInfo { | |
bytes32 pType; | |
uint currencyUSD; | |
uint bonusPercent; | |
uint payValue; | |
uint totalToken; | |
uint tokenBonus; | |
uint usdAbsRaisedInCents; | |
bool refund; | |
} | |
struct CurrencyInfo { | |
uint value; | |
uint usdRaised; | |
uint usdAbsRaisedInCents; | |
uint coinRaisedInWei; | |
uint coinRaisedBonusInWei; | |
} | |
struct EditPaymentInfo { | |
uint usdAmount; | |
uint currencyUSD; | |
uint bonusPercent; | |
uint totalToken; | |
uint tokenWithoutBonus; | |
uint tokenBonus; | |
CurrencyInfo currency; | |
} | |
function () external whenNotPaused payable { | |
buyTokens(msg.sender); | |
} | |
/** | |
* @dev Run after deploy. Initialize initial variables | |
* @param _coinAddress address coinContract | |
* @param _storageContract address storageContract | |
* @param _currencyContract address currencyContract | |
* @param _bonusContract address bonusContract | |
* @param _multiSig1 address multiSig where eth will be transferred | |
* @param _startPreSaleDate timestamp | |
* @param _endPreSaleDate timestamp | |
* @param _startSaleDate timestamp | |
* @param _endSaleDate timestamp | |
*/ | |
function init( | |
address _coinAddress, | |
address _storageContract, | |
address _currencyContract, | |
address _bonusContract, | |
address _multiSig1, | |
uint _startPreSaleDate, | |
uint _endPreSaleDate, | |
uint _startSaleDate, | |
uint _endSaleDate | |
) | |
public | |
onlyOwner | |
{ | |
require(_coinAddress != address(0)); | |
require(_storageContract != address(0)); | |
require(_currencyContract != address(0)); | |
require(_multiSig1 != address(0)); | |
require(_bonusContract != address(0)); | |
require(_startPreSaleDate > 0 && _startSaleDate > 0); | |
require(_startSaleDate > _endPreSaleDate); | |
require(_endSaleDate > _startSaleDate); | |
require(startSaleDate == 0); | |
coinContract = ERC20Basic(_coinAddress); | |
storageContract = IStorage(_storageContract); | |
currencyContract = ICurrency(_currencyContract); | |
bonusContract = IBonus(_bonusContract); | |
multiSig1 = _multiSig1; | |
multiSig2 = 0x231121dFCB61C929BCdc0D1E6fC760c84e9A02ad; | |
startPreSaleDate = _startPreSaleDate; | |
endPreSaleDate = _endPreSaleDate; | |
startSaleDate = _startSaleDate; | |
endSaleDate = _endSaleDate; | |
unfreezeRefundPreSale = _endSaleDate; | |
unfreezeRefundAll = _endSaleDate.add(ONE_DAY); | |
state = SaleState.NEW; | |
} | |
/** | |
* @dev called by the owner to pause, triggers stopped state | |
*/ | |
function pause() public onlyOwner { | |
paused = true; | |
} | |
/** | |
* @dev called by the owner to unpause, returns to normal state | |
*/ | |
function unpause() public onlyOwner { | |
paused = false; | |
} | |
/** | |
* @dev Change the minimum amount in dollars indicated in cents to accept payment. | |
* @param minContribUsd in cents | |
*/ | |
function setMinimalContributionUSD(uint minContribUsd) public onlyOwner { | |
require(minContribUsd > 100); // > 1$ | |
uint oldMinAmount = minimalContributionUSD; | |
minimalContributionUSD = minContribUsd; | |
emit ChangeMinContribUSD(oldMinAmount, minimalContributionUSD); | |
} | |
/** | |
* @dev Set the time when contributors can receive tokens | |
* @param _time timestamp | |
*/ | |
function setUnfreezeRefund(uint _time) public onlyOwner { | |
require(_time > startSaleDate); | |
unfreezeRefundPreSale = _time; | |
unfreezeRefundAll = _time.add(ONE_DAY); | |
} | |
/** | |
* @dev Change address ShipCoinStorage contracts. | |
* @param _storageContract address ShipCoinStorage contracts | |
*/ | |
function setStorageContract(address _storageContract) public onlyOwner { | |
require(_storageContract != address(0)); | |
address oldStorageContract = storageContract; | |
storageContract = IStorage(_storageContract); | |
emit ChangeStorageContract(oldStorageContract, storageContract); | |
} | |
/** | |
* @dev Change address ShipCoin contracts. | |
* @param _coinContract address ShipCoin contracts | |
*/ | |
function setCoinContract(address _coinContract) public onlyOwner { | |
require(_coinContract != address(0)); | |
address oldCoinContract = coinContract; | |
coinContract = ERC20Basic(_coinContract); | |
emit ChangeCoinContract(oldCoinContract, coinContract); | |
} | |
/** | |
* @dev Change address ShipCoinCurrency contracts. | |
* @param _currencyContract address ShipCoinCurrency contracts | |
*/ | |
function setCurrencyContract(address _currencyContract) public onlyOwner { | |
require(_currencyContract != address(0)); | |
address oldCurContract = currencyContract; | |
currencyContract = ICurrency(_currencyContract); | |
emit ChangeCurrencyContract(oldCurContract, currencyContract); | |
} | |
/** | |
* @dev Change address ShipCoinBonusSystem contracts. | |
* @param _bonusContract address ShipCoinBonusSystem contracts | |
*/ | |
function setBonusContract(address _bonusContract) public onlyOwner { | |
require(_bonusContract != address(0)); | |
address oldContract = _bonusContract; | |
bonusContract = IBonus(_bonusContract); | |
emit ChangeBonusContract(oldContract, bonusContract); | |
} | |
/** | |
* @dev Change address multiSig1. | |
* @param _address address multiSig1 | |
*/ | |
function setMultisig(address _address) public onlyOwner { | |
require(_address != address(0)); | |
multiSig1 = _address; | |
} | |
/** | |
* @dev Set softCapUSD | |
* @param _softCapUsdInCents uint softCapUSD > 100000 | |
*/ | |
function setSoftCap(uint _softCapUsdInCents) public onlyOwner { | |
require(_softCapUsdInCents > 100000); | |
softCapUSD = _softCapUsdInCents; | |
emit SoftCapChanged(); | |
} | |
/** | |
* @dev Change maximum number of tokens sold | |
* @param _maxCoin maxDistributeCoin | |
*/ | |
function changeMaxDistributeCoin(uint _maxCoin) public onlyOwner { | |
require(_maxCoin > 0 && _maxCoin >= currencyContract.getCoinRaisedInWei()); | |
maxDistributeCoin = _maxCoin; | |
} | |
/** | |
* @dev Change status. Start presale. | |
*/ | |
function startPreSale() public onlyMultiOwnersType(1) { | |
require(block.timestamp <= endPreSaleDate); | |
require(state == SaleState.NEW); | |
state = SaleState.PRESALE; | |
emit ChangeState(block.number, state); | |
} | |
/** | |
* @dev Change status. Start calculate presale bonus. | |
*/ | |
function startCalculatePreSaleBonus() public onlyMultiOwnersType(5) { | |
require(state == SaleState.PRESALE); | |
state = SaleState.CALCPSBONUS; | |
emit ChangeState(block.number, state); | |
} | |
/** | |
* @dev Change status. Start sale. | |
*/ | |
function startSale() public onlyMultiOwnersType(2) { | |
require(block.timestamp <= endSaleDate); | |
require(state == SaleState.CALCPSBONUS); | |
//require(!storageContract.checkNeedProcessPreSaleBonus(getMinReachUsdPayInCents())); | |
state = SaleState.SALE; | |
emit ChangeState(block.number, state); | |
} | |
/** | |
* @dev Change status. Set end if sale it was successful. | |
*/ | |
function saleSetEnded() public onlyMultiOwnersType(3) { | |
require((state == SaleState.SALE) || (state == SaleState.PRESALE)); | |
require(block.timestamp >= startSaleDate); | |
require(checkSoftCapAchieved()); | |
state = SaleState.END; | |
storageContract.changeSupportChangeMainWallet(false); | |
emit ChangeState(block.number, state); | |
} | |
/** | |
* @dev Change status. Set refund when sale did not reach softcap. | |
*/ | |
function saleSetRefund() public onlyMultiOwnersType(4) { | |
require((state == SaleState.SALE) || (state == SaleState.PRESALE)); | |
require(block.timestamp >= endSaleDate); | |
require(!checkSoftCapAchieved()); | |
state = SaleState.REFUND; | |
emit ChangeState(block.number, state); | |
} | |
/** | |
* @dev Payable function. Processes contribution in ETH. | |
*/ | |
function buyTokens(address _beneficiary) public whenNotPaused payable { | |
require((state == SaleState.PRESALE && block.timestamp >= startPreSaleDate && block.timestamp <= endPreSaleDate) || (state == SaleState.SALE && block.timestamp >= startSaleDate && block.timestamp <= endSaleDate)); | |
require(_beneficiary != address(0)); | |
require(msg.value > 0); | |
uint usdAmount = currencyContract.getUsdFromETH(msg.value); | |
assert(usdAmount >= minimalContributionUSD); | |
uint bonusPercent = 0; | |
if (state == SaleState.SALE) { | |
bonusPercent = bonusContract.getCurrentDayBonus(startSaleDate, (state == SaleState.SALE)); | |
} | |
(uint totalToken, uint tokenWithoutBonus, uint tokenBonus) = calcToken(usdAmount, bonusPercent); | |
assert((totalToken > 0 && totalToken <= calculateMaxCoinIssued())); | |
uint usdRate = currencyContract.getCurrencyRate("ETH"); | |
assert(storageContract.addPayment(_beneficiary, "ETH", msg.value, usdAmount, usdRate, tokenWithoutBonus, tokenBonus, bonusPercent, 0)); | |
assert(currencyContract.addPay("ETH", msg.value, usdAmount, totalToken, tokenBonus)); | |
emit AddPay(_beneficiary); | |
} | |
/** | |
* @dev Manually add alternative contribution payment. | |
* @param ticker string | |
* @param value uint | |
* @param uId uint contributor identificator | |
* @param _pId uint payment identificator | |
* @param _currencyUSD uint current ticker rate (optional field) | |
*/ | |
function addPay(string ticker, uint value, uint uId, uint _pId, uint _currencyUSD) public onlyMultiOwnersType(6) { | |
require(value > 0); | |
require(storageContract.checkUserIdExists(uId)); | |
require(_pId > 0); | |
string memory _ticker = ticker; | |
uint _value = value; | |
assert(currencyContract.checkTickerExists(_ticker)); | |
uint usdAmount = currencyContract.getUsdFromCurrency(_ticker, _value, _currencyUSD); | |
assert(usdAmount > 0); | |
uint bonusPercent = 0; | |
if (state == SaleState.SALE) { | |
bonusPercent = bonusContract.getCurrentDayBonus(startSaleDate, (state == SaleState.SALE)); | |
} | |
(uint totalToken, uint tokenWithoutBonus, uint tokenBonus) = calcToken(usdAmount, bonusPercent); | |
assert(tokenWithoutBonus > 0); | |
uint usdRate = _currencyUSD > 0 ? _currencyUSD : currencyContract.getCurrencyRate(_ticker); | |
uint pId = _pId; | |
assert(storageContract.addPayment(uId, _ticker, _value, usdAmount, usdRate, tokenWithoutBonus, tokenBonus, bonusPercent, pId)); | |
assert(currencyContract.addPay(_ticker, _value, usdAmount, totalToken, tokenBonus)); | |
emit AddPay(storageContract.getContributorAddressById(uId)); | |
} | |
/** | |
* @dev Edit contribution payment. | |
* @param uId uint contributor identificator | |
* @param payId uint payment identificator | |
* @param value uint | |
* @param _currencyUSD uint current ticker rate (optional field) | |
* @param _bonusPercent uint current ticker rate (optional field) | |
*/ | |
function editPay(uint uId, uint payId, uint value, uint _currencyUSD, uint _bonusPercent) public onlyMultiOwnersType(7) { | |
require(value > 0); | |
require(storageContract.checkUserIdExists(uId)); | |
require(payId > 0); | |
require((_bonusPercent == 0 || _bonusPercent <= getPreSaleBonusPercent())); | |
PaymentInfo memory payment = getPaymentInfo(uId, payId); | |
EditPaymentInfo memory paymentInfo = calcEditPaymentInfo(payment, value, _currencyUSD, _bonusPercent); | |
assert(paymentInfo.tokenWithoutBonus > 0); | |
assert(paymentInfo.currency.value > 0); | |
assert(paymentInfo.currency.usdRaised > 0); | |
assert(paymentInfo.currency.usdAbsRaisedInCents > 0); | |
assert(paymentInfo.currency.coinRaisedInWei > 0); | |
assert(currencyContract.editPay(payment.pType, paymentInfo.currency.value, paymentInfo.currency.usdRaised, paymentInfo.currency.usdAbsRaisedInCents, paymentInfo.currency.coinRaisedInWei, paymentInfo.currency.coinRaisedBonusInWei)); | |
assert(storageContract.editPaymentByUserId(uId, payId, value, paymentInfo.usdAmount, paymentInfo.currencyUSD, paymentInfo.totalToken, paymentInfo.tokenWithoutBonus, paymentInfo.tokenBonus, paymentInfo.bonusPercent)); | |
assert(reCountUserPreSaleBonus(uId)); | |
emit EditPay(storageContract.getContributorAddressById(uId)); | |
} | |
/** | |
* @dev Refund contribution payment. | |
* @param uId uint | |
* @param payId uint | |
*/ | |
function refundPay(uint uId, uint payId) public onlyMultiOwnersType(18) { | |
require(storageContract.checkUserIdExists(uId)); | |
require(payId > 0); | |
(CurrencyInfo memory currencyInfo, bytes32 pType) = calcCurrency(getPaymentInfo(uId, payId), 0, 0, 0, 0); | |
assert(storageContract.refundPaymentByUserId(uId, payId)); | |
assert(currencyContract.editPay(pType, currencyInfo.value, currencyInfo.usdRaised, currencyInfo.usdAbsRaisedInCents, currencyInfo.coinRaisedInWei, currencyInfo.coinRaisedBonusInWei)); | |
assert(reCountUserPreSaleBonus(uId)); | |
emit RefundPay(storageContract.getContributorAddressById(uId)); | |
} | |
/** | |
* @dev Check if softCap is reached | |
*/ | |
function checkSoftCapAchieved() public view returns(bool) { | |
return softCapAchieved || getTotalUsdRaisedInCents() >= softCapUSD; | |
} | |
/** | |
* @dev Set softCapAchieved=true if softCap is reached | |
*/ | |
function activeSoftCapAchieved() public onlyMultiOwnersType(8) { | |
require(checkSoftCapAchieved()); | |
require(getCoinBalance() >= maxDistributeCoin); | |
softCapAchieved = true; | |
emit SoftCapAchieved(getTotalUsdRaisedInCents()); | |
} | |
/** | |
* @dev Send ETH from contract balance to multiSig. | |
*/ | |
function getEther() public onlyMultiOwnersType(9) { | |
require(getETHBalance() > 0); | |
require(softCapAchieved && (!multiSigReceivedSoftCap || (state == SaleState.END))); | |
uint sendEther = (address(this).balance / 2); | |
assert(sendEther > 0); | |
address(multiSig1).transfer(sendEther); | |
address(multiSig2).transfer(sendEther); | |
multiSigReceivedSoftCap = true; | |
} | |
/** | |
* @dev Return maximum amount buy token. | |
*/ | |
function calculateMaxCoinIssued() public view returns (uint) { | |
return maxDistributeCoin - currencyContract.getCoinRaisedInWei(); | |
} | |
/** | |
* @dev Return raised SHPC in wei. | |
*/ | |
function getCoinRaisedInWei() public view returns (uint) { | |
return currencyContract.getCoinRaisedInWei(); | |
} | |
/** | |
* @dev Return raised usd in cents. | |
*/ | |
function getTotalUsdRaisedInCents() public view returns (uint) { | |
return currencyContract.getTotalUsdRaisedInCents(); | |
} | |
/** | |
* @dev Return all currency rate in json. | |
*/ | |
function getAllCurrencyTicker() public view returns (string) { | |
return currencyContract.getAllCurrencyTicker(); | |
} | |
/** | |
* @dev Return SHPC price in cents. | |
*/ | |
function getCoinUSDRate() public view returns (uint) { | |
return currencyContract.getCoinUSDRate(); | |
} | |
/** | |
* @dev Retrun SHPC balance in contract. | |
*/ | |
function getCoinBalance() public view returns (uint) { | |
return coinContract.balanceOf(address(this)); | |
} | |
/** | |
* @dev Return balance ETH from contract. | |
*/ | |
function getETHBalance() public view returns (uint) { | |
return address(this).balance; | |
} | |
/** | |
* @dev Processing of the data of the contributors. Bonus assignment for presale. | |
* @param start uint > 0 | |
* @param limit uint > 0 | |
*/ | |
function processSetPreSaleBonus(uint start, uint limit) public onlyMultiOwnersType(10) { | |
require(state == SaleState.CALCPSBONUS); | |
require(start >= 0 && limit > 0); | |
//require(storageContract.checkNeedProcessPreSaleBonus(getMinReachUsdPayInCents())); | |
uint bonusToken = storageContract.processPreSaleBonus(getMinReachUsdPayInCents(), getPreSaleBonusPercent(), start, limit); | |
if (bonusToken > 0) { | |
assert(currencyContract.addPreSaleBonus(bonusToken)); | |
} | |
} | |
/** | |
* @dev Processing of the data of the contributor by uId. Bonus assignment for presale. | |
* @param uId uint | |
*/ | |
function reCountUserPreSaleBonus(uint uId) public onlyMultiOwnersType(11) returns(bool) { | |
if (uint(state) > 1) { // > PRESALE | |
uint maxPayTime = 0; | |
if (state != SaleState.CALCPSBONUS) { | |
maxPayTime = startSaleDate; | |
} | |
(uint befTokenBonus, uint aftTokenBonus) = storageContract.reCountUserPreSaleBonus(uId, getMinReachUsdPayInCents(), getPreSaleBonusPercent(), maxPayTime); | |
assert(currencyContract.editPreSaleBonus(befTokenBonus, aftTokenBonus)); | |
} | |
return true; | |
} | |
/** | |
* @dev Contributor get SHPC. | |
*/ | |
function getCoins() public { | |
return _getCoins(msg.sender); | |
} | |
/** | |
* @dev Send contributors SHPC. | |
* @param start uint | |
* @param limit uint | |
*/ | |
function sendSHPCtoContributors(uint start, uint limit) public onlyMultiOwnersType(12) { | |
require(state == SaleState.END); | |
require(start >= 0 && limit > 0); | |
require(getCoinBalance() > 0); | |
//require(storageContract.checkNeedSendSHPC(state == SaleState.END)); | |
for (uint i = start; i < limit; i++) { | |
uint uId = storageContract.getContributorIndexes(i); | |
if (uId > 0) { | |
address addr = storageContract.getContributorAddressById(uId); | |
uint coins = storageContract.getTotalCoin(addr); | |
if (!storageContract.checkReceivedCoins(addr) && storageContract.checkWalletExists(addr) && coins > 0 && ((storageContract.checkPreSaleReceivedBonus(addr) && block.timestamp >= unfreezeRefundPreSale) || (!storageContract.checkPreSaleReceivedBonus(addr) && block.timestamp >= unfreezeRefundAll))) { | |
if (coinContract.transfer(addr, coins)) { | |
storageContract.setReceivedCoin(uId); | |
emit SendSHPCtoContributor(addr); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* @dev Set startPreSaleDate | |
* @param date timestamp | |
*/ | |
function setStartPreSaleDate(uint date) public onlyMultiOwnersType(13) { | |
uint oldDate = startPreSaleDate; | |
startPreSaleDate = date; | |
emit ManualChangeStartPreSaleDate(oldDate, date); | |
} | |
/** | |
* @dev Set startPreSaleDate | |
* @param date timestamp | |
*/ | |
function setEndPreSaleDate(uint date) public onlyMultiOwnersType(14) { | |
uint oldDate = endPreSaleDate; | |
endPreSaleDate = date; | |
emit ManualChangeEndPreSaleDate(oldDate, date); | |
} | |
/** | |
* @dev Set startSaleDate | |
* @param date timestamp | |
*/ | |
function setStartSaleDate(uint date) public onlyMultiOwnersType(15) { | |
uint oldDate = startSaleDate; | |
startSaleDate = date; | |
emit ManualChangeStartSaleDate(oldDate, date); | |
} | |
/** | |
* @dev Set endSaleDate | |
* @param date timestamp | |
*/ | |
function setEndSaleDate(uint date) public onlyMultiOwnersType(16) { | |
uint oldDate = endSaleDate; | |
endSaleDate = date; | |
emit ManualEndSaleDate(oldDate, date); | |
} | |
/** | |
* @dev Return SHPC from contract. When sale ended end contributor got SHPC. | |
*/ | |
function getSHPCBack() public onlyMultiOwnersType(17) { | |
require(state == SaleState.END); | |
require(getCoinBalance() > 0); | |
//require(!storageContract.checkNeedSendSHPC(state == SaleState.END)); | |
coinContract.transfer(msg.sender, getCoinBalance()); | |
} | |
/** | |
* @dev Refund ETH contributor. | |
*/ | |
function refundETH() public { | |
return _refundETH(msg.sender); | |
} | |
/** | |
* @dev Refund ETH contributors. | |
* @param start uint | |
* @param limit uint | |
*/ | |
function refundETHContributors(uint start, uint limit) public onlyMultiOwnersType(19) { | |
require(state == SaleState.REFUND); | |
require(start >= 0 && limit > 0); | |
require(getETHBalance() > 0); | |
//require(storageContract.checkETHRefund(state == SaleState.REFUND)); | |
for (uint i = start; i < limit; i++) { | |
uint uId = storageContract.getContributorIndexes(i); | |
if (uId > 0) { | |
address addr = storageContract.getContributorAddressById(uId); | |
uint ethAmount = storageContract.getEthPaymentContributor(addr); | |
if (!storageContract.checkRefund(addr) && storageContract.checkWalletExists(addr) && ethAmount > 0) { | |
storageContract.setRefund(uId); | |
addr.transfer(ethAmount); | |
emit Refund(addr); | |
} | |
} | |
} | |
} | |
/** | |
* @dev Return pre-sale bonus getPreSaleBonusPercent. | |
*/ | |
function getPreSaleBonusPercent() public view returns(uint) { | |
return bonusContract.getPreSaleBonusPercent(); | |
} | |
/** | |
* @dev Return pre-sale minReachUsdPayInCents. | |
*/ | |
function getMinReachUsdPayInCents() public view returns(uint) { | |
return bonusContract.getMinReachUsdPayInCents(); | |
} | |
/** | |
* @dev Return current sale day. | |
*/ | |
function _currentDay() public view returns(uint) { | |
return bonusContract._currentDay(startSaleDate, (state == SaleState.SALE)); | |
} | |
/** | |
* @dev Return current sale day bonus percent. | |
*/ | |
function getCurrentDayBonus() public view returns(uint) { | |
return bonusContract.getCurrentDayBonus(startSaleDate, (state == SaleState.SALE)); | |
} | |
/** | |
* @dev Return contributor payment info. | |
* @param uId uint | |
* @param pId uint | |
*/ | |
function getPaymentInfo(uint uId, uint pId) private view returns(PaymentInfo) { | |
(, bytes32 pType, | |
uint currencyUSD, | |
uint bonusPercent, | |
uint payValue, | |
uint totalToken, | |
uint tokenBonus,, | |
uint usdAbsRaisedInCents, | |
bool refund) = storageContract.getUserPaymentById(uId, pId); | |
return PaymentInfo(pType, currencyUSD, bonusPercent, payValue, totalToken, tokenBonus, usdAbsRaisedInCents, refund); | |
} | |
/** | |
* @dev Return recalculate payment data from old payment user. | |
*/ | |
function calcEditPaymentInfo(PaymentInfo payment, uint value, uint _currencyUSD, uint _bonusPercent) private view returns(EditPaymentInfo) { | |
(uint usdAmount, uint currencyUSD, uint bonusPercent) = getUsdAmountFromPayment(payment, value, _currencyUSD, _bonusPercent); | |
(uint totalToken, uint tokenWithoutBonus, uint tokenBonus) = calcToken(usdAmount, bonusPercent); | |
(CurrencyInfo memory currency,) = calcCurrency(payment, value, usdAmount, totalToken, tokenBonus); | |
return EditPaymentInfo(usdAmount, currencyUSD, bonusPercent, totalToken, tokenWithoutBonus, tokenBonus, currency); | |
} | |
/** | |
* @dev Return usd from payment amount. | |
*/ | |
function getUsdAmountFromPayment(PaymentInfo payment, uint value, uint _currencyUSD, uint _bonusPercent) private view returns(uint, uint, uint) { | |
_currencyUSD = _currencyUSD > 0 ? _currencyUSD : payment.currencyUSD; | |
_bonusPercent = _bonusPercent > 0 ? _bonusPercent : payment.bonusPercent; | |
uint usdAmount = currencyContract.getUsdFromCurrency(payment.pType, value, _currencyUSD); | |
return (usdAmount, _currencyUSD, _bonusPercent); | |
} | |
/** | |
* @dev Return payment SHPC data from usd amount and bonusPercent | |
*/ | |
function calcToken(uint usdAmount, uint _bonusPercent) private view returns(uint, uint, uint) { | |
uint tokenWithoutBonus = currencyContract.getTokenWeiFromUSD(usdAmount); | |
uint tokenBonus = _bonusPercent > 0 ? tokenWithoutBonus.mul(_bonusPercent).div(100) : 0; | |
uint totalToken = tokenBonus > 0 ? tokenWithoutBonus.add(tokenBonus) : tokenWithoutBonus; | |
return (totalToken, tokenWithoutBonus, tokenBonus); | |
} | |
/** | |
* @dev Calculate currency data when edit user payment data | |
*/ | |
function calcCurrency(PaymentInfo payment, uint value, uint usdAmount, uint totalToken, uint tokenBonus) private view returns(CurrencyInfo, bytes32) { | |
(,,, uint currencyValue, uint currencyUsdRaised,,,) = currencyContract.getCurrencyList(payment.pType); | |
uint usdAbsRaisedInCents = currencyContract.getUsdAbsRaisedInCents(); | |
uint coinRaisedInWei = currencyContract.getCoinRaisedInWei(); | |
uint coinRaisedBonusInWei = currencyContract.getCoinRaisedBonusInWei(); | |
currencyValue -= payment.payValue; | |
currencyUsdRaised -= payment.usdAbsRaisedInCents; | |
usdAbsRaisedInCents -= payment.usdAbsRaisedInCents; | |
coinRaisedInWei -= payment.totalToken; | |
coinRaisedBonusInWei -= payment.tokenBonus; | |
currencyValue += value; | |
currencyUsdRaised += usdAmount; | |
usdAbsRaisedInCents += usdAmount; | |
coinRaisedInWei += totalToken; | |
coinRaisedBonusInWei += tokenBonus; | |
return (CurrencyInfo(currencyValue, currencyUsdRaised, usdAbsRaisedInCents, coinRaisedInWei, coinRaisedBonusInWei), payment.pType); | |
} | |
/** | |
* @dev Getting the SHPC from the contributor | |
*/ | |
function _getCoins(address addr) private { | |
require(state == SaleState.END); | |
require(storageContract.checkWalletExists(addr)); | |
require(!storageContract.checkReceivedCoins(addr)); | |
require((storageContract.checkPreSaleReceivedBonus(addr) && block.timestamp >= unfreezeRefundPreSale) || (!storageContract.checkPreSaleReceivedBonus(addr) && block.timestamp >= unfreezeRefundAll)); | |
uint uId = storageContract.getContributorId(addr); | |
uint coins = storageContract.getTotalCoin(addr); | |
assert(uId > 0 && coins > 0); | |
if (coinContract.transfer(addr, coins)) { | |
storageContract.setReceivedCoin(uId); | |
emit SendSHPCtoContributor(addr); | |
} | |
} | |
/** | |
* @dev Refund ETH contributor when sale not reach softcap. | |
*/ | |
function _refundETH(address addr) private { | |
require(state == SaleState.REFUND); | |
require(storageContract.checkWalletExists(addr)); | |
require(!storageContract.checkRefund(addr)); | |
uint uId = storageContract.getContributorId(addr); | |
uint ethAmount = storageContract.getEthPaymentContributor(addr); | |
assert(uId > 0 && ethAmount > 0 && getETHBalance() >= ethAmount); | |
storageContract.setRefund(uId); | |
addr.transfer(ethAmount); | |
emit Refund(addr); | |
} | |
} |
This file contains 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.24; | |
import "./MultiOwnable.sol"; | |
import "./String.sol"; | |
import "./SafeMath.sol"; | |
import "./ICurrency.sol"; | |
/** | |
* @title Convert eth,btc,eur,amb to usd and storage payment from currency | |
*/ | |
contract ShipCoinCurrency is ICurrency, MultiOwnable, String { | |
using SafeMath for uint256; | |
uint private coinUSDRate = 12; // in wei 0.12$ | |
uint private currVolPercent = 5; // 5% currency volatility | |
// Amount of wei raised SHPC | |
uint256 private coinRaisedInWei = 0; | |
// Amount of cents raised USD at the time of payment | |
uint private usdAbsRaisedInCents = 0; | |
uint private coinRaisedBonusInWei = 0; | |
struct CurrencyData { | |
bool active; | |
uint usd; | |
uint devision; | |
uint raised; | |
uint usdRaised; | |
uint counter; | |
uint lastUpdate; | |
} | |
mapping(bytes32 => CurrencyData) private currencyList; | |
bytes32[] private currencyTicker; | |
/* Events */ | |
event ChangeCoinUSDRate(uint oldPrice, uint newPrice); | |
event ChangeCurrVolPercent(uint oldPercent, uint newPercent); | |
event ChangeCurrency(); | |
event AddPay(); | |
event EditPay(); | |
/** | |
* @dev constructor 50328,655575,116 | |
* @param _ethPrice in cents example 58710 = 587.10$ | |
* @param _btcPrice in cents example 772301 = 7723.01$ | |
* @param _eurPrice in cents example 117 = 1.17$ | |
* @param _ambPrice in cents example 18 = 0.18$ | |
*/ | |
constructor(uint _ethPrice, uint _btcPrice, uint _eurPrice, uint _ambPrice) public { | |
require(addUpdateCurrency("ETH", _ethPrice, (1 ether))); | |
require(addUpdateCurrency("BTC", _btcPrice, (10**8))); | |
require(addUpdateCurrency("USD", 1, 1)); | |
require(addUpdateCurrency("EUR", _eurPrice, 100)); | |
require(addUpdateCurrency("AMB", _ambPrice, (1 ether))); | |
} | |
/** | |
* @dev Returns the collected amount in dollars. Summarize at the rate when the payment was made. | |
*/ | |
function getUsdAbsRaisedInCents() external view returns(uint) { | |
return usdAbsRaisedInCents; | |
} | |
/** | |
* @dev Return the amount of SHPC sold as a bonus. | |
*/ | |
function getCoinRaisedBonusInWei() external view returns(uint) { | |
return coinRaisedBonusInWei; | |
} | |
/** | |
* @dev Add or Update currency | |
*/ | |
function addUpdateCurrency(string _ticker, uint _usd, uint _devision) public returns(bool) { | |
return addUpdateCurrency(_ticker, _usd, _devision, 0, 0); | |
} | |
/** | |
* @dev Add or Update currency | |
*/ | |
function addUpdateCurrency(string _ticker, uint _usd) public returns(bool) { | |
return addUpdateCurrency(_ticker, _usd, 0, 0, 0); | |
} | |
/** | |
* @dev Add or Update currency | |
* @param _ticker string | |
* @param _usd uint rate in cents | |
* @param _devision uint | |
* @param _raised uint | |
* @param _usdRaised uint raised in usd cents | |
*/ | |
function addUpdateCurrency(string _ticker, uint _usd, uint _devision, uint _raised, uint _usdRaised) public onlyMultiOwnersType(1) returns(bool) { | |
require(_usd > 0, "1"); | |
bytes32 ticker = stringToBytes32(_ticker); | |
if (!currencyList[ticker].active) { | |
currencyTicker.push(ticker); | |
} | |
currencyList[ticker] = CurrencyData({ | |
active : true, | |
usd : _usd, | |
devision : (_devision == 0) ? currencyList[ticker].devision : _devision, | |
raised : currencyList[ticker].raised > 0 ? currencyList[ticker].raised : _raised, | |
usdRaised: currencyList[ticker].usdRaised > 0 ? currencyList[ticker].usdRaised : _usdRaised, | |
counter: currencyList[ticker].counter > 0 ? currencyList[ticker].counter : 0, | |
lastUpdate: block.timestamp | |
}); | |
return true; | |
} | |
/** | |
* @dev Set SHPC price in cents | |
*/ | |
function setCoinUSDRate(uint _value) public onlyOwner returns(bool) { | |
require(_value > 0); | |
uint oldCoinUSDRate = coinUSDRate; | |
coinUSDRate = _value; | |
emit ChangeCoinUSDRate(oldCoinUSDRate, coinUSDRate); | |
return true; | |
} | |
/** | |
* @dev Percent deducted from the amount raised getTotalUsdRaisedInCents | |
*/ | |
function setCurrVolPercent(uint _value) public onlyOwner returns(bool) { | |
require(_value > 0 && _value <= 10); | |
uint oldCurrVolPercent = currVolPercent; | |
currVolPercent = _value; | |
emit ChangeCurrVolPercent(oldCurrVolPercent, currVolPercent); | |
return true; | |
} | |
/** | |
* @dev Returns the number of SHPC from USD | |
* @param usdCents amount of dollars in cents example 100$ = 10000 | |
* @return SHPC in wei | |
*/ | |
function getTokenWeiFromUSD(uint usdCents) public view returns(uint) { | |
return usdCents.mul(1 ether).div(coinUSDRate); // (100.00$ * (10**18)) / 0.12$ = 833333333333333333333 SHPC wei = 833.33 SHPC | |
} | |
/** | |
* @dev Returns the number of SHPC in wei | |
* @param ethWei eth в wei | |
* @return SHPC in wei | |
*/ | |
function getTokenFromETH(uint ethWei) public view returns(uint) { | |
return ethWei.mul(currencyList["ETH"].usd).div(coinUSDRate); // (1 ETH * 587.10$) / 0.12$ = 4892500000000000000000 SHPC wei = 4892.50 SHPC | |
} | |
/** | |
* @dev Returns the amount of USD from ETH | |
* @param ethWei ETH в wei | |
* @return USD in cents | |
*/ | |
function getUsdFromETH(uint ethWei) public view returns(uint) { | |
return ethWei.mul(currencyList["ETH"].usd).div(1 ether); | |
} | |
/** | |
* @dev Add payment data to currency | |
* @param _ticker string | |
* @param value uint | |
* @param usdAmount uint in cents | |
* @param coinRaised uint in wei | |
* @param coinRaisedBonus uint in wei (optional field) | |
*/ | |
function addPay(string _ticker, uint value, uint usdAmount, uint coinRaised, uint coinRaisedBonus) public onlyMultiOwnersType(2) returns(bool) { | |
require(value > 0); | |
require(usdAmount > 0); | |
require(coinRaised > 0); | |
bytes32 ticker = stringToBytes32(_ticker); | |
assert(currencyList[ticker].active); | |
coinRaisedInWei += coinRaised; | |
coinRaisedBonusInWei += coinRaisedBonus; | |
usdAbsRaisedInCents += usdAmount; | |
currencyList[ticker].usdRaised += usdAmount; | |
currencyList[ticker].raised += value; | |
currencyList[ticker].counter++; | |
emit AddPay(); | |
return true; | |
} | |
/** | |
* @dev Chacnge currency data when change contributor payment | |
* @param ticker bytes32 | |
* @param currencyValue uint | |
* @param currencyUsdRaised uint in cents | |
* @param _usdAbsRaisedInCents uint in cents | |
* @param _coinRaisedInWei uint in wei | |
* @param _coinRaisedBonusInWei uint in wei (optional field) | |
*/ | |
function editPay( | |
bytes32 ticker, | |
uint currencyValue, | |
uint currencyUsdRaised, | |
uint _usdAbsRaisedInCents, | |
uint _coinRaisedInWei, | |
uint _coinRaisedBonusInWei | |
) | |
public | |
onlyMultiOwnersType(3) | |
returns(bool) | |
{ | |
require(currencyValue > 0); | |
require(currencyUsdRaised > 0); | |
require(_usdAbsRaisedInCents > 0); | |
require(_coinRaisedInWei > 0); | |
assert(currencyList[ticker].active); | |
coinRaisedInWei = _coinRaisedInWei; | |
coinRaisedBonusInWei = _coinRaisedBonusInWei; | |
usdAbsRaisedInCents = _usdAbsRaisedInCents; | |
currencyList[ticker].usdRaised = currencyUsdRaised; | |
currencyList[ticker].raised = currencyValue; | |
emit EditPay(); | |
return true; | |
} | |
/** | |
* @dev Add bonus SHPC | |
*/ | |
function addPreSaleBonus(uint bonusToken) public onlyMultiOwnersType(4) returns(bool) { | |
coinRaisedInWei += bonusToken; | |
coinRaisedBonusInWei += bonusToken; | |
emit EditPay(); | |
return true; | |
} | |
/** | |
* @dev Change bonus SHPC | |
*/ | |
function editPreSaleBonus(uint beforeBonus, uint afterBonus) public onlyMultiOwnersType(5) returns(bool) { | |
coinRaisedInWei -= beforeBonus; | |
coinRaisedBonusInWei -= beforeBonus; | |
coinRaisedInWei += afterBonus; | |
coinRaisedBonusInWei += afterBonus; | |
emit EditPay(); | |
return true; | |
} | |
/** | |
* @dev Returns the sum of investments with conversion to dollars at the current rate with a deduction of interest. | |
*/ | |
function getTotalUsdRaisedInCents() public view returns(uint) { | |
uint totalUsdAmount = 0; | |
if (currencyTicker.length > 0) { | |
for (uint i = 0; i < currencyTicker.length; i++) { | |
if (currencyList[currencyTicker[i]].raised > 0) { | |
totalUsdAmount += getUsdFromCurrency(currencyTicker[i], currencyList[currencyTicker[i]].raised); | |
} | |
} | |
} | |
return subPercent(totalUsdAmount, currVolPercent); | |
} | |
/** | |
* @dev Converts to dollars | |
*/ | |
function getUsdFromCurrency(string ticker, uint value) public view returns(uint) { | |
return getUsdFromCurrency(stringToBytes32(ticker), value); | |
} | |
/** | |
* @dev Converts to dollars | |
*/ | |
function getUsdFromCurrency(string ticker, uint value, uint usd) public view returns(uint) { | |
return getUsdFromCurrency(stringToBytes32(ticker), value, usd); | |
} | |
/** | |
* @dev Converts to dollars | |
*/ | |
function getUsdFromCurrency(bytes32 ticker, uint value) public view returns(uint) { | |
return getUsdFromCurrency(ticker, value, 0); | |
} | |
/** | |
* @dev Converts to dollars | |
*/ | |
function getUsdFromCurrency(bytes32 ticker, uint value, uint usd) public view returns(uint) { | |
if (currencyList[ticker].active && value > 0) { | |
return value.mul(usd > 0 ? usd : currencyList[ticker].usd).div(currencyList[ticker].devision); | |
} | |
return 0; | |
} | |
/** | |
* @dev Returns information about available currencies in json format | |
*/ | |
function getAllCurrencyTicker() public view returns(string) { | |
string memory _tickers = "{"; | |
for (uint i = 0; i < currencyTicker.length; i++) { | |
_tickers = strConcat(_tickers, strConcat("\"", bytes32ToString(currencyTicker[i]), "\":"), uint2str(currencyList[currencyTicker[i]].usd), (i+1 < currencyTicker.length) ? "," : "}"); | |
} | |
return _tickers; | |
} | |
/** | |
* @dev Update currency rate. | |
*/ | |
function updateCurrency(string ticker, uint value) public onlyMultiOwnersType(6) returns(bool) { | |
bytes32 _ticker = stringToBytes32(ticker); | |
require(currencyList[_ticker].active); | |
require(value > 0); | |
currencyList[_ticker].usd = value; | |
currencyList[_ticker].lastUpdate = block.timestamp; | |
emit ChangeCurrency(); | |
return true; | |
} | |
/** | |
* @dev Check currency is available. | |
*/ | |
function checkTickerExists(string ticker) public view returns(bool) { | |
return currencyList[stringToBytes32(ticker)].active; | |
} | |
/** | |
* @dev Returns currency info. | |
*/ | |
function getCurrencyList(string ticker) | |
public | |
view | |
returns( | |
bool active, | |
uint usd, | |
uint devision, | |
uint raised, | |
uint usdRaised, | |
uint usdRaisedExchangeRate, | |
uint counter, | |
uint lastUpdate | |
) | |
{ | |
return getCurrencyList(stringToBytes32(ticker)); | |
} | |
/** | |
* @dev Return curency info. | |
*/ | |
function getCurrencyList(bytes32 ticker) | |
public | |
view | |
returns( | |
bool active, | |
uint usd, | |
uint devision, | |
uint raised, | |
uint usdRaised, | |
uint usdRaisedExchangeRate, | |
uint counter, | |
uint lastUpdate | |
) | |
{ | |
CurrencyData memory _obj = currencyList[ticker]; | |
uint _usdRaisedExchangeRate = getUsdFromCurrency(ticker, _obj.raised); | |
return ( | |
_obj.active, | |
_obj.usd, | |
_obj.devision, | |
_obj.raised, | |
_obj.usdRaised, | |
_usdRaisedExchangeRate, | |
_obj.counter, | |
_obj.lastUpdate | |
); | |
} | |
function getCurrencyRate(string _ticker) public view returns(uint) { | |
return currencyList[stringToBytes32(_ticker)].usd; | |
} | |
/** | |
* @dev Return all currency data in json. | |
*/ | |
function getCurrencyData() public view returns(string) { | |
string memory _array = "{"; | |
if (currencyTicker.length > 0) { | |
for (uint i = 0; i < currencyTicker.length; i++) { | |
if (currencyList[currencyTicker[i]].active) { | |
_array = strConcat(_array, strConcat("\"", bytes32ToString(currencyTicker[i]), "\":"), getJsonCurrencyData(currencyList[currencyTicker[i]]), (i+1 == currencyTicker.length) ? "}" : ","); | |
} | |
} | |
} else { | |
return "[]"; | |
} | |
return _array; | |
} | |
/** | |
* @dev Returns the number of SHPC sold | |
*/ | |
function getCoinRaisedInWei() public view returns(uint) { | |
return coinRaisedInWei; | |
} | |
/** | |
* @dev Returns SHPC price in cents | |
*/ | |
function getCoinUSDRate() public view returns(uint) { | |
return coinUSDRate; | |
} | |
/** | |
* @dev Returns percent. | |
*/ | |
function getCurrVolPercent() public view returns(uint) { | |
return currVolPercent; | |
} | |
/** | |
* @dev Returns json info from currency | |
*/ | |
function getJsonCurrencyData(CurrencyData memory _obj) private pure returns (string) { | |
return strConcat( | |
strConcat("{\"usd\":", uint2str(_obj.usd), ",\"devision\":", uint2str(_obj.devision), ",\"raised\":\""), | |
strConcat(uint2str(_obj.raised), "\",\"usdRaised\":", uint2str(_obj.usdRaised), ",\"usdRaisedCurrency\":", uint2str((_obj.raised.mul(_obj.usd).div(_obj.devision)))), | |
strConcat(",\"counter\":", uint2str(_obj.counter), ",\"lastUpdate\":", uint2str(_obj.lastUpdate), "}") | |
); | |
} | |
/** | |
* @dev Calculate the percentage of the amount | |
* example: 100 - 5% = 95 | |
*/ | |
function subPercent(uint a, uint b) private pure returns(uint) { | |
uint c = (a / 100) * b; | |
assert(c <= a); | |
return a - c; | |
} | |
} |
This file contains 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.24; | |
import "./MultiOwnable.sol"; | |
import "./String.sol"; | |
import "./SafeMath.sol"; | |
import "./IStorage.sol"; | |
/** | |
* @title Whitelist | |
* @dev The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions. | |
* @dev This simplifies the implementation of "user permissions". | |
*/ | |
contract ShipCoinStorage is IStorage, MultiOwnable, String { | |
using SafeMath for uint256; | |
/* Events */ | |
event WhitelistAddressAdded(address addr); | |
event WhitelistAddressRemoved(address addr); | |
event AddPayment(address addr); | |
event GotPreSaleBonus(address addr); | |
event EditUserPayments(address addr, uint payId); | |
event RefundPayment(address addr, uint payId); | |
event ReceivedCoin(address addr); | |
event Refund(address addr); | |
event ChangeMainWallet(address addr); | |
struct PaymentData { | |
uint time; | |
bytes32 pType; | |
uint currencyUSD; | |
uint payValue; | |
uint totalToken; | |
uint tokenWithoutBonus; | |
uint tokenBonus; | |
uint bonusPercent; | |
uint usdAbsRaisedInCents; | |
} | |
struct StorageData { | |
bool active; | |
mapping(bytes32 => uint) payInCurrency; | |
uint totalToken; | |
uint tokenWithoutBonus; | |
uint tokenBonus; | |
uint usdAbsRaisedInCents; | |
mapping(uint => PaymentData) paymentInfo; | |
address mainWallet; | |
address[] wallet; | |
} | |
// uId = { } | |
mapping(uint => StorageData) private contributorList; | |
// wallet = uId | |
mapping(address => uint) private contributorIds; | |
// i++ = uId | |
mapping(uint => uint) private contributorIndexes; | |
//uId = payIds | |
mapping(uint => uint[]) private contributorPayIds; | |
uint public nextContributorIndex; | |
bytes32[] private currencyTicker; | |
// uId | |
mapping(uint => uint) private receivedPreSaleBonus; | |
// uId | |
mapping(uint => bool) private receivedCoin; | |
//payIds | |
mapping(uint => bool) private payIds; | |
//payIds | |
mapping(uint => bool) private refundPayIds; | |
//uId | |
mapping(uint => bool) private refundUserIds; | |
uint private startGenId = 100000; | |
bool public supportChangeMainWallet = true; | |
/** | |
* @dev Calculate contributors appoint presale bonus | |
*/ | |
function processPreSaleBonus(uint minTotalUsdAmountInCents, uint bonusPercent, uint _start, uint _limit) external onlyMultiOwnersType(12) returns(uint) { | |
require(minTotalUsdAmountInCents > 10000); | |
require(bonusPercent > 20 && bonusPercent < 50); | |
require(_limit >= 10); | |
uint start = _start; | |
uint limit = _limit; | |
uint bonusTokenAll = 0; | |
for (uint i = start; i < limit; i++) { | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !checkPreSaleReceivedBonus(uId) && contributorList[uId].usdAbsRaisedInCents >= minTotalUsdAmountInCents) { | |
uint bonusToken = contributorList[uId].tokenWithoutBonus.mul(bonusPercent).div(100); | |
contributorList[uId].totalToken += bonusToken; | |
contributorList[uId].tokenBonus = bonusToken; | |
receivedPreSaleBonus[uId] = bonusToken; | |
bonusTokenAll += bonusToken; | |
emit GotPreSaleBonus(contributorList[uId].mainWallet); | |
} | |
} | |
return bonusTokenAll; | |
} | |
/** | |
* @dev Checks contributors who have not received their presale bonuses | |
*/ | |
function checkNeedProcessPreSaleBonus(uint minTotalUsdAmountInCents) external view returns(bool) { | |
require(minTotalUsdAmountInCents > 10000); | |
bool processed = false; | |
for (uint i = 0; i < nextContributorIndex; i++) { | |
if (processed) { | |
break; | |
} | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !refundUserIds[uId] && !checkPreSaleReceivedBonus(uId) && contributorList[uId].usdAbsRaisedInCents >= minTotalUsdAmountInCents) { | |
processed = true; | |
} | |
} | |
return processed; | |
} | |
/** | |
* @dev Returns the number of contributors who have not received their presale bonuses | |
*/ | |
function getCountNeedProcessPreSaleBonus(uint minTotalUsdAmountInCents, uint start, uint limit) external view returns(uint) { | |
require(minTotalUsdAmountInCents > 10000); | |
require(start >= 0 && limit >= 10); | |
uint processed = 0; | |
for (uint i = start; i < (limit > nextContributorIndex ? nextContributorIndex : limit); i++) { | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !refundUserIds[uId] && !checkPreSaleReceivedBonus(uId) && contributorList[uId].usdAbsRaisedInCents >= minTotalUsdAmountInCents) { | |
processed++; | |
} | |
} | |
return processed; | |
} | |
/** | |
* @dev Checks contributors who have not received their SHPC | |
*/ | |
function checkNeedSendSHPC(bool proc) external view returns(bool) { | |
bool processed = false; | |
if (proc) { | |
for (uint i = 0; i < nextContributorIndex; i++) { | |
if (processed) { | |
break; | |
} | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !refundUserIds[uId] && !checkReceivedCoins(uId) && contributorList[uId].totalToken > 0) { | |
processed = true; | |
} | |
} | |
} | |
return processed; | |
} | |
/** | |
* @dev Returns the number of contributors who have not received their SHPC | |
*/ | |
function getCountNeedSendSHPC(uint start, uint limit) external view returns(uint) { | |
require(start >= 0 && limit >= 10); | |
uint processed = 0; | |
for (uint i = start; i < (limit > nextContributorIndex ? nextContributorIndex : limit); i++) { | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !refundUserIds[uId] && !checkReceivedCoins(uId) && contributorList[uId].totalToken > 0) { | |
processed++; | |
} | |
} | |
return processed; | |
} | |
/** | |
* @dev Checks contributors who have not received their ETH when refund | |
*/ | |
function checkETHRefund(bool proc) external view returns(bool) { | |
bool processed = false; | |
if (proc) { | |
for (uint i = 0; i < nextContributorIndex; i++) { | |
if (processed) { | |
break; | |
} | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !refundUserIds[uId] && getEthPaymentContributor(uId) > 0) { | |
processed = true; | |
} | |
} | |
} | |
return processed; | |
} | |
/** | |
* @dev Returns the number of contributors who have not received their ETH when refund | |
*/ | |
function getCountETHRefund(uint start, uint limit) external view returns(uint) { | |
require(start >= 0 && limit >= 10); | |
uint processed = 0; | |
for (uint i = start; i < (limit > nextContributorIndex ? nextContributorIndex : limit); i++) { | |
uint uId = contributorIndexes[i]; | |
if (contributorList[uId].active && !refundUserIds[uId] && getEthPaymentContributor(uId) > 0) { | |
processed++; | |
} | |
} | |
return processed; | |
} | |
/** | |
* @dev Returns uId by index; | |
*/ | |
function getContributorIndexes(uint index) external onlyMultiOwnersType(7) view returns(uint) { | |
return contributorIndexes[index]; | |
} | |
/** | |
* @dev Recalculation contributors presale bonus | |
*/ | |
function reCountUserPreSaleBonus(uint _uId, uint minTotalUsdAmountInCents, uint bonusPercent, uint maxPayTime) external onlyMultiOwnersType(13) returns(uint, uint) { | |
require(_uId > 0); | |
require(contributorList[_uId].active); | |
require(!refundUserIds[_uId]); | |
require(minTotalUsdAmountInCents > 10000); | |
require(bonusPercent > 20 && bonusPercent < 50); | |
uint bonusToken = 0; | |
uint uId = _uId; | |
uint beforeBonusToken = receivedPreSaleBonus[uId]; | |
if (beforeBonusToken > 0) { | |
contributorList[uId].totalToken -= beforeBonusToken; | |
contributorList[uId].tokenBonus -= beforeBonusToken; | |
receivedPreSaleBonus[uId] = 0; | |
} | |
if (contributorList[uId].usdAbsRaisedInCents >= minTotalUsdAmountInCents) { | |
if (maxPayTime > 0) { | |
for (uint i = 0; i < contributorPayIds[uId].length; i++) { | |
PaymentData memory _payment = contributorList[uId].paymentInfo[contributorPayIds[uId][i]]; | |
if (!refundPayIds[contributorPayIds[uId][i]] && _payment.bonusPercent == 0 && _payment.time < maxPayTime) { | |
bonusToken += _payment.tokenWithoutBonus.mul(bonusPercent).div(100); | |
} | |
} | |
} else { | |
bonusToken = contributorList[uId].tokenWithoutBonus.mul(bonusPercent).div(100); | |
} | |
if (bonusToken > 0) { | |
contributorList[uId].totalToken += bonusToken; | |
contributorList[uId].tokenBonus += bonusToken; | |
receivedPreSaleBonus[uId] = bonusToken; | |
emit GotPreSaleBonus(contributorList[uId].mainWallet); | |
} | |
} | |
return (beforeBonusToken, bonusToken); | |
} | |
/** | |
* @dev add user and wallet to whitelist | |
*/ | |
function addWhiteList(uint uId, address addr) public onlyMultiOwnersType(1) returns(bool success) { | |
require(addr != address(0), "1"); | |
require(uId > 0, "2"); | |
require(!refundUserIds[uId]); | |
if (contributorIds[addr] > 0 && contributorIds[addr] != uId) { | |
success = false; | |
revert("3"); | |
} | |
if (contributorList[uId].active != true) { | |
contributorList[uId].active = true; | |
contributorIndexes[nextContributorIndex] = uId; | |
nextContributorIndex++; | |
contributorList[uId].mainWallet = addr; | |
} | |
if (inArray(contributorList[uId].wallet, addr) != true && contributorList[uId].wallet.length < 3) { | |
contributorList[uId].wallet.push(addr); | |
contributorIds[addr] = uId; | |
emit WhitelistAddressAdded(addr); | |
success = true; | |
} else { | |
success = false; | |
} | |
} | |
/** | |
* @dev remove user wallet from whitelist | |
*/ | |
function removeWhiteList(uint uId, address addr) public onlyMultiOwnersType(2) returns(bool success) { | |
require(contributorList[uId].active, "1"); | |
require(addr != address(0), "2"); | |
require(uId > 0, "3"); | |
require(inArray(contributorList[uId].wallet, addr)); | |
if (contributorPayIds[uId].length > 0 || contributorList[uId].mainWallet == addr) { | |
success = false; | |
revert("5"); | |
} | |
contributorList[uId].wallet = removeValueFromArray(contributorList[uId].wallet, addr); | |
delete contributorIds[addr]; | |
emit WhitelistAddressRemoved(addr); | |
success = true; | |
} | |
/** | |
* @dev Change contributor mainWallet | |
*/ | |
function changeMainWallet(uint uId, address addr) public onlyMultiOwnersType(3) returns(bool) { | |
require(supportChangeMainWallet); | |
require(addr != address(0)); | |
require(uId > 0); | |
require(contributorList[uId].active); | |
require(!refundUserIds[uId]); | |
require(inArray(contributorList[uId].wallet, addr)); | |
contributorList[uId].mainWallet = addr; | |
emit ChangeMainWallet(addr); | |
return true; | |
} | |
/** | |
* @dev Change the right to change mainWallet | |
*/ | |
function changeSupportChangeMainWallet(bool support) public onlyMultiOwnersType(21) returns(bool) { | |
supportChangeMainWallet = support; | |
return supportChangeMainWallet; | |
} | |
/** | |
* @dev Returns all contributor info by uId | |
*/ | |
function getContributionInfoById(uint _uId) public onlyMultiOwnersType(4) view returns( | |
bool active, | |
string payInCurrency, | |
uint totalToken, | |
uint tokenWithoutBonus, | |
uint tokenBonus, | |
uint usdAbsRaisedInCents, | |
uint[] paymentInfoIds, | |
address mainWallet, | |
address[] wallet, | |
uint preSaleReceivedBonus, | |
bool receivedCoins, | |
bool refund | |
) | |
{ | |
uint uId = _uId; | |
return getContributionInfo(contributorList[uId].mainWallet); | |
} | |
/** | |
* @dev Returns all contributor info by address | |
*/ | |
function getContributionInfo(address _addr) | |
public | |
view | |
returns( | |
bool active, | |
string payInCurrency, | |
uint totalToken, | |
uint tokenWithoutBonus, | |
uint tokenBonus, | |
uint usdAbsRaisedInCents, | |
uint[] paymentInfoIds, | |
address mainWallet, | |
address[] wallet, | |
uint preSaleReceivedBonus, | |
bool receivedCoins, | |
bool refund | |
) | |
{ | |
address addr = _addr; | |
StorageData memory storData = contributorList[contributorIds[addr]]; | |
(preSaleReceivedBonus, receivedCoins, refund) = getInfoAdditionl(addr); | |
return( | |
storData.active, | |
(contributorPayIds[contributorIds[addr]].length > 0 ? getContributorPayInCurrency(contributorIds[addr]) : "[]"), | |
storData.totalToken, | |
storData.tokenWithoutBonus, | |
storData.tokenBonus, | |
storData.usdAbsRaisedInCents, | |
contributorPayIds[contributorIds[addr]], | |
storData.mainWallet, | |
storData.wallet, | |
preSaleReceivedBonus, | |
receivedCoins, | |
refund | |
); | |
} | |
/** | |
* @dev Returns contributor id by address | |
*/ | |
function getContributorId(address addr) public onlyMultiOwnersType(5) view returns(uint) { | |
return contributorIds[addr]; | |
} | |
/** | |
* @dev Returns contributors address by uId | |
*/ | |
function getContributorAddressById(uint uId) public onlyMultiOwnersType(6) view returns(address) { | |
require(uId > 0); | |
require(contributorList[uId].active); | |
return contributorList[uId].mainWallet; | |
} | |
/** | |
* @dev Check wallet exists by address | |
*/ | |
function checkWalletExists(address addr) public view returns(bool result) { | |
result = false; | |
if (contributorList[contributorIds[addr]].wallet.length > 0) { | |
result = inArray(contributorList[contributorIds[addr]].wallet, addr); | |
} | |
} | |
/** | |
* @dev Check userId is exists | |
*/ | |
function checkUserIdExists(uint uId) public onlyMultiOwnersType(8) view returns(bool) { | |
return contributorList[uId].active; | |
} | |
/** | |
* @dev Add payment by address | |
*/ | |
function addPayment( | |
address _addr, | |
string pType, | |
uint _value, | |
uint usdAmount, | |
uint currencyUSD, | |
uint tokenWithoutBonus, | |
uint tokenBonus, | |
uint bonusPercent, | |
uint payId | |
) | |
public | |
onlyMultiOwnersType(9) | |
returns(bool) | |
{ | |
require(_value > 0); | |
require(usdAmount > 0); | |
require(tokenWithoutBonus > 0); | |
require(bytes(pType).length > 0); | |
assert((payId == 0 && stringsEqual(pType, "ETH")) || (payId > 0 && !payIds[payId])); | |
address addr = _addr; | |
uint uId = contributorIds[addr]; | |
assert(addr != address(0)); | |
assert(checkWalletExists(addr)); | |
assert(uId > 0); | |
assert(contributorList[uId].active); | |
assert(!refundUserIds[uId]); | |
assert(!receivedCoin[uId]); | |
if (payId == 0) { | |
payId = genId(addr, _value, 0); | |
} | |
bytes32 _pType = stringToBytes32(pType); | |
PaymentData memory userPayment; | |
uint totalToken = tokenWithoutBonus.add(tokenBonus); | |
//userPayment.payId = payId; | |
userPayment.time = block.timestamp; | |
userPayment.pType = _pType; | |
userPayment.currencyUSD = currencyUSD; | |
userPayment.payValue = _value; | |
userPayment.totalToken = totalToken; | |
userPayment.tokenWithoutBonus = tokenWithoutBonus; | |
userPayment.tokenBonus = tokenBonus; | |
userPayment.bonusPercent = bonusPercent; | |
userPayment.usdAbsRaisedInCents = usdAmount; | |
if (!inArray(currencyTicker, _pType)) { | |
currencyTicker.push(_pType); | |
} | |
if (payId > 0) { | |
payIds[payId] = true; | |
} | |
contributorList[uId].usdAbsRaisedInCents += usdAmount; | |
contributorList[uId].totalToken += totalToken; | |
contributorList[uId].tokenWithoutBonus += tokenWithoutBonus; | |
contributorList[uId].tokenBonus += tokenBonus; | |
contributorList[uId].payInCurrency[_pType] += _value; | |
contributorList[uId].paymentInfo[payId] = userPayment; | |
contributorPayIds[uId].push(payId); | |
emit AddPayment(addr); | |
return true; | |
} | |
/** | |
* @dev Add payment by uId | |
*/ | |
function addPayment( | |
uint uId, | |
string pType, | |
uint _value, | |
uint usdAmount, | |
uint currencyUSD, | |
uint tokenWithoutBonus, | |
uint tokenBonus, | |
uint bonusPercent, | |
uint payId | |
) | |
public | |
returns(bool) | |
{ | |
require(contributorList[uId].active); | |
require(contributorList[uId].mainWallet != address(0)); | |
return addPayment(contributorList[uId].mainWallet, pType, _value, usdAmount, currencyUSD, tokenWithoutBonus, tokenBonus, bonusPercent, payId); | |
} | |
/** | |
* @dev Edit user payment info | |
*/ | |
function editPaymentByUserId( | |
uint uId, | |
uint payId, | |
uint _payValue, | |
uint _usdAmount, | |
uint _currencyUSD, | |
uint _totalToken, | |
uint _tokenWithoutBonus, | |
uint _tokenBonus, | |
uint _bonusPercent | |
) | |
public | |
onlyMultiOwnersType(10) | |
returns(bool) | |
{ | |
require(contributorList[uId].active); | |
require(inArray(contributorPayIds[uId], payId)); | |
require(!refundPayIds[payId]); | |
require(!refundUserIds[uId]); | |
require(!receivedCoin[uId]); | |
PaymentData memory oldPayment = contributorList[uId].paymentInfo[payId]; | |
contributorList[uId].usdAbsRaisedInCents -= oldPayment.usdAbsRaisedInCents; | |
contributorList[uId].totalToken -= oldPayment.totalToken; | |
contributorList[uId].tokenWithoutBonus -= oldPayment.tokenWithoutBonus; | |
contributorList[uId].tokenBonus -= oldPayment.tokenBonus; | |
contributorList[uId].payInCurrency[oldPayment.pType] -= oldPayment.payValue; | |
contributorList[uId].paymentInfo[payId] = PaymentData( | |
oldPayment.time, | |
oldPayment.pType, | |
_currencyUSD, | |
_payValue, | |
_totalToken, | |
_tokenWithoutBonus, | |
_tokenBonus, | |
_bonusPercent, | |
_usdAmount | |
); | |
contributorList[uId].usdAbsRaisedInCents += _usdAmount; | |
contributorList[uId].totalToken += _totalToken; | |
contributorList[uId].tokenWithoutBonus += _tokenWithoutBonus; | |
contributorList[uId].tokenBonus += _tokenBonus; | |
contributorList[uId].payInCurrency[oldPayment.pType] += _payValue; | |
emit EditUserPayments(contributorList[uId].mainWallet, payId); | |
return true; | |
} | |
/** | |
* @dev Refund user payment | |
*/ | |
function refundPaymentByUserId(uint uId, uint payId) public onlyMultiOwnersType(20) returns(bool) { | |
require(contributorList[uId].active); | |
require(inArray(contributorPayIds[uId], payId)); | |
require(!refundPayIds[payId]); | |
require(!refundUserIds[uId]); | |
require(!receivedCoin[uId]); | |
PaymentData memory oldPayment = contributorList[uId].paymentInfo[payId]; | |
assert(oldPayment.pType != stringToBytes32("ETH")); | |
contributorList[uId].usdAbsRaisedInCents -= oldPayment.usdAbsRaisedInCents; | |
contributorList[uId].totalToken -= oldPayment.totalToken; | |
contributorList[uId].tokenWithoutBonus -= oldPayment.tokenWithoutBonus; | |
contributorList[uId].tokenBonus -= oldPayment.tokenBonus; | |
contributorList[uId].payInCurrency[oldPayment.pType] -= oldPayment.payValue; | |
refundPayIds[payId] = true; | |
emit RefundPayment(contributorList[uId].mainWallet, payId); | |
return true; | |
} | |
/** | |
* @dev Reutrns user payment info by uId and paymentId | |
*/ | |
function getUserPaymentById(uint _uId, uint _payId) public onlyMultiOwnersType(11) view returns( | |
uint time, | |
bytes32 pType, | |
uint currencyUSD, | |
uint bonusPercent, | |
uint payValue, | |
uint totalToken, | |
uint tokenBonus, | |
uint tokenWithoutBonus, | |
uint usdAbsRaisedInCents, | |
bool refund | |
) | |
{ | |
uint uId = _uId; | |
uint payId = _payId; | |
require(contributorList[uId].active); | |
require(inArray(contributorPayIds[uId], payId)); | |
PaymentData memory payment = contributorList[uId].paymentInfo[payId]; | |
return ( | |
payment.time, | |
payment.pType, | |
payment.currencyUSD, | |
payment.bonusPercent, | |
payment.payValue, | |
payment.totalToken, | |
payment.tokenBonus, | |
payment.tokenWithoutBonus, | |
payment.usdAbsRaisedInCents, | |
refundPayIds[payId] ? true : false | |
); | |
} | |
/** | |
* @dev Reutrns user payment info by address and payment id | |
*/ | |
function getUserPayment(address addr, uint _payId) public view returns( | |
uint time, | |
string pType, | |
uint currencyUSD, | |
uint bonusPercent, | |
uint payValue, | |
uint totalToken, | |
uint tokenBonus, | |
uint tokenWithoutBonus, | |
uint usdAbsRaisedInCents, | |
bool refund | |
) | |
{ | |
address _addr = addr; | |
require(contributorList[contributorIds[_addr]].active); | |
require(inArray(contributorPayIds[contributorIds[_addr]], _payId)); | |
uint payId = _payId; | |
PaymentData memory payment = contributorList[contributorIds[_addr]].paymentInfo[payId]; | |
return ( | |
payment.time, | |
bytes32ToString(payment.pType), | |
payment.currencyUSD, | |
payment.bonusPercent, | |
payment.payValue, | |
payment.totalToken, | |
payment.tokenBonus, | |
payment.tokenWithoutBonus, | |
payment.usdAbsRaisedInCents, | |
refundPayIds[payId] ? true : false | |
); | |
} | |
/** | |
* @dev Returns payment in ETH from address | |
*/ | |
function getEthPaymentContributor(address addr) public view returns(uint) { | |
return contributorList[contributorIds[addr]].payInCurrency[stringToBytes32("ETH")]; | |
} | |
/** | |
* @dev Returns SHPC from address | |
*/ | |
function getTotalCoin(address addr) public view returns(uint) { | |
return contributorList[contributorIds[addr]].totalToken; | |
} | |
/** | |
* @dev Check user get pre sale bonus by address | |
*/ | |
function checkPreSaleReceivedBonus(address addr) public view returns(bool) { | |
return receivedPreSaleBonus[contributorIds[addr]] > 0 ? true : false; | |
} | |
/** | |
* @dev Check payment refund by payment id | |
*/ | |
function checkPaymentRefund(uint payId) public view returns(bool) { | |
return refundPayIds[payId]; | |
} | |
/** | |
* @dev Check user refund by address | |
*/ | |
function checkRefund(address addr) public view returns(bool) { | |
return refundUserIds[contributorIds[addr]]; | |
} | |
/** | |
* @dev Set start number generate payment id when user pay in eth | |
*/ | |
function setStartGenId(uint startId) public onlyMultiOwnersType(14) { | |
require(startId > 0); | |
startGenId = startId; | |
} | |
/** | |
* @dev Set contributer got SHPC | |
*/ | |
function setReceivedCoin(uint uId) public onlyMultiOwnersType(15) returns(bool) { | |
require(contributorList[uId].active); | |
require(!refundUserIds[uId]); | |
require(!receivedCoin[uId]); | |
receivedCoin[uId] = true; | |
emit ReceivedCoin(contributorList[uId].mainWallet); | |
return true; | |
} | |
/** | |
* @dev Set contributer got refund ETH | |
*/ | |
function setRefund(uint uId) public onlyMultiOwnersType(16) returns(bool) { | |
require(contributorList[uId].active); | |
require(!refundUserIds[uId]); | |
require(!receivedCoin[uId]); | |
refundUserIds[uId] = true; | |
emit Refund(contributorList[uId].mainWallet); | |
return true; | |
} | |
/** | |
* @dev Check contributor got SHPC | |
*/ | |
function checkReceivedCoins(address addr) public view returns(bool) { | |
return receivedCoin[contributorIds[addr]]; | |
} | |
/** | |
* @dev Check contributor got ETH | |
*/ | |
function checkReceivedEth(address addr) public view returns(bool) { | |
return refundUserIds[contributorIds[addr]]; | |
} | |
/** | |
* @dev Returns all contributor currency amount in json | |
*/ | |
function getContributorPayInCurrency(uint uId) private view returns(string) { | |
require(uId > 0); | |
require(contributorList[uId].active); | |
string memory payInCurrency = "{"; | |
for (uint i = 0; i < currencyTicker.length; i++) { | |
payInCurrency = strConcat(payInCurrency, strConcat("\"", bytes32ToString(currencyTicker[i]), "\":\""), uint2str(contributorList[uId].payInCurrency[currencyTicker[i]]), (i+1 < currencyTicker.length) ? "\"," : "\"}"); | |
} | |
return payInCurrency; | |
} | |
/** | |
* @dev Check receives presale bonud by uId | |
*/ | |
function checkPreSaleReceivedBonus(uint uId) private view returns(bool) { | |
return receivedPreSaleBonus[uId] > 0 ? true : false; | |
} | |
/** | |
* @dev Check refund by uId | |
*/ | |
function checkRefund(uint uId) private view returns(bool) { | |
return refundUserIds[uId]; | |
} | |
/** | |
* @dev Check received SHPC by uI | |
*/ | |
function checkReceivedCoins(uint id) private view returns(bool) { | |
return receivedCoin[id]; | |
} | |
/** | |
* @dev Check received eth by uId | |
*/ | |
function checkReceivedEth(uint id) private view returns(bool) { | |
return refundUserIds[id]; | |
} | |
/** | |
* @dev Returns new uniq payment id | |
*/ | |
function genId(address addr, uint ammount, uint rand) private view returns(uint) { | |
uint id = startGenId + uint8(keccak256(abi.encodePacked(addr, blockhash(block.number), ammount, rand))) + contributorPayIds[contributorIds[addr]].length; | |
if (!payIds[id]) { | |
return id; | |
} else { | |
return genId(addr, ammount, id); | |
} | |
} | |
/** | |
* @dev Returns payment in ETH from uid | |
*/ | |
function getEthPaymentContributor(uint uId) private view returns(uint) { | |
return contributorList[uId].payInCurrency[stringToBytes32("ETH")]; | |
} | |
/** | |
* @dev Returns adittional info by contributor address | |
*/ | |
function getInfoAdditionl(address addr) private view returns(uint, bool, bool) { | |
return(receivedPreSaleBonus[contributorIds[addr]], receivedCoin[contributorIds[addr]], refundUserIds[contributorIds[addr]]); | |
} | |
/** | |
* @dev Returns payments info by userId in json | |
*/ | |
function getArrayjsonPaymentInfo(uint uId) private view returns (string) { | |
string memory _array = "{"; | |
for (uint i = 0; i < contributorPayIds[uId].length; i++) { | |
_array = strConcat(_array, getJsonPaymentInfo(contributorList[uId].paymentInfo[contributorPayIds[uId][i]], contributorPayIds[uId][i]), (i+1 == contributorPayIds[uId].length) ? "}" : ","); | |
} | |
return _array; | |
} | |
/** | |
* @dev Returns payment info by payment data in json | |
*/ | |
function getJsonPaymentInfo(PaymentData memory _obj, uint payId) private view returns (string) { | |
return strConcat( | |
strConcat("\"", uint2str(payId), "\":{", strConcat("\"", "time", "\":"), uint2str(_obj.time)), | |
strConcat(",\"pType\":\"", bytes32ToString(_obj.pType), "\",\"currencyUSD\":", uint2str(_obj.currencyUSD), ",\"payValue\":\""), | |
strConcat(uint2str(_obj.payValue), "\",\"totalToken\":\"", uint2str(_obj.totalToken), "\",\"tokenWithoutBonus\":\"", uint2str(_obj.tokenWithoutBonus)), | |
strConcat("\",\"tokenBonus\":\"", uint2str(_obj.tokenBonus), "\",\"bonusPercent\":", uint2str(_obj.bonusPercent)), | |
strConcat(",\"usdAbsRaisedInCents\":\"", uint2str(_obj.usdAbsRaisedInCents), "\",\"refund\":\"", (refundPayIds[payId] ? "1" : "0"), "\"}") | |
); | |
} | |
/** | |
* @dev Check if value contains array | |
*/ | |
function inArray(address[] _array, address _value) private pure returns(bool result) { | |
if (_array.length == 0 || _value == address(0)) { | |
return false; | |
} | |
result = false; | |
for (uint i = 0; i < _array.length; i++) { | |
if (_array[i] == _value) { | |
result = true; | |
return true; | |
} | |
} | |
} | |
/** | |
* @dev Check if value contains array | |
*/ | |
function inArray(uint[] _array, uint _value) private pure returns(bool result) { | |
if (_array.length == 0 || _value == 0) { | |
return false; | |
} | |
result = false; | |
for (uint i = 0; i < _array.length; i++) { | |
if (_array[i] == _value) { | |
result = true; | |
return true; | |
} | |
} | |
} | |
/** | |
* @dev Check if value contains array | |
*/ | |
function inArray(bytes32[] _array, bytes32 _value) private pure returns(bool result) { | |
if (_array.length == 0 || _value.length == 0) { | |
return false; | |
} | |
result = false; | |
for (uint i = 0; i < _array.length; i++) { | |
if (_array[i] == _value) { | |
result = true; | |
return true; | |
} | |
} | |
} | |
/** | |
* @dev Remove value from arary | |
*/ | |
function removeValueFromArray(address[] _array, address _value) private pure returns(address[]) { | |
address[] memory arrayNew = new address[](_array.length-1); | |
if (arrayNew.length == 0) { | |
return arrayNew; | |
} | |
uint i1 = 0; | |
for (uint i = 0; i < _array.length; i++) { | |
if (_array[i] != _value) { | |
arrayNew[i1++] = _array[i]; | |
} | |
} | |
return arrayNew; | |
} | |
} |
This file contains 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.22; | |
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 | |
*/ | |
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); | |
emit 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; | |
emit 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]; | |
} | |
/** | |
* @dev Increase the amount of tokens that an owner allowed to a 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 | |
* @param _spender The address which will spend the funds. | |
* @param _addedValue The amount of tokens to increase the allowance by. | |
*/ | |
function increaseApproval(address _spender, uint _addedValue) public returns (bool) { | |
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue); | |
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); | |
return true; | |
} | |
/** | |
* @dev Decrease the amount of tokens that an owner allowed to a spender. | |
* | |
* approve should be called when allowed[_spender] == 0. To decrement | |
* allowed value is better to use this function to avoid 2 calls (and wait until | |
* the first transaction is mined) | |
* From MonolithDAO Token.sol | |
* @param _spender The address which will spend the funds. | |
* @param _subtractedValue The amount of tokens to decrease the allowance by. | |
*/ | |
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); | |
} | |
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); | |
return true; | |
} | |
} |
This file contains 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.24; | |
/** | |
* @title String | |
* @dev ConcatenationString, uintToString, stringsEqual, stringToBytes32, bytes32ToString | |
*/ | |
contract String { | |
function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string memory) { | |
bytes memory _ba = bytes(_a); | |
bytes memory _bb = bytes(_b); | |
bytes memory _bc = bytes(_c); | |
bytes memory _bd = bytes(_d); | |
bytes memory _be = bytes(_e); | |
bytes memory abcde = bytes(new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length)); | |
uint k = 0; | |
uint i; | |
for (i = 0; i < _ba.length; i++) { | |
abcde[k++] = _ba[i]; | |
} | |
for (i = 0; i < _bb.length; i++) { | |
abcde[k++] = _bb[i]; | |
} | |
for (i = 0; i < _bc.length; i++) { | |
abcde[k++] = _bc[i]; | |
} | |
for (i = 0; i < _bd.length; i++) { | |
abcde[k++] = _bd[i]; | |
} | |
for (i = 0; i < _be.length; i++) { | |
abcde[k++] = _be[i]; | |
} | |
return string(abcde); | |
} | |
function strConcat(string _a, string _b, string _c, string _d) internal pure returns(string) { | |
return strConcat(_a, _b, _c, _d, ""); | |
} | |
function strConcat(string _a, string _b, string _c) internal pure returns(string) { | |
return strConcat(_a, _b, _c, "", ""); | |
} | |
function strConcat(string _a, string _b) internal pure returns(string) { | |
return strConcat(_a, _b, "", "", ""); | |
} | |
function uint2str(uint i) internal pure returns(string) { | |
if (i == 0) { | |
return "0"; | |
} | |
uint j = i; | |
uint length; | |
while (j != 0) { | |
length++; | |
j /= 10; | |
} | |
bytes memory bstr = new bytes(length); | |
uint k = length - 1; | |
while (i != 0) { | |
bstr[k--] = byte(uint8(48 + i % 10)); | |
i /= 10; | |
} | |
return string(bstr); | |
} | |
function stringsEqual(string memory _a, string memory _b) internal pure returns(bool) { | |
bytes memory a = bytes(_a); | |
bytes memory b = bytes(_b); | |
if (a.length != b.length) | |
return false; | |
for (uint i = 0; i < a.length; i++) { | |
if (a[i] != b[i]) { | |
return false; | |
} | |
} | |
return true; | |
} | |
function stringToBytes32(string memory source) internal pure returns(bytes32 result) { | |
bytes memory _tmp = bytes(source); | |
if (_tmp.length == 0) { | |
return 0x0; | |
} | |
assembly { | |
result := mload(add(source, 32)) | |
} | |
} | |
function bytes32ToString(bytes32 x) internal pure returns (string) { | |
bytes memory bytesString = new bytes(32); | |
uint charCount = 0; | |
uint j; | |
for (j = 0; j < 32; j++) { | |
byte char = byte(bytes32(uint(x) * 2 ** (8 * j))); | |
if (char != 0) { | |
bytesString[charCount] = char; | |
charCount++; | |
} | |
} | |
bytes memory bytesStringTrimmed = new bytes(charCount); | |
for (j = 0; j < charCount; j++) { | |
bytesStringTrimmed[j] = bytesString[j]; | |
} | |
return string(bytesStringTrimmed); | |
} | |
function inArray(string[] _array, string _value) internal pure returns(bool result) { | |
if (_array.length == 0 || bytes(_value).length == 0) { | |
return false; | |
} | |
result = false; | |
for (uint i = 0; i < _array.length; i++) { | |
if (stringsEqual(_array[i],_value)) { | |
result = true; | |
return true; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment