update mineV3
This commit is contained in:
35
README.md
35
README.md
@@ -1,35 +1,12 @@
|
|||||||
# DODO V2: Help 1 Trillion People Issue Token
|
# Scope of Audit
|
||||||
|
|
||||||
## Audit Report
|
- contracts/DODOToken/DODOMineV3/
|
||||||
|
|
||||||
[Audited by Peckshield](https://github.com/DODOEX/contractV2/blob/main/audit/PeckShield-Audit-DODOV2-v1.0.pdf)
|
- contracts/Factory/Registries/DODOMineV3Registry.sol
|
||||||
|
|
||||||
## Bug Bounty 💰
|
- contracts/SmartRoute/proxies/DODOMineV3Proxy.sol
|
||||||
|
|
||||||
### Rewards
|
- contracts/external/CustomERC20.sol
|
||||||
|
|
||||||
Severity of bugs will be assessed under the [CVSS Risk Rating](https://www.first.org/cvss/calculator/3.0) scale, as follows:
|
- contracts/Factory/ERC20V2Factory.sol
|
||||||
|
|
||||||
- Critical (9.0-10.0): Up to $100,000
|
|
||||||
- High (7.0-8.9): Up to $10,000
|
|
||||||
- Medium (4.0-6.9): Up to $5,000
|
|
||||||
- Low (0.1-3.9): Up to $1,000
|
|
||||||
|
|
||||||
In addition to assessing severity, rewards will be considered based on the impact of the discovered vulnerability as well as the level of difficulty in discovering such vulnerability.
|
|
||||||
|
|
||||||
### Disclosure
|
|
||||||
|
|
||||||
Any vulnerability or bug discovered must be reported only to the following email: contact@dodoex.io; must not be disclosed publicly; must not be disclosed to any other person, entity or email address prior to disclosure to the contact@dodoex.io email; and must not be disclosed in any way other than to the contact@dodoex.io email. In addition, disclosure to contact@dodoex.io must be made promptly following discovery of the vulnerability. Please include as much information about the vulnerability as possible, including:
|
|
||||||
|
|
||||||
- The conditions on which reproducing the bug is contingent.
|
|
||||||
- The steps needed to reproduce the bug or, preferably, a proof of concept.
|
|
||||||
- The potential implications of the vulnerability being abused.
|
|
||||||
|
|
||||||
A detailed report of a vulnerability increases the likelihood of a reward and may increase the reward amount.
|
|
||||||
|
|
||||||
Anyone who reports a unique, previously-unreported vulnerability that results in a change to the code or a configuration change and who keeps such vulnerability confidential until it has been resolved by our engineers will be recognized publicly for their contribution, if agreed.
|
|
||||||
|
|
||||||
## Contact Us
|
|
||||||
|
|
||||||
Send E-mail to contact@dodoex.io
|
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,10 @@ contract BaseMine is InitializableOwnable {
|
|||||||
rt.rewardPerBlock = rewardPerBlock;
|
rt.rewardPerBlock = rewardPerBlock;
|
||||||
rt.rewardVault = address(new RewardVault(rewardToken));
|
rt.rewardVault = address(new RewardVault(rewardToken));
|
||||||
|
|
||||||
|
uint256 rewardAmount = rewardPerBlock.mul(endBlock.sub(startBlock));
|
||||||
|
IERC20(rewardToken).transfer(rt.rewardVault, rewardAmount);
|
||||||
|
RewardVault(rt.rewardVault).syncValue();
|
||||||
|
|
||||||
emit NewRewardToken(len, rewardToken);
|
emit NewRewardToken(len, rewardToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +187,12 @@ contract BaseMine is InitializableOwnable {
|
|||||||
_updateReward(address(0), i);
|
_updateReward(address(0), i);
|
||||||
RewardTokenInfo storage rt = rewardTokenInfos[i];
|
RewardTokenInfo storage rt = rewardTokenInfos[i];
|
||||||
|
|
||||||
|
|
||||||
|
uint256 totalDepositReward = RewardVault(rt.rewardVault)._TOTAL_REWARD_();
|
||||||
|
uint256 gap = newEndBlock.sub(rt.lastFlagBlock);
|
||||||
|
uint256 totalReward = rt.workThroughReward.add(gap.mul(rt.rewardPerBlock));
|
||||||
|
require(totalDepositReward >= totalReward, "DODOMineV3: REWARD_NOT_ENOUGH");
|
||||||
|
|
||||||
require(block.number < newEndBlock, "DODOMineV3: END_BLOCK_INVALID");
|
require(block.number < newEndBlock, "DODOMineV3: END_BLOCK_INVALID");
|
||||||
require(block.number > rt.startBlock, "DODOMineV3: NOT_START");
|
require(block.number > rt.startBlock, "DODOMineV3: NOT_START");
|
||||||
require(block.number < rt.endBlock, "DODOMineV3: ALREADY_CLOSE");
|
require(block.number < rt.endBlock, "DODOMineV3: ALREADY_CLOSE");
|
||||||
@@ -205,6 +215,11 @@ contract BaseMine is InitializableOwnable {
|
|||||||
rt.rewardPerBlock = newRewardPerBlock;
|
rt.rewardPerBlock = newRewardPerBlock;
|
||||||
rt.lastFlagBlock = block.number;
|
rt.lastFlagBlock = block.number;
|
||||||
|
|
||||||
|
uint256 totalDepositReward = RewardVault(rt.rewardVault)._TOTAL_REWARD_();
|
||||||
|
uint256 gap = rt.endBlock.sub(block.number);
|
||||||
|
uint256 totalReward = rt.workThroughReward.add(gap.mul(newRewardPerBlock));
|
||||||
|
require(totalDepositReward >= totalReward, "DODOMineV3: REWARD_NOT_ENOUGH");
|
||||||
|
|
||||||
emit UpdateReward(i, newRewardPerBlock);
|
emit UpdateReward(i, newRewardPerBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {IERC20} from "../../intf/IERC20.sol";
|
|||||||
interface IRewardVault {
|
interface IRewardVault {
|
||||||
function reward(address to, uint256 amount) external;
|
function reward(address to, uint256 amount) external;
|
||||||
function withdrawLeftOver(address to, uint256 amount) external;
|
function withdrawLeftOver(address to, uint256 amount) external;
|
||||||
function depositReward() external;
|
function syncValue() external;
|
||||||
function _TOTAL_REWARD_() external view returns(uint256);
|
function _TOTAL_REWARD_() external view returns(uint256);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ contract RewardVault is Ownable {
|
|||||||
IERC20(_REWARD_TOKEN_).safeTransfer(to, amount);
|
IERC20(_REWARD_TOKEN_).safeTransfer(to, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function depositReward() external {
|
function syncValue() external {
|
||||||
uint256 rewardBalance = IERC20(_REWARD_TOKEN_).balanceOf(address(this));
|
uint256 rewardBalance = IERC20(_REWARD_TOKEN_).balanceOf(address(this));
|
||||||
uint256 rewardInput = rewardBalance.sub(_REWARD_RESERVE_);
|
uint256 rewardInput = rewardBalance.sub(_REWARD_RESERVE_);
|
||||||
|
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2021 DODO ZOO.
|
|
||||||
SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pragma solidity 0.6.9;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
|
|
||||||
import {IDODOApproveProxy} from "../SmartRoute/DODOApproveProxy.sol";
|
|
||||||
import {IRewardVault} from "../DODOToken/DODOMineV3/RewardVault.sol";
|
|
||||||
import {ICloneFactory} from "../lib/CloneFactory.sol";
|
|
||||||
import {SafeMath} from "../lib/SafeMath.sol";
|
|
||||||
|
|
||||||
interface IMineV3 {
|
|
||||||
function init(address owner, address token) external;
|
|
||||||
|
|
||||||
function addRewardToken(
|
|
||||||
address rewardToken,
|
|
||||||
uint256 rewardPerBlock,
|
|
||||||
uint256 startBlock,
|
|
||||||
uint256 endBlock
|
|
||||||
) external;
|
|
||||||
|
|
||||||
function getVaultByRewardToken(address rewardToken) external view returns(address);
|
|
||||||
|
|
||||||
function directTransferOwnership(address newOwner) external;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @title DODOMineV3 Factory
|
|
||||||
* @author DODO Breeder
|
|
||||||
*
|
|
||||||
* @notice Create And Register DODOMineV3 Contracts
|
|
||||||
*/
|
|
||||||
contract DODOMineV3Factory is InitializableOwnable {
|
|
||||||
using SafeMath for uint256;
|
|
||||||
// ============ Templates ============
|
|
||||||
|
|
||||||
address public immutable _CLONE_FACTORY_;
|
|
||||||
address public _MINEV3_TEMPLATE_;
|
|
||||||
address public _DODO_APPROVE_PROXY_;
|
|
||||||
mapping (address => bool) public singleTokenList;
|
|
||||||
|
|
||||||
// minePool -> stakeToken
|
|
||||||
mapping(address => address) public _MINE_REGISTRY_;
|
|
||||||
// lpToken -> minePool
|
|
||||||
mapping(address => address) public _LP_REGISTRY_;
|
|
||||||
// singleToken -> minePool
|
|
||||||
mapping(address => address[]) public _SINGLE_REGISTRY_;
|
|
||||||
|
|
||||||
// ============ Events ============
|
|
||||||
|
|
||||||
event NewMineV3(address mine, address stakeToken, bool isLpToken);
|
|
||||||
event RemoveMineV3(address mine, address stakeToken);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
address cloneFactory,
|
|
||||||
address mineTemplate,
|
|
||||||
address dodoApproveProxy
|
|
||||||
) public {
|
|
||||||
_CLONE_FACTORY_ = cloneFactory;
|
|
||||||
_MINEV3_TEMPLATE_ = mineTemplate;
|
|
||||||
_DODO_APPROVE_PROXY_ = dodoApproveProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ Functions ============
|
|
||||||
|
|
||||||
function createDODOMineV3(
|
|
||||||
address stakeToken,
|
|
||||||
bool isLpToken,
|
|
||||||
address[] memory rewardTokens,
|
|
||||||
uint256[] memory rewardPerBlock,
|
|
||||||
uint256[] memory startBlock,
|
|
||||||
uint256[] memory endBlock
|
|
||||||
) external returns (address newMineV3) {
|
|
||||||
require(rewardTokens.length > 0, "REWARD_EMPTY");
|
|
||||||
require(rewardTokens.length == rewardPerBlock.length, "REWARD_PARAM_NOT_MATCH");
|
|
||||||
require(startBlock.length == rewardPerBlock.length, "REWARD_PARAM_NOT_MATCH");
|
|
||||||
require(endBlock.length == rewardPerBlock.length, "REWARD_PARAM_NOT_MATCH");
|
|
||||||
|
|
||||||
newMineV3 = ICloneFactory(_CLONE_FACTORY_).clone(_MINEV3_TEMPLATE_);
|
|
||||||
|
|
||||||
IMineV3(newMineV3).init(address(this), stakeToken);
|
|
||||||
|
|
||||||
for(uint i = 0; i<rewardTokens.length; i++) {
|
|
||||||
IMineV3(newMineV3).addRewardToken(
|
|
||||||
rewardTokens[i],
|
|
||||||
rewardPerBlock[i],
|
|
||||||
startBlock[i],
|
|
||||||
endBlock[i]
|
|
||||||
);
|
|
||||||
|
|
||||||
address rewardVault = IMineV3(newMineV3).getVaultByRewardToken(rewardTokens[i]);
|
|
||||||
uint256 rewardAmount = rewardPerBlock[i].mul(endBlock[i].sub(startBlock[i]));
|
|
||||||
IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(rewardTokens[i], msg.sender, rewardVault, rewardAmount);
|
|
||||||
IRewardVault(rewardVault).depositReward();
|
|
||||||
}
|
|
||||||
|
|
||||||
IMineV3(newMineV3).directTransferOwnership(msg.sender);
|
|
||||||
|
|
||||||
_MINE_REGISTRY_[newMineV3] = stakeToken;
|
|
||||||
if(isLpToken) {
|
|
||||||
_LP_REGISTRY_[stakeToken] = newMineV3;
|
|
||||||
}else {
|
|
||||||
require(_SINGLE_REGISTRY_[stakeToken].length == 0 || singleTokenList[stakeToken], "ALREADY_EXSIT_POOL");
|
|
||||||
_SINGLE_REGISTRY_[stakeToken].push(newMineV3);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit NewMineV3(newMineV3, stakeToken, isLpToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ Admin Operation Functions ============
|
|
||||||
|
|
||||||
function updateMineV2Template(address _newMineV3Template) external onlyOwner {
|
|
||||||
_MINEV3_TEMPLATE_ = _newMineV3Template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function addByAdmin(
|
|
||||||
address mine,
|
|
||||||
bool isLpToken,
|
|
||||||
address stakeToken
|
|
||||||
) external onlyOwner {
|
|
||||||
_MINE_REGISTRY_[mine] = stakeToken;
|
|
||||||
if(isLpToken) {
|
|
||||||
_LP_REGISTRY_[stakeToken] = mine;
|
|
||||||
}else {
|
|
||||||
require(_SINGLE_REGISTRY_[stakeToken].length == 0 || singleTokenList[stakeToken], "ALREADY_EXSIT_POOL");
|
|
||||||
_SINGLE_REGISTRY_[stakeToken].push(mine);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit NewMineV3(mine, stakeToken, isLpToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeByAdmin(
|
|
||||||
address mine,
|
|
||||||
bool isLpToken,
|
|
||||||
address stakeToken
|
|
||||||
) external onlyOwner {
|
|
||||||
_MINE_REGISTRY_[mine] = address(0);
|
|
||||||
if(isLpToken) {
|
|
||||||
_LP_REGISTRY_[stakeToken] = address(0);
|
|
||||||
}else {
|
|
||||||
uint256 len = _SINGLE_REGISTRY_[stakeToken].length;
|
|
||||||
for (uint256 i = 0; i < len; i++) {
|
|
||||||
if (stakeToken == _SINGLE_REGISTRY_[stakeToken][i]) {
|
|
||||||
if(i != len - 1) {
|
|
||||||
_SINGLE_REGISTRY_[stakeToken][i] = _SINGLE_REGISTRY_[stakeToken][len - 1];
|
|
||||||
}
|
|
||||||
_SINGLE_REGISTRY_[stakeToken].pop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit RemoveMineV3(mine, stakeToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
102
contracts/Factory/Registries/DODOMineV3Registry.sol
Normal file
102
contracts/Factory/Registries/DODOMineV3Registry.sol
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 DODO ZOO.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
|
||||||
|
|
||||||
|
interface IDODOMineV3Registry {
|
||||||
|
function addMineV3(
|
||||||
|
address mine,
|
||||||
|
bool isLpToken,
|
||||||
|
address stakeToken
|
||||||
|
) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title DODOMineV3 Registry
|
||||||
|
* @author DODO Breeder
|
||||||
|
*
|
||||||
|
* @notice Register DODOMineV3 Pools
|
||||||
|
*/
|
||||||
|
contract DODOMineV3Registry is InitializableOwnable, IDODOMineV3Registry {
|
||||||
|
|
||||||
|
mapping (address => bool) public isAdminListed;
|
||||||
|
mapping (address => bool) public singleTokenList;
|
||||||
|
|
||||||
|
// ============ Registry ============
|
||||||
|
// minePool -> stakeToken
|
||||||
|
mapping(address => address) public _MINE_REGISTRY_;
|
||||||
|
// lpToken -> minePool
|
||||||
|
mapping(address => address) public _LP_REGISTRY_;
|
||||||
|
// singleToken -> minePool
|
||||||
|
mapping(address => address[]) public _SINGLE_REGISTRY_;
|
||||||
|
|
||||||
|
|
||||||
|
// ============ Events ============
|
||||||
|
event NewMineV3(address mine, address stakeToken, bool isLpToken);
|
||||||
|
event RemoveMineV3(address mine, address stakeToken);
|
||||||
|
|
||||||
|
|
||||||
|
function addMineV3(
|
||||||
|
address mine,
|
||||||
|
bool isLpToken,
|
||||||
|
address stakeToken
|
||||||
|
) override external {
|
||||||
|
require(isAdminListed[msg.sender], "ACCESS_DENIED");
|
||||||
|
_MINE_REGISTRY_[mine] = stakeToken;
|
||||||
|
if(isLpToken) {
|
||||||
|
_LP_REGISTRY_[stakeToken] = mine;
|
||||||
|
}else {
|
||||||
|
require(_SINGLE_REGISTRY_[stakeToken].length == 0 || singleTokenList[stakeToken], "ALREADY_EXSIT_POOL");
|
||||||
|
_SINGLE_REGISTRY_[stakeToken].push(mine);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit NewMineV3(mine, stakeToken, isLpToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ Admin Operation Functions ============
|
||||||
|
|
||||||
|
function removeMineV3(
|
||||||
|
address mine,
|
||||||
|
bool isLpToken,
|
||||||
|
address stakeToken
|
||||||
|
) external onlyOwner {
|
||||||
|
_MINE_REGISTRY_[mine] = address(0);
|
||||||
|
if(isLpToken) {
|
||||||
|
_LP_REGISTRY_[stakeToken] = address(0);
|
||||||
|
}else {
|
||||||
|
uint256 len = _SINGLE_REGISTRY_[stakeToken].length;
|
||||||
|
for (uint256 i = 0; i < len; i++) {
|
||||||
|
if (mine == _SINGLE_REGISTRY_[stakeToken][i]) {
|
||||||
|
if(i != len - 1) {
|
||||||
|
_SINGLE_REGISTRY_[stakeToken][i] = _SINGLE_REGISTRY_[stakeToken][len - 1];
|
||||||
|
}
|
||||||
|
_SINGLE_REGISTRY_[stakeToken].pop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit RemoveMineV3(mine, stakeToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAdminList (address contractAddr) external onlyOwner {
|
||||||
|
isAdminListed[contractAddr] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAdminList (address contractAddr) external onlyOwner {
|
||||||
|
isAdminListed[contractAddr] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSingleTokenList(address token) external onlyOwner {
|
||||||
|
singleTokenList[token] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSingleTokenList(address token) external onlyOwner {
|
||||||
|
singleTokenList[token] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
131
contracts/SmartRoute/proxies/DODOMineV3Proxy.sol
Normal file
131
contracts/SmartRoute/proxies/DODOMineV3Proxy.sol
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2021 DODO ZOO.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
|
||||||
|
import {IDODOApproveProxy} from "../DODOApproveProxy.sol";
|
||||||
|
import {IRewardVault} from "../../DODOToken/DODOMineV3/RewardVault.sol";
|
||||||
|
import {IDODOMineV3Registry} from "../../Factory/Registries/DODOMineV3Registry.sol";
|
||||||
|
import {ICloneFactory} from "../../lib/CloneFactory.sol";
|
||||||
|
import {SafeMath} from "../../lib/SafeMath.sol";
|
||||||
|
|
||||||
|
interface IMineV3 {
|
||||||
|
function init(address owner, address token) external;
|
||||||
|
|
||||||
|
function addRewardToken(
|
||||||
|
address rewardToken,
|
||||||
|
uint256 rewardPerBlock,
|
||||||
|
uint256 startBlock,
|
||||||
|
uint256 endBlock
|
||||||
|
) external;
|
||||||
|
|
||||||
|
function directTransferOwnership(address newOwner) external;
|
||||||
|
|
||||||
|
function getVaultByRewardToken(address rewardToken) external view returns(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title DODOMineV3 Proxy
|
||||||
|
* @author DODO Breeder
|
||||||
|
*
|
||||||
|
* @notice Create And Register DODOMineV3 Contracts
|
||||||
|
*/
|
||||||
|
contract DODOMineV3Proxy is InitializableOwnable {
|
||||||
|
using SafeMath for uint256;
|
||||||
|
// ============ Templates ============
|
||||||
|
|
||||||
|
address public immutable _CLONE_FACTORY_;
|
||||||
|
address public immutable _DODO_APPROVE_PROXY_;
|
||||||
|
address public immutable _DODO_MINEV3_REGISTRY_;
|
||||||
|
address public _MINEV3_TEMPLATE_;
|
||||||
|
|
||||||
|
|
||||||
|
// ============ Events ============
|
||||||
|
event DepositRewardToVault(address mine, address rewardToken, uint256 amount);
|
||||||
|
event DepositRewardToMine(address mine, address rewardToken, uint256 amount);
|
||||||
|
event CreateMineV3(address account, address mineV3);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
address cloneFactory,
|
||||||
|
address mineTemplate,
|
||||||
|
address dodoApproveProxy,
|
||||||
|
address dodoMineV3Registry
|
||||||
|
) public {
|
||||||
|
_CLONE_FACTORY_ = cloneFactory;
|
||||||
|
_MINEV3_TEMPLATE_ = mineTemplate;
|
||||||
|
_DODO_APPROVE_PROXY_ = dodoApproveProxy;
|
||||||
|
_DODO_MINEV3_REGISTRY_ = dodoMineV3Registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ Functions ============
|
||||||
|
|
||||||
|
function createDODOMineV3(
|
||||||
|
address stakeToken,
|
||||||
|
bool isLpToken,
|
||||||
|
address[] memory rewardTokens,
|
||||||
|
uint256[] memory rewardPerBlock,
|
||||||
|
uint256[] memory startBlock,
|
||||||
|
uint256[] memory endBlock
|
||||||
|
) external returns (address newMineV3) {
|
||||||
|
require(rewardTokens.length > 0, "REWARD_EMPTY");
|
||||||
|
require(rewardTokens.length == rewardPerBlock.length, "REWARD_PARAM_NOT_MATCH");
|
||||||
|
require(startBlock.length == rewardPerBlock.length, "REWARD_PARAM_NOT_MATCH");
|
||||||
|
require(endBlock.length == rewardPerBlock.length, "REWARD_PARAM_NOT_MATCH");
|
||||||
|
|
||||||
|
newMineV3 = ICloneFactory(_CLONE_FACTORY_).clone(_MINEV3_TEMPLATE_);
|
||||||
|
|
||||||
|
IMineV3(newMineV3).init(address(this), stakeToken);
|
||||||
|
|
||||||
|
for(uint i = 0; i<rewardTokens.length; i++) {
|
||||||
|
uint256 rewardAmount = rewardPerBlock[i].mul(endBlock[i].sub(startBlock[i]));
|
||||||
|
IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(rewardTokens[i], msg.sender, newMineV3, rewardAmount);
|
||||||
|
IMineV3(newMineV3).addRewardToken(
|
||||||
|
rewardTokens[i],
|
||||||
|
rewardPerBlock[i],
|
||||||
|
startBlock[i],
|
||||||
|
endBlock[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMineV3(newMineV3).directTransferOwnership(msg.sender);
|
||||||
|
|
||||||
|
IDODOMineV3Registry(_DODO_MINEV3_REGISTRY_).addMineV3(newMineV3, isLpToken, stakeToken);
|
||||||
|
|
||||||
|
emit CreateMineV3(msg.sender, newMineV3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function depositRewardToVault(
|
||||||
|
address mineV3,
|
||||||
|
address rewardToken,
|
||||||
|
uint256 amount
|
||||||
|
) external {
|
||||||
|
address rewardVault = IMineV3(mineV3).getVaultByRewardToken(rewardToken);
|
||||||
|
IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(rewardToken, msg.sender, rewardVault, amount);
|
||||||
|
IRewardVault(rewardVault).syncValue();
|
||||||
|
|
||||||
|
emit DepositRewardToVault(mineV3,rewardToken,amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function depositRewardToMine(
|
||||||
|
address mineV3,
|
||||||
|
address rewardToken,
|
||||||
|
uint256 amount
|
||||||
|
) external {
|
||||||
|
require(mineV3 != address(0), "MINE_EMPTY");
|
||||||
|
IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(rewardToken, msg.sender, mineV3, amount);
|
||||||
|
|
||||||
|
emit DepositRewardToMine(mineV3,rewardToken,amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ Admin Operation Functions ============
|
||||||
|
|
||||||
|
function updateMineV2Template(address _newMineV3Template) external onlyOwner {
|
||||||
|
_MINEV3_TEMPLATE_ = _newMineV3Template;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user