update mineV3

This commit is contained in:
owen05
2021-06-09 12:29:36 +08:00
parent 546c25653b
commit aebf0275bb
6 changed files with 256 additions and 193 deletions

View File

@@ -172,6 +172,10 @@ contract BaseMine is InitializableOwnable {
rt.rewardPerBlock = rewardPerBlock;
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);
}
@@ -183,6 +187,12 @@ contract BaseMine is InitializableOwnable {
_updateReward(address(0), 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 > rt.startBlock, "DODOMineV3: NOT_START");
require(block.number < rt.endBlock, "DODOMineV3: ALREADY_CLOSE");
@@ -205,6 +215,11 @@ contract BaseMine is InitializableOwnable {
rt.rewardPerBlock = newRewardPerBlock;
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);
}

View File

@@ -16,7 +16,7 @@ import {IERC20} from "../../intf/IERC20.sol";
interface IRewardVault {
function reward(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);
}
@@ -47,7 +47,7 @@ contract RewardVault is Ownable {
IERC20(_REWARD_TOKEN_).safeTransfer(to, amount);
}
function depositReward() external {
function syncValue() external {
uint256 rewardBalance = IERC20(_REWARD_TOKEN_).balanceOf(address(this));
uint256 rewardInput = rewardBalance.sub(_REWARD_RESERVE_);

View File

@@ -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);
}
}

View 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;
}
}

View 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;
}
}