pragma solidity ^0.4.24; import "../math/SafeMath.sol"; import "../ownership/Ownable.sol"; import "./ElectroJewel.sol"; interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; } contract ERC20Token { using SafeMath for uint; string public name; string public symbol; uint8 public decimals = 18; uint256 public totalSupply; address public jewels; uint public difficulty = 10**28; uint public minTransactions = 5; uint public minAmount = 100000; struct transfers{ uint128 amount; uint64 time; } struct _transfers{ uint amountOverTime; uint transactions; uint timeSinceLastMint; uint noOfMints; uint[] transactionTimes; } mapping(address => transfers[]) public transferIns; mapping(address => uint256) public balanceOf; mapping(address => mapping (address => uint256)) public allowance; mapping(address => _transfers) public __transfers; event Transfer(address indexed from, address indexed to, uint256 value); event Burn(address indexed from, uint256 value); /** * @dev Constructor that gives msg.sender all of existing tokens. */ constructor( uint256 initialSupply, string tokenName, string tokenSymbol ) public { totalSupply = initialSupply * 10 ** uint256(decimals); balanceOf[msg.sender] = totalSupply; name = tokenName; symbol = tokenSymbol; } function logTransaction(uint _value, address _to) internal { if(transferIns[msg.sender].length > 0) delete transferIns[msg.sender]; uint64 _now = uint64(now); __transfers[msg.sender].transactions++; __transfers[msg.sender].amountOverTime += _value; __transfers[msg.sender].transactionTimes.push(now); transferIns[msg.sender].push(transfers(uint128(balanceOf[msg.sender]),_now)); transferIns[_to].push(transfers(uint128(_value),_now)); } function _transfer(address _from, address _to, uint _value) internal { require(_to != 0x0); require(balanceOf[_from] >= _value); require(balanceOf[_to] + _value > balanceOf[_to]); uint previousBalances = balanceOf[_from].add(balanceOf[_to]); balanceOf[_from] -= _value; balanceOf[_to] += _value; emit Transfer(_from, _to, _value); assert(balanceOf[_from] + balanceOf[_to] == previousBalances); logTransaction(_value, _to); } function checkLogs(address _sender) view external returns(bool) { return transferIns[_sender].length > 0; } function transferLength(address _sender) view external returns(uint) { return transferIns[_sender].length; } function getPOSTokenAge(address _addr, uint _now, uint stakeMinAge, uint stakeMaxAge) external view returns (uint _coinAge){ require(transferIns[_addr].length > 0); for (uint i = 0; i <transferIns[_addr].length; i++){ if(_now < uint(transferIns[_addr][i].time).add(stakeMinAge)) continue; uint nCoinsSeconds = _now.sub(uint(transferIns[_addr][i].time)); if( nCoinsSeconds > stakeMaxAge ) nCoinsSeconds = stakeMaxAge; _coinAge = _coinAge.add(uint(transferIns[_addr][i].amount) * nCoinsSeconds.div(1 days)); } } function checkTransactionTimes(address _addr, uint _now) internal returns(uint t){ require(transferIns[_addr].length > 0); for (uint i = 0; i <transferIns[_addr].length; i++){ if(_now < uint(transferIns[_addr][i].time).add(10 hours)) continue; uint nCoinsSeconds = _now.sub(uint(transferIns[_addr][i].time)); if( nCoinsSeconds > 2 days ) nCoinsSeconds = 2 days; t = t.add(uint(transferIns[_addr][i].amount) * nCoinsSeconds.div(1 days)); } } function getPOUTokenWeight(address _addr) external returns (uint _tokenWeight){ uint z; uint w; //require(now - transferIns[_addr].time >= 10 hours); require(__transfers[_addr].transactions > 0 && __transfers[_addr].transactions >= minTransactions); require(__transfers[_addr].amountOverTime > __transfers[_addr].transactions && __transfers[_addr].amountOverTime >= minAmount); uint _tokenRatio = (__transfers[_addr].amountOverTime).mul(__transfers[_addr].transactions); bytes8 n = bytes8(sha256(block.number,_tokenWeight)); require(n >= bytes8(difficulty)); uint _timeSinceLastMint = __transfers[_addr].timeSinceLastMint; if(_timeSinceLastMint !=0 ){ uint lastTime = now - _timeSinceLastMint; require(lastTime >= 30 days); z = (block.difficulty).div(_tokenRatio); w = (z + 1) / 2; _tokenWeight = z; while(w < _tokenWeight) { _tokenWeight = w; w = (z / w + w) / 2;} difficulty = difficulty.mul(25 minutes).div(lastTime + 1); __transfers[_addr].timeSinceLastMint = now; } else { z = (block.difficulty).div(_tokenRatio); w = (z + 1) / 2; _tokenWeight = z; while(w < _tokenWeight) { _tokenWeight = w; w = (z / w + w) / 2; } difficulty = difficulty.mul(25 minutes).div(500 seconds + 1); __transfers[_addr].timeSinceLastMint = now; __transfers[_addr].amountOverTime = 0; __transfers[_addr].transactions = 0; } } /** * Transfer tokens * * Send `_value` tokens to `_to` from your account * * @param _to The address of the recipient * * @param _value the amount to send */ function transfer(address _to, uint256 _value) public { _transfer(msg.sender, _to, _value); } /** * Transfer tokens from other address * * Send `_value` tokens to `_to` in behalf of `_from` * * @param _from The address of the sender * @param _to The address of the recipient * @param _value the amount to send */ function transferFrom(address _from, address _to, uint256 _value) public returns(bool success) { require (_value <= allowance[_from][msg.sender]); allowance[_from][msg.sender] -= _value; _transfer(_from, _to, _value); return true; } /** * Set allowance for other address * * Allows `_spender` to spend no more than `_value` tokens in your behalf * * @param _spender The address authorized to spend * @param _value the max amount they can spend */ function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } /** * Set allowance for other address and notify * * Allows `_spender` to spend no more than `_value` tokens in your behalf, and then ping the contract about it * * @param _spender The address authorized to spend * @param _value the max amount they can spend * @param _extraData some extra information to send to the approved contract */ function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) { tokenRecipient spender = tokenRecipient(_spender); if (approve (_spender, _value)) { spender.receiveApproval(msg.sender, _value, this, _extraData); return true; } } /** * Destroy tokens * * Remove `_value` tokens from the system irreversibly * * @param _value the amount of money to burn */ function burn(uint256 _value) public returns (bool success) { require (balanceOf[msg.sender] >= _value); balanceOf[msg.sender] -= _value; emit Burn(msg.sender, _value); return true; } /** * Destroy tokens from other account * * Remove `_value` tokens from the system irreversibly on behalf of `_from`. * * @param _from the address of the sender * @param _value the amount of money to burn */ function burnFrom(address _from, uint256 _value) public returns (bool success) { require(balanceOf[_from] >= _value); // Check if the targeted balance is enough require(_value <= allowance[_from][msg.sender]); // Check allowance balanceOf[_from] -= _value; // Subtract from the targeted balance allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance totalSupply -= _value; // Update totalSupply emit Burn(_from, _value); return true; } } contract ElectroGem is ERC20Token,Ownable { ElectroJewel gems; mapping (address => bool) public frozenAccount; event FrozenFunds(address target, bool frozen); constructor ( uint256 initialSupply, string tokenName, string tokenSymbol) ERC20Token(initialSupply, tokenName, tokenSymbol) public {} /* Internal transfer, only can be called by this contract */ function _transfer(address _from, address _to, uint _value) internal { require (_to != 0x0); // Prevent transfer to 0x0 address. Use burn() instead require (balanceOf[_from] >= _value); // Check if the sender has enough require (balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows require(!frozenAccount[_from]); // Check if sender is frozen require(!frozenAccount[_to]); // Check if recipient is frozen balanceOf[_from] -= _value; // Subtract from the sender balanceOf[_to] += _value; // Add the same to the recipient emit Transfer(_from, _to, _value); } function mint(address target, uint256 mintedAmount) public onlyOwner { balanceOf[target] += mintedAmount; totalSupply += mintedAmount; emit Transfer(0, target, mintedAmount); } /// @notice `freeze? Prevent | Allow` `target` from sending & receiving tokens /// @param target Address to be frozen /// @param freeze either to freeze it or not function freezeAccount(address target, bool freeze) onlyOwner public { frozenAccount[target] = freeze; emit FrozenFunds(target, freeze); } }
0.4.18