ETH Price: $3,297.45 (-1.26%)

Transaction Decoder

Block:
14975104 at Jun-16-2022 07:40:48 PM +UTC
Transaction Fee:
0.00302020992 ETH $9.96
Gas Used:
36,582 Gas / 82.56 Gwei

Emitted Events:

Account State Difference:

  Address   Before After State Difference Code
0x0031e147...6142FCBA1
(Nexo 3)
246.32299814389058695 Eth
Nonce: 849466
246.31997793397058695 Eth
Nonce: 849467
0.00302020992
(Hiveon Pool)
18,184.302310973873703327 Eth18,184.303377596969435157 Eth0.00106662309573183
0xB62132e3...d8d815206

Execution Trace

0x9e21d0d1f44e439a139bcbf901d4cbddc9b133e8.e6d66ac8( )
  • NexoToken.transfer( _to=0x65b0BF8Ee4947edD2A500D74E50a3d757DC79de0, _value=4200231486318510112374 ) => ( success=True )
    pragma solidity 0.4.23;
    
    //
    // This source file is part of the current-contracts open source project
    // Copyright 2018 Zerion LLC
    // Licensed under Apache License v2.0
    //
    
    
    // @title Abstract ERC20 token interface
    contract AbstractToken {
    	function balanceOf(address owner) public view returns (uint256 balance);
    	function transfer(address to, uint256 value) public returns (bool success);
    	function transferFrom(address from, address to, uint256 value) public returns (bool success);
    	function approve(address spender, uint256 value) public returns (bool success);
    	function allowance(address owner, address spender) public view returns (uint256 remaining);
    
    	event Transfer(address indexed from, address indexed to, uint256 value);
    	event Approval(address indexed owner, address indexed spender, uint256 value);
    }
    
    contract Owned {
    
    	address public owner = msg.sender;
    	address public potentialOwner;
    
    	modifier onlyOwner {
    		require(msg.sender == owner);
    		_;
    	}
    
    	modifier onlyPotentialOwner {
    		require(msg.sender == potentialOwner);
    		_;
    	}
    
    	event NewOwner(address old, address current);
    	event NewPotentialOwner(address old, address potential);
    
    	function setOwner(address _new)
    		public
    		onlyOwner
    	{
    		emit NewPotentialOwner(owner, _new);
    		potentialOwner = _new;
    	}
    
    	function confirmOwnership()
    		public
    		onlyPotentialOwner
    	{
    		emit NewOwner(owner, potentialOwner);
    		owner = potentialOwner;
    		potentialOwner = address(0);
    	}
    }
    
    // @title SafeMath contract - Math operations with safety checks.
    // @author OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
    contract SafeMath {
    	/**
    	* @dev Multiplies two numbers, throws on overflow.
    	*/
    	function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    		if (a == 0) {
    			return 0;
    		}
    		uint256 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) {
    		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) {
    		uint256 c = a + b;
    		assert(c >= a);
    		return c;
    	}
    
    	/**
    	* @dev Raises `a` to the `b`th power, throws on overflow.
    	*/
    	function pow(uint256 a, uint256 b) internal pure returns (uint256) {
    		uint256 c = a ** b;
    		assert(c >= a);
    		return c;
    	}
    }
    
    /// Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/issues/20
    contract StandardToken is AbstractToken, Owned, SafeMath {
    
    	/*
    	 *  Data structures
    	 */
    	mapping (address => uint256) internal balances;
    	mapping (address => mapping (address => uint256)) internal allowed;
    	uint256 public totalSupply;
    
    	/*
    	 *  Read and write storage functions
    	 */
    	/// @dev Transfers sender's tokens to a given address. Returns success.
    	/// @param _to Address of token receiver.
    	/// @param _value Number of tokens to transfer.
    	function transfer(address _to, uint256 _value) public returns (bool success) {
    		return _transfer(msg.sender, _to, _value);
    	}
    
    	/// @dev Allows allowed third party to transfer tokens from one address to another. Returns success.
    	/// @param _from Address from where tokens are withdrawn.
    	/// @param _to Address to where tokens are sent.
    	/// @param _value Number of tokens to transfer.
    	function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    		require(allowed[_from][msg.sender] >= _value);
    		allowed[_from][msg.sender] -= _value;
    
    		return _transfer(_from, _to, _value);
    	}
    
    	/// @dev Returns number of tokens owned by given address.
    	/// @param _owner Address of token owner.
    	function balanceOf(address _owner) public view returns (uint256 balance) {
    		return balances[_owner];
    	}
    
    	/// @dev Sets approved amount of tokens for spender. Returns success.
    	/// @param _spender Address of allowed account.
    	/// @param _value Number of approved tokens.
    	function approve(address _spender, uint256 _value) public returns (bool success) {
    		allowed[msg.sender][_spender] = _value;
    		emit Approval(msg.sender, _spender, _value);
    		return true;
    	}
    
    	/*
    	 * Read storage functions
    	 */
    	/// @dev Returns number of allowed tokens for given address.
    	/// @param _owner Address of token owner.
    	/// @param _spender Address of token spender.
    	function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
    		return allowed[_owner][_spender];
    	}
    
    	/**
    	* @dev Private transfer, can only be called by this contract.
    	* @param _from The address of the sender.
    	* @param _to The address of the recipient.
    	* @param _value The amount to send.
    	* @return success True if the transfer was successful, or throws.
    	*/
    	function _transfer(address _from, address _to, uint256 _value) private returns (bool success) {
    		require(_to != address(0));
    		require(balances[_from] >= _value);
    		balances[_from] -= _value;
    		balances[_to] = add(balances[_to], _value);
    		emit Transfer(_from, _to, _value);
    		return true;
    	}
    }
    
    /// @title Token contract - Implements Standard ERC20 with additional features.
    /// @author Zerion - <[email protected]>
    contract Token is StandardToken {
    
    	// Time of the contract creation
    	uint256 public creationTime;
    
    	function Token() public {
    		/* solium-disable-next-line security/no-block-members */
    		creationTime = now;
    	}
    
    	/// @dev Owner can transfer out any accidentally sent ERC20 tokens
    	function transferERC20Token(AbstractToken _token, address _to, uint256 _value)
    		public
    		onlyOwner
    		returns (bool success)
    	{
    		require(_token.balanceOf(address(this)) >= _value);
    		uint256 receiverBalance = _token.balanceOf(_to);
    		require(_token.transfer(_to, _value));
    
    		uint256 receiverNewBalance = _token.balanceOf(_to);
    		assert(receiverNewBalance == add(receiverBalance, _value));
    
    		return true;
    	}
    
    	/// @dev Increases approved amount of tokens for spender. Returns success.
    	function increaseApproval(address _spender, uint256 _value) public returns (bool success) {
    		allowed[msg.sender][_spender] = add(allowed[msg.sender][_spender], _value);
    		emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    		return true;
    	}
    
    	/// @dev Decreases approved amount of tokens for spender. Returns success.
    	function decreaseApproval(address _spender, uint256 _value) public returns (bool success) {
    		uint256 oldValue = allowed[msg.sender][_spender];
    		if (_value > oldValue) {
    			allowed[msg.sender][_spender] = 0;
    		} else {
    			allowed[msg.sender][_spender] = sub(oldValue, _value);
    		}
    		emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    		return true;
    	}
    }
    
    // @title Token contract - Implements Standard ERC20 Token for NEXO project.
    /// @author Zerion - <[email protected]>
    contract NexoToken is Token {
    
    	/// TOKEN META DATA
    	string constant public name = 'Nexo';
    	string constant public symbol = 'NEXO';
    	uint8  constant public decimals = 18;
    
    
    	/// ALOCATIONS
    	// To calculate vesting periods we assume that 1 month is always equal to 30 days 
    
    
    	/*** Initial Investors' tokens ***/
    
    	// 525,000,000 (52.50%) tokens are distributed among initial investors
    	// These tokens will be distributed without vesting
    
    	address public investorsAllocation = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF);
    	uint256 public investorsTotal = 525000000e18;
    
    
    	/*** Overdraft Reserves ***/
    
    	// 250,000,000 (25%) tokens will be eventually available for overdraft
    	// These tokens will be distributed monthly with a 6 month cliff within a year
    	// 41,666,666 tokens will be unlocked every month after the cliff
    	// 4 tokens will be unlocked without vesting to ensure that total amount sums up to 250,000,000.
    
    	address public overdraftAllocation = address(0x1111111111111111111111111111111111111111);
    	uint256 public overdraftTotal = 250000000e18;
    	uint256 public overdraftPeriodAmount = 41666666e18;
    	uint256 public overdraftUnvested = 4e18;
    	uint256 public overdraftCliff = 5 * 30 days;
    	uint256 public overdraftPeriodLength = 30 days;
    	uint8   public overdraftPeriodsNumber = 6;
    
    
    	/*** Tokens reserved for Founders and Team ***/
    
    	// 112,500,000 (11.25%) tokens will be eventually available for the team
    	// These tokens will be distributed every 3 month without a cliff within 4 years
    	// 7,031,250 tokens will be unlocked every 3 month
    
    	address public teamAllocation  = address(0x2222222222222222222222222222222222222222);
    	uint256 public teamTotal = 112500000e18;
    	uint256 public teamPeriodAmount = 7031250e18;
    	uint256 public teamUnvested = 0;
    	uint256 public teamCliff = 0;
    	uint256 public teamPeriodLength = 3 * 30 days;
    	uint8   public teamPeriodsNumber = 16;
    
    
    
    	/*** Tokens reserved for Community Building and Airdrop Campaigns ***/
    
    	// 60,000,000 (6%) tokens will be eventually available for the community
    	// 10,000,002 tokens will be available instantly without vesting
    	// 49,999,998 tokens will be distributed every 3 month without a cliff within 18 months
    	// 8,333,333 tokens will be unlocked every 3 month
    
    
    	address public communityAllocation  = address(0x3333333333333333333333333333333333333333);
    	uint256 public communityTotal = 60000000e18;
    	uint256 public communityPeriodAmount = 8333333e18;
    	uint256 public communityUnvested = 10000002e18;
    	uint256 public communityCliff = 0;
    	uint256 public communityPeriodLength = 3 * 30 days;
    	uint8   public communityPeriodsNumber = 6;
    
    
    
    	/*** Tokens reserved for Advisors, Legal and PR ***/
    
    	// 52,500,000 (5.25%) tokens will be eventually available for advisers
    	// 25,000,008 tokens will be available instantly without vesting
    	// 27 499 992 tokens will be distributed monthly without a cliff within 12 months
    	// 2,291,666 tokens will be unlocked every month
    
    	address public advisersAllocation  = address(0x4444444444444444444444444444444444444444);
    	uint256 public advisersTotal = 52500000e18;
    	uint256 public advisersPeriodAmount = 2291666e18;
    	uint256 public advisersUnvested = 25000008e18;
    	uint256 public advisersCliff = 0;
    	uint256 public advisersPeriodLength = 30 days;
    	uint8   public advisersPeriodsNumber = 12;
    
    
    	/// CONSTRUCTOR
    
    	function NexoToken() public {
    		//  Overall, 1,000,000,000 tokens exist
    		totalSupply = 1000000000e18;
    
    		balances[investorsAllocation] = investorsTotal;
    		balances[overdraftAllocation] = overdraftTotal;
    		balances[teamAllocation] = teamTotal;
    		balances[communityAllocation] = communityTotal;
    		balances[advisersAllocation] = advisersTotal;
    
    		// Unlock some tokens without vesting
    		allowed[investorsAllocation][msg.sender] = investorsTotal;
    		allowed[overdraftAllocation][msg.sender] = overdraftUnvested;
    		allowed[communityAllocation][msg.sender] = communityUnvested;
    		allowed[advisersAllocation][msg.sender] = advisersUnvested;
    	}
    
    	/// DISTRIBUTION
    
    	function distributeInvestorsTokens(address _to, uint256 _amountWithDecimals)
    		public
    		onlyOwner
    	{
    		require(transferFrom(investorsAllocation, _to, _amountWithDecimals));
    	}
    
    	/// VESTING
    
    	function withdrawOverdraftTokens(address _to, uint256 _amountWithDecimals)
    		public
    		onlyOwner
    	{
    		allowed[overdraftAllocation][msg.sender] = allowance(overdraftAllocation, msg.sender);
    		require(transferFrom(overdraftAllocation, _to, _amountWithDecimals));
    	}
    
    	function withdrawTeamTokens(address _to, uint256 _amountWithDecimals)
    		public
    		onlyOwner 
    	{
    		allowed[teamAllocation][msg.sender] = allowance(teamAllocation, msg.sender);
    		require(transferFrom(teamAllocation, _to, _amountWithDecimals));
    	}
    
    	function withdrawCommunityTokens(address _to, uint256 _amountWithDecimals)
    		public
    		onlyOwner 
    	{
    		allowed[communityAllocation][msg.sender] = allowance(communityAllocation, msg.sender);
    		require(transferFrom(communityAllocation, _to, _amountWithDecimals));
    	}
    
    	function withdrawAdvisersTokens(address _to, uint256 _amountWithDecimals)
    		public
    		onlyOwner 
    	{
    		allowed[advisersAllocation][msg.sender] = allowance(advisersAllocation, msg.sender);
    		require(transferFrom(advisersAllocation, _to, _amountWithDecimals));
    	}
    
    	/// @dev Overrides StandardToken.sol function
    	function allowance(address _owner, address _spender)
    		public
    		view
    		returns (uint256 remaining)
    	{   
    		if (_spender != owner) {
    			return allowed[_owner][_spender];
    		}
    
    		uint256 unlockedTokens;
    		uint256 spentTokens;
    
    		if (_owner == overdraftAllocation) {
    			unlockedTokens = _calculateUnlockedTokens(
    				overdraftCliff,
    				overdraftPeriodLength,
    				overdraftPeriodAmount,
    				overdraftPeriodsNumber,
    				overdraftUnvested
    			);
    			spentTokens = sub(overdraftTotal, balanceOf(overdraftAllocation));
    		} else if (_owner == teamAllocation) {
    			unlockedTokens = _calculateUnlockedTokens(
    				teamCliff,
    				teamPeriodLength,
    				teamPeriodAmount,
    				teamPeriodsNumber,
    				teamUnvested
    			);
    			spentTokens = sub(teamTotal, balanceOf(teamAllocation));
    		} else if (_owner == communityAllocation) {
    			unlockedTokens = _calculateUnlockedTokens(
    				communityCliff,
    				communityPeriodLength,
    				communityPeriodAmount,
    				communityPeriodsNumber,
    				communityUnvested
    			);
    			spentTokens = sub(communityTotal, balanceOf(communityAllocation));
    		} else if (_owner == advisersAllocation) {
    			unlockedTokens = _calculateUnlockedTokens(
    				advisersCliff,
    				advisersPeriodLength,
    				advisersPeriodAmount,
    				advisersPeriodsNumber,
    				advisersUnvested
    			);
    			spentTokens = sub(advisersTotal, balanceOf(advisersAllocation));
    		} else {
    			return allowed[_owner][_spender];
    		}
    
    		return sub(unlockedTokens, spentTokens);
    	}
    
    	/// @dev Overrides Owned.sol function
    	function confirmOwnership()
    		public
    		onlyPotentialOwner
    	{   
    		// Forbid the old owner to distribute investors' tokens
    		allowed[investorsAllocation][owner] = 0;
    
    		// Allow the new owner to distribute investors' tokens
    		allowed[investorsAllocation][msg.sender] = balanceOf(investorsAllocation);
    
    		// Forbid the old owner to withdraw any tokens from the reserves
    		allowed[overdraftAllocation][owner] = 0;
    		allowed[teamAllocation][owner] = 0;
    		allowed[communityAllocation][owner] = 0;
    		allowed[advisersAllocation][owner] = 0;
    
    		super.confirmOwnership();
    	}
    
    	function _calculateUnlockedTokens(
    		uint256 _cliff,
    		uint256 _periodLength,
    		uint256 _periodAmount,
    		uint8 _periodsNumber,
    		uint256 _unvestedAmount
    	)
    		private
    		view
    		returns (uint256) 
    	{
    		/* solium-disable-next-line security/no-block-members */
    		if (now < add(creationTime, _cliff)) {
    			return _unvestedAmount;
    		}
    		/* solium-disable-next-line security/no-block-members */
    		uint256 periods = div(sub(now, add(creationTime, _cliff)), _periodLength);
    		periods = periods > _periodsNumber ? _periodsNumber : periods;
    		return add(_unvestedAmount, mul(periods, _periodAmount));
    	}
    }