update ercV3
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@ deploy-detail-periphery.txt
|
|||||||
deploy-drops.txt
|
deploy-drops.txt
|
||||||
deploy-nft.txt
|
deploy-nft.txt
|
||||||
kovan-mock-v2.0.txt
|
kovan-mock-v2.0.txt
|
||||||
|
deploy-detail-erc20V3.txt
|
||||||
|
|
||||||
# VIM
|
# VIM
|
||||||
*.swo
|
*.swo
|
||||||
|
|||||||
148
archive/CustomERC20.sol
Normal file
148
archive/CustomERC20.sol
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2021 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 CustomERC20 is InitializableOwnable {
|
||||||
|
using SafeMath for uint256;
|
||||||
|
|
||||||
|
string public name;
|
||||||
|
uint8 public decimals;
|
||||||
|
string public symbol;
|
||||||
|
uint256 public totalSupply;
|
||||||
|
|
||||||
|
uint256 public tradeBurnRatio;
|
||||||
|
uint256 public tradeFeeRatio;
|
||||||
|
address public team;
|
||||||
|
bool public isMintable;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
event ChangeTeam(address oldTeam, address newTeam);
|
||||||
|
|
||||||
|
|
||||||
|
function init(
|
||||||
|
address _creator,
|
||||||
|
uint256 _initSupply,
|
||||||
|
string memory _name,
|
||||||
|
string memory _symbol,
|
||||||
|
uint8 _decimals,
|
||||||
|
uint256 _tradeBurnRatio,
|
||||||
|
uint256 _tradeFeeRatio,
|
||||||
|
address _team,
|
||||||
|
bool _isMintable
|
||||||
|
) public {
|
||||||
|
initOwner(_creator);
|
||||||
|
name = _name;
|
||||||
|
symbol = _symbol;
|
||||||
|
decimals = _decimals;
|
||||||
|
totalSupply = _initSupply;
|
||||||
|
balances[_creator] = _initSupply;
|
||||||
|
require(_tradeBurnRatio >= 0 && _tradeBurnRatio <= 5000, "TRADE_BURN_RATIO_INVALID");
|
||||||
|
require(_tradeFeeRatio >= 0 && _tradeFeeRatio <= 5000, "TRADE_FEE_RATIO_INVALID");
|
||||||
|
tradeBurnRatio = _tradeBurnRatio;
|
||||||
|
tradeFeeRatio = _tradeFeeRatio;
|
||||||
|
team = _team;
|
||||||
|
isMintable = _isMintable;
|
||||||
|
emit Transfer(address(0), _creator, _initSupply);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transfer(address to, uint256 amount) public returns (bool) {
|
||||||
|
_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(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH");
|
||||||
|
_transfer(from,to,amount);
|
||||||
|
allowed[from][msg.sender] = allowed[from][msg.sender].sub(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 _transfer(
|
||||||
|
address sender,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount
|
||||||
|
) internal virtual {
|
||||||
|
require(sender != address(0), "ERC20: transfer from the zero address");
|
||||||
|
require(recipient != address(0), "ERC20: transfer to the zero address");
|
||||||
|
require(balances[sender] >= amount, "ERC20: transfer amount exceeds balance");
|
||||||
|
|
||||||
|
balances[sender] = balances[sender].sub(amount);
|
||||||
|
|
||||||
|
uint256 burnAmount;
|
||||||
|
uint256 feeAmount;
|
||||||
|
if(tradeBurnRatio > 0) {
|
||||||
|
burnAmount = amount.mul(tradeBurnRatio).div(10000);
|
||||||
|
balances[address(0)] = balances[address(0)].add(burnAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeFeeRatio > 0) {
|
||||||
|
feeAmount = amount.mul(tradeFeeRatio).div(10000);
|
||||||
|
balances[team] = balances[team].add(feeAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
balances[recipient] = balances[recipient].add(amount.sub(burnAmount).sub(feeAmount));
|
||||||
|
|
||||||
|
emit Transfer(sender, recipient, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function burn(uint256 value) external {
|
||||||
|
require(isMintable, "NOT_MINTABEL_TOKEN");
|
||||||
|
require(balances[msg.sender] >= value, "VALUE_NOT_ENOUGH");
|
||||||
|
|
||||||
|
balances[msg.sender] = balances[msg.sender].sub(value);
|
||||||
|
totalSupply = totalSupply.sub(value);
|
||||||
|
emit Burn(msg.sender, value);
|
||||||
|
emit Transfer(msg.sender, address(0), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=================== Ownable ======================
|
||||||
|
function mint(address user, uint256 value) external onlyOwner {
|
||||||
|
require(isMintable, "NOT_MINTABEL_TOKEN");
|
||||||
|
require(user == _OWNER_, "NOT_OWNER");
|
||||||
|
|
||||||
|
balances[user] = balances[user].add(value);
|
||||||
|
totalSupply = totalSupply.add(value);
|
||||||
|
emit Mint(user, value);
|
||||||
|
emit Transfer(address(0), user, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTeamAccount(address newTeam) external onlyOwner {
|
||||||
|
require(tradeFeeRatio > 0, "NOT_TRADE_FEE_TOKEN");
|
||||||
|
emit ChangeTeam(team,newTeam);
|
||||||
|
team = newTeam;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,8 +24,8 @@ module.exports = {
|
|||||||
CP: "0x6850eE8cF963B913a8eC3610B5f128C3100178E5",
|
CP: "0x6850eE8cF963B913a8eC3610B5f128C3100178E5",
|
||||||
ERC20MineV3: "0xd5Bbb5497d0503a8d0CB5A9410EcFfF840Fe0012",
|
ERC20MineV3: "0xd5Bbb5497d0503a8d0CB5A9410EcFfF840Fe0012",
|
||||||
ERC20: "0x7119D1Ec8235bd0a82289fDb1cCAa4bD4D1e0605",
|
ERC20: "0x7119D1Ec8235bd0a82289fDb1cCAa4bD4D1e0605",
|
||||||
MintableERC20: "",
|
CustomERC20: "0x0cAe1660A490145C23A9393096CC58DD05f17a47",//0x0Cd57DC8367362314C510446FD106B66989Eb81a
|
||||||
CustomERC20: "0x0Cd57DC8367362314C510446FD106B66989Eb81a",
|
CustomMintableERC20: "0xa22Af2C70D4b81fD6e74a0Ff20807DE9b3088F31",
|
||||||
|
|
||||||
|
|
||||||
//Factory
|
//Factory
|
||||||
@@ -37,6 +37,7 @@ module.exports = {
|
|||||||
ERC20Factory: "0x48476599281CB7DD46dbE47264C4594d1d2E19A8",
|
ERC20Factory: "0x48476599281CB7DD46dbE47264C4594d1d2E19A8",
|
||||||
ERC20V2Factory: "0x7A22e361cB74E69B5B1C800A3aAbE3E50e84F4F6",
|
ERC20V2Factory: "0x7A22e361cB74E69B5B1C800A3aAbE3E50e84F4F6",
|
||||||
DODOMineV3Registry: "0xeA12A4F762B6D8e2a122847aB1ecF60BB690fEd8",
|
DODOMineV3Registry: "0xeA12A4F762B6D8e2a122847aB1ecF60BB690fEd8",
|
||||||
|
ERC20V3Factory: "0x8C4690eF31a0F6f0c1C645E62abF420Fe7dC4f81",
|
||||||
|
|
||||||
//Approve
|
//Approve
|
||||||
DODOApprove: "0xcC8d87A7C747eeE4242045C47Ef25e0A81D56ae3",
|
DODOApprove: "0xcC8d87A7C747eeE4242045C47Ef25e0A81D56ae3",
|
||||||
|
|||||||
192
contracts/Factory/ERC20V3Factory.sol
Normal file
192
contracts/Factory/ERC20V3Factory.sol
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2022 DODO ZOO.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {ICloneFactory} from "../lib/CloneFactory.sol";
|
||||||
|
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
|
||||||
|
|
||||||
|
interface IStdERC20 {
|
||||||
|
function init(
|
||||||
|
address _creator,
|
||||||
|
uint256 _totalSupply,
|
||||||
|
string memory _name,
|
||||||
|
string memory _symbol,
|
||||||
|
uint8 _decimals
|
||||||
|
) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICustomERC20 {
|
||||||
|
function init(
|
||||||
|
address _creator,
|
||||||
|
uint256 _initSupply,
|
||||||
|
string memory _name,
|
||||||
|
string memory _symbol,
|
||||||
|
uint8 _decimals,
|
||||||
|
uint256 _tradeBurnRatio,
|
||||||
|
uint256 _tradeFeeRatio,
|
||||||
|
address _team
|
||||||
|
) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title DODO ERC20V2Factory
|
||||||
|
* @author DODO Breeder
|
||||||
|
*
|
||||||
|
* @notice Help user to create erc20 token
|
||||||
|
*/
|
||||||
|
contract ERC20V3Factory is InitializableOwnable {
|
||||||
|
// ============ Templates ============
|
||||||
|
|
||||||
|
address public immutable _CLONE_FACTORY_;
|
||||||
|
address public _ERC20_TEMPLATE_;
|
||||||
|
address public _CUSTOM_ERC20_TEMPLATE_;
|
||||||
|
address public _CUSTOM_MINTABLE_ERC20_TEMPLATE_;
|
||||||
|
uint256 public _CREATE_FEE_;
|
||||||
|
|
||||||
|
// ============ Events ============
|
||||||
|
// 0 Std 1 TradeBurn or TradeFee 2 Mintable
|
||||||
|
event NewERC20(address erc20, address creator, uint256 erc20Type);
|
||||||
|
event ChangeCreateFee(uint256 newFee);
|
||||||
|
event Withdraw(address account, uint256 amount);
|
||||||
|
event ChangeStdTemplate(address newStdTemplate);
|
||||||
|
event ChangeCustomTemplate(address newCustomTemplate);
|
||||||
|
event ChangeCustomMintableTemplate(address newCustomMintableTemplate);
|
||||||
|
|
||||||
|
// ============ Registry ============
|
||||||
|
// creator -> token address list
|
||||||
|
mapping(address => address[]) public _USER_STD_REGISTRY_;
|
||||||
|
mapping(address => address[]) public _USER_CUSTOM_REGISTRY_;
|
||||||
|
mapping(address => address[]) public _USER_CUSTOM_MINTABLE_REGISTRY_;
|
||||||
|
|
||||||
|
// ============ Functions ============
|
||||||
|
|
||||||
|
fallback() external payable {}
|
||||||
|
|
||||||
|
receive() external payable {}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
address cloneFactory,
|
||||||
|
address erc20Template,
|
||||||
|
address customErc20Template,
|
||||||
|
address customMintableErc20Template,
|
||||||
|
uint256 createFee
|
||||||
|
) public {
|
||||||
|
_CLONE_FACTORY_ = cloneFactory;
|
||||||
|
_ERC20_TEMPLATE_ = erc20Template;
|
||||||
|
_CUSTOM_ERC20_TEMPLATE_ = customErc20Template;
|
||||||
|
_CUSTOM_MINTABLE_ERC20_TEMPLATE_ = customMintableErc20Template;
|
||||||
|
_CREATE_FEE_ = createFee;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStdERC20(
|
||||||
|
uint256 totalSupply,
|
||||||
|
string memory name,
|
||||||
|
string memory symbol,
|
||||||
|
uint8 decimals
|
||||||
|
) external payable returns (address newERC20) {
|
||||||
|
require(msg.value >= _CREATE_FEE_, "CREATE_FEE_NOT_ENOUGH");
|
||||||
|
newERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC20_TEMPLATE_);
|
||||||
|
IStdERC20(newERC20).init(msg.sender, totalSupply, name, symbol, decimals);
|
||||||
|
_USER_STD_REGISTRY_[msg.sender].push(newERC20);
|
||||||
|
emit NewERC20(newERC20, msg.sender, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCustomERC20(
|
||||||
|
uint256 totalSupply,
|
||||||
|
string memory name,
|
||||||
|
string memory symbol,
|
||||||
|
uint8 decimals,
|
||||||
|
uint256 tradeBurnRatio,
|
||||||
|
uint256 tradeFeeRatio,
|
||||||
|
address teamAccount
|
||||||
|
) external payable returns (address newCustomERC20) {
|
||||||
|
require(msg.value >= _CREATE_FEE_, "CREATE_FEE_NOT_ENOUGH");
|
||||||
|
newCustomERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_CUSTOM_ERC20_TEMPLATE_);
|
||||||
|
|
||||||
|
ICustomERC20(newCustomERC20).init(
|
||||||
|
msg.sender,
|
||||||
|
totalSupply,
|
||||||
|
name,
|
||||||
|
symbol,
|
||||||
|
decimals,
|
||||||
|
tradeBurnRatio,
|
||||||
|
tradeFeeRatio,
|
||||||
|
teamAccount
|
||||||
|
);
|
||||||
|
|
||||||
|
_USER_CUSTOM_REGISTRY_[msg.sender].push(newCustomERC20);
|
||||||
|
|
||||||
|
emit NewERC20(newCustomERC20, msg.sender, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCustomMintableERC20(
|
||||||
|
uint256 initSupply,
|
||||||
|
string memory name,
|
||||||
|
string memory symbol,
|
||||||
|
uint8 decimals,
|
||||||
|
uint256 tradeBurnRatio,
|
||||||
|
uint256 tradeFeeRatio,
|
||||||
|
address teamAccount
|
||||||
|
) external payable returns (address newCustomMintableERC20) {
|
||||||
|
require(msg.value >= _CREATE_FEE_, "CREATE_FEE_NOT_ENOUGH");
|
||||||
|
newCustomMintableERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_CUSTOM_MINTABLE_ERC20_TEMPLATE_);
|
||||||
|
|
||||||
|
ICustomERC20(newCustomMintableERC20).init(
|
||||||
|
msg.sender,
|
||||||
|
initSupply,
|
||||||
|
name,
|
||||||
|
symbol,
|
||||||
|
decimals,
|
||||||
|
tradeBurnRatio,
|
||||||
|
tradeFeeRatio,
|
||||||
|
teamAccount
|
||||||
|
);
|
||||||
|
|
||||||
|
_USER_CUSTOM_MINTABLE_REGISTRY_[msg.sender].push(newCustomMintableERC20);
|
||||||
|
|
||||||
|
emit NewERC20(newCustomMintableERC20, msg.sender, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============ View ============
|
||||||
|
function getTokenByUser(address user)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (address[] memory stds,address[] memory customs,address[] memory mintables)
|
||||||
|
{
|
||||||
|
return (_USER_STD_REGISTRY_[user], _USER_CUSTOM_REGISTRY_[user], _USER_CUSTOM_MINTABLE_REGISTRY_[user]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ Ownable =============
|
||||||
|
function changeCreateFee(uint256 newFee) external onlyOwner {
|
||||||
|
_CREATE_FEE_ = newFee;
|
||||||
|
emit ChangeCreateFee(newFee);
|
||||||
|
}
|
||||||
|
|
||||||
|
function withdraw() external onlyOwner {
|
||||||
|
uint256 amount = address(this).balance;
|
||||||
|
msg.sender.transfer(amount);
|
||||||
|
emit Withdraw(msg.sender, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStdTemplate(address newStdTemplate) external onlyOwner {
|
||||||
|
_ERC20_TEMPLATE_ = newStdTemplate;
|
||||||
|
emit ChangeStdTemplate(newStdTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCustomTemplate(address newCustomTemplate) external onlyOwner {
|
||||||
|
_CUSTOM_ERC20_TEMPLATE_ = newCustomTemplate;
|
||||||
|
emit ChangeCustomTemplate(newCustomTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCustomMintableTemplate(address newCustomMintableTemplate) external onlyOwner {
|
||||||
|
_CUSTOM_MINTABLE_ERC20_TEMPLATE_ = newCustomMintableTemplate;
|
||||||
|
emit ChangeCustomMintableTemplate(newCustomMintableTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
42
contracts/external/ERC20/CustomERC20.sol
vendored
42
contracts/external/ERC20/CustomERC20.sol
vendored
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright 2021 DODO ZOO.
|
Copyright 2022 DODO ZOO.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@@ -21,43 +21,38 @@ contract CustomERC20 is InitializableOwnable {
|
|||||||
uint256 public tradeBurnRatio;
|
uint256 public tradeBurnRatio;
|
||||||
uint256 public tradeFeeRatio;
|
uint256 public tradeFeeRatio;
|
||||||
address public team;
|
address public team;
|
||||||
bool public isMintable;
|
|
||||||
|
|
||||||
mapping(address => uint256) balances;
|
mapping(address => uint256) balances;
|
||||||
mapping(address => mapping(address => uint256)) internal allowed;
|
mapping(address => mapping(address => uint256)) internal allowed;
|
||||||
|
|
||||||
event Transfer(address indexed from, address indexed to, uint256 amount);
|
event Transfer(address indexed from, address indexed to, uint256 amount);
|
||||||
event Approval(address indexed owner, address indexed spender, 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);
|
|
||||||
|
|
||||||
event ChangeTeam(address oldTeam, address newTeam);
|
event ChangeTeam(address oldTeam, address newTeam);
|
||||||
|
|
||||||
|
|
||||||
function init(
|
function init(
|
||||||
address _creator,
|
address _creator,
|
||||||
uint256 _initSupply,
|
uint256 _totalSupply,
|
||||||
string memory _name,
|
string memory _name,
|
||||||
string memory _symbol,
|
string memory _symbol,
|
||||||
uint8 _decimals,
|
uint8 _decimals,
|
||||||
uint256 _tradeBurnRatio,
|
uint256 _tradeBurnRatio,
|
||||||
uint256 _tradeFeeRatio,
|
uint256 _tradeFeeRatio,
|
||||||
address _team,
|
address _team
|
||||||
bool _isMintable
|
|
||||||
) public {
|
) public {
|
||||||
initOwner(_creator);
|
initOwner(_creator);
|
||||||
name = _name;
|
name = _name;
|
||||||
symbol = _symbol;
|
symbol = _symbol;
|
||||||
decimals = _decimals;
|
decimals = _decimals;
|
||||||
totalSupply = _initSupply;
|
totalSupply = _totalSupply;
|
||||||
balances[_creator] = _initSupply;
|
balances[_creator] = _totalSupply;
|
||||||
require(_tradeBurnRatio >= 0 && _tradeBurnRatio <= 5000, "TRADE_BURN_RATIO_INVALID");
|
require(_tradeBurnRatio >= 0 && _tradeBurnRatio <= 5000, "TRADE_BURN_RATIO_INVALID");
|
||||||
require(_tradeFeeRatio >= 0 && _tradeFeeRatio <= 5000, "TRADE_FEE_RATIO_INVALID");
|
require(_tradeFeeRatio >= 0 && _tradeFeeRatio <= 5000, "TRADE_FEE_RATIO_INVALID");
|
||||||
tradeBurnRatio = _tradeBurnRatio;
|
tradeBurnRatio = _tradeBurnRatio;
|
||||||
tradeFeeRatio = _tradeFeeRatio;
|
tradeFeeRatio = _tradeFeeRatio;
|
||||||
team = _team;
|
team = _team;
|
||||||
isMintable = _isMintable;
|
emit Transfer(address(0), _creator, _totalSupply);
|
||||||
emit Transfer(address(0), _creator, _initSupply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function transfer(address to, uint256 amount) public returns (bool) {
|
function transfer(address to, uint256 amount) public returns (bool) {
|
||||||
@@ -119,30 +114,17 @@ contract CustomERC20 is InitializableOwnable {
|
|||||||
emit Transfer(sender, recipient, amount);
|
emit Transfer(sender, recipient, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function burn(uint256 value) external {
|
|
||||||
require(isMintable, "NOT_MINTABEL_TOKEN");
|
|
||||||
require(balances[msg.sender] >= value, "VALUE_NOT_ENOUGH");
|
|
||||||
|
|
||||||
balances[msg.sender] = balances[msg.sender].sub(value);
|
|
||||||
totalSupply = totalSupply.sub(value);
|
|
||||||
emit Burn(msg.sender, value);
|
|
||||||
emit Transfer(msg.sender, address(0), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=================== Ownable ======================
|
//=================== Ownable ======================
|
||||||
function mint(address user, uint256 value) external onlyOwner {
|
|
||||||
require(isMintable, "NOT_MINTABEL_TOKEN");
|
|
||||||
require(user == _OWNER_, "NOT_OWNER");
|
|
||||||
|
|
||||||
balances[user] = balances[user].add(value);
|
|
||||||
totalSupply = totalSupply.add(value);
|
|
||||||
emit Mint(user, value);
|
|
||||||
emit Transfer(address(0), user, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeTeamAccount(address newTeam) external onlyOwner {
|
function changeTeamAccount(address newTeam) external onlyOwner {
|
||||||
require(tradeFeeRatio > 0, "NOT_TRADE_FEE_TOKEN");
|
require(tradeFeeRatio > 0, "NOT_TRADE_FEE_TOKEN");
|
||||||
emit ChangeTeam(team,newTeam);
|
emit ChangeTeam(team,newTeam);
|
||||||
team = newTeam;
|
team = newTeam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function abandonOwnership(address zeroAddress) external onlyOwner {
|
||||||
|
require(zeroAddress == address(0), "NOT_ZERO_ADDRESS");
|
||||||
|
emit OwnershipTransferred(_OWNER_, address(0));
|
||||||
|
_OWNER_ = address(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
149
contracts/external/ERC20/CustomMintableERC20.sol
vendored
Normal file
149
contracts/external/ERC20/CustomMintableERC20.sol
vendored
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2022 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 CustomMintableERC20 is InitializableOwnable {
|
||||||
|
using SafeMath for uint256;
|
||||||
|
|
||||||
|
string public name;
|
||||||
|
uint8 public decimals;
|
||||||
|
string public symbol;
|
||||||
|
uint256 public totalSupply;
|
||||||
|
|
||||||
|
uint256 public tradeBurnRatio;
|
||||||
|
uint256 public tradeFeeRatio;
|
||||||
|
address public team;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
event ChangeTeam(address oldTeam, address newTeam);
|
||||||
|
|
||||||
|
|
||||||
|
function init(
|
||||||
|
address _creator,
|
||||||
|
uint256 _initSupply,
|
||||||
|
string memory _name,
|
||||||
|
string memory _symbol,
|
||||||
|
uint8 _decimals,
|
||||||
|
uint256 _tradeBurnRatio,
|
||||||
|
uint256 _tradeFeeRatio,
|
||||||
|
address _team
|
||||||
|
) public {
|
||||||
|
initOwner(_creator);
|
||||||
|
name = _name;
|
||||||
|
symbol = _symbol;
|
||||||
|
decimals = _decimals;
|
||||||
|
totalSupply = _initSupply;
|
||||||
|
balances[_creator] = _initSupply;
|
||||||
|
require(_tradeBurnRatio >= 0 && _tradeBurnRatio <= 5000, "TRADE_BURN_RATIO_INVALID");
|
||||||
|
require(_tradeFeeRatio >= 0 && _tradeFeeRatio <= 5000, "TRADE_FEE_RATIO_INVALID");
|
||||||
|
tradeBurnRatio = _tradeBurnRatio;
|
||||||
|
tradeFeeRatio = _tradeFeeRatio;
|
||||||
|
team = _team;
|
||||||
|
emit Transfer(address(0), _creator, _initSupply);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transfer(address to, uint256 amount) public returns (bool) {
|
||||||
|
_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(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH");
|
||||||
|
_transfer(from,to,amount);
|
||||||
|
allowed[from][msg.sender] = allowed[from][msg.sender].sub(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 _transfer(
|
||||||
|
address sender,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount
|
||||||
|
) internal virtual {
|
||||||
|
require(sender != address(0), "ERC20: transfer from the zero address");
|
||||||
|
require(recipient != address(0), "ERC20: transfer to the zero address");
|
||||||
|
require(balances[sender] >= amount, "ERC20: transfer amount exceeds balance");
|
||||||
|
|
||||||
|
balances[sender] = balances[sender].sub(amount);
|
||||||
|
|
||||||
|
uint256 burnAmount;
|
||||||
|
uint256 feeAmount;
|
||||||
|
if(tradeBurnRatio > 0) {
|
||||||
|
burnAmount = amount.mul(tradeBurnRatio).div(10000);
|
||||||
|
balances[address(0)] = balances[address(0)].add(burnAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeFeeRatio > 0) {
|
||||||
|
feeAmount = amount.mul(tradeFeeRatio).div(10000);
|
||||||
|
balances[team] = balances[team].add(feeAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
balances[recipient] = balances[recipient].add(amount.sub(burnAmount).sub(feeAmount));
|
||||||
|
|
||||||
|
emit Transfer(sender, recipient, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function burn(uint256 value) external {
|
||||||
|
require(balances[msg.sender] >= value, "VALUE_NOT_ENOUGH");
|
||||||
|
|
||||||
|
balances[msg.sender] = balances[msg.sender].sub(value);
|
||||||
|
totalSupply = totalSupply.sub(value);
|
||||||
|
emit Burn(msg.sender, value);
|
||||||
|
emit Transfer(msg.sender, address(0), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=================== Ownable ======================
|
||||||
|
function mint(address user, uint256 value) external onlyOwner {
|
||||||
|
require(user == _OWNER_, "NOT_OWNER");
|
||||||
|
|
||||||
|
balances[user] = balances[user].add(value);
|
||||||
|
totalSupply = totalSupply.add(value);
|
||||||
|
emit Mint(user, value);
|
||||||
|
emit Transfer(address(0), user, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTeamAccount(address newTeam) external onlyOwner {
|
||||||
|
require(tradeFeeRatio > 0, "NOT_TRADE_FEE_TOKEN");
|
||||||
|
emit ChangeTeam(team,newTeam);
|
||||||
|
team = newTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
function abandonOwnership(address zeroAddress) external onlyOwner {
|
||||||
|
require(zeroAddress == address(0), "NOT_ZERO_ADDRESS");
|
||||||
|
emit OwnershipTransferred(_OWNER_, address(0));
|
||||||
|
_OWNER_ = address(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
61
migrations/2_deploy_erc20V3.js
Normal file
61
migrations/2_deploy_erc20V3.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const { deploySwitch } = require('../truffle-config.js')
|
||||||
|
const file = fs.createWriteStream("../deploy-detail-erc20V3.txt", { 'flags': 'a' });
|
||||||
|
let logger = new console.Console(file, file);
|
||||||
|
const { GetConfig } = require("../configAdapter.js")
|
||||||
|
|
||||||
|
const ERC20V3Factory = artifacts.require("ERC20V3Factory");
|
||||||
|
const CustomERC20 = artifacts.require("CustomERC20");
|
||||||
|
const CustomMintableERC20 = artifacts.require("CustomMintableERC20");
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = async (deployer, network, accounts) => {
|
||||||
|
let CONFIG = GetConfig(network, accounts)
|
||||||
|
let CloneFactoryAddress = CONFIG.CloneFactory;
|
||||||
|
let ERC20Address = CONFIG.ERC20;
|
||||||
|
if (CONFIG == null || ERC20Address == "") return;
|
||||||
|
|
||||||
|
let ERC20V3FactoryAddress = CONFIG.ERC20V3Factory;
|
||||||
|
let CustomERC20Address = CONFIG.CustomERC20;
|
||||||
|
let CustomMintableERC20Address = CONFIG.CustomMintableERC20;
|
||||||
|
|
||||||
|
let multiSigAddress = CONFIG.multiSigAddress;
|
||||||
|
|
||||||
|
if (deploySwitch.ERC20V3Factory) {
|
||||||
|
logger.log("====================================================");
|
||||||
|
logger.log("network type: " + network);
|
||||||
|
logger.log("Deploy time: " + new Date().toLocaleString());
|
||||||
|
logger.log("Deploy type: ERC20V3Factory");
|
||||||
|
|
||||||
|
|
||||||
|
if (CustomERC20Address == "") {
|
||||||
|
await deployer.deploy(CustomERC20);
|
||||||
|
CustomERC20Address = CustomERC20.address;
|
||||||
|
logger.log("CustomERC20Address: ", CustomERC20Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CustomMintableERC20Address == "") {
|
||||||
|
await deployer.deploy(CustomMintableERC20);
|
||||||
|
CustomMintableERC20Address = CustomMintableERC20.address;
|
||||||
|
logger.log("CustomMintableERC20Address: ", CustomMintableERC20Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ERC20V3FactoryAddress == "") {
|
||||||
|
await deployer.deploy(
|
||||||
|
ERC20V3Factory,
|
||||||
|
CloneFactoryAddress,
|
||||||
|
ERC20Address,
|
||||||
|
CustomERC20Address,
|
||||||
|
CustomMintableERC20Address,
|
||||||
|
"100000000000000000" //0.1
|
||||||
|
);
|
||||||
|
ERC20V3FactoryAddress = ERC20V3Factory.address;
|
||||||
|
logger.log("ERC20V3FactoryAddress: ", ERC20V3FactoryAddress);
|
||||||
|
|
||||||
|
const erc20V3FactoryInstance = await ERC20V3Factory.at(ERC20V3FactoryAddress);
|
||||||
|
var tx = await erc20V3FactoryInstance.initOwner(multiSigAddress);
|
||||||
|
logger.log("Init ERC20V3Factory Tx:", tx.tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -40,7 +40,8 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
deploySwitch: {
|
deploySwitch: {
|
||||||
DEPLOY_V1: false,
|
DEPLOY_V1: false,
|
||||||
DEPLOY_V2: true,
|
DEPLOY_V2: false,
|
||||||
|
ERC20V3Factory: true,
|
||||||
MOCK_TOKEN: false,
|
MOCK_TOKEN: false,
|
||||||
MOCK_V2_POOL: false,
|
MOCK_V2_POOL: false,
|
||||||
vDODOToken: false,
|
vDODOToken: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user