Transaction Hash:
Block:
10593336 at Aug-04-2020 12:46:28 PM +UTC
Transaction Fee:
0.004827004259763556 ETH
$11.65
Gas Used:
59,111 Gas / 81.659999996 Gwei
Emitted Events:
64 |
ShareToken.Transfer( _from=[Sender] 0x6b50aa75c593f72a2ec022ab0be72949d13cc927, _to=0x901B2b41194Dc5228d923346D253C2C191243932, _value=4359100 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 507.822435679749170284 Eth | 507.82726268400893384 Eth | 0.004827004259763556 | |
0x6B50aa75...9d13cc927 |
3.99238425000037 Eth
Nonce: 4
|
3.987557245740606444 Eth
Nonce: 5
| 0.004827004259763556 | ||
0xEE5fE244...56630beFC |
Execution Trace
ShareToken.transfer( _to=0x901B2b41194Dc5228d923346D253C2C191243932, _amount=4359100 ) => ( success=True )
transfer[ShareToken (ln:326)]
isLocked[ShareToken (ln:328)]
isWhitelisted[ShareToken (ln:296)]
isLocked[ShareToken (ln:329)]
isWhitelisted[ShareToken (ln:296)]
transfer[ShareToken (ln:331)]
pragma solidity ^0.4.21; contract ERC20Interface { event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); function totalSupply() public view returns (uint256); function balanceOf(address _owner) public view returns (uint256); function transfer(address _to, uint256 _value) public returns (bool); function transferFrom(address _from, address _to, uint256 _value) public returns (bool); function approve(address _spender, uint256 _value) public returns (bool); function allowance(address _owner, address _spender) public view returns (uint256); } contract ERC20Token is ERC20Interface { using SafeMath for uint256; // Total amount of tokens issued uint256 internal totalTokenIssued; mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) internal allowed; function totalSupply() public view returns (uint256) { return totalTokenIssued; } /* Get the account balance for an address */ function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } /* Check whether an address is a contract address */ function isContract(address addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return (size > 0); } /* Transfer the balance from owner's account to another account */ function transfer(address _to, uint256 _amount) public returns (bool) { require(_to != address(0x0)); // Do not allow to transfer token to contract address to avoid tokens getting stuck require(isContract(_to) == false); // amount sent cannot exceed balance require(balances[msg.sender] >= _amount); // update balances balances[msg.sender] = balances[msg.sender].sub(_amount); balances[_to] = balances[_to].add(_amount); // log event emit Transfer(msg.sender, _to, _amount); return true; } /* Allow _spender to withdraw from your account up to _amount */ function approve(address _spender, uint256 _amount) public returns (bool) { require(_spender != address(0x0)); // update allowed amount allowed[msg.sender][_spender] = _amount; // log event emit Approval(msg.sender, _spender, _amount); return true; } /* Spender of tokens transfers tokens from the owner's balance */ /* Must be pre-approved by owner */ function transferFrom(address _from, address _to, uint256 _amount) public returns (bool) { require(_to != address(0x0)); // Do not allow to transfer token to contract address to avoid tokens getting stuck require(isContract(_to) == false); // balance checks require(balances[_from] >= _amount); require(allowed[_from][msg.sender] >= _amount); // update balances and allowed amount balances[_from] = balances[_from].sub(_amount); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amount); balances[_to] = balances[_to].add(_amount); // log event emit Transfer(_from, _to, _amount); return true; } /* Returns the amount of tokens approved by the owner */ /* that can be transferred by spender */ function allowance(address _owner, address _spender) public view returns (uint256) { return allowed[_owner][_spender]; } } 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. */ function Ownable() 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); } } library SafeMath { function mul(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a * b; assert(a == 0 || c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 return (a / b); } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return (a - b); } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } } contract WhiteListManager is Ownable { // The list here will be updated by multiple separate WhiteList contracts mapping (address => bool) public list; function unset(address addr) public onlyOwner { list[addr] = false; } function unsetMany(address[] addrList) public onlyOwner { for (uint256 i = 0; i < addrList.length; i++) { unset(addrList[i]); } } function set(address addr) public onlyOwner { list[addr] = true; } function setMany(address[] addrList) public onlyOwner { for (uint256 i = 0; i < addrList.length; i++) { set(addrList[i]); } } function isWhitelisted(address addr) public view returns (bool) { return list[addr]; } } contract ShareToken is ERC20Token, WhiteListManager { using SafeMath for uint256; string public constant name = "ShareToken"; string public constant symbol = "SHR"; uint8 public constant decimals = 2; address public icoContract; // Any token amount must be multiplied by this const to reflect decimals uint256 constant E2 = 10**2; mapping(address => bool) public rewardTokenLocked; bool public mainSaleTokenLocked = true; uint256 public constant TOKEN_SUPPLY_MAINSALE_LIMIT = 1000000000 * E2; // 1,000,000,000 tokens (1 billion) uint256 public constant TOKEN_SUPPLY_AIRDROP_LIMIT = 6666666667; // 66,666,666.67 tokens (0.066 billion) uint256 public constant TOKEN_SUPPLY_BOUNTY_LIMIT = 33333333333; // 333,333,333.33 tokens (0.333 billion) uint256 public airDropTokenIssuedTotal; uint256 public bountyTokenIssuedTotal; uint256 public constant TOKEN_SUPPLY_SEED_LIMIT = 500000000 * E2; // 500,000,000 tokens (0.5 billion) uint256 public constant TOKEN_SUPPLY_PRESALE_LIMIT = 2500000000 * E2; // 2,500,000,000.00 tokens (2.5 billion) uint256 public constant TOKEN_SUPPLY_SEED_PRESALE_LIMIT = TOKEN_SUPPLY_SEED_LIMIT + TOKEN_SUPPLY_PRESALE_LIMIT; uint256 public seedAndPresaleTokenIssuedTotal; uint8 private constant PRESALE_EVENT = 0; uint8 private constant MAINSALE_EVENT = 1; uint8 private constant BOUNTY_EVENT = 2; uint8 private constant AIRDROP_EVENT = 3; function ShareToken() public { totalTokenIssued = 0; airDropTokenIssuedTotal = 0; bountyTokenIssuedTotal = 0; seedAndPresaleTokenIssuedTotal = 0; mainSaleTokenLocked = true; } function unlockMainSaleToken() public onlyOwner { mainSaleTokenLocked = false; } function lockMainSaleToken() public onlyOwner { mainSaleTokenLocked = true; } function unlockRewardToken(address addr) public onlyOwner { rewardTokenLocked[addr] = false; } function unlockRewardTokenMany(address[] addrList) public onlyOwner { for (uint256 i = 0; i < addrList.length; i++) { unlockRewardToken(addrList[i]); } } function lockRewardToken(address addr) public onlyOwner { rewardTokenLocked[addr] = true; } function lockRewardTokenMany(address[] addrList) public onlyOwner { for (uint256 i = 0; i < addrList.length; i++) { lockRewardToken(addrList[i]); } } // Check if a given address is locked. The address can be in the whitelist or in the reward function isLocked(address addr) public view returns (bool) { // Main sale is running, any addr is locked if (mainSaleTokenLocked) { return true; } else { // Main sale is ended and thus any whitelist addr is unlocked if (isWhitelisted(addr)) { return false; } else { // If the addr is in the reward, it must be checked if locked // If the addr is not in the reward, it is considered unlocked return rewardTokenLocked[addr]; } } } function totalSupply() public view returns (uint256) { return totalTokenIssued.add(seedAndPresaleTokenIssuedTotal).add(airDropTokenIssuedTotal).add(bountyTokenIssuedTotal); } function totalMainSaleTokenIssued() public view returns (uint256) { return totalTokenIssued; } function totalMainSaleTokenLimit() public view returns (uint256) { return TOKEN_SUPPLY_MAINSALE_LIMIT; } function totalPreSaleTokenIssued() public view returns (uint256) { return seedAndPresaleTokenIssuedTotal; } function transfer(address _to, uint256 _amount) public returns (bool success) { require(isLocked(msg.sender) == false); require(isLocked(_to) == false); return super.transfer(_to, _amount); } function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success) { require(isLocked(_from) == false); require(isLocked(_to) == false); return super.transferFrom(_from, _to, _amount); } function setIcoContract(address _icoContract) public onlyOwner { // Allow to set the ICO contract only once require(icoContract == address(0)); require(_icoContract != address(0)); icoContract = _icoContract; } function sell(address buyer, uint256 tokens) public returns (bool success) { require (icoContract != address(0)); // The sell() method can only be called by the fixedly-set ICO contract require (msg.sender == icoContract); require (tokens > 0); require (buyer != address(0)); // Only whitelisted address can buy tokens. Otherwise, refund require (isWhitelisted(buyer)); require (totalTokenIssued.add(tokens) <= TOKEN_SUPPLY_MAINSALE_LIMIT); // Register tokens issued to the buyer balances[buyer] = balances[buyer].add(tokens); // Update total amount of tokens issued totalTokenIssued = totalTokenIssued.add(tokens); emit Transfer(address(MAINSALE_EVENT), buyer, tokens); return true; } function rewardAirdrop(address _to, uint256 _amount) public onlyOwner { // this check also ascertains _amount is positive require(_amount <= TOKEN_SUPPLY_AIRDROP_LIMIT); require(airDropTokenIssuedTotal < TOKEN_SUPPLY_AIRDROP_LIMIT); uint256 remainingTokens = TOKEN_SUPPLY_AIRDROP_LIMIT.sub(airDropTokenIssuedTotal); if (_amount > remainingTokens) { _amount = remainingTokens; } // Register tokens to the receiver balances[_to] = balances[_to].add(_amount); // Update total amount of tokens issued airDropTokenIssuedTotal = airDropTokenIssuedTotal.add(_amount); // Lock the receiver rewardTokenLocked[_to] = true; emit Transfer(address(AIRDROP_EVENT), _to, _amount); } function rewardBounty(address _to, uint256 _amount) public onlyOwner { // this check also ascertains _amount is positive require(_amount <= TOKEN_SUPPLY_BOUNTY_LIMIT); require(bountyTokenIssuedTotal < TOKEN_SUPPLY_BOUNTY_LIMIT); uint256 remainingTokens = TOKEN_SUPPLY_BOUNTY_LIMIT.sub(bountyTokenIssuedTotal); if (_amount > remainingTokens) { _amount = remainingTokens; } // Register tokens to the receiver balances[_to] = balances[_to].add(_amount); // Update total amount of tokens issued bountyTokenIssuedTotal = bountyTokenIssuedTotal.add(_amount); // Lock the receiver rewardTokenLocked[_to] = true; emit Transfer(address(BOUNTY_EVENT), _to, _amount); } function rewardBountyMany(address[] addrList, uint256[] amountList) public onlyOwner { require(addrList.length == amountList.length); for (uint256 i = 0; i < addrList.length; i++) { rewardBounty(addrList[i], amountList[i]); } } function rewardAirdropMany(address[] addrList, uint256[] amountList) public onlyOwner { require(addrList.length == amountList.length); for (uint256 i = 0; i < addrList.length; i++) { rewardAirdrop(addrList[i], amountList[i]); } } function handlePresaleToken(address _to, uint256 _amount) public onlyOwner { require(_amount <= TOKEN_SUPPLY_SEED_PRESALE_LIMIT); require(seedAndPresaleTokenIssuedTotal < TOKEN_SUPPLY_SEED_PRESALE_LIMIT); uint256 remainingTokens = TOKEN_SUPPLY_SEED_PRESALE_LIMIT.sub(seedAndPresaleTokenIssuedTotal); require (_amount <= remainingTokens); // Register tokens to the receiver balances[_to] = balances[_to].add(_amount); // Update total amount of tokens issued seedAndPresaleTokenIssuedTotal = seedAndPresaleTokenIssuedTotal.add(_amount); emit Transfer(address(PRESALE_EVENT), _to, _amount); // Also add to whitelist set(_to); } function handlePresaleTokenMany(address[] addrList, uint256[] amountList) public onlyOwner { require(addrList.length == amountList.length); for (uint256 i = 0; i < addrList.length; i++) { handlePresaleToken(addrList[i], amountList[i]); } } }