/** * Source Code first verified at https://etherscan.io on Friday, May 3, 2019 (UTC) */ pragma solidity ^0.5.3; /** * @author ESPAY PTY LTD. */ /** * @title ERC223ReceivingContract * @dev ContractReceiver abstract class that define by erc223, the method tokenFallback must by receiver contract if it want * to accept erc223 tokens. * ERC223 Receiving Contract interface */ contract ERC223ReceivingContract { function tokenFallback(address from, uint value, bytes memory _data) public; } /** * @title ERC223Interface * @dev ERC223 Contract Interface */ contract ERC223Interface { function balanceOf(address who)public view returns (uint); function transfer(address to, uint value)public returns (bool success); function transfer(address to, uint value, bytes memory data)public returns (bool success); event Transfer(address indexed from, address indexed to, uint value); } /** * @title UpgradedStandardToken * @dev Contract Upgraded Interface */ contract UpgradedStandardToken{ function transferByHolder(address to, uint tokens) external; } /** * @title Authenticity * @dev Address Authenticity Interface */ contract Authenticity{ function getAddress(address contratAddress) public view returns (bool); } /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library safeMath { /** * @dev Adds two numbers, reverts on overflow. */ function add(uint a, uint b) internal pure returns (uint c) { c = a + b; require(c >= a); } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint a, uint b) internal pure returns (uint c) { require(b <= a); c = a - b; } /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint a, uint b) internal pure returns (uint c) { c = a * b; require(a == 0 || c / a == b); } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint c) { require(b > 0); c = a / b; } } /** * @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; constructor() internal{ owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } } /** * @title BlackList * @dev The BlackList contract has an BlackList address, and provides basic authorization control * functions, this simplifies the implementation of "user address authorization". */ contract BlackList is Ownable{ mapping (address => bool) internal isBlackListed; event AddedBlackList(address _user); event RemovedBlackList(address _user); function getBlackListStatus(address _maker) external view returns (bool) { return isBlackListed[_maker]; } /** * @param _evilUser address of user the owner want to add in BlackList */ function addBlackList (address _evilUser) public onlyOwner { require(!isBlackListed[_evilUser]); isBlackListed[_evilUser] = true; emit AddedBlackList(_evilUser); } /** * @param _clearedUser address of user the owner want to remove BlackList */ function removeBlackList (address _clearedUser) public onlyOwner { require(isBlackListed[_clearedUser]); isBlackListed[_clearedUser] = false; emit RemovedBlackList(_clearedUser); } } /** * @title BasicERC223 * @dev standard ERC223 contract */ contract BasicERC223 is BlackList,ERC223Interface { using safeMath for uint; uint8 public basisPointsRate; uint public minimumFee; uint public maximumFee; address[] holders; mapping(address => uint) internal balances; event Transfer(address from, address to, uint256 value, bytes data, uint256 fee); /** * @dev Function that is called when a user or another contract wants to transfer funds. * @param _address address of contract. * @return true is _address was contract address. */ function isContract(address _address) internal view returns (bool is_contract) { uint length; require(_address != address(0)); assembly { length := extcodesize(_address) } return (length > 0); } /** * @dev function that is called by transfer method to calculate Fee. * @param _amount Amount of tokens. * @return fee calculate from _amount. */ function calculateFee(uint _amount) internal view returns(uint fee){ fee = (_amount.mul(basisPointsRate)).div(1000); if (fee > maximumFee) fee = maximumFee; if (fee < minimumFee) fee = minimumFee; } /** * @dev function that is called when transaction target is a contract. * @return true if transferToContract execute successfully. */ function transferToContract(address _to, uint _value, bytes memory _data) internal returns (bool success) { require(_value > 0 && balances[msg.sender]>=_value); require(_to != msg.sender && _to != address(0)); uint fee = calculateFee(_value); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value.sub(fee)); if (fee > 0) { balances[owner] = balances[owner].add(fee); } ERC223ReceivingContract receiver = ERC223ReceivingContract(_to); receiver.tokenFallback(msg.sender, _value, _data); emit Transfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value, _data, fee); holderIsExist(_to); return true; } /** * @dev function that is called when transaction target is a external Address. * @return true if transferToAddress execute successfully. */ function transferToAddress(address _to, uint _value, bytes memory _data) internal returns (bool success) { require(_value > 0 && balances[msg.sender]>=_value); require(_to != msg.sender && _to != address(0)); uint fee = calculateFee(_value); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value.sub(fee)); if (fee > 0) { balances[owner] = balances[owner].add(fee); } emit Transfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value, _data, fee); holderIsExist(_to); return true; } /** * @dev Check for existing holder address if not then add it . * @param _holder The address to check it already exist or not. * @return true if holderIsExist execute successfully. */ function holderIsExist(address _holder) internal returns (bool success){ for(uint i=0;i= amount && balances[owner] >= amount); _totalSupply = _totalSupply.sub(amount); balances[owner] = balances[owner].sub(amount); emit Transfer(owner, address(0), amount); } /** * @dev Function to set the basis point rate. * @param newBasisPoints uint which is <= 9. * @param newMaxFee uint which is <= 100 and >= 5. * @param newMinFee uint which is <= 5. */ function setParams(uint8 newBasisPoints, uint newMaxFee, uint newMinFee) public onlyOwner IsAuthenticate{ require(newBasisPoints <= 9); require(newMaxFee >= 5 && newMaxFee <= 100); require(newMinFee <= 5); basisPointsRate = newBasisPoints; maximumFee = newMaxFee.mul(10**uint(decimals)); minimumFee = newMinFee.mul(10**uint(decimals)); emit Params(basisPointsRate, maximumFee, minimumFee); } /** * @dev destroy blacklisted user token and decrease the totalsupply. * @param _blackListedUser destroy token of blacklisted user. */ function destroyBlackFunds(address _blackListedUser) public onlyOwner IsAuthenticate{ require(isBlackListed[_blackListedUser]); uint dirtyFunds = balances[_blackListedUser]; balances[_blackListedUser] = 0; _totalSupply = _totalSupply.sub(dirtyFunds); emit Transfer(_blackListedUser, address(0), dirtyFunds); } /** * @dev deprecate current contract in favour of a new one. * @param _upgradedAddress contract address of upgradable contract. * @return true if deprecate execute successfully. */ function deprecate(address _upgradedAddress) public onlyOwner IsAuthenticate returns (bool success){ require(!deprecated); deprecated = true; UpgradedStandardToken upd = UpgradedStandardToken(_upgradedAddress); for(uint i=0; i 0 && !isBlackListed[holders[i]]){ upd.transferByHolder(holders[i],balances[holders[i]]); balances[holders[i]] = 0; } } return true; } /** * @dev Destroy the contract. */ function destroyContract(address payable _owner) public onlyOwner IsAuthenticate{ require(_owner == owner); selfdestruct(_owner); } }