ing
This commit is contained in:
@@ -79,7 +79,7 @@ contract Fragment is InitializableERC20 {
|
|||||||
|
|
||||||
|
|
||||||
function buyout(address newVaultOwner) external {
|
function buyout(address newVaultOwner) external {
|
||||||
require(_BUYOUT_TIMESTAMP_ == 0, "DODOFragment: NOT_SUPPORT_BUYOUT");
|
require(_BUYOUT_TIMESTAMP_ != 0, "DODOFragment: NOT_SUPPORT_BUYOUT");
|
||||||
require(block.timestamp > _BUYOUT_TIMESTAMP_, "DODOFragment: BUYOUT_NOT_START");
|
require(block.timestamp > _BUYOUT_TIMESTAMP_, "DODOFragment: BUYOUT_NOT_START");
|
||||||
require(!_IS_BUYOUT_, "DODOFragment: ALREADY_BUYOUT");
|
require(!_IS_BUYOUT_, "DODOFragment: ALREADY_BUYOUT");
|
||||||
_IS_BUYOUT_ = true;
|
_IS_BUYOUT_ = true;
|
||||||
@@ -97,6 +97,8 @@ contract Fragment is InitializableERC20 {
|
|||||||
uint256(-1)
|
uint256(-1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_clearBalance(address(this));
|
||||||
|
|
||||||
uint256 preOwnerQuote = DecimalMath.mulFloor(_BUYOUT_PRICE_, balances[_VAULT_PRE_OWNER_]);
|
uint256 preOwnerQuote = DecimalMath.mulFloor(_BUYOUT_PRICE_, balances[_VAULT_PRE_OWNER_]);
|
||||||
IERC20(_QUOTE_).safeTransfer(_VAULT_PRE_OWNER_, preOwnerQuote);
|
IERC20(_QUOTE_).safeTransfer(_VAULT_PRE_OWNER_, preOwnerQuote);
|
||||||
_clearBalance(_VAULT_PRE_OWNER_);
|
_clearBalance(_VAULT_PRE_OWNER_);
|
||||||
@@ -131,7 +133,7 @@ contract Fragment is InitializableERC20 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getBuyoutRequirement() external view returns (uint256 requireQuote){
|
function getBuyoutRequirement() external view returns (uint256 requireQuote){
|
||||||
require(_BUYOUT_TIMESTAMP_ == 0, "NOT SUPPORT BUYOUT");
|
require(_BUYOUT_TIMESTAMP_ != 0, "NOT SUPPORT BUYOUT");
|
||||||
require(!_IS_BUYOUT_, "ALREADY BUYOUT");
|
require(!_IS_BUYOUT_, "ALREADY BUYOUT");
|
||||||
uint256 price = IDVM(_DVM_).getMidPrice();
|
uint256 price = IDVM(_DVM_).getMidPrice();
|
||||||
requireQuote = DecimalMath.mulCeil(price, totalSupply);
|
requireQuote = DecimalMath.mulCeil(price, totalSupply);
|
||||||
|
|||||||
@@ -136,3 +136,78 @@ network type: development
|
|||||||
Deploy time: 2021/4/12 下午9:22:30
|
Deploy time: 2021/4/12 下午9:22:30
|
||||||
Deploy type: NFT
|
Deploy type: NFT
|
||||||
multiSigAddress: undefined
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:11:34
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:14:33
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:16:02
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:23:01
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:25:16
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:26:59
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:51:35
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午1:53:57
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午2:35:23
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午2:42:02
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午2:43:47
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午2:50:26
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午2:53:12
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午2:56:12
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
====================================================
|
||||||
|
network type: development
|
||||||
|
Deploy time: 2021/4/13 下午3:11:16
|
||||||
|
Deploy type: NFT
|
||||||
|
multiSigAddress: undefined
|
||||||
|
|||||||
@@ -9,21 +9,26 @@ import { logGas } from '../utils/Log';
|
|||||||
import { NFTContext, getDODONftContext } from '../utils/NFTContext';
|
import { NFTContext, getDODONftContext } from '../utils/NFTContext';
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as contracts from '../utils/Contracts';
|
import * as contracts from '../utils/Contracts';
|
||||||
|
const truffleAssert = require('truffle-assertions');
|
||||||
|
|
||||||
let author: string;
|
let author: string;
|
||||||
let user1: string;
|
let user1: string;
|
||||||
let user2: string;
|
let user2: string;
|
||||||
|
let buyer: string;
|
||||||
|
|
||||||
async function init(ctx: NFTContext): Promise<void> {
|
async function init(ctx: NFTContext): Promise<void> {
|
||||||
author = ctx.SpareAccounts[1];
|
author = ctx.SpareAccounts[1];
|
||||||
user1 = ctx.SpareAccounts[2];
|
user1 = ctx.SpareAccounts[2];
|
||||||
user2 = ctx.SpareAccounts[3];
|
user2 = ctx.SpareAccounts[3];
|
||||||
|
buyer = ctx.SpareAccounts[4];
|
||||||
|
|
||||||
await ctx.mintTestToken(user1, ctx.USDT, mweiStr("10000"));
|
await ctx.mintTestToken(user1, ctx.USDT, mweiStr("10000"));
|
||||||
await ctx.mintTestToken(user2, ctx.USDT, mweiStr("10000"));
|
await ctx.mintTestToken(user2, ctx.USDT, mweiStr("10000"));
|
||||||
|
await ctx.mintTestToken(buyer, ctx.USDT, mweiStr("1000000000"));
|
||||||
|
|
||||||
await ctx.approveProxy(ctx.USDT, user1);
|
await ctx.approveProxy(ctx.USDT, user1);
|
||||||
await ctx.approveProxy(ctx.USDT, user2);
|
await ctx.approveProxy(ctx.USDT, user2);
|
||||||
|
await ctx.approveProxy(ctx.USDT, buyer);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFeeGlobalState(ctx: NFTContext, feeAddress: string, baseToken, quoteToken, stakeToken) {
|
async function getFeeGlobalState(ctx: NFTContext, feeAddress: string, baseToken, quoteToken, stakeToken) {
|
||||||
@@ -88,6 +93,13 @@ async function mockTrade(ctx: NFTContext, dvmAddress: string, dvmInstance, fragI
|
|||||||
await dvmInstance.methods.sellBase(user2).send(ctx.sendParam(user2));
|
await dvmInstance.methods.sellBase(user2).send(ctx.sendParam(user2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getUserBalance(user: string, baseToken, quoteToken, logInfo: string) {
|
||||||
|
var baseBalance = await baseToken.methods.balanceOf(user).call();
|
||||||
|
var quoteBalance = await quoteToken.methods.balanceOf(user).call();
|
||||||
|
console.log(logInfo + " baseBalance:" + fromWei(baseBalance, 'ether') + " quoteBalance:" + fromWei(quoteBalance, 'mwei'));
|
||||||
|
return [baseBalance, quoteBalance];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe("DODONFT", () => {
|
describe("DODONFT", () => {
|
||||||
@@ -182,7 +194,7 @@ describe("DODONFT", () => {
|
|||||||
// assert(fragAddress, newVaultOwner);
|
// assert(fragAddress, newVaultOwner);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only("stakeToFeeDistributor", async () => {
|
it("stakeToFeeDistributor", async () => {
|
||||||
let [vaultAddress, fragAddress, feeAddress, dvmAddress] = await ctx.createFragment(ctx, author, null, null, null);
|
let [vaultAddress, fragAddress, feeAddress, dvmAddress] = await ctx.createFragment(ctx, author, null, null, null);
|
||||||
|
|
||||||
var nftFeeInstance = contracts.getContractWithAddress(contracts.NFT_FEE, feeAddress);
|
var nftFeeInstance = contracts.getContractWithAddress(contracts.NFT_FEE, feeAddress);
|
||||||
@@ -243,7 +255,7 @@ describe("DODONFT", () => {
|
|||||||
|
|
||||||
//unstake
|
//unstake
|
||||||
var user2BaseBalanceStart = await fragInstance.methods.balanceOf(user2).call()
|
var user2BaseBalanceStart = await fragInstance.methods.balanceOf(user2).call()
|
||||||
await logGas(await nftFeeInstance.methods.unstake(decimalStr("30"),user2, true), ctx.sendParam(user2), "unstake");
|
await logGas(await nftFeeInstance.methods.unstake(decimalStr("30"), user2, true), ctx.sendParam(user2), "unstake");
|
||||||
var user2BaseBalanceEnd = await fragInstance.methods.balanceOf(user2).call()
|
var user2BaseBalanceEnd = await fragInstance.methods.balanceOf(user2).call()
|
||||||
user2Obj = await getFeeUserState(ctx, feeAddress, user2);
|
user2Obj = await getFeeUserState(ctx, feeAddress, user2);
|
||||||
await getFeeGlobalState(ctx, feeAddress, fragInstance, ctx.USDT, fragInstance);
|
await getFeeGlobalState(ctx, feeAddress, fragInstance, ctx.USDT, fragInstance);
|
||||||
@@ -254,16 +266,81 @@ describe("DODONFT", () => {
|
|||||||
assert(user2BaseBalanceEnd - user2BaseBalanceStart, "30666664800004540000");
|
assert(user2BaseBalanceEnd - user2BaseBalanceStart, "30666664800004540000");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("buyout", async () => {
|
it("buyout and redeem", async () => {
|
||||||
|
var fragParams = [
|
||||||
|
decimalStr("10000"), //totalSupply
|
||||||
|
decimalStr("0.2"), //ownerRatio
|
||||||
|
Math.floor(new Date().getTime() / 1000) //buyoutTimeStamp
|
||||||
|
]
|
||||||
|
let [vaultAddress, fragAddress, feeAddress, dvmAddress] = await ctx.createFragment(ctx, author, null, fragParams, null);
|
||||||
|
var dvmInstance = contracts.getContractWithAddress(contracts.DVM_NAME, dvmAddress);
|
||||||
|
var fragInstance = contracts.getContractWithAddress(contracts.NFT_FRAG, fragAddress);
|
||||||
|
var vaultInstance = contracts.getContractWithAddress(contracts.NFT_VAULT, vaultAddress);
|
||||||
|
|
||||||
|
await mockTrade(ctx, dvmAddress, dvmInstance, fragInstance);
|
||||||
|
|
||||||
|
await getUserBalance(author, fragInstance, ctx.USDT, "Author Before");
|
||||||
|
await getUserBalance(buyer, fragInstance, ctx.USDT, "Buyer Before");
|
||||||
|
await getUserBalance(dvmAddress, fragInstance, ctx.USDT, "DVM Before");
|
||||||
|
await getUserBalance(fragAddress, fragInstance, ctx.USDT, "FRAG Before");
|
||||||
|
|
||||||
|
var requireQuote = await fragInstance.methods.getBuyoutRequirement().call();
|
||||||
|
await logGas(await ctx.NFTProxy.methods.buyout(fragAddress, requireQuote, 0), ctx.sendParam(buyer), "buyout");
|
||||||
|
|
||||||
|
let [authorFrag, authorQuote] = await getUserBalance(author, fragInstance, ctx.USDT, "Author After");
|
||||||
|
await getUserBalance(buyer, fragInstance, ctx.USDT, "Buyer After");
|
||||||
|
await getUserBalance(dvmAddress, fragInstance, ctx.USDT, "DVM After");
|
||||||
|
await getUserBalance(fragAddress, fragInstance, ctx.USDT, "FRAG After");
|
||||||
|
assert(authorQuote, "2034932000");
|
||||||
|
assert(authorFrag, "0");
|
||||||
|
|
||||||
|
var vaultNewOwner = await vaultInstance.methods._OWNER_().call();
|
||||||
|
assert(vaultNewOwner, buyer);
|
||||||
|
|
||||||
|
await getUserBalance(user1, fragInstance, ctx.USDT, "User1 Redeem Before");
|
||||||
|
await getUserBalance(user2, fragInstance, ctx.USDT, "User2 Redeem Before");
|
||||||
|
|
||||||
|
await logGas(await fragInstance.methods.redeem(user1, "0x"), ctx.sendParam(user1), "redeem");
|
||||||
|
await logGas(await fragInstance.methods.redeem(user2, "0x"), ctx.sendParam(user2), "redeem");
|
||||||
|
|
||||||
|
let [user1Frag, user1Quote] = await getUserBalance(user1, fragInstance, ctx.USDT, "User1 Redeem After");
|
||||||
|
await getUserBalance(user2, fragInstance, ctx.USDT, "User2 Redeem After");
|
||||||
|
await getUserBalance(fragAddress, fragInstance, ctx.USDT, "FRAG Redeem After");
|
||||||
|
assert(user1Quote, "99998580370")
|
||||||
|
assert(user1Frag, "0")
|
||||||
});
|
});
|
||||||
|
|
||||||
it("redeem", async () => {
|
it.only("withdrawNFTFromVault", async () => {
|
||||||
|
var erc721Address = await ctx.createERC721(ctx, author);
|
||||||
|
var erc1155Address = await ctx.createERC1155(ctx, author,100);
|
||||||
|
var vaultAddress = await ctx.createNFTVault(ctx, author);
|
||||||
|
var nftVaultInstance = contracts.getContractWithAddress(contracts.NFT_VAULT, vaultAddress);
|
||||||
|
var erc721Instance = contracts.getContractWithAddress(contracts.ERC721, erc721Address);
|
||||||
|
var erc1155Instance = contracts.getContractWithAddress(contracts.ERC1155, erc1155Address);
|
||||||
|
await erc721Instance.methods.safeTransferFrom(author, vaultAddress, 0).send(ctx.sendParam(author));
|
||||||
|
await erc1155Instance.methods.safeTransferFrom(author, vaultAddress, 0, 100, "0x").send(ctx.sendParam(author));
|
||||||
|
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')
|
||||||
|
|
||||||
});
|
nftIndex = await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc1155Address, 0).call();
|
||||||
|
nftInfo = await nftVaultInstance.methods.getNftInfoById(nftIndex).call();
|
||||||
|
assert(nftInfo.amount, '100')
|
||||||
|
assert(nftInfo.tokenId, '0')
|
||||||
|
|
||||||
it("withdrawNFTFromVault", async () => {
|
await logGas(await nftVaultInstance.methods.withdrawERC721(erc721Address,0), ctx.sendParam(author), "withdrawERC721");
|
||||||
|
await logGas(await nftVaultInstance.methods.withdrawERC1155(erc1155Address,[0], 50), ctx.sendParam(author), "withdrawERC1155");
|
||||||
|
|
||||||
|
await truffleAssert.reverts(
|
||||||
|
await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc721Address, 0).call(),
|
||||||
|
"TOKEN_ID_NOT_FOUND"
|
||||||
|
)
|
||||||
|
|
||||||
|
nftIndex = await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc1155Address, 0).call();
|
||||||
|
nftInfo = await nftVaultInstance.methods.getNftInfoById(nftIndex).call();
|
||||||
|
assert(nftInfo.amount, '50')
|
||||||
|
assert(nftInfo.tokenId, '0')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -174,6 +174,14 @@ export class NFTContext {
|
|||||||
return tx.events['NewERC721']['returnValues']['erc721'];
|
return tx.events['NewERC721']['returnValues']['erc721'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async createERC1155(ctx: NFTContext, author: string, amount) {
|
||||||
|
var tx = await ctx.NFTTokenFacotry.methods.createERC1155(
|
||||||
|
amount,
|
||||||
|
"https://app.dodoex.io"
|
||||||
|
).send(ctx.sendParam(author));
|
||||||
|
return tx.events['NewERC1155']['returnValues']['erc1155'];
|
||||||
|
}
|
||||||
|
|
||||||
async createFragment(ctx: NFTContext, author: string, dvmParams, fragParams, addrs) {
|
async createFragment(ctx: NFTContext, author: string, dvmParams, fragParams, addrs) {
|
||||||
var erc721Address = await this.createERC721(ctx, author);
|
var erc721Address = await this.createERC721(ctx, author);
|
||||||
var vaultAddress = await this.createNFTVault(ctx, author);
|
var vaultAddress = await this.createNFTVault(ctx, author);
|
||||||
|
|||||||
Reference in New Issue
Block a user