Skip to content

Instantly share code, notes, and snippets.

@nikita-fuchs
Created August 29, 2018 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikita-fuchs/dd09f08f63060791862c29161372f0a4 to your computer and use it in GitHub Desktop.
Save nikita-fuchs/dd09f08f63060791862c29161372f0a4 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=true&gist=
pragma solidity ^0.4.24;
import "https://github.com/staramba/com.staramba.token.STT/StandardToken.sol";
import "https://github.com/staramba/com.staramba.token.STT/RelocationToken.sol";
/**
* @title The STT Token contract.
*
* By Nikita Fuchs
* Credit: Taking ideas from BAT token, NET token and Nimiq token.
*/
/*is StandardToken */
contract StarambaToken is StandardToken {
// Token metadata
string public constant name = "STARAMBA.Token";
string public constant symbol = "STT";
uint256 public constant decimals = 18;
string public constant version = "1";
uint256 public TOKEN_CREATION_CAP = 1000 * (10**6) * 10**decimals; // 1000 million STTs
uint256 public constant TOKEN_MIN = 1 * 10**decimals; // 1 STT
address public STTadmin1; // First administrator for multi-sig mechanism
address public STTadmin2; // Second administrator for multi-sig mechanism
// Contracts current state (transactions still paused during sale or already publicly available)
bool public transactionsActive;
// Indicate if the token is in relocation mode
bool public relocationActive;
address public newTokenContractAddress;
// How often was the supply adjusted ? (See STT Whitepaper Version 1.0 from 23. May 2018 )
uint8 supplyAdjustmentCount = 0;
// Keep track of holders and icoBuyers
mapping (address => bool) public isHolder; // track if a user is a known token holder to the smart contract - important for payouts later
address[] public holders; // array of all known holders - important for payouts later
// Store the hashes of admins' msg.data
mapping (address => bytes32) private multiSigHashes;
// Declare vendor keys
mapping (address => bool) public vendors;
// Count amount of vendors for easier verification of correct contract deployment
uint8 public vendorCount;
// Events used for logging
event LogDeliverSTT(address indexed _to, uint256 _value);
//event Log
modifier onlyVendor() {
require(vendors[msg.sender] == true);
_;
}
modifier isTransferable() {
require (transactionsActive == true);
_;
}
modifier onlyOwner() {
// check if transaction sender is admin.
require (msg.sender == STTadmin1 || msg.sender == STTadmin2);
// if yes, store his msg.data.
multiSigHashes[msg.sender] = keccak256(msg.data);
// check if his stored msg.data hash equals to the one of the other admin
if ((multiSigHashes[STTadmin1]) == (multiSigHashes[STTadmin2])) {
// if yes, both admins agreed - continue.
_;
// Reset hashes after successful execution
multiSigHashes[STTadmin1] = 0x0;
multiSigHashes[STTadmin2] = 0x0;
} else {
// if not (yet), return.
return;
}
}
/**
* @dev Create a new STTToken contract.
*
* _admin1 The first admin account that owns this contract.
* _admin2 The second admin account that owns this contract.
* _vendors List of exactly 10 addresses that are allowed to deliver tokens.
*/
constructor(address _admin1, address _admin2, address[] _vendors)
public
{
// Check if the parameters make sense
// admin1 and admin2 address must be set and must be different
require (_admin1 != 0x0);
require (_admin2 != 0x0);
require (_admin1 != _admin2);
// 10 vendor instances for delivering token purchases
require (_vendors.length == 10);
totalSupply = 0;
// define state
STTadmin1 = _admin1;
STTadmin2 = _admin2;
for (uint8 i = 0; i < _vendors.length; i++){
vendors[_vendors[i]] = true;
vendorCount++;
}
}
// Overridden method to check for end of fundraising before allowing transfer of tokens
function transfer(address _to, uint256 _value)
public
isTransferable // Only allow token transfer after the fundraising has ended
returns (bool success)
{
bool result = super.transfer(_to, _value);
if (result) {
trackHolder(_to); // track the owner for later payouts
}
return result;
}
// Overridden method to check for end of fundraising before allowing transfer of tokens
function transferFrom(address _from, address _to, uint256 _value)
public
isTransferable // Only allow token transfer after the fundraising has ended
returns (bool success)
{
bool result = super.transferFrom(_from, _to, _value);
if (result) {
trackHolder(_to); // track the owner for later payouts
}
return result;
}
// Allow for easier balance checking
function getBalanceOf(address _owner)
public
view
returns (uint256 _balance)
{
return balances[_owner];
}
// Perform an atomic swap between two token contracts
function relocate()
external
{
// Check if relocation was activated
require (relocationActive == true);
// Define new token contract is
RelocationToken newSTT = RelocationToken(newTokenContractAddress);
// Burn the old balance
uint256 balance = balances[msg.sender];
balances[msg.sender] = 0;
// Perform the relocation of balances to new contract
require(newSTT.recieveRelocation(msg.sender, balance));
}
// Allows to figure out the amount of known token holders
function getHolderCount()
public
view
returns (uint256 _holderCount)
{
return holders.length;
}
// Allows for easier retrieval of holder by array index
function getHolder(uint256 _index)
public
view
returns (address _holder)
{
return holders[_index];
}
function trackHolder(address _to)
private
returns (bool success)
{
// Check if the recipient is a known token holder
if (isHolder[_to] == false) {
// if not, add him to the holders array and mark him as a known holder
holders.push(_to);
isHolder[_to] = true;
}
return true;
}
/// @dev delivers STT tokens from Leondra (Leondrino Exchange Germany)
function deliverTokens(address _buyer, uint256 _amount)
external
onlyVendor
{
require(_amount >= TOKEN_MIN);
uint256 checkedSupply = SafeMath.add(totalSupply, _amount);
require(checkedSupply <= TOKEN_CREATION_CAP);
// Adjust the balance
uint256 oldBalance = balances[_buyer];
balances[_buyer] = SafeMath.add(oldBalance, _amount);
totalSupply = checkedSupply;
trackHolder(_buyer);
// Log the creation of these tokens
emit LogDeliverSTT(_buyer, _amount);
}
/// @dev Creates new STT tokens
function deliverTokensBatch(address[] _buyer, uint256[] _amount)
external
onlyVendor
{
require(_buyer.length == _amount.length);
for (uint8 i=0; i < _buyer.length; i++) {
require(_amount[i] >= TOKEN_MIN);
require(_buyer[i] != 0x0);
uint256 checkedSupply = SafeMath.add(totalSupply, _amount[i]);
require(checkedSupply <= TOKEN_CREATION_CAP);
// Adjust the balance
uint256 oldBalance = balances[_buyer[i]];
balances[_buyer[i]] = SafeMath.add(oldBalance, _amount[i]);
totalSupply = checkedSupply;
trackHolder(_buyer[i]);
// Log the creation of these tokens
emit LogDeliverSTT(_buyer[i], _amount[i]);
}
}
// Allow / Deny transfer of tokens
function transactionSwitch(bool _transactionsActive)
external
onlyOwner
{
transactionsActive = _transactionsActive;
}
// For eventual later moving to another token contract
function relocationSwitch(bool _relocationActive, address _newTokenContractAddress)
external
onlyOwner
{
if (_relocationActive) {
require(_newTokenContractAddress != 0x0);
} else {
require(_newTokenContractAddress == 0x0);
}
relocationActive = _relocationActive;
newTokenContractAddress = _newTokenContractAddress;
}
// Adjust the cap according to the white paper terms (See STT Whitepaper Version 1.0 from 23. May 2018 )
function adjustCap()
external
onlyOwner
{
require (supplyAdjustmentCount < 4);
TOKEN_CREATION_CAP = SafeMath.add(TOKEN_CREATION_CAP, 50 * (10**6) * 10**decimals); // 50 million STTs
supplyAdjustmentCount++;
}
// Burn function - name indicating the burn of ALL owner's tokens
function burnWholeBalance()
external
{
require(balances[msg.sender] >0);
totalSupply = SafeMath.sub(totalSupply, balances[msg.sender]);
balances[msg.sender] = 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment