This commit is contained in:
owen05
2021-05-19 19:13:46 +08:00
parent cd256984a7
commit 056e8b8ece
5 changed files with 112 additions and 36 deletions

View File

@@ -6,7 +6,6 @@ pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IERC20} from "../../intf/IERC20.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
import {UniversalERC20} from "../../SmartRoute/lib/UniversalERC20.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {Address} from "../../external/utils/Address.sol";
@@ -15,7 +14,7 @@ import {IRandomGenerator} from "../../lib/RandomGenerator.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {InitializableERC20} from "../../external/ERC20/InitializableERC20.sol";
interface IMysteryBoxPay {
interface IMysteryBoxFeeModel {
function getPayAmount(address mysteryBox, address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256, uint256);
}
@@ -34,7 +33,7 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
address public _BUY_TOKEN_;
uint256 public _BUY_RESERVE_;
address public _FEE_MODEL_;
address public _DEFAULT_FEE_MODEL_;
address payable public _DEFAULT_MAINTAINER_;
address public _NFT_TOKEN_;
@@ -46,9 +45,9 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
uint256 public _REDEEM_ALLOWED_TIME_;
uint256[] public _BOX_INTERVAL_; // index => Interval probability (For ProbMode) index => tokenId (For FixedAmount mode)
uint256[][] public _TOKEN_ID_SET_; // Interval index => tokenIds (For ProbMode)
uint256[][] public _TOKEN_ID_SET_; // Interval index => tokenIds (Only For ProbMode)
bool public _IS_PROB_MODE; // false FixedAmount true ProbMode
bool public _IS_PROB_MODE; // false = FixedAmount mode, true = ProbMode
bool public _IS_REVEAL_MODE_;
uint256 public _REVEAL_RNG_ = 0;
address public _RANDOM_GENERATOR_;
@@ -75,13 +74,13 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
event SetPriceInterval();
event SetBoxInterval();
event SetTokenIds();
event SetTokenIdByIndex(uint256 index);
event SetTokenIds(); // only for ProbMode
event SetTokenIdByIndex(uint256 index); // only for ProbMode
function init(
address[] memory contractList, //0 owner, 1 buyToken, 2 feeModel, 3 defaultMaintainer 4 randomGenerator 5 nftToken
uint256[][] memory priceList, //0 priceTimeInterval, 1 priceSet, 2 sellAmount
address[] memory addrList, //0 owner, 1 buyToken, 2 feeModel, 3 defaultMaintainer 4 randomGenerator 5 nftToken
uint256[][] memory priceSetList, //0 priceTimeInterval, 1 priceSet, 2 sellAmount
uint256[] memory boxIntervals,
uint256[][] memory tokenIds,
uint256 redeemAllowedTime,
@@ -89,15 +88,15 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
bool isProbMode,
uint256 totalTickets
) public {
initOwner(contractList[0]);
_BUY_TOKEN_ = contractList[1];
_FEE_MODEL_ = contractList[2];
_DEFAULT_MAINTAINER_ = payable(contractList[3]);
_RANDOM_GENERATOR_ = contractList[4];
_NFT_TOKEN_ = contractList[5];
initOwner(addrList[0]);
_BUY_TOKEN_ = addrList[1];
_DEFAULT_FEE_MODEL_ = addrList[2];
_DEFAULT_MAINTAINER_ = payable(addrList[3]);
_RANDOM_GENERATOR_ = addrList[4];
_NFT_TOKEN_ = addrList[5];
_REDEEM_ALLOWED_TIME_ = redeemAllowedTime;
if(priceList.length > 0) _setPrice(priceList[0], priceList[1], priceList[2]);
if(priceSetList.length > 0) _setPrice(priceSetList[0], priceSetList[1], priceSetList[2]);
_IS_REVEAL_MODE_ = isRevealMode;
_IS_PROB_MODE = isProbMode;
@@ -116,7 +115,7 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
(uint256 curPrice, uint256 sellAmount, uint256 index) = getPriceAndSellAmount();
require(curPrice > 0 && sellAmount > 0, "CAN_NOT_BUY");
require(ticketAmount <= sellAmount, "TICKETS_NOT_ENOUGH");
(uint256 payAmount, uint256 feeAmount) = IMysteryBoxPay(_FEE_MODEL_).getPayAmount(address(this), assetTo, curPrice, ticketAmount);
(uint256 payAmount, uint256 feeAmount) = IMysteryBoxFeeModel(_DEFAULT_FEE_MODEL_).getPayAmount(address(this), assetTo, curPrice, ticketAmount);
require(payAmount > 0, "UnQualified");
uint256 baseBalance = IERC20(_BUY_TOKEN_).universalBalanceOf(address(this));
@@ -189,8 +188,8 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
require(priceIntervals.length == prices.length && prices.length == amounts.length, "PARAM_NOT_INVALID");
for (uint256 i = 0; i < priceIntervals.length - 1; i++) {
require(priceIntervals[i] < priceIntervals[i + 1], "INTERVAL_INVALID");
require(prices[i] != 0, "INTERVAL_INVALID");
require(amounts[i] != 0, "INTERVAL_INVALID");
require(prices[i] != 0, "PRICE_INVALID");
require(amounts[i] != 0, "SELL_AMOUNT_INVALID");
}
_PRICE_TIME_INTERVAL_ = priceIntervals;
_PRICE_SET_ = prices;
@@ -292,8 +291,8 @@ contract BaseMysteryBox is InitializableERC20, InitializableOwnable, ReentrancyG
break;
}
}
sellAmount = _SELLING_AMOUNT_SET_[i-1];
curPrice = _PRICE_SET_[i-1];
sellAmount = _SELLING_AMOUNT_SET_[i-1];
index = i - 1;
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2020 DODO ZOO.
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
@@ -10,15 +10,21 @@ pragma solidity 0.6.9;
import {ERC1155} from "../../external/ERC1155/ERC1155.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
contract MysteryBoxERC1155 is ERC1155,InitializableOwnable {
contract MysteryBoxERC1155 is ERC1155, InitializableOwnable {
mapping (address => bool) public _IS_ALLOWED_MINT_;
// ============ Event =============
event addMinter(address account);
event removeMinter(address account);
function addMintAccount(address account) public onlyOwner {
_IS_ALLOWED_MINT_[account] = true;
emit addMinter(account);
}
function removeMintAccount(address account) public onlyOwner {
_IS_ALLOWED_MINT_[account] = false;
emit removeMinter(account);
}
function init(

View File

@@ -10,15 +10,21 @@ pragma solidity 0.6.9;
import {ERC721} from "../../external/ERC721/ERC721.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
contract MysteryBoxERC721 is ERC721,InitializableOwnable {
contract MysteryBoxERC721 is ERC721, InitializableOwnable {
mapping (address => bool) public _IS_ALLOWED_MINT_;
// ============ Event =============
event addMinter(address account);
event removeMinter(address account);
function addMintAccount(address account) public onlyOwner {
_IS_ALLOWED_MINT_[account] = true;
emit addMinter(account);
}
function removeMintAccount(address account) public onlyOwner {
_IS_ALLOWED_MINT_[account] = false;
emit removeMinter(account);
}
function init(

View File

@@ -0,0 +1,71 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
interface IFee {
function getUserFee(address user,uint256 ticketAmount) external view returns (uint256);
}
interface IPrice {
function getUserPrice(address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256);
}
contract MysteryBoxFeeModel is InitializableOwnable {
using SafeMath for uint256;
struct MysteryBoxInfo {
bool isSet;
uint256 globalFee;
address feeAddr;
address priceAddr;
}
mapping(address => MysteryBoxInfo) mysteryBoxes;
function addMysteryBoxInfo(address mysteryBox, uint256 globalFee, address feeAddr, address priceAddr) external onlyOwner {
MysteryBoxInfo memory boxInfo = MysteryBoxInfo({
isSet: true,
globalFee: globalFee,
feeAddr: feeAddr,
priceAddr: priceAddr
});
mysteryBoxes[mysteryBox] = boxInfo;
}
function setMysteryBoxInfo(address mysteryBox, uint256 globalFee, address feeAddr, address priceAddr) external onlyOwner {
require(mysteryBoxes[mysteryBox].isSet, "NOT_FOUND_BOX");
mysteryBoxes[mysteryBox].globalFee = globalFee;
mysteryBoxes[mysteryBox].feeAddr = feeAddr;
mysteryBoxes[mysteryBox].priceAddr = priceAddr;
}
function getPayAmount(address mysteryBox, address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256 payAmount, uint256 feeAmount) {
MysteryBoxInfo memory boxInfo = mysteryBoxes[mysteryBox];
if(!mysteryBoxes[mysteryBox].isSet) {
payAmount = originalPrice.mul(ticketAmount);
feeAmount = 0;
} else {
uint256 feeRate = boxInfo.globalFee;
address feeAddr = boxInfo.feeAddr;
if(feeAddr != address(0))
feeRate = IFee(feeAddr).getUserFee(user, ticketAmount);
uint256 price = originalPrice;
address priceAddr = boxInfo.priceAddr;
if(priceAddr != address(0))
price = IPrice(priceAddr).getUserPrice(user, originalPrice, ticketAmount);
payAmount = price.mul(ticketAmount);
feeAmount = DecimalMath.mulFloor(payAmount, feeRate);
}
}
}

View File

@@ -8,19 +8,18 @@ pragma solidity 0.6.9;
import {IDODOApproveProxy} from "../DODOApproveProxy.sol";
import {IERC20} from "../../intf/IERC20.sol";
import {IWETH} from "../../intf/IWETH.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol";
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
interface IDODOMysteryBox {
function _BUY_TOKEN_() external view returns (address);
function _FEE_MODEL_() external view returns (address);
function _DEFAULT_FEE_MODEL_() external view returns (address);
function getPriceAndSellAmount() external view returns (uint256, uint256, uint256);
function buyTickets(address assetTo, uint256 ticketAmount) external;
}
interface IMysteryBoxPay {
interface IMysteryBoxFeeModel {
function getPayAmount(address mysteryBox, address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256, uint256);
}
@@ -35,8 +34,7 @@ contract DODOMysteryBoxProxy is ReentrancyGuard {
// ============ Storage ============
address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public immutable _WETH_;
address constant _BASE_COIN_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public immutable _DODO_APPROVE_PROXY_;
// ============ Events ============
@@ -46,11 +44,7 @@ contract DODOMysteryBoxProxy is ReentrancyGuard {
receive() external payable {}
constructor(
address payable weth,
address dodoApproveProxy
) public {
_WETH_ = weth;
constructor(address dodoApproveProxy) public {
_DODO_APPROVE_PROXY_ = dodoApproveProxy;
}
@@ -59,12 +53,12 @@ contract DODOMysteryBoxProxy is ReentrancyGuard {
require(curPrice > 0 && sellAmount > 0, "CAN_NOT_BUY");
require(ticketAmount <= sellAmount, "TICKETS_NOT_ENOUGH");
address feeModel = IDODOMysteryBox(dodoMysteryBox)._FEE_MODEL_();
(uint256 payAmount,) = IMysteryBoxPay(feeModel).getPayAmount(dodoMysteryBox, msg.sender, curPrice, ticketAmount);
address feeModel = IDODOMysteryBox(dodoMysteryBox)._DEFAULT_FEE_MODEL_();
(uint256 payAmount,) = IMysteryBoxFeeModel(feeModel).getPayAmount(dodoMysteryBox, msg.sender, curPrice, ticketAmount);
require(payAmount > 0, "UnQualified");
address buyToken = IDODOMysteryBox(dodoMysteryBox)._BUY_TOKEN_();
if(buyToken == _ETH_ADDRESS_) {
if(buyToken == _BASE_COIN_) {
require(msg.value >= payAmount, "PAYAMOUNT_NOT_ENOUGH");
dodoMysteryBox.transfer(payAmount);
}else {