DODO Mine reward vault & reader

This commit is contained in:
mingda
2020-10-04 10:47:47 +08:00
parent 4dd24368cf
commit d983485948
7 changed files with 104 additions and 12 deletions

View File

@@ -8,6 +8,7 @@
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface IDODO {
function init(
address owner,
@@ -42,6 +43,8 @@ interface IDODO {
function queryBuyBaseToken(uint256 amount) external view returns (uint256 payQuote);
function getExpectedTarget() external view returns (uint256 baseTarget, uint256 quoteTarget);
function depositBaseTo(address to, uint256 amount) external returns (uint256);
function withdrawBase(uint256 amount) external returns (uint256);
@@ -54,9 +57,9 @@ interface IDODO {
function withdrawAllQuote() external returns (uint256);
function _BASE_CAPITAL_TOKEN_() external returns (address);
function _BASE_CAPITAL_TOKEN_() external view returns (address);
function _QUOTE_CAPITAL_TOKEN_() external returns (address);
function _QUOTE_CAPITAL_TOKEN_() external view returns (address);
function _BASE_TOKEN_() external returns (address);

View File

@@ -13,6 +13,7 @@ import {DecimalMath} from "../lib/DecimalMath.sol";
import {SafeERC20} from "../lib/SafeERC20.sol";
import {SafeMath} from "../lib/SafeMath.sol";
import {IERC20} from "../intf/IERC20.sol";
import {IDODORewardVault, DODORewardVault} from "./DODORewardVault.sol";
contract DODOMine is Ownable {
@@ -44,7 +45,7 @@ contract DODOMine is Ownable {
uint256 accDODOPerShare; // Accumulated DODOs per share, times 1e12. See below.
}
address public dodoToken;
address public dodoRewardVault;
uint256 public dodoPerBlock;
// Info of each pool.
@@ -65,7 +66,7 @@ contract DODOMine is Ownable {
event Claim(address indexed user, uint256 amount);
constructor(address _dodoToken, uint256 _startBlock) public {
dodoToken = _dodoToken;
dodoRewardVault = address(new DODORewardVault(_dodoToken));
startBlock = _startBlock;
}
@@ -307,9 +308,9 @@ contract DODOMine is Ownable {
safeDODOTransfer(msg.sender, pending);
}
// Safe DODO transfer function, just in case if rounding error causes pool to not have enough DODOs.
// Safe DODO transfer function
function safeDODOTransfer(address _to, uint256 _amount) internal {
IERC20(dodoToken).safeTransfer(_to, _amount);
IDODORewardVault(dodoRewardVault).reward(_to, _amount);
realizedReward[_to] = realizedReward[_to].add(_amount);
emit Claim(_to, _amount);
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IDODO} from "../intf/IDODO.sol";
import {IERC20} from "../intf/IERC20.sol";
import {SafeMath} from "../lib/SafeMath.sol";
interface IDODOMine {
function getUserLpBalance(address _lpToken, address _user) external view returns (uint256);
}
contract DODOMineReader {
using SafeMath for uint256;
function getUserStakedBalance(
address _dodoMine,
address _dodo,
address _user
) external view returns (uint256 baseBalance, uint256 quoteBalance) {
address baseLpToken = IDODO(_dodo)._BASE_CAPITAL_TOKEN_();
address quoteLpToken = IDODO(_dodo)._QUOTE_CAPITAL_TOKEN_();
uint256 baseLpBalance = IDODOMine(_dodoMine).getUserLpBalance(baseLpToken, _user);
uint256 quoteLpBalance = IDODOMine(_dodoMine).getUserLpBalance(quoteLpToken, _user);
uint256 baseLpTotalSupply = IERC20(baseLpToken).totalSupply();
uint256 quoteLpTotalSupply = IERC20(quoteLpToken).totalSupply();
(uint256 baseTarget, uint256 quoteTarget) = IDODO(_dodo).getExpectedTarget();
baseBalance = baseTarget.mul(baseLpBalance).div(baseLpTotalSupply);
quoteBalance = quoteTarget.mul(quoteLpBalance).div(quoteLpTotalSupply);
return (baseBalance, quoteBalance);
}
}

View File

@@ -0,0 +1,33 @@
/*
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 {SafeERC20} from "../lib/SafeERC20.sol";
import {IERC20} from "../intf/IERC20.sol";
interface IDODORewardVault {
function reward(address to, uint256 amount) external;
}
contract DODORewardVault is Ownable {
using SafeERC20 for IERC20;
address public dodoToken;
constructor(address _dodoToken) public {
dodoToken = _dodoToken;
}
function reward(address to, uint256 amount) external onlyOwner {
IERC20(dodoToken).safeTransfer(to, amount);
}
}

View File

@@ -19,7 +19,7 @@ contract DODOToken {
using SafeMath for uint256;
string public symbol = "DODO";
string public name = "DODO bird food";
string public name = "DODO bird";
uint256 public decimals = 18;
uint256 public totalSupply = 1000000000 * 10**18; // 1 Billion

View File

@@ -8,7 +8,7 @@
import { DODOContext, getDODOContext } from './utils/Context';
import { decimalStr, MAX_UINT256 } from './utils/Converter';
// import * as assert from "assert"
import { newContract, DODO_TOKEN_CONTRACT_NAME, DODO_MINE_NAME, TEST_ERC20_CONTRACT_NAME, getContractWithAddress } from './utils/Contracts';
import { newContract, DODO_TOKEN_CONTRACT_NAME, DODO_MINE_NAME, TEST_ERC20_CONTRACT_NAME, getContractWithAddress, DODO_MINE_READER_NAME } from './utils/Contracts';
import { Contract } from 'web3-eth-contract';
import { assert } from 'chai';
import { logGas } from './utils/Log';
@@ -17,6 +17,7 @@ let BaseDLP: Contract
let QuoteDLP: Contract
let DODOToken: Contract
let DODOMine: Contract
let DODOMineReader: Contract
let lp1: string;
let lp2: string;
@@ -38,6 +39,7 @@ async function init(ctx: DODOContext): Promise<void> {
DODOToken = await newContract(DODO_TOKEN_CONTRACT_NAME)
DODOMine = await newContract(DODO_MINE_NAME, [DODOToken.options.address, (await ctx.Web3.eth.getBlockNumber()).toString()])
DODOMineReader = await newContract(DODO_MINE_READER_NAME)
BaseDLP = await getContractWithAddress(TEST_ERC20_CONTRACT_NAME, await ctx.DODO.methods._BASE_CAPITAL_TOKEN_().call())
QuoteDLP = await getContractWithAddress(TEST_ERC20_CONTRACT_NAME, await ctx.DODO.methods._QUOTE_CAPITAL_TOKEN_().call())
@@ -48,10 +50,12 @@ async function init(ctx: DODOContext): Promise<void> {
await BaseDLP.methods.approve(DODOMine.options.address, MAX_UINT256).send(ctx.sendParam(lp2))
await QuoteDLP.methods.approve(DODOMine.options.address, MAX_UINT256).send(ctx.sendParam(lp2))
await DODOMine.methods.setReward(decimalStr("100")).send(ctx.sendParam(ctx.Deployer))
await DODOMine.methods.setReward(decimalStr("100"), true).send(ctx.sendParam(ctx.Deployer))
await DODOMine.methods.addLpToken(BaseDLP.options.address, "1", true).send(ctx.sendParam(ctx.Deployer))
await DODOMine.methods.addLpToken(QuoteDLP.options.address, "2", true).send(ctx.sendParam(ctx.Deployer))
await DODOToken.methods.transfer(DODOMine.options.address, decimalStr("100000000")).send(ctx.sendParam(ctx.Deployer))
const rewardVault = await DODOMine.methods.dodoRewardVault().call()
await DODOToken.methods.transfer(rewardVault, decimalStr("100000000")).send(ctx.sendParam(ctx.Deployer))
}
describe("Lock DODO Token", () => {
@@ -73,7 +77,7 @@ describe("Lock DODO Token", () => {
});
describe("Lp Deposit", () => {
it.only("single lp deposit", async () => {
it("single lp deposit", async () => {
await logGas(DODOMine.methods.deposit(BaseDLP.options.address, decimalStr("100")), ctx.sendParam(lp1), "deposit")
await ctx.EVM.fastMove(100)
assert.equal(await DODOMine.methods.getPendingReward(BaseDLP.options.address, lp1).call(), "3333333333333333333300")
@@ -99,7 +103,7 @@ describe("Lock DODO Token", () => {
assert.equal(await DODOMine.methods.getAllPendingReward(lp2).call(), "8366666666666666666600")
})
it("lp multi deposit and withdraw", async () => {
it.only("lp multi deposit and withdraw", async () => {
await DODOMine.methods.deposit(BaseDLP.options.address, decimalStr("100")).send(ctx.sendParam(lp2))
await DODOMine.methods.deposit(BaseDLP.options.address, decimalStr("100")).send(ctx.sendParam(lp1))
await ctx.EVM.fastMove(100)
@@ -112,6 +116,10 @@ describe("Lock DODO Token", () => {
assert.equal(await DODOMine.methods.getAllPendingReward(lp1).call(), "0")
assert.equal(await DODOToken.methods.balanceOf(lp1).call(), "2805555555555555555500")
assert.equal(await DODOMine.methods.getRealizedReward(lp1).call(), "2805555555555555555500")
var balance = await DODOMineReader.methods.getUserStakedBalance(DODOMine.options.address, ctx.DODO.options.address, lp1).call()
assert.equal(balance.baseBalance, decimalStr("100"))
assert.equal(balance.quoteBalance, decimalStr("0"))
})
it("lp claim", async () => {

View File

@@ -22,6 +22,7 @@ const Uniswap = require(`${jsonPath}UniswapV2Pair.json`)
const UniswapArbitrageur = require(`${jsonPath}UniswapArbitrageur.json`)
const DODOToken = require(`${jsonPath}DODOToken.json`)
const DODOMine = require(`${jsonPath}DODOMine.json`)
const DODOMineReader = require(`${jsonPath}DODOMineReader.json`)
const LockedTokenVault = require(`${jsonPath}LockedTokenVault.json`)
import { getDefaultWeb3 } from './EVM';
@@ -41,6 +42,7 @@ export const UNISWAP_ARBITRAGEUR_CONTRACT_NAME = "UniswapArbitrageur"
export const DODO_TOKEN_CONTRACT_NAME = "DODOToken"
export const LOCKED_TOKEN_VAULT_CONTRACT_NAME = "LockedTokenVault"
export const DODO_MINE_NAME = "DODOMine"
export const DODO_MINE_READER_NAME = "DODOMineReader"
var contractMap: { [name: string]: any } = {}
contractMap[CLONE_FACTORY_CONTRACT_NAME] = CloneFactory
@@ -56,6 +58,7 @@ contractMap[UNISWAP_ARBITRAGEUR_CONTRACT_NAME] = UniswapArbitrageur
contractMap[DODO_TOKEN_CONTRACT_NAME] = DODOToken
contractMap[LOCKED_TOKEN_VAULT_CONTRACT_NAME] = LockedTokenVault
contractMap[DODO_MINE_NAME] = DODOMine
contractMap[DODO_MINE_READER_NAME] = DODOMineReader
interface ContractJson {
abi: any;