diff --git a/config/bsc-config.js b/config/bsc-config.js index cd27911..a0c8521 100644 --- a/config/bsc-config.js +++ b/config/bsc-config.js @@ -76,7 +76,8 @@ module.exports = { DODONFTProxy: "", //================= MysteryBox ================= - MysteryBoxV1: "0xc25286ef3BaE3f6Fe2d6d0A6e2acAd0301AF97b8", + // MysteryBoxV1: "0xc25286ef3BaE3f6Fe2d6d0A6e2acAd0301AF97b8", //波老师 + MysteryBoxV1: "0xDf7E00Cd0bb91D1502a1A14575E58b5d8f20C8D4", //KAVA RandomGenerator: "0x7C062B9C584fA6eC2504270790D38240A2c5fE72", RandomPool: [ "0x82aff931d74f0645ce80e8f419b94c8f93952686", diff --git a/config/kovan-config.js b/config/kovan-config.js index 062f386..9af0dae 100644 --- a/config/kovan-config.js +++ b/config/kovan-config.js @@ -62,8 +62,8 @@ module.exports = { //================== NFT ==================== - Fragment: "0x446014c6060ea7DE7DD9Ce3B8026a50c74F9B7eD", - NFTCollateralVault: "0xBC57c99df21E306bEf61251aa068F46686F057AF", + Fragment: "0x7DD98F5F25fa946DA1F796E093bD259435646520", + NFTCollateralVault: "0xD25278cd387e54E77C5490F5220b551fe2feb772", DODONFTRouteHelper: "0xDD1511f2Bcdb0E6F916F9740BF83f31dF0fb63b4", InitializableERC721: "0x62dC4615AC755959a82b6D22FA5652A037284c0b", @@ -71,10 +71,11 @@ module.exports = { NFTTokenFactory: "0x834D13Ca0322Ccfe67596f09Cc26Ee3584297B94", DODONFTRegistry: "0x579eBcC668b5517F733587091C35D495FE8d6b68", - DODONFTProxy: "0x649CFCC1713Cb7f4866DcAF0FAD52903a3902373", + DODONFTProxy: "0x5A6ba7ad175a2Be5176f76cfaf61E63abe9A7D12", //================= MysteryBox ================= - MysteryBoxV1: "0x47d2b27525b93A9c9E03001E1D19310A08748D55", + // MysteryBoxV1: "0x47d2b27525b93A9c9E03001E1D19310A08748D55",//波老师 + MysteryBoxV1: "0xd56Fd300aE2e4C46cd34460776007dCE1C4F2043", RandomGenerator: "0x53F54E4760FA5f839e5624782D032495613DF218", RandomPool: [ "0xa2e0ef85618732d80e5ef362773da1c92e8b1c57", diff --git a/contracts/CollateralVault/impl/NFTCollateralVault.sol b/contracts/CollateralVault/impl/NFTCollateralVault.sol index 2bf7ac1..ac0615b 100644 --- a/contracts/CollateralVault/impl/NFTCollateralVault.sol +++ b/contracts/CollateralVault/impl/NFTCollateralVault.sol @@ -39,14 +39,22 @@ contract NFTCollateralVault is InitializableOwnable, IERC721Receiver, IERC1155Re // ============ TransferFrom NFT ============ function depositERC721(address nftContract, uint256[] memory tokenIds) public { - + require(nftContract != address(0), "DODONftVault: ZERO_ADDRESS"); + for(uint256 i = 0; i < tokenIds.length; i++) { + IERC721(nftContract).safeTransferFrom(msg.sender, address(this), tokenIds[i]); + emit AddNftToken(nftContract, tokenIds[i], 1); + } } function depoistERC1155(address nftContract, uint256[] memory tokenIds, uint256[] memory amounts) public { - + require(nftContract != address(0), "DODONftVault: ZERO_ADDRESS"); + require(tokenIds.length == amounts.length, "PARAMS_NOT_MATCH"); + IERC1155(nftContract).safeBatchTransferFrom(msg.sender, address(this), tokenIds, amounts, ""); + for(uint256 i = 0; i < tokenIds.length; i++) { + emit AddNftToken(nftContract, tokenIds[i], amounts[i]); + } } - // ============ Ownable ============ function directTransferOwnership(address newOwner) external onlyOwner { require(newOwner != address(0), "DODONftVault: ZERO_ADDRESS"); @@ -62,10 +70,12 @@ contract NFTCollateralVault is InitializableOwnable, IERC721Receiver, IERC1155Re emit OwnershipTransferred(_OWNER_, nftProxy); } - function withdrawERC721(address nftContract, uint256 tokenId) external onlyOwner { + function withdrawERC721(address nftContract, uint256[] memory tokenIds) external onlyOwner { require(nftContract != address(0), "DODONftVault: ZERO_ADDRESS"); - IERC721(nftContract).safeTransferFrom(address(this), _OWNER_, tokenId, ""); - emit RemoveNftToken(nftContract, tokenId, 1); + for(uint256 i = 0; i < tokenIds.length; i++) { + IERC721(nftContract).safeTransferFrom(address(this), _OWNER_, tokenIds[i]); + emit RemoveNftToken(nftContract, tokenIds[i], 1); + } } function withdrawERC1155(address nftContract, uint256[] memory tokenIds, uint256[] memory amounts) external onlyOwner { diff --git a/contracts/DODODrops/DODODropsV1.sol b/contracts/DODODrops/MysteryBoxKAKA.sol similarity index 98% rename from contracts/DODODrops/DODODropsV1.sol rename to contracts/DODODrops/MysteryBoxKAKA.sol index e545250..45fedbd 100644 --- a/contracts/DODODrops/DODODropsV1.sol +++ b/contracts/DODODrops/MysteryBoxKAKA.sol @@ -13,7 +13,7 @@ import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; import {Address} from "../external/utils/Address.sol"; import {ERC721URIStorage} from "../external/ERC721/ERC721URIStorage.sol"; -contract DODODropsV1 is ERC721URIStorage, InitializableOwnable { +contract MysteryBoxKAKA is ERC721URIStorage, InitializableOwnable { using SafeMath for uint256; using SafeERC20 for IERC20; using Address for address; diff --git a/contracts/GeneralizedFragment/impl/Fragment.sol b/contracts/GeneralizedFragment/impl/Fragment.sol index 07bac56..a245c7b 100644 --- a/contracts/GeneralizedFragment/impl/Fragment.sol +++ b/contracts/GeneralizedFragment/impl/Fragment.sol @@ -26,6 +26,7 @@ contract Fragment is InitializableERC20 { uint256 public _BUYOUT_TIMESTAMP_; uint256 public _BUYOUT_PRICE_; uint256 public _DEFAULT_BUYOUT_FEE_; + uint256 public _DISTRIBUTION_RATIO_; address public _COLLATERAL_VAULT_; address public _VAULT_PRE_OWNER_; @@ -52,7 +53,8 @@ contract Fragment is InitializableERC20 { uint256 ownerRatio, uint256 buyoutTimestamp, address defaultMaintainer, - uint256 defaultBuyoutFee + uint256 defaultBuyoutFee, + uint256 distributionRatio ) external { require(!_FRAG_INITIALIZED_, "DODOFragment: ALREADY_INITIALIZED"); _FRAG_INITIALIZED_ = true; @@ -65,6 +67,7 @@ contract Fragment is InitializableERC20 { _BUYOUT_TIMESTAMP_ = buyoutTimestamp; _DEFAULT_MAINTAINER_ = defaultMaintainer; _DEFAULT_BUYOUT_FEE_ = defaultBuyoutFee; + _DISTRIBUTION_RATIO_ = distributionRatio; // init FRAG meta data string memory prefix = "FRAG_"; @@ -75,7 +78,10 @@ contract Fragment is InitializableERC20 { // init FRAG distribution uint256 vaultPreOwnerBalance = DecimalMath.mulFloor(_totalSupply, ownerRatio); - _transfer(address(this), _VAULT_PRE_OWNER_, vaultPreOwnerBalance); + uint256 distributionBalance = DecimalMath.mulFloor(vaultPreOwnerBalance, distributionRatio); + + if(distributionBalance > 0) _transfer(address(this), _DEFAULT_MAINTAINER_, distributionBalance); + _transfer(address(this), _VAULT_PRE_OWNER_, vaultPreOwnerBalance.sub(distributionBalance)); _transfer(address(this), _DVM_, _totalSupply.sub(vaultPreOwnerBalance)); // init DVM liquidity diff --git a/contracts/GeneralizedFragment/intf/IFragment.sol b/contracts/GeneralizedFragment/intf/IFragment.sol index 638d75d..cdcf335 100644 --- a/contracts/GeneralizedFragment/intf/IFragment.sol +++ b/contracts/GeneralizedFragment/intf/IFragment.sol @@ -18,7 +18,8 @@ interface IFragment { uint256 ownerRatio, uint256 buyoutTimestamp, address defaultMaintainer, - uint256 defaultBuyoutFee + uint256 defaultBuyoutFee, + uint256 distributionRatio ) external; function buyout(address newVaultOwner) external; diff --git a/contracts/SmartRoute/proxies/DODONFTProxy.sol b/contracts/SmartRoute/proxies/DODONFTProxy.sol index b2759f6..a066c89 100644 --- a/contracts/SmartRoute/proxies/DODONFTProxy.sol +++ b/contracts/SmartRoute/proxies/DODONFTProxy.sol @@ -101,7 +101,7 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable { address quoteToken, address vaultPreOwner, uint256[] calldata dvmParams, //0 - lpFeeRate, 1 - I, 2 - K - uint256[] calldata fragParams, //0 - totalSupply, 1 - ownerRatio, 2 - buyoutTimestamp + uint256[] calldata fragParams, //0 - totalSupply, 1 - ownerRatio, 2 - buyoutTimestamp, 3 - distributionRatio bool isOpenTwap ) external returns (address newFragment, address newDvm) { newFragment = ICloneFactory(_CLONE_FACTORY_).clone(_FRAG_TEMPLATE_); @@ -130,7 +130,8 @@ contract DODONFTProxy is ReentrancyGuard, InitializableOwnable { _fragParams[1], _fragParams[2], _DEFAULT_MAINTAINER_, - _DEFAULT_BUYOUT_FEE_ + _DEFAULT_BUYOUT_FEE_, + _fragParams[3] ); } diff --git a/deploy-nft.txt b/deploy-nft.txt index bd334b7..9f9de14 100644 --- a/deploy-nft.txt +++ b/deploy-nft.txt @@ -272,3 +272,51 @@ Init DODONFTProxyAddress Tx: 0x017a2006bd347a361bc598b2b19198fa32bf616ffe9564003 DODOApproveProxy unlockAddProxy tx: 0xb2de58e227a7792cf40d5082a27f4d48967d5c50162009c833c6cdfc20439c18 DODOApproveProxy addDODOProxy tx: 0xebdfacca787f8df90f4eb69d7c200b55acf634b2e3e0f79607071c84b3d910cf Add AdminList on DODONFTRegistry Tx: 0xc29f81fa10e41e5e3bc6625b05838462741aae646e7b238669a661793661e6c9 +==================================================== +network type: kovan +Deploy time: 2021/5/25 上午9:44:26 +Deploy type: NFT +multiSigAddress: 0x7e83d9d94837eE82F0cc18a691da6f42F03F1d86 +NFTCollateralVaultAddress: 0xD25278cd387e54E77C5490F5220b551fe2feb772 +DODOApproveProxy unlockAddProxy tx: 0x6997bc7b30ea5aaca1b100c74afe7b61829b9bb27eb1edd6c76ab0821675953b +DODOApproveProxy addDODOProxy tx: 0xbec5a999e878259dc5b1bd5660e1a76c818b5c40f88c20afc4600308e094db5a +Add AdminList on DODONFTRegistry Tx: 0xf720be5a488ada5f744f06145379fe40cae1ce772ea33961364494adc3988419 +==================================================== +network type: bsclive +Deploy time: 2021/5/25 上午10:58:10 +Deploy type: MysteryBoxKAKA +MysteryBoxV1Address: 0xDf7E00Cd0bb91D1502a1A14575E58b5d8f20C8D4 +Init MysteryBoxV1 Tx: 0xd3db0145423fad6cc874c69edc4e0ed380341a9d34715e257dda1ea45054acf5 +==================================================== +network type: kovan +Deploy time: 2021/5/25 上午11:19:00 +Deploy type: MysteryBoxKAKA +MysteryBoxV1Address: 0xd56Fd300aE2e4C46cd34460776007dCE1C4F2043 +Init MysteryBoxV1 Tx: 0xa9e04e7e1c76c8c270be49952bbe80e019fc5606e9806d130b678b9b3a9b099d +==================================================== +network type: development +Deploy time: 2021/5/25 下午1:18:25 +Deploy type: MysteryBoxKAKA +==================================================== +network type: development +Deploy time: 2021/5/25 下午1:21:08 +Deploy type: MysteryBoxKAKA +==================================================== +network type: development +Deploy time: 2021/5/25 下午1:23:37 +Deploy type: MysteryBoxKAKA +==================================================== +network type: development +Deploy time: 2021/5/25 下午1:25:40 +Deploy type: MysteryBoxKAKA +==================================================== +network type: kovan +Deploy time: 2021/5/25 下午1:31:48 +Deploy type: NFT +multiSigAddress: 0x7e83d9d94837eE82F0cc18a691da6f42F03F1d86 +FragmentAddress: 0x7DD98F5F25fa946DA1F796E093bD259435646520 +DODONFTProxyAddress: 0x5A6ba7ad175a2Be5176f76cfaf61E63abe9A7D12 +Init DODONFTProxyAddress Tx: 0xb4c5fd59e7d4bf2705295aeb0a05ccb745df3603af902d6b8ac54c6460567640 +DODOApproveProxy unlockAddProxy tx: 0xe8915536c6f0b5cae8df32fc5e62ed344b1cf9eb8e8c79a59c90f78d34680a47 +DODOApproveProxy addDODOProxy tx: 0xe81647348464194ec395de39fd088f06feed5abe428209b3ed264abeed6358b6 +Add AdminList on DODONFTRegistry Tx: 0x774f02629e4635303a28faa1914460ed07516facfc2e2818d2908a93488f1b5d diff --git a/migrations/5_deploy_nft.js b/migrations/5_deploy_nft.js index 45b0747..1f00e12 100644 --- a/migrations/5_deploy_nft.js +++ b/migrations/5_deploy_nft.js @@ -15,7 +15,7 @@ const InitializableERC721 = artifacts.require("InitializableERC721"); const InitializableERC1155 = artifacts.require("InitializableERC1155"); const NFTTokenFactory = artifacts.require("NFTTokenFactory"); -const DODODropsV1 = artifacts.require("DODODropsV1"); +const DODODropsV1 = artifacts.require("MysteryBoxKAKA"); const RandomGenerator = artifacts.require("RandomGenerator"); module.exports = async (deployer, network, accounts) => { @@ -52,7 +52,7 @@ module.exports = async (deployer, network, accounts) => { logger.log("===================================================="); logger.log("network type: " + network); logger.log("Deploy time: " + new Date().toLocaleString()); - logger.log("Deploy type: MysteryBoxV1"); + logger.log("Deploy type: MysteryBoxKAKA"); if (RandomGeneratorAddress == "") { await deployer.deploy(RandomGenerator, RandomPool); @@ -66,8 +66,8 @@ module.exports = async (deployer, network, accounts) => { logger.log("MysteryBoxV1Address: ", MysteryBoxV1Address); const MysteryBoxV1Instance = await DODODropsV1.at(MysteryBoxV1Address); var tx = await MysteryBoxV1Instance.init( - "DODOMysteryBox", - "DODOBox", + "DODOMysteryBoxKAKA", + "KAKA_Marvel", "", multiSigAddress, RandomGeneratorAddress diff --git a/test/DODONFT/nftMainFlow.test.ts b/test/DODONFT/nftMainFlow.test.ts index a713db6..3ea4e75 100644 --- a/test/DODONFT/nftMainFlow.test.ts +++ b/test/DODONFT/nftMainFlow.test.ts @@ -137,10 +137,10 @@ describe("DODONFT", () => { 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 nftInfo = await nftVaultInstance.methods.getNftInfoById(nftIndex).call(); - assert(nftInfo.amount, '1') - assert(nftInfo.tokenId, '0') + // 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("createFragment", async () => { @@ -163,7 +163,8 @@ describe("DODONFT", () => { var fragParams = [ decimalStr("100000000"), //totalSupply decimalStr("0.2"), //ownerRatio - Math.floor(new Date().getTime() / 1000 + 60 * 60) //buyoutTimeStamp 1h later + Math.floor(new Date().getTime() / 1000 + 60 * 60), //buyoutTimeStamp 1h later + decimalStr("0") ] var isOpenTwap = false @@ -266,7 +267,8 @@ describe("DODONFT", () => { var fragParams = [ decimalStr("10000"), //totalSupply decimalStr("0.2"), //ownerRatio - Math.floor(new Date().getTime() / 1000) //buyoutTimeStamp + Math.floor(new Date().getTime() / 1000), //buyoutTimeStamp + decimalStr("0") ] let [vaultAddress, fragAddress, , dvmAddress] = await ctx.createFragment(ctx, author, null, fragParams, null); var dvmInstance = contracts.getContractWithAddress(contracts.DVM_NAME, dvmAddress); @@ -316,28 +318,28 @@ describe("DODONFT", () => { 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') + // 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') + // nftIndex = await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc1155Address, 0).call(); + // nftInfo = await nftVaultInstance.methods.getNftInfoById(nftIndex).call(); + // assert(nftInfo.amount, '100') + // assert(nftInfo.tokenId, '0') - await logGas(await nftVaultInstance.methods.withdrawERC721(erc721Address,0), ctx.sendParam(author), "withdrawERC721"); + 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( - nftVaultInstance.methods.getIdByTokenIdAndAddr(erc721Address, 0).call(), - "TOKEN_ID_NOT_FOUND" - ) + // await truffleAssert.reverts( + // 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') + // nftIndex = await nftVaultInstance.methods.getIdByTokenIdAndAddr(erc1155Address, 0).call(); + // nftInfo = await nftVaultInstance.methods.getNftInfoById(nftIndex).call(); + // assert(nftInfo.amount, '50') + // assert(nftInfo.tokenId, '0') }); }); });