ERC20 factory

This commit is contained in:
mingda
2020-12-05 23:23:23 +08:00
parent b14eef1b80
commit 6ba698480a
3 changed files with 250 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {Ownable} from "../lib/Ownable.sol";
import {ICloneFactory} from "../lib/CloneFactory.sol";
import {IConstFeeRateModel} from "../lib/ConstFeeRateModel.sol";
import {IDVM} from "../DODOVendingMachine/intf/IDVM.sol";
import {IDVMAdmin} from "../DODOVendingMachine/intf/IDVMAdmin.sol";
import {IPermissionManager} from "../lib/PermissionManager.sol";
import {InitializableERC20} from "../external/ERC20/InitializableERC20.sol";
import {InitializableMintableERC20} from "../external/ERC20/InitializableMintableERC20.sol";
contract ERC20Factory is Ownable {
// ============ Templates ============
address public _CLONE_FACTORY_;
address public _ERC20_TEMPLATE_;
address public _MINTABLE_ERC20_TEMPLATE_;
// ============ Events ============
event NewERC20(address indexed erc20, address indexed creator, bool isMintable);
// ============ Functions ============
constructor(
address cloneFactory,
address erc20Template,
address mintableErc20Template
) public {
_CLONE_FACTORY_ = cloneFactory;
_ERC20_TEMPLATE_ = erc20Template;
_MINTABLE_ERC20_TEMPLATE_ = mintableErc20Template;
}
function createStdERC20(
uint256 totalSupply,
string memory name,
string memory symbol,
uint256 decimals
) external returns (address newERC20) {
newERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC20_TEMPLATE_);
InitializableERC20(newERC20).init(msg.sender, totalSupply, name, symbol, decimals);
emit NewERC20(newERC20, msg.sender, false);
}
function createMintableERC20(
uint256 initSupply,
string memory name,
string memory symbol,
uint256 decimals
) external returns (address newMintableERC20) {
newMintableERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_MINTABLE_ERC20_TEMPLATE_);
InitializableMintableERC20(newMintableERC20).init(
msg.sender,
initSupply,
name,
symbol,
decimals
);
emit NewERC20(newMintableERC20, msg.sender, true);
}
}

View File

@@ -0,0 +1,83 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
import {SafeMath} from "../../lib/SafeMath.sol";
contract InitializableERC20 {
using SafeMath for uint256;
string public name;
uint256 public decimals;
string public symbol;
uint256 public totalSupply;
bool public initialized;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) internal allowed;
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
function init(
address _creator,
uint256 _totalSupply,
string memory _name,
string memory _symbol,
uint256 _decimals
) public {
require(!initialized, "TOKEN_INITIALIZED");
initialized = true;
totalSupply = _totalSupply;
balances[_creator] = _totalSupply;
name = _name;
symbol = _symbol;
decimals = _decimals;
}
function transfer(address to, uint256 amount) public returns (bool) {
require(to != address(0), "TO_ADDRESS_IS_EMPTY");
require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH");
balances[msg.sender] = balances[msg.sender].sub(amount);
balances[to] = balances[to].add(amount);
emit Transfer(msg.sender, to, amount);
return true;
}
function balanceOf(address owner) public view returns (uint256 balance) {
return balances[owner];
}
function transferFrom(
address from,
address to,
uint256 amount
) public returns (bool) {
require(to != address(0), "TO_ADDRESS_IS_EMPTY");
require(amount <= balances[from], "BALANCE_NOT_ENOUGH");
require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH");
balances[from] = balances[from].sub(amount);
balances[to] = balances[to].add(amount);
allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);
emit Transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
allowed[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return allowed[owner][spender];
}
}

View File

@@ -0,0 +1,97 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
import {SafeMath} from "../../lib/SafeMath.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
contract InitializableMintableERC20 is InitializableOwnable {
using SafeMath for uint256;
string public name;
uint256 public decimals;
string public symbol;
uint256 public totalSupply;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) internal allowed;
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
event Mint(address indexed user, uint256 value);
event Burn(address indexed user, uint256 value);
function init(
address _creator,
uint256 _initSupply,
string memory _name,
string memory _symbol,
uint256 _decimals
) public {
initOwner(_creator);
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _initSupply;
balances[_creator] = _initSupply;
}
function transfer(address to, uint256 amount) public returns (bool) {
require(to != address(0), "TO_ADDRESS_IS_EMPTY");
require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH");
balances[msg.sender] = balances[msg.sender].sub(amount);
balances[to] = balances[to].add(amount);
emit Transfer(msg.sender, to, amount);
return true;
}
function balanceOf(address owner) public view returns (uint256 balance) {
return balances[owner];
}
function transferFrom(
address from,
address to,
uint256 amount
) public returns (bool) {
require(to != address(0), "TO_ADDRESS_IS_EMPTY");
require(amount <= balances[from], "BALANCE_NOT_ENOUGH");
require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH");
balances[from] = balances[from].sub(amount);
balances[to] = balances[to].add(amount);
allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);
emit Transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
allowed[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return allowed[owner][spender];
}
function mint(address user, uint256 value) external onlyOwner {
balances[user] = balances[user].add(value);
totalSupply = totalSupply.add(value);
emit Mint(user, value);
emit Transfer(address(0), user, value);
}
function burn(address user, uint256 value) external onlyOwner {
balances[user] = balances[user].sub(value);
totalSupply = totalSupply.sub(value);
emit Burn(user, value);
emit Transfer(user, address(0), value);
}
}