// File: math/SafeMath.sol
pragma solidity 0.5.17;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
require(c >= a, "SafeMath: addition overflow");
}
function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
}
function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
// Since Solidity automatically asserts when dividing by 0,
// but we only need it to revert.
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256 c) {
// Same reason as `div`.
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
}
// File: token/erc20/IERC20.sol
pragma solidity 0.5.17;
interface IERC20 {
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
function totalSupply() external view returns (uint256 _supply);
function balanceOf(address _owner) external view returns (uint256 _balance);
function approve(address _spender, uint256 _value) external returns (bool _success);
function allowance(address _owner, address _spender) external view returns (uint256 _value);
function transfer(address _to, uint256 _value) external returns (bool _success);
function transferFrom(address _from, address _to, uint256 _value) external returns (bool _success);
}
// File: token/erc20/ERC20.sol
pragma solidity 0.5.17;
contract ERC20 is IERC20 {
using SafeMath for uint256;
uint256 public totalSupply;
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) internal _allowance;
function approve(address _spender, uint256 _value) public returns (bool) {
_approve(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256) {
return _allowance[_owner][_spender];
}
function increaseAllowance(address _spender, uint256 _value) public returns (bool) {
_approve(msg.sender, _spender, _allowance[msg.sender][_spender].add(_value));
return true;
}
function decreaseAllowance(address _spender, uint256 _value) public returns (bool) {
_approve(msg.sender, _spender, _allowance[msg.sender][_spender].sub(_value));
return true;
}
function transfer(address _to, uint256 _value) public returns (bool _success) {
_transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool _success) {
_transfer(_from, _to, _value);
_approve(_from, msg.sender, _allowance[_from][msg.sender].sub(_value));
return true;
}
function _approve(address _owner, address _spender, uint256 _amount) internal {
require(_owner != address(0), "ERC20: approve from the zero address");
require(_spender != address(0), "ERC20: approve to the zero address");
_allowance[_owner][_spender] = _amount;
emit Approval(_owner, _spender, _amount);
}
function _transfer(address _from, address _to, uint256 _value) internal {
require(_from != address(0), "ERC20: transfer from the zero address");
require(_to != address(0), "ERC20: transfer to the zero address");
require(_to != address(this), "ERC20: transfer to this contract address");
balanceOf[_from] = balanceOf[_from].sub(_value);
balanceOf[_to] = balanceOf[_to].add(_value);
emit Transfer(_from, _to, _value);
}
}
// File: token/erc20/IERC20Detailed.sol
pragma solidity 0.5.17;
interface IERC20Detailed {
function name() external view returns (string memory _name);
function symbol() external view returns (string memory _symbol);
function decimals() external view returns (uint8 _decimals);
}
// File: token/erc20/ERC20Detailed.sol
pragma solidity 0.5.17;
contract ERC20Detailed is ERC20, IERC20Detailed {
string public name;
string public symbol;
uint8 public decimals;
constructor(string memory _name, string memory _symbol, uint8 _decimals) public {
name = _name;
symbol = _symbol;
decimals = _decimals;
}
}
// File: token/erc20/ERC20GatewayWhitelist.sol
pragma solidity 0.5.17;
contract ERC20GatewayWhitelist is ERC20 {
address public mainchainGateway;
function allowance(address _owner, address _spender)
public
view
returns (uint256 _value)
{
if (_spender == mainchainGateway) return uint256(-1);
return _allowance[_owner][_spender];
}
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool _success)
{
if (allowance(_from, msg.sender) != uint256(-1)) {
super._approve(_from, msg.sender, _allowance[_from][msg.sender].sub(_value));
}
_transfer(_from, _to, _value);
return true;
}
function _setGateway(address _mainchainGateway) internal {
require(
_mainchainGateway != address(0),
"ERC20GatewayWhitelist: setting gateway to the zero address"
);
mainchainGateway = _mainchainGateway;
}
}
// File: access/HasAdmin.sol
pragma solidity 0.5.17;
contract HasAdmin {
event AdminChanged(address indexed _oldAdmin, address indexed _newAdmin);
event AdminRemoved(address indexed _oldAdmin);
address public admin;
modifier onlyAdmin {
require(msg.sender == admin, "HasAdmin: not admin");
_;
}
constructor() internal {
admin = msg.sender;
emit AdminChanged(address(0), admin);
}
function changeAdmin(address _newAdmin) external onlyAdmin {
require(_newAdmin != address(0), "HasAdmin: new admin is the zero address");
emit AdminChanged(admin, _newAdmin);
admin = _newAdmin;
}
function removeAdmin() external onlyAdmin {
emit AdminRemoved(admin);
admin = address(0);
}
}
// File: access/HasMinters.sol
pragma solidity 0.5.17;
contract HasMinters is HasAdmin {
event MinterAdded(address indexed _minter);
event MinterRemoved(address indexed _minter);
address[] public minters;
mapping (address => bool) public minter;
modifier onlyMinter {
require(minter[msg.sender]);
_;
}
function addMinters(address[] memory _addedMinters) public onlyAdmin {
address _minter;
for (uint256 i = 0; i < _addedMinters.length; i++) {
_minter = _addedMinters[i];
if (!minter[_minter]) {
minters.push(_minter);
minter[_minter] = true;
emit MinterAdded(_minter);
}
}
}
function removeMinters(address[] memory _removedMinters) public onlyAdmin {
address _minter;
for (uint256 i = 0; i < _removedMinters.length; i++) {
_minter = _removedMinters[i];
if (minter[_minter]) {
minter[_minter] = false;
emit MinterRemoved(_minter);
}
}
uint256 i = 0;
while (i < minters.length) {
_minter = minters[i];
if (!minter[_minter]) {
minters[i] = minters[minters.length - 1];
delete minters[minters.length - 1];
minters.length--;
} else {
i++;
}
}
}
function isMinter(address _addr) public view returns (bool) {
return minter[_addr];
}
}
// File: token/erc20/ERC20Mintable.sol
pragma solidity 0.5.17;
contract ERC20Mintable is HasMinters, ERC20 {
function mint(address _to, uint256 _value) public onlyMinter returns (bool _success) {
return _mint(_to, _value);
}
function _mint(address _to, uint256 _value) internal returns (bool success) {
totalSupply = totalSupply.add(_value);
balanceOf[_to] = balanceOf[_to].add(_value);
emit Transfer(address(0), _to, _value);
return true;
}
}
// File: SmoothLovePotion.sol
pragma solidity 0.5.17;
contract SmoothLovePotion is ERC20Detailed, ERC20Mintable, ERC20GatewayWhitelist {
constructor(address _mainchainGateway)
public
ERC20Detailed("Smooth Love Potion", "SLP", 0)
{
_setGateway(_mainchainGateway);
address[] memory _minters = new address[](1);
_minters[0] = _mainchainGateway;
addMinters(_minters);
}
}
{
"compilationTarget": {
"SmoothLovePotion.sol": "SmoothLovePotion"
},
"evmVersion": "istanbul",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_mainchainGateway","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"_newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_addedMinters","type":"address[]"}],"name":"addMinters","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mainchainGateway","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"minters","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"removeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_removedMinters","type":"address[]"}],"name":"removeMinters","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]