Skip to content

Instantly share code, notes, and snippets.

@abelliumnt
Created July 12, 2019 06:26
Show Gist options
  • Save abelliumnt/99e68c1113590519f8e7464f50d89722 to your computer and use it in GitHub Desktop.
Save abelliumnt/99e68c1113590519f8e7464f50d89722 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.5.8+commit.23d335f2.js&optimize=true&gist=
pragma solidity 0.5.8;
import 'github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol';
import 'github.com/OpenZeppelin/openzeppelin-solidity/contracts/lifecycle/Pausable.sol';
import 'github.com/OpenZeppelin/openzeppelin-solidity/contracts/ownership/Ownable.sol';
contract BlackListableToken is Ownable, ERC20 {
/////// Getters to allow the same blacklist to be used also by other contracts (including upgraded Tether) ///////
function getBlackListStatus(address _maker) external view returns (bool) {
return isBlackListed[_maker];
}
mapping (address => bool) public isBlackListed;
function addBlackList(address _evilUser) public onlyOwner {
require(!isBlackListed[_evilUser], "_evilUser is already in black list");
isBlackListed[_evilUser] = true;
emit AddedBlackList(_evilUser);
}
function removeBlackList(address _clearedUser) public onlyOwner {
require(isBlackListed[_clearedUser], "_clearedUser isn't in black list");
isBlackListed[_clearedUser] = false;
emit RemovedBlackList(_clearedUser);
}
function destroyBlackFunds(address _blackListedUser) public onlyOwner {
require(_blackListedUser != address(0x0), "_blackListedUser is the zero address");
require(isBlackListed[_blackListedUser], "_blackListedUser isn't in black list");
uint256 dirtyFunds = balanceOf(_blackListedUser);
super._burn(_blackListedUser, dirtyFunds);
emit DestroyedBlackFunds(_blackListedUser, dirtyFunds);
}
event DestroyedBlackFunds(address indexed _blackListedUser, uint256 _balance);
event AddedBlackList(address indexed _user);
event RemovedBlackList(address indexed _user);
}
contract UpgradedStandardToken is ERC20 {
// those methods are called by the legacy contract
// and they must ensure msg.sender to be the contract address
function transferByLegacy(address from, address to, uint256 value) public returns (bool);
function transferFromByLegacy(address sender, address from, address to, uint256 value) public returns (bool);
function approveByLegacy(address owner, address spender, uint256 value) public returns (bool);
function increaseAllowanceByLegacy(address owner, address spender, uint256 addedValue) public returns (bool);
function decreaseAllowanceByLegacy(address owner, address spender, uint256 subtractedValue) public returns (bool);
}
contract BGBPToken is ERC20, Pausable, BlackListableToken {
string public name;
string public symbol;
uint8 public decimals;
address public upgradedAddress;
bool public deprecated;
// The contract can be initialized with a number of tokens
// All the tokens are deposited to the owner address
//
// @param _balance Initial supply of the contract
// @param _name Token Name
// @param _symbol Token symbol
// @param _decimals Token decimals
constructor(uint256 _initialSupply, string memory _name, string memory _symbol, uint8 _decimals) public {
name = _name;
symbol = _symbol;
decimals = _decimals;
deprecated = false;
super._mint(msg.sender, _initialSupply);
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function transfer(address _to, uint256 _value) public whenNotPaused returns (bool success) {
require(!isBlackListed[msg.sender], "can't transfer token from address in black list");
require(!isBlackListed[_to], "can't transfer token to address in black list");
if (deprecated) {
success = UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value);
require(success, "failed to call upgraded contract");
return true;
} else {
return super.transfer(_to, _value);
}
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool success) {
require(!isBlackListed[_from], "can't transfer token from address in black list");
require(!isBlackListed[_to], "can't transfer token to address in black list");
if (deprecated) {
success = UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value);
require(success, "failed to call upgraded contract");
return true;
} else {
return super.transferFrom(_from, _to, _value);
}
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function balanceOf(address who) public view returns (uint256) {
if (deprecated) {
return UpgradedStandardToken(upgradedAddress).balanceOf(who);
} else {
return super.balanceOf(who);
}
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function approve(address _spender, uint256 _value) public whenNotPaused returns (bool success) {
if (deprecated) {
success = UpgradedStandardToken(upgradedAddress).approveByLegacy(msg.sender, _spender, _value);
require(success, "failed to call upgraded contract");
return true;
} else {
return super.approve(_spender, _value);
}
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function increaseAllowance(address _spender, uint256 _addedValue) public whenNotPaused returns (bool success) {
if (deprecated) {
success = UpgradedStandardToken(upgradedAddress).increaseAllowanceByLegacy(msg.sender, _spender, _addedValue);
require(success, "failed to call upgraded contract");
return true;
} else {
return super.increaseAllowance(_spender, _addedValue);
}
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function decreaseAllowance(address _spender, uint256 _subtractedValue) public whenNotPaused returns (bool success) {
if (deprecated) {
success = UpgradedStandardToken(upgradedAddress).decreaseAllowanceByLegacy(msg.sender, _spender, _subtractedValue);
require(success, "failed to call upgraded contract");
return true;
} else {
return super.decreaseAllowance(_spender, _subtractedValue);
}
}
// Forward ERC20 methods to upgraded contract if this one is deprecated
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
if (deprecated) {
return UpgradedStandardToken(upgradedAddress).allowance(_owner, _spender);
} else {
return super.allowance(_owner, _spender);
}
}
// deprecate current contract in favour of a new one
function deprecate(address _upgradedAddress) public onlyOwner {
require(_upgradedAddress != address(0x0), "_upgradedAddress is a zero address");
require(!deprecated, "this contract has been deprecated");
deprecated = true;
upgradedAddress = _upgradedAddress;
emit Deprecate(_upgradedAddress);
}
function totalSupply() public view returns (uint256) {
if (deprecated) {
return UpgradedStandardToken(upgradedAddress).totalSupply();
} else {
return super.totalSupply();
}
}
// Issue a new amount of tokens
// these tokens are deposited into the owner address
//
// @param _amount Number of tokens to be issued
function issue(uint256 amount) public onlyOwner whenNotPaused {
require(!deprecated, "this contract has been deprecated");
super._mint(msg.sender, amount);
emit Issue(amount);
}
// Redeem tokens.
// These tokens are withdrawn from the owner address
// if the balance must be enough to cover the redeem
// or the call will fail.
// @param _amount Number of tokens to be issued
function redeem(uint256 amount) public onlyOwner whenNotPaused {
require(!deprecated, "this contract has been deprecated");
super._burn(msg.sender, amount);
emit Redeem(amount);
}
// Called when new token are issued
event Issue(uint256 amount);
// Called when tokens are redeemed
event Redeem(uint256 amount);
// Called when contract is deprecated
event Deprecate(address indexed newAddress);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment