Contract Name:
MomocoToken
Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import './modules/ERC20Token.sol';
contract MomocoToken is ERC20Token {
using SafeMath for uint;
uint public constant MAXSUPPLY = 1e26;
address public owner;
address public admin;
address public team;
uint public teamRate;
mapping (address => uint) public funds;
event OwnerChanged(address indexed _user, address indexed _old, address indexed _new);
event AdminChanged(address indexed _user, address indexed _old, address indexed _new);
event TeamChanged(address indexed _user, address indexed _old, address indexed _new);
event TeamRateChanged(address indexed _user, uint indexed _old, uint indexed _new);
event FundChanged(address indexed _user, uint indexed _old, uint indexed _new);
event Mint(address indexed from, address indexed to, uint value);
modifier onlyOwner() {
require(msg.sender == owner, 'forbidden');
_;
}
modifier onlyAdmin() {
require(msg.sender == admin || msg.sender == owner, "forbidden");
_;
}
modifier onlyTeam() {
require(msg.sender == team || msg.sender == owner, "forbidden");
_;
}
constructor() {
decimals = 18;
name = 'Momoco Token';
symbol = 'MOMOCO';
owner = msg.sender;
admin = msg.sender;
team = msg.sender;
}
function changeOwner(address _user) external onlyOwner {
require(owner != _user, 'no change');
emit OwnerChanged(msg.sender, owner, _user);
owner = _user;
}
function changeAdmin(address _user) external onlyAdmin {
require(admin != _user, 'no change');
emit AdminChanged(msg.sender, admin, _user);
admin = _user;
}
function changeTeam(address _user) external onlyTeam {
require(team != _user, 'no change');
emit TeamChanged(msg.sender, team, _user);
team = _user;
}
function changeTeamRate(uint _teamRate) external onlyAdmin {
require(teamRate != _teamRate, 'no change');
emit TeamRateChanged(msg.sender, teamRate, _teamRate);
teamRate = _teamRate;
}
function increaseFund (address _user, uint _value) public onlyAdmin {
require(_value > 0, 'zero');
uint _old = funds[_user];
funds[_user] = _old.add(_value);
emit FundChanged(msg.sender, _old, funds[_user]);
}
function decreaseFund (address _user, uint _value) public onlyAdmin {
uint _old = funds[_user];
require(_value > 0, 'zero');
require(_old >= _value, 'insufficient');
funds[_user] = _old.sub(_value);
emit FundChanged(msg.sender, _old, funds[_user]);
}
function increaseFunds (address[] calldata _users, uint[] calldata _values) external onlyAdmin {
require(_users.length == _values.length, 'invalid parameters');
for (uint i=0; i<_users.length; i++){
increaseFund(_users[i], _values[i]);
}
}
function decreaseFunds (address[] calldata _users, uint[] calldata _values) external onlyAdmin {
require(_users.length == _values.length, 'invalid parameters');
for (uint i=0; i<_users.length; i++){
decreaseFund(_users[i], _values[i]);
}
}
function _mint(address to, uint value) internal returns (bool) {
balanceOf[to] = balanceOf[to].add(value);
totalSupply = totalSupply.add(value);
require(totalSupply <= MAXSUPPLY, 'over max supply');
emit Transfer(address(this), to, value);
emit Mint(msg.sender, to, value);
return true;
}
function mint(address to, uint value) external returns (bool) {
require(funds[msg.sender] >= value, "fund insufficient");
funds[msg.sender] = funds[msg.sender].sub(value);
_mint(to, value);
if(value > 0 && teamRate > 0 && team != to) {
uint reward = value.div(teamRate);
_mint(team, reward);
}
return true;
}
function burn(uint value) external returns (bool) {
_transfer(msg.sender, address(0), value);
return true;
}
function take() public view returns (uint) {
return funds[msg.sender];
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '../libraries/SafeMath.sol';
contract ERC20Token {
using SafeMath for uint;
string public name;
string public symbol;
uint8 public decimals;
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
function _transfer(address from, address to, uint value) internal {
require(balanceOf[from] >= value, 'ERC20Token: INSUFFICIENT_BALANCE');
balanceOf[from] = balanceOf[from].sub(value);
balanceOf[to] = balanceOf[to].add(value);
if (to == address(0)) { // burn
totalSupply = totalSupply.sub(value);
}
emit Transfer(from, to, value);
}
function approve(address spender, uint value) external returns (bool) {
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transfer(address to, uint value) external returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(address from, address to, uint value) external returns (bool) {
require(allowance[from][msg.sender] >= value, 'ERC20Token: INSUFFICIENT_ALLOWANCE');
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
_transfer(from, to, value);
return true;
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}