nft test ing

This commit is contained in:
owen05
2021-04-12 00:53:59 +08:00
parent 805f639c3a
commit 0bace9f613
7 changed files with 361 additions and 124 deletions

View File

@@ -63,7 +63,7 @@ module.exports = {
//================== NFT ====================
ConstFeeRateModel: "0xBDAcEcF886a4F0C509260d9678D5673C3E8fa4b7",
FeeDistributor: "0x1eD92Fe9c3AE1cC427004eC27AAd96df4928B3ec",
FeeDistributor: "",
Fragment: "0x64193839f8b6e85A257411a945085783cbA9976B",
NFTCollateralVault: "0xFDf7604649dfBb733e784afAEdC19892706cc683",
DODONFTRouteHelper: "0xAE683548702be6d651e179e5F9313272bb18596A",
@@ -73,6 +73,6 @@ module.exports = {
NFTTokenFactory: "0x38c109aF4f3454172BA4eecf5676aA213b589e75",
DODONFTRegistry: "0xF405372b7808363DCfbb5Eb81204889B7a69Aa3e",
DODONFTProxy: "0x622332C5e5B3E8B67Aee300184Ce024E428A89f8",
DODONFTProxy: "",
}
}

View File

@@ -29,15 +29,15 @@ contract FeeDistributor {
uint256 public _STAKE_RESERVE_;
uint256 public _BASE_REWARD_RATIO_;
mapping(address => uint256) internal _USER_BASE_REWARDS_;
mapping(address => uint256) internal _USER_BASE_PER_SHARE_;
uint256 public _QUOTE_REWARD_RATIO_;
mapping(address => uint256) internal _USER_QUOTE_REWARDS_;
mapping(address => uint256) internal _USER_QUOTE_PER_SHARE_;
mapping(address => uint256) public _USER_BASE_REWARDS_;
mapping(address => uint256) public _USER_BASE_PER_SHARE_;
uint256 public _QUOTE_REWARD_RATIO_;
mapping(address => uint256) public _USER_QUOTE_REWARDS_;
mapping(address => uint256) public _USER_QUOTE_PER_SHARE_;
mapping(address => uint256) public _SHARES_;
mapping(address => uint256) internal _SHARES_;
bool internal _FEE_INITIALIZED_;
// ============ Event ============
@@ -46,13 +46,13 @@ contract FeeDistributor {
event Claim(address sender, uint256 baseAmount, uint256 quoteAmount);
function init(
address baseToken,
address quoteToken,
address stakeToken
address baseToken,
address quoteToken,
address stakeToken
) external {
require(!_FEE_INITIALIZED_, "ALREADY_INITIALIZED");
_FEE_INITIALIZED_ = true;
_BASE_TOKEN_ = baseToken;
_QUOTE_TOKEN_ = quoteToken;
_STAKE_TOKEN_ = stakeToken;
@@ -60,86 +60,126 @@ contract FeeDistributor {
}
function stake(address to) external {
_updateGlobalState();
_updateUserReward(to);
uint256 stakeVault = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
uint256 stakeInput = stakeVault.sub(_STAKE_RESERVE_);
_addShares(stakeInput, to);
emit Stake(to, stakeInput);
_updateGlobalState();
_updateUserReward(to);
uint256 stakeVault = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
uint256 stakeInput = stakeVault.sub(_STAKE_RESERVE_);
_addShares(stakeInput, to);
emit Stake(to, stakeInput);
}
function claim(address to) external {
_updateGlobalState();
_updateUserReward(msg.sender);
_claim(msg.sender, to);
_updateGlobalState();
_updateUserReward(msg.sender);
_claim(msg.sender, to);
}
function unstake(uint256 amount, address to, bool withClaim) external {
require(_SHARES_[msg.sender]>=amount, "STAKE BALANCE ONT ENOUGH");
_updateGlobalState();
_updateUserReward(msg.sender);
function unstake(
uint256 amount,
address to,
bool withClaim
) external {
require(_SHARES_[msg.sender] >= amount, "STAKE BALANCE ONT ENOUGH");
_updateGlobalState();
_updateUserReward(msg.sender);
if (withClaim) {
_claim(msg.sender, to);
}
if (withClaim) {
_claim(msg.sender, to);
}
_removeShares(amount, msg.sender);
StakeVault(_STAKE_VAULT_).transferOut(_STAKE_TOKEN_, amount, to);
emit UnStake(msg.sender, amount);
StakeVault(_STAKE_VAULT_).transferOut(_STAKE_TOKEN_, amount, to);
_removeShares(amount, msg.sender);
emit UnStake(msg.sender, amount);
}
// ============ View ================
function getPendingReward(address user)
external
view
returns (uint256 baseReward, uint256 quoteReward)
{
uint256 baseInput = IERC20(_BASE_TOKEN_).balanceOf(address(this)).sub(_BASE_RESERVE_);
uint256 quoteInput = IERC20(_QUOTE_TOKEN_).balanceOf(address(this)).sub(_QUOTE_RESERVE_);
uint256 baseRwardRatio = _BASE_REWARD_RATIO_;
uint256 quoteRewardRatio = _QUOTE_REWARD_RATIO_;
if (_STAKE_RESERVE_ != 0) {
baseRwardRatio = _BASE_REWARD_RATIO_.add(
DecimalMath.divFloor(baseInput, _STAKE_RESERVE_)
);
quoteRewardRatio = _QUOTE_REWARD_RATIO_.add(
DecimalMath.divFloor(quoteInput, _STAKE_RESERVE_)
);
}
baseReward = DecimalMath
.mulFloor(_SHARES_[user], baseRwardRatio.sub(_USER_BASE_PER_SHARE_[user]))
.add(_USER_BASE_REWARDS_[user]);
quoteReward = DecimalMath
.mulFloor(_SHARES_[user], quoteRewardRatio.sub(_USER_QUOTE_PER_SHARE_[user]))
.add(_USER_QUOTE_REWARDS_[user]);
}
// ============ Internal ============
function _claim(address sender, address to) internal {
uint256 allBase = _USER_BASE_REWARDS_[sender];
uint256 allQuote = _USER_QUOTE_REWARDS_[sender];
IERC20(_BASE_TOKEN_).safeTransfer(to, allBase);
IERC20(_QUOTE_TOKEN_).safeTransfer(to, allQuote);
_USER_BASE_REWARDS_[sender] = 0;
_USER_BASE_REWARDS_[sender] = 0;
emit Claim(sender, allBase, allQuote);
uint256 allBase = _USER_BASE_REWARDS_[sender];
uint256 allQuote = _USER_QUOTE_REWARDS_[sender];
IERC20(_BASE_TOKEN_).safeTransfer(to, allBase);
IERC20(_QUOTE_TOKEN_).safeTransfer(to, allQuote);
_BASE_RESERVE_ = _BASE_RESERVE_.sub(allBase);
_QUOTE_RESERVE_ = _QUOTE_RESERVE_.sub(allQuote);
_USER_BASE_REWARDS_[sender] = 0;
_USER_QUOTE_REWARDS_[sender] = 0;
emit Claim(sender, allBase, allQuote);
}
function _updateGlobalState() internal {
uint256 baseInput = IERC20(_BASE_TOKEN_).balanceOf(address(this)).sub(_BASE_RESERVE_);
uint256 quoteInput = IERC20(_QUOTE_TOKEN_).balanceOf(address(this)).sub(_QUOTE_RESERVE_);
_BASE_REWARD_RATIO_ = _BASE_REWARD_RATIO_.add(DecimalMath.divFloor(baseInput, _STAKE_RESERVE_));
_QUOTE_REWARD_RATIO_ = _QUOTE_REWARD_RATIO_.add(DecimalMath.divFloor(quoteInput, _STAKE_RESERVE_));
_BASE_RESERVE_ = _BASE_RESERVE_.add(baseInput);
_QUOTE_RESERVE_ = _QUOTE_RESERVE_.add(quoteInput);
uint256 baseInput = IERC20(_BASE_TOKEN_).balanceOf(address(this)).sub(_BASE_RESERVE_);
uint256 quoteInput = IERC20(_QUOTE_TOKEN_).balanceOf(address(this)).sub(_QUOTE_RESERVE_);
if (_STAKE_RESERVE_ != 0) {
_BASE_REWARD_RATIO_ = _BASE_REWARD_RATIO_.add(
DecimalMath.divFloor(baseInput, _STAKE_RESERVE_)
);
_QUOTE_REWARD_RATIO_ = _QUOTE_REWARD_RATIO_.add(
DecimalMath.divFloor(quoteInput, _STAKE_RESERVE_)
);
}
_BASE_RESERVE_ = _BASE_RESERVE_.add(baseInput);
_QUOTE_RESERVE_ = _QUOTE_RESERVE_.add(quoteInput);
}
function _updateUserReward(address user) internal {
_USER_BASE_REWARDS_[user] = DecimalMath.mulFloor(
_SHARES_[user],
_BASE_REWARD_RATIO_.sub(_USER_BASE_PER_SHARE_[user])
).add(_USER_BASE_REWARDS_[user]);
_USER_BASE_REWARDS_[user] = DecimalMath
.mulFloor(_SHARES_[user], _BASE_REWARD_RATIO_.sub(_USER_BASE_PER_SHARE_[user]))
.add(_USER_BASE_REWARDS_[user]);
_USER_BASE_PER_SHARE_[user] = _BASE_REWARD_RATIO_;
_USER_QUOTE_REWARDS_[user] = DecimalMath.mulFloor(
_SHARES_[user],
_QUOTE_REWARD_RATIO_.sub(_USER_QUOTE_PER_SHARE_[user])
).add(_USER_QUOTE_REWARDS_[user]);
_USER_QUOTE_REWARDS_[user] = DecimalMath
.mulFloor(_SHARES_[user], _QUOTE_REWARD_RATIO_.sub(_USER_QUOTE_PER_SHARE_[user]))
.add(_USER_QUOTE_REWARDS_[user]);
_USER_QUOTE_PER_SHARE_[user] = _QUOTE_REWARD_RATIO_;
}
function _addShares(uint256 amount, address to) internal {
_SHARES_[to] = _SHARES_[to].add(amount);
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
_SHARES_[to] = _SHARES_[to].add(amount);
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
}
function _removeShares(uint256 amount, address from) internal {
_SHARES_[from] = _SHARES_[from].sub(amount);
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
_SHARES_[from] = _SHARES_[from].sub(amount);
_STAKE_RESERVE_ = IERC20(_STAKE_TOKEN_).balanceOf(_STAKE_VAULT_);
}
}
contract StakeVault is Ownable {
using SafeERC20 for IERC20;
function transferOut(
address token,
uint256 amount,

View File

@@ -95,11 +95,10 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable {
emit CreateNFTCollateralVault(msg.sender, newVault, name, baseURI);
}
//Stake 碎片
function createFragment(
address quoteToken,
address vaultPreOwner,
address stakeToken,
address stakeToken, //address(0) using frag token
uint256[] calldata dvmParams, //0 - lpFeeRate, 1 - mtFeeRate 2 - I, 3 - K
uint256[] calldata fragParams, //0 - totalSupply, 1 - ownerRatio, 2 - buyoutTimestamp
bool isOpenTwap
@@ -108,11 +107,11 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable {
address _quoteToken = quoteToken == _ETH_ADDRESS_ ? _WETH_ : quoteToken;
if(stakeToken == address(0)) {
newFeeDistributor = address(0);
} else {
newFeeDistributor = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_TEMPLATE_);
IFeeDistributor(newFeeDistributor).init(newFragment, _quoteToken, stakeToken);
}
stakeToken = newFragment;
}
newFeeDistributor = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_TEMPLATE_);
IFeeDistributor(newFeeDistributor).init(newFragment, _quoteToken, stakeToken);
{
uint256[] memory _dvmParams = dvmParams;
@@ -161,7 +160,9 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable {
uint256 stakeAmount,
uint8 flag // 0 - ERC20, 1 - ETH
) external payable preventReentrant {
_deposit(msg.sender, feeDistributor, IFeeDistributor(feeDistributor)._STAKE_TOKEN_(), stakeAmount, flag == 1);
address stakeVault = IFeeDistributor(feeDistributor)._STAKE_VAULT_();
require(stakeVault != address(0), "DODONFTProxy:STAKE_VAULT_EMPTY");
_deposit(msg.sender, stakeVault, IFeeDistributor(feeDistributor)._STAKE_TOKEN_(), stakeAmount, flag == 1);
IFeeDistributor(feeDistributor).stake(msg.sender);
emit Stake(msg.sender, feeDistributor, stakeAmount);
}

View File

@@ -18,4 +18,6 @@ interface IFeeDistributor {
function _STAKE_TOKEN_() external view returns(address);
function _STAKE_VAULT_() external view returns(address);
}

View File

@@ -4,12 +4,11 @@
SPDX-License-Identifier: Apache-2.0
*/
import { decimalStr, mweiStr } from '../utils/Converter';
import { decimalStr, mweiStr, fromWei } from '../utils/Converter';
import { logGas } from '../utils/Log';
import { NFTContext, getDODONftContext } from '../utils/NFTContext';
import { assert } from 'chai';
import * as contracts from '../utils/Contracts';
import { Contract } from 'web3-eth-contract';
let author: string;
let user1: string;
@@ -23,26 +22,73 @@ async function init(ctx: NFTContext): Promise<void> {
await ctx.mintTestToken(user1, ctx.USDT, mweiStr("10000"));
await ctx.mintTestToken(user2, ctx.USDT, mweiStr("10000"));
await ctx.approveProxy(user1);
await ctx.approveProxy(user2);
await ctx.approveProxy(ctx.USDT, user1);
await ctx.approveProxy(ctx.USDT, user2);
}
async function createNFTVault(ctx: NFTContext) {
var tx = await ctx.NFTProxy.methods.createNFTCollateralVault(
"DODONFT",
"https://app.dodoex.io"
).send(ctx.sendParam(author));
async function getFeeGlobalState(ctx: NFTContext, feeAddress: string, baseToken, quoteToken, stakeToken) {
let feeInstance = contracts.getContractWithAddress(contracts.NFT_FEE, feeAddress);
let baseReserve = await feeInstance.methods._BASE_RESERVE_().call();
let quoteReserve = await feeInstance.methods._QUOTE_RESERVE_().call();
let baseBalance = await baseToken.methods.balanceOf(feeAddress).call();
let quoteBalance = await quoteToken.methods.balanceOf(feeAddress).call();
let stakeVault = await feeInstance.methods._STAKE_VAULT_().call();
let stakeBalance = await stakeToken.methods.balanceOf(stakeVault).call();
let stakeReserve = await feeInstance.methods._STAKE_RESERVE_().call();
let baseRatio = await feeInstance.methods._BASE_REWARD_RATIO_().call();
let quoteRatio = await feeInstance.methods._QUOTE_REWARD_RATIO_().call();
return tx.events['CreateNFTCollateralVault']['returnValues']['vault'];
console.log("fee baseBalance:" + fromWei(baseBalance, 'ether') + " quoteBalance:" + fromWei(quoteBalance, 'mwei') + " vault stakeBalance:" + fromWei(stakeBalance, 'ether'));
console.log("fee baseReserve:" + fromWei(baseReserve, 'ether') + " quoteReserve:" + fromWei(quoteReserve, 'mwei') + " stakeReserve:" + fromWei(stakeReserve, 'ether'));
console.log("baseRatio:" + fromWei(baseRatio, 'ether') + " quoteRatio:" + fromWei(quoteRatio, 'mwei'));
return {
"baseReserve": baseReserve,
"quoteReserve": quoteReserve,
"stakeReserve": stakeReserve,
"baseBalance": baseBalance,
"quoteBalance": quoteBalance,
"stakeBalance": stakeBalance,
"baseRatio": baseRatio,
"quoteRatio": quoteRatio
}
}
async function createERC721(ctx:NFTContext) {
var tx = await ctx.NFTTokenFacotry.methods.createERC721(
"https://app.dodoex.io"
).send(ctx.sendParam(author));
return tx.events['NewERC721']['returnValues']['erc721'];
async function getFeeUserState(ctx: NFTContext, feeAddress: string, userAddress: string) {
let feeInstance = contracts.getContractWithAddress(contracts.NFT_FEE, feeAddress);
let userShares = await feeInstance.methods._SHARES_(userAddress).call();
let [baseRewards, quoteRewards] = await feeInstance.methods.getPendingReward(userAddress).call();
let userBasePerShares = await feeInstance.methods._USER_BASE_PER_SHARE_(userAddress).call();
let userQuotePerShares = await feeInstance.methods._USER_QUOTE_PER_SHARE_(userAddress).call();
console.log("user shares:" + fromWei(userShares, 'ether'));
console.log("user baseRewards:" + fromWei(baseRewards, 'ether') + " userQuoteRewards:" + fromWei(quoteRewards, 'mwei'));
console.log("user basePerShares:" + fromWei(userBasePerShares, 'ether') + " userQuotePerShares:" + fromWei(userQuotePerShares, 'mwei'));
return {
"userShares": userShares,
"userBaseRewards": baseRewards,
"userQuoteRewards": quoteRewards,
"userBasePerShares": userBasePerShares,
"userQuotePerShares": userQuotePerShares
}
}
async function mockTrade(ctx: NFTContext, dvmAddress: string, dvmInstance, fragInstance) {
await ctx.transferQuoteToDVM(ctx.USDT, dvmAddress, user1, mweiStr("20"));
await dvmInstance.methods.sellQuote(user1).send(ctx.sendParam(user1));
await ctx.transferBaseToDVM(fragInstance, dvmAddress, user1, decimalStr("10"));
await dvmInstance.methods.sellBase(user1).send(ctx.sendParam(user1));
await ctx.transferQuoteToDVM(ctx.USDT, dvmAddress, user2, mweiStr("80"));
await dvmInstance.methods.sellQuote(user2).send(ctx.sendParam(user2));
await ctx.transferBaseToDVM(fragInstance, dvmAddress, user2, decimalStr("20"));
await dvmInstance.methods.sellBase(user2).send(ctx.sendParam(user2));
}
describe("DODONFT", () => {
let snapshotId: string;
@@ -74,41 +120,43 @@ describe("DODONFT", () => {
});
it("createTokenAndTransferToVault", async () => {
var erc721Address = await createERC721(ctx);
var vaultAddress = await createNFTVault(ctx);
var erc721Address = await ctx.createERC721(ctx, author);
var vaultAddress = await ctx.createNFTVault(ctx, author);
var nftVaultInstance = contracts.getContractWithAddress(contracts.NFT_VAULT, vaultAddress);
var erc721Instance = contracts.getContractWithAddress(contracts.ERC721, erc721Address);
await erc721Instance.methods.safeTransferFrom(author, vaultAddress, 0).send(ctx.sendParam(author));
var nftIndex = await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc721Address,0).call();
var nftIndex = await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc721Address, 0).call();
var nftInfo = await nftVaultInstance.methods.getNftInfoById(nftIndex).call();
assert(nftInfo.amount, '1')
assert(nftInfo.tokenId, '0')
});
it.only("createFragment", async () => {
var erc721Address = await createERC721(ctx);
var vaultAddress = await createNFTVault(ctx);
it("createFragment", async () => {
var erc721Address = await ctx.createERC721(ctx, author);
var vaultAddress = await ctx.createNFTVault(ctx, author);
var nftVaultInstance = contracts.getContractWithAddress(contracts.NFT_VAULT, vaultAddress);
var erc721Instance = contracts.getContractWithAddress(contracts.ERC721, erc721Address);
await erc721Instance.methods.safeTransferFrom(author, vaultAddress, 0).send(ctx.sendParam(author));
var quoteToken = "0x156595bAF85D5C29E91d959889B022d952190A64";
var vaultPreOwner = "0xaac153c1344cA14497A5dd22b1F70C28793625aa";
var stakeToken = "0x854b0f89BAa9101e49Bfb357A38071C9db5d0DFa";
// var quoteToken = ctx.USDT.options.address;
// var vaultPreOwner = author;
// var stakeToken = "0x0000000000000000000000000000000000000000";
// var quoteToken = "0x156595bAF85D5C29E91d959889B022d952190A64";
// var vaultPreOwner = "0xaac153c1344cA14497A5dd22b1F70C28793625aa";
// var stakeToken = "0x854b0f89BAa9101e49Bfb357A38071C9db5d0DFa";
var quoteToken = ctx.USDT.options.address;
var vaultPreOwner = author;
var stakeToken = "0x0000000000000000000000000000000000000000";
var dvmParams = [
"0",
"10000000000000000",
"1000000",
"1000000000000000000"
"0", //lpFeeRate
decimalStr("0.01"), //mtFeeRate
mweiStr("1"), // I
decimalStr("1") // K
];
var fragParams = [
"100000000000000000000000000",
"200000000000000000",
"1617976800"
decimalStr("100000000"), //totalSupply
decimalStr("0.2"), //ownerRatio
Math.floor(new Date().getTime() / 1000 + 60 * 60) //buyoutTimeStamp 1h later
]
var isOpenTwap = false
var callData = ctx.NFTProxy.methods.createFragment(
quoteToken,
@@ -118,35 +166,96 @@ describe("DODONFT", () => {
fragParams,
isOpenTwap
).encodeABI();
console.log("data:",callData);
console.log("data:", callData);
// var tx = await logGas(await nftVaultInstance.methods.createFragment(
// ctx.NFTProxy.options.address,
// callData
// ), ctx.sendParam(author), "createFragment");
await logGas(await nftVaultInstance.methods.createFragment(
ctx.NFTProxy.options.address,
callData
), ctx.sendParam(author), "createFragment");
// console.log("tx:",tx);
let [fragAddress, , dvmAddress] = await ctx.getRegistry(ctx, vaultAddress);
var dvmInstance = contracts.getContractWithAddress(contracts.DVM_NAME, dvmAddress);
var midPrice = await dvmInstance.methods.getMidPrice().call();
assert(midPrice, mweiStr("1"));
let newVaultOwner = await nftVaultInstance.methods._OWNER_().call();
assert(fragAddress, newVaultOwner);
});
it("stakeToFeeDistributor", async () => {
it.only("stakeToFeeDistributor", async () => {
let [vaultAddress, fragAddress, feeAddress, dvmAddress] = await ctx.createFragment(ctx, author, null, null, null);
});
var nftFeeInstance = contracts.getContractWithAddress(contracts.NFT_FEE, feeAddress);
var dvmInstance = contracts.getContractWithAddress(contracts.DVM_NAME, dvmAddress);
var fragInstance = contracts.getContractWithAddress(contracts.NFT_FRAG, fragAddress);
await ctx.approveProxy(fragInstance, user1);
await ctx.approveProxy(fragInstance, user2);
//mock trading
//stake
await mockTrade(ctx, dvmAddress, dvmInstance, fragInstance);
it("dvm-trade", async () => {
await logGas(await ctx.NFTProxy.methods.stakeToFeeDistributor(
feeAddress,
decimalStr("5"),
0
), ctx.sendParam(user1), "stakeToFeeDistributor");
});
await logGas(await ctx.NFTProxy.methods.stakeToFeeDistributor(
feeAddress,
decimalStr("10"),
0
), ctx.sendParam(user2), "stakeToFeeDistributor");
it("claim", async () => {
await mockTrade(ctx, dvmAddress, dvmInstance, fragInstance);
});
await logGas(await ctx.NFTProxy.methods.stakeToFeeDistributor(
feeAddress,
decimalStr("10"),
0
), ctx.sendParam(user1), "stakeToFeeDistributor");
it("unstake", async () => {
await logGas(await ctx.NFTProxy.methods.stakeToFeeDistributor(
feeAddress,
decimalStr("20"),
0
), ctx.sendParam(user2), "stakeToFeeDistributor");
let globalObj = await getFeeGlobalState(ctx, feeAddress, fragInstance, ctx.USDT, fragInstance);
assert(globalObj['quoteBalance'], mweiStr("0.6"));
assert(globalObj['stakeReserve'], decimalStr("45"));
let user1Obj = await getFeeUserState(ctx, feeAddress, user1);
assert(user1Obj['userQuoteRewards'], mweiStr("0.1"));
assert(user1Obj['userShares'], decimalStr("15"));
let user2Obj = await getFeeUserState(ctx, feeAddress, user2);
assert(user2Obj['userBaseRewards'], decimalStr("0.66666480000453957"));
assert(user2Obj['userShares'], decimalStr("30"));
//claim
var user1BaseBalanceStart = await fragInstance.methods.balanceOf(user1).call()
await logGas(await nftFeeInstance.methods.claim(user1), ctx.sendParam(user1), "claim");
var user1BaseBalanceEnd = await fragInstance.methods.balanceOf(user1).call()
user1Obj = await getFeeUserState(ctx, feeAddress, user1);
await getFeeGlobalState(ctx, feeAddress, fragInstance, ctx.USDT, fragInstance);
assert(user1Obj['userQuoteRewards'], "0");
assert(globalObj['quoteBalance'], mweiStr("0.5"));
assert(user1BaseBalanceEnd - user1BaseBalanceStart, "333332400002269700");
//unstake
var user2BaseBalanceStart = await fragInstance.methods.balanceOf(user2).call()
await logGas(await nftFeeInstance.methods.unstake(decimalStr("30"),user2, true), ctx.sendParam(user2), "unstake");
var user2BaseBalanceEnd = await fragInstance.methods.balanceOf(user2).call()
user2Obj = await getFeeUserState(ctx, feeAddress, user2);
await getFeeGlobalState(ctx, feeAddress, fragInstance, ctx.USDT, fragInstance);
assert(user2Obj['userQuoteRewards'], "0");
assert(globalObj['quoteBalance'], mweiStr("0.3"));
assert(globalObj['stakeReserve'], mweiStr("15"));
assert(globalObj['stakeBalance'], mweiStr("15"));
assert(user2BaseBalanceEnd - user2BaseBalanceStart, "30666664800004540000");
});
it("buyout", async () => {
});
it("redeem", async () => {

View File

@@ -24,7 +24,7 @@ export class NFTContext {
EVM: EVM;
Web3: Web3;
NFTTokenFacotry: Contract;
NFTRegister: Contract;
CollatteralVault: Contract;
Fragment: Contract;
@@ -33,10 +33,11 @@ export class NFTContext {
NFTProxy: Contract;
DODOApprove: Contract;
DODOApproveProxy: Contract;
//token
USDT: Contract;
WETH: Contract;
DODO: Contract;
Deployer: string;
Maintainer: string;
@@ -59,6 +60,11 @@ export class NFTContext {
["USDT Token", "USDT", 6]
);
this.DODO = await contracts.newContract(
contracts.MINTABLE_ERC20_CONTRACT_NAME,
["DODO Token", "DODO", 6]
);
var cloneFactory = await contracts.newContract(
contracts.CLONE_FACTORY_CONTRACT_NAME
);
@@ -116,6 +122,8 @@ export class NFTContext {
await this.NFTProxy.methods.initOwner(this.Deployer).send(this.sendParam(this.Deployer));
await this.NFTRegister.methods.addAmindList(this.NFTProxy.options.address).send(this.sendParam(this.Deployer));
await this.DODOApprove.methods.init(this.Deployer, this.DODOApproveProxy.options.address).send(this.sendParam(this.Deployer));
await this.DODOApproveProxy.methods.init(this.Deployer, [this.NFTProxy.options.address]).send(this.sendParam(this.Deployer));
@@ -136,14 +144,91 @@ export class NFTContext {
await token.methods.mint(to, amount).send(this.sendParam(this.Deployer));
}
async approveProxy(account: string) {
await this.USDT.methods
.approve(this.DODOApprove.options.address, MAX_UINT256)
.send(this.sendParam(account));
await this.WETH.methods
async approveProxy(token, account: string) {
await token.methods
.approve(this.DODOApprove.options.address, MAX_UINT256)
.send(this.sendParam(account));
}
async getRegistry(ctx: NFTContext, vaultAddress: string) {
let fragAddress = await ctx.NFTRegister.methods._VAULT_FRAG_REGISTRY_(vaultAddress).call();
let feeDistrubitor = await ctx.NFTRegister.methods._FRAG_FEE_REGISTRY_(fragAddress).call();
let fragInstance = contracts.getContractWithAddress(contracts.NFT_FRAG, fragAddress);
let dvmAddress = await fragInstance.methods._DVM_().call();
return [fragAddress, feeDistrubitor, dvmAddress];
}
async createNFTVault(ctx: NFTContext, author: string) {
var tx = await ctx.NFTProxy.methods.createNFTCollateralVault(
"DODONFT",
"https://app.dodoex.io"
).send(ctx.sendParam(author));
return tx.events['CreateNFTCollateralVault']['returnValues']['vault'];
}
async createERC721(ctx: NFTContext, author: string) {
var tx = await ctx.NFTTokenFacotry.methods.createERC721(
"https://app.dodoex.io"
).send(ctx.sendParam(author));
return tx.events['NewERC721']['returnValues']['erc721'];
}
async createFragment(ctx: NFTContext, author: string, dvmParams, fragParams, addrs) {
var erc721Address = await this.createERC721(ctx, author);
var vaultAddress = await this.createNFTVault(ctx, author);
var nftVaultInstance = contracts.getContractWithAddress(contracts.NFT_VAULT, vaultAddress);
var erc721Instance = contracts.getContractWithAddress(contracts.ERC721, erc721Address);
await erc721Instance.methods.safeTransferFrom(author, vaultAddress,0).send(ctx.sendParam(author));
if (dvmParams == null) {
dvmParams = [
"0", //lpFeeRate
decimalStr("0.01"), //mtFeeRate
mweiStr("1"), // I
decimalStr("1") // K
];
}
if (fragParams == null) {
fragParams = [
decimalStr("100000000"), //totalSupply
decimalStr("0.2"), //ownerRatio
Math.floor(new Date().getTime() / 1000 + 60 * 60) //buyoutTimeStamp 1h later
]
}
if (addrs == null) {
addrs = []
addrs.push(ctx.USDT.options.address);//quoteToken
addrs.push(author);//vaultPreOwner
addrs.push("0x0000000000000000000000000000000000000000");//stakeToken
}
var callData = ctx.NFTProxy.methods.createFragment(
addrs[0],
addrs[1],
addrs[2],
dvmParams,
fragParams,
false
).encodeABI();
await nftVaultInstance.methods.createFragment(
ctx.NFTProxy.options.address,
callData
).send(ctx.sendParam(author));
let [fragAddress, feeAddress, dvmAddress] = await this.getRegistry(ctx, vaultAddress);
return [vaultAddress, fragAddress, feeAddress, dvmAddress, callData]
}
async transferBaseToDVM(baseToken, dvm: string, account: string, amount: string) {
await baseToken.methods.transfer(dvm, amount).send(this.sendParam(account))
}
async transferQuoteToDVM(quoteToken, dvm: string, account: string, amount: string) {
await quoteToken.methods.transfer(dvm, amount).send(this.sendParam(account))
}
}
export async function getDODONftContext(weth: string): Promise<NFTContext> {

View File

@@ -1,5 +1,5 @@
#!/bin/bash
# truffle compile --all
truffle compile --all
if [ "$1"x = "proxy-dpp"x ]
then