dev
This commit is contained in:
@@ -16,13 +16,11 @@ contract ControllerModel is InitializableOwnable {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 public _GLOBAL_NFT_IN_FEE_ = 0;
|
||||
uint256 public _GLOBAL_NFT_RANDOM_OUT_FEE_ = 0;
|
||||
uint256 public _GLOBAL_NFT_TARGET_OUT_FEE_ = 50000000000000000;//0.05
|
||||
uint256 public _GLOBAL_NFT_OUT_FEE_ = 0;
|
||||
|
||||
struct FilterAdminFeeInfo {
|
||||
uint256 nftInFee;
|
||||
uint256 nftRandomOutFee;
|
||||
uint256 nftTargetOutFee;
|
||||
uint256 nftOutFee;
|
||||
bool isSet;
|
||||
}
|
||||
|
||||
@@ -35,26 +33,23 @@ contract ControllerModel is InitializableOwnable {
|
||||
|
||||
//==================== Ownable ====================
|
||||
|
||||
function addFilterAdminFeeInfo(address filterAdminAddr, uint256 nftInFee, uint256 nftRandomOutFee, uint256 nftTargetOutFee) external onlyOwner {
|
||||
function addFilterAdminFeeInfo(address filterAdminAddr, uint256 nftInFee, uint256 nftOutFee) external onlyOwner {
|
||||
FilterAdminFeeInfo memory filterAdmin = FilterAdminFeeInfo({
|
||||
nftInFee: nftInFee,
|
||||
nftRandomOutFee: nftRandomOutFee,
|
||||
nftTargetOutFee: nftTargetOutFee,
|
||||
nftOutFee: nftOutFee,
|
||||
isSet: true
|
||||
});
|
||||
filterAdminFees[filterAdminAddr] = filterAdmin;
|
||||
}
|
||||
|
||||
function setFilterAdminFeeInfo(address filterAdminAddr, uint256 nftInFee, uint256 nftRandomOutFee, uint256 nftTargetOutFee) external onlyOwner {
|
||||
function setFilterAdminFeeInfo(address filterAdminAddr, uint256 nftInFee, uint256 nftOutFee) external onlyOwner {
|
||||
filterAdminFees[filterAdminAddr].nftInFee = nftInFee;
|
||||
filterAdminFees[filterAdminAddr].nftRandomOutFee = nftRandomOutFee;
|
||||
filterAdminFees[filterAdminAddr].nftTargetOutFee = nftTargetOutFee;
|
||||
filterAdminFees[filterAdminAddr].nftOutFee = nftOutFee;
|
||||
}
|
||||
|
||||
function setGlobalParam(uint256 nftInFee, uint256 nftRandomOutFee, uint256 nftTargetOutFee) external onlyOwner {
|
||||
function setGlobalParam(uint256 nftInFee, uint256 nftOutFee) external onlyOwner {
|
||||
_GLOBAL_NFT_IN_FEE_ = nftInFee;
|
||||
_GLOBAL_NFT_RANDOM_OUT_FEE_ = nftRandomOutFee;
|
||||
_GLOBAL_NFT_TARGET_OUT_FEE_ = nftTargetOutFee;
|
||||
_GLOBAL_NFT_OUT_FEE_ = nftOutFee;
|
||||
}
|
||||
|
||||
function setEmergencyWithdraw(address filter, bool isOpen) external onlyOwner {
|
||||
@@ -63,7 +58,7 @@ contract ControllerModel is InitializableOwnable {
|
||||
}
|
||||
|
||||
//===================== View ========================
|
||||
function getNFTInFee(address filterAdminAddr, address) external view returns(uint256) {
|
||||
function getMintFee(address filterAdminAddr) external view returns(uint256) {
|
||||
FilterAdminFeeInfo memory filterAdminFeeInfo = filterAdminFees[filterAdminAddr];
|
||||
|
||||
if(filterAdminFeeInfo.isSet) {
|
||||
@@ -73,26 +68,16 @@ contract ControllerModel is InitializableOwnable {
|
||||
}
|
||||
}
|
||||
|
||||
function getNFTRandomOutFee(address filterAdminAddr, address) external view returns(uint256) {
|
||||
function getBurnFee(address filterAdminAddr) external view returns(uint256) {
|
||||
FilterAdminFeeInfo memory filterAdminFeeInfo = filterAdminFees[filterAdminAddr];
|
||||
|
||||
if(filterAdminFeeInfo.isSet) {
|
||||
return filterAdminFeeInfo.nftRandomOutFee;
|
||||
return filterAdminFeeInfo.nftOutFee;
|
||||
}else {
|
||||
return _GLOBAL_NFT_RANDOM_OUT_FEE_;
|
||||
return _GLOBAL_NFT_OUT_FEE_;
|
||||
}
|
||||
}
|
||||
|
||||
function getNFTTargetOutFee(address filterAdminAddr, address) external view returns(uint256) {
|
||||
FilterAdminFeeInfo memory filterAdminFeeInfo = filterAdminFees[filterAdminAddr];
|
||||
|
||||
if(filterAdminFeeInfo.isSet) {
|
||||
return filterAdminFeeInfo.nftTargetOutFee;
|
||||
}else {
|
||||
return _GLOBAL_NFT_TARGET_OUT_FEE_;
|
||||
}
|
||||
}
|
||||
|
||||
function getEmergencySwitch(address filter) external view returns(bool) {
|
||||
return isEmergencyWithdraw[filter];
|
||||
}
|
||||
|
||||
@@ -10,12 +10,10 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
import {InitializableInternalMintableERC20} from "../../external/ERC20/InitializableInternalMintableERC20.sol";
|
||||
import {SafeMath} from "../../lib/SafeMath.sol";
|
||||
import {IFilterModel} from "../intf/IFilterModel.sol";
|
||||
import {IControllerModel} from "../intf/IControllerModel.sol";
|
||||
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
|
||||
import {DecimalMath} from "../../lib/DecimalMath.sol";
|
||||
|
||||
contract FilterAdmin is InitializableInternalMintableERC20, ReentrancyGuard {
|
||||
contract FilterAdmin is InitializableInternalMintableERC20 {
|
||||
using SafeMath for uint256;
|
||||
|
||||
// ============ Storage ============
|
||||
@@ -28,69 +26,57 @@ contract FilterAdmin is InitializableInternalMintableERC20, ReentrancyGuard {
|
||||
event ChangeFee(uint256 fee);
|
||||
|
||||
function init(
|
||||
address _owner,
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address owner,
|
||||
uint256 initSupply,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
uint256 fee,
|
||||
address controllerModel,
|
||||
address defaultMaintainer,
|
||||
address[] memory filters
|
||||
) external {
|
||||
super.init(_owner, 0, _name, _symbol, 18);
|
||||
super.init(owner, initSupply, name, symbol, 18);
|
||||
_FILTER_REGISTRY_ = filters;
|
||||
_FEE_ = fee;
|
||||
_CONTROLLER_MODEL_ = controllerModel;
|
||||
_DEFAULT_MAINTAINER_ = defaultMaintainer;
|
||||
}
|
||||
|
||||
function chargeMint(address user, uint256 totalMintAmount) external {
|
||||
function mintFragTo(address to, uint256 rawAmount) external returns (uint256 received){
|
||||
require(isIncludeFilter(msg.sender), "FILTER_NOT_REGISTRIED");
|
||||
|
||||
(uint256 poolFeeAmount, uint256 mtFeeAmount) = getMintFee(user, totalMintAmount);
|
||||
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
|
||||
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
|
||||
(uint256 poolFee, uint256 mtFee) = queryChargeMintFee(rawAmount);
|
||||
if(poolFee > 0) _mint(_OWNER_, poolFee);
|
||||
if(mtFee > 0) _mint(_DEFAULT_MAINTAINER_, mtFee);
|
||||
|
||||
_mint(user, totalMintAmount.sub(poolFeeAmount).sub(mtFeeAmount));
|
||||
received = rawAmount.sub(poolFee).sub(mtFee);
|
||||
_mint(to, received);
|
||||
}
|
||||
|
||||
function chargeRandomBurn(address user, uint256 totalBurnAmount) external {
|
||||
function burnFragFrom(address from, uint256 rawAmount) external returns (uint256 paid){
|
||||
require(isIncludeFilter(msg.sender), "FILTER_NOT_REGISTRIED");
|
||||
|
||||
(uint256 poolFeeAmount, uint256 mtFeeAmount) = getRandomBurnFee(user, totalBurnAmount);
|
||||
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
|
||||
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
|
||||
(uint256 poolFee, uint256 mtFee) = queryChargeBurnFee(rawAmount);
|
||||
if(poolFee > 0) _mint(_OWNER_, poolFee);
|
||||
if(mtFee > 0) _mint(_DEFAULT_MAINTAINER_, mtFee);
|
||||
|
||||
_burn(user, totalBurnAmount);
|
||||
}
|
||||
|
||||
function chargeTargetBurn(address user, uint256 totalBurnAmount) external {
|
||||
require(isIncludeFilter(msg.sender), "FILTER_NOT_REGISTRIED");
|
||||
|
||||
(uint256 poolFeeAmount, uint256 mtFeeAmount) = getTargetBurnFee(user, totalBurnAmount);
|
||||
if(poolFeeAmount > 0) _mint(_OWNER_, poolFeeAmount);
|
||||
if(mtFeeAmount > 0) _mint(_DEFAULT_MAINTAINER_, mtFeeAmount);
|
||||
|
||||
_burn(user, totalBurnAmount);
|
||||
paid = rawAmount.add(poolFee).add(mtFee);
|
||||
_burn(from, paid);
|
||||
}
|
||||
|
||||
//================ View ================
|
||||
function getMintFee(address user, uint256 totalMintAmount) public returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
|
||||
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTInFee(address(this), user);
|
||||
poolFeeAmount = DecimalMath.mulFloor(totalMintAmount, _FEE_);
|
||||
mtFeeAmount = DecimalMath.mulFloor(totalMintAmount, mtFeeRate);
|
||||
function queryChargeMintFee(uint256 rawAmount) public returns (uint256 poolFee, uint256 mtFee) {
|
||||
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getMintFee(address(this));
|
||||
poolFee = DecimalMath.mulFloor(rawAmount, _FEE_);
|
||||
mtFee = DecimalMath.mulFloor(rawAmount, mtFeeRate);
|
||||
}
|
||||
|
||||
function getRandomBurnFee(address user, uint256 totalBurnAmount) public returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
|
||||
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTRandomOutFee(address(this), user);
|
||||
poolFeeAmount = DecimalMath.mulFloor(totalBurnAmount, _FEE_);
|
||||
mtFeeAmount = DecimalMath.mulFloor(totalBurnAmount, mtFeeRate);
|
||||
function queryChargeBurnFee(uint256 rawAmount) public returns (uint256 poolFee, uint256 mtFee) {
|
||||
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getBurnFee(address(this));
|
||||
poolFee = DecimalMath.mulFloor(rawAmount, _FEE_);
|
||||
mtFee = DecimalMath.mulFloor(rawAmount, mtFeeRate);
|
||||
}
|
||||
|
||||
function getTargetBurnFee(address user, uint256 totalBurnAmount) public returns (uint256 poolFeeAmount, uint256 mtFeeAmount) {
|
||||
uint256 mtFeeRate = IControllerModel(_CONTROLLER_MODEL_).getNFTTargetOutFee(address(this), user);
|
||||
poolFeeAmount = DecimalMath.mulFloor(totalBurnAmount, _FEE_);
|
||||
mtFeeAmount = DecimalMath.mulFloor(totalBurnAmount, mtFeeRate);
|
||||
}
|
||||
|
||||
function isIncludeFilter(address filter) view public returns (bool) {
|
||||
uint256 i = 0;
|
||||
|
||||
@@ -15,9 +15,9 @@ import {IControllerModel} from "../intf/IControllerModel.sol";
|
||||
import {IERC721} from "../../intf/IERC721.sol";
|
||||
import {IERC721Receiver} from "../../intf/IERC721Receiver.sol";
|
||||
import {DecimalMath} from "../../lib/DecimalMath.sol";
|
||||
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
|
||||
|
||||
|
||||
contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
contract FilterERC721V1 is InitializableOwnable, IERC721Receiver, ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
|
||||
//=================== Storage ===================
|
||||
@@ -27,6 +27,7 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
|
||||
//tokenId => isRegistered
|
||||
mapping(uint256 => bool) public _SPREAD_IDS_REGISTRY_;
|
||||
//tokenId => 1
|
||||
mapping(uint256 => uint256) public _NFT_RESERVE_;
|
||||
|
||||
uint256[] public _NFT_IDS_;
|
||||
@@ -54,9 +55,25 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
function init(
|
||||
address filterAdmin,
|
||||
address nftCollection,
|
||||
bool[] memory switches,
|
||||
uint256[] memory tokenRanges,
|
||||
uint256[] memory nftAmounts,
|
||||
uint256[] memory priceRules,
|
||||
uint256[] memory spreadIds
|
||||
) external {
|
||||
initOwner(filterAdmin);
|
||||
_NFT_COLLECTION_ = nftCollection;
|
||||
|
||||
_changeNFTInPrice(priceRules[0],priceRules[1],switches[0]);
|
||||
_changeNFTRandomInPrice(priceRules[2],priceRules[3],switches[1]);
|
||||
_changeNFTTargetOutPrice(priceRules[4],priceRules[5],switches[2]);
|
||||
|
||||
_changeNFTAmount(nftAmounts[0],nftAmounts[1]);
|
||||
|
||||
_changeTokenIdRange(tokenRanges[0],tokenRanges[1]);
|
||||
for(uint256 i = 0; i < spreadIds.length; i++) {
|
||||
_SPREAD_IDS_REGISTRY_[spreadIds[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
//==================== Query ==================
|
||||
@@ -69,54 +86,69 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
}
|
||||
}
|
||||
|
||||
function isNFTIDValid(uint256 nftId) public view returns(bool){
|
||||
if((nftId >= _TOKEN_ID_START_ && nftId <= _TOKEN_ID_END_) || _SPREAD_IDS_REGISTRY_[nftId]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
function isNFTIDValid(uint256 nftId) public view returns(bool) {
|
||||
if((nftId >= _NFT_ID_START_ && nftId <= _NFT_ID_END_) || _SPREAD_IDS_REGISTRY_[nftId]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getAvaliableNFTIn() public view returns(uint256) {
|
||||
if(_MAX_NFT_AMOUNT_ < _TOKEN_IDS_.length) {
|
||||
if(_MAX_NFT_AMOUNT_ < _NFT_IDS_.length) {
|
||||
return 0;
|
||||
}else {
|
||||
return _MAX_NFT_AMOUNT_ - _TOKEN_IDS_.length;
|
||||
return _MAX_NFT_AMOUNT_ - _NFT_IDS_.length;
|
||||
}
|
||||
}
|
||||
|
||||
function getAvaliableNFTOut() public view returns(uint256) {
|
||||
if(_TOKEN_IDS_.length < _MIN_NFT_AMOUNT_) {
|
||||
if(_NFT_IDS_.length < _MIN_NFT_AMOUNT_) {
|
||||
return 0;
|
||||
}else {
|
||||
return _TOKEN_IDS_.length - _MIN_NFT_AMOUNT_;
|
||||
return _NFT_IDS_.length - _MIN_NFT_AMOUNT_;
|
||||
}
|
||||
}
|
||||
|
||||
function queryNFTIn(uint256 NFTInAmount) external view returns (uint256 rawReceive, uint256 receive) {
|
||||
function getNFTIndexById(uint256 tokenId) public view returns(uint256) {
|
||||
uint256 i = 0;
|
||||
for(; i < _NFT_IDS_.length; i++) {
|
||||
if(_NFT_IDS_[i] == tokenId) break;
|
||||
}
|
||||
require(i < _NFT_IDS_.length, "TOKEN_ID_NOT_EXSIT");
|
||||
return i;
|
||||
}
|
||||
|
||||
function queryNFTIn(uint256 NFTInAmount) public view returns (uint256 rawReceive, uint256 received) {
|
||||
require(NFTInAmount <= getAvaliableNFTIn(), "EXCEDD_IN_AMOUNT");
|
||||
rawReceive = geometricCalc(_GS_START_IN_, _CR_IN_, _NFT_AMOUNT_, _NFT_AMOUNT_+NFTInAmount);
|
||||
receive = IFilterAdmin(_OWNER_).queryChargeMintFee(rawReceive);
|
||||
uint256 nftAmount = _NFT_IDS_.length;
|
||||
rawReceive = geometricCalc(_GS_START_IN_, _CR_IN_, nftAmount, nftAmount + NFTInAmount);
|
||||
(uint256 poolFee, uint256 mtFee) = IFilterAdmin(_OWNER_).queryChargeMintFee(rawReceive);
|
||||
received = rawReceive.sub(poolFee).sub(mtFee);
|
||||
}
|
||||
|
||||
function queryNFTTargetOut(uint256 NFTOutAmount) external view returns (uint256 rawPay, uint256 pay) {
|
||||
function queryNFTTargetOut(uint256 NFTOutAmount) public view returns (uint256 rawPay, uint256 pay) {
|
||||
require(NFTOutAmount <= getAvaliableNFTOut(), "EXCEED_OUT_AMOUNT");
|
||||
rawPay = geometricCalc(_GS_START_TARGET_OUT_,_CR_TARGET_OUT_, _NFT_AMOUNT_-NFTOutAmount,_NFT_AMOUNT_);
|
||||
pay = IFilterAdmin(_OWNER_).queryChargeBurnFee(rawPay);
|
||||
uint256 nftAmount = _NFT_IDS_.length;
|
||||
rawPay = geometricCalc(_GS_START_TARGET_OUT_,_CR_TARGET_OUT_, nftAmount - NFTOutAmount, nftAmount);
|
||||
(uint256 poolFee, uint256 mtFee) = IFilterAdmin(_OWNER_).queryChargeBurnFee(rawPay);
|
||||
pay = rawPay.add(poolFee).add(mtFee);
|
||||
}
|
||||
|
||||
function queryNFTRandomOut(uint256 NFTOutAmount) external view returns (uint256 rawPay, uint256 pay) {
|
||||
function queryNFTRandomOut(uint256 NFTOutAmount) public view returns (uint256 rawPay, uint256 pay) {
|
||||
require(NFTOutAmount <= getAvaliableNFTOut(), "EXCEED_OUT_AMOUNT");
|
||||
rawPay = geometricCalc(_GS_START_RANDOM_OUT_,_CR_RANDOM_OUT_, _NFT_AMOUNT_-NFTOutAmount,_NFT_AMOUNT_);
|
||||
pay = IFilterAdmin(_OWNER_).chargeBurnFee(rawPay);
|
||||
uint256 nftAmount = _NFT_IDS_.length;
|
||||
rawPay = geometricCalc(_GS_START_RANDOM_OUT_,_CR_RANDOM_OUT_, nftAmount - NFTOutAmount, nftAmount);
|
||||
(uint256 poolFee, uint256 mtFee) = IFilterAdmin(_OWNER_).queryChargeBurnFee(rawPay);
|
||||
pay = rawPay.add(poolFee).add(mtFee);
|
||||
}
|
||||
|
||||
// ================= Trading ================
|
||||
|
||||
function ERC721In(uint256[] memory tokenIds, address to) external preventReentrant returns(uint256 received) {
|
||||
for (uint256 i = 0; i < tokenIds.length; i++) {
|
||||
require(!_NFT_RESERVE_[tokenIds[i]] && IERC721(_NFT_COLLECTION_).ownerOf(tokenIds[i])==address(this), "NFT_NOT_SEND");
|
||||
_NFT_IDS_.push(tokenId);
|
||||
require(_NFT_RESERVE_[tokenIds[i]] == 0 && IERC721(_NFT_COLLECTION_).ownerOf(tokenIds[i])==address(this), "NFT_NOT_SEND");
|
||||
_NFT_IDS_.push(tokenIds[i]);
|
||||
_NFT_RESERVE_[tokenIds[i]] = 1;
|
||||
}
|
||||
(uint256 rawReceive,) = queryNFTIn(tokenIds.length);
|
||||
@@ -124,7 +156,7 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
}
|
||||
|
||||
function ERC721TargetOut(uint256[] memory indexes, address to) external preventReentrant returns(uint256 paid) {
|
||||
(uint256 rawPay, ) = queryNFTOut(tokenIds.length);
|
||||
(uint256 rawPay, ) = queryNFTTargetOut(indexes.length);
|
||||
paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay);
|
||||
for (uint256 i = 0; i < indexes.length; i++) {
|
||||
_transferOutERC721(to, indexes[i]);
|
||||
@@ -132,7 +164,7 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
}
|
||||
|
||||
function ERC721RandomOut(uint256 amount, address to) external preventReentrant returns (uint256 paid) {
|
||||
(uint256 rawPay, ) = queryNFTOut(amount);
|
||||
(uint256 rawPay, ) = queryNFTRandomOut(amount);
|
||||
paid = IFilterAdmin(_OWNER_).burnFragFrom(msg.sender, rawPay);
|
||||
for (uint256 i = 0; i < amount; i++) {
|
||||
_transferOutERC721(to, getRandomOutId());
|
||||
@@ -144,18 +176,18 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
function onERC721Received(
|
||||
address,
|
||||
address,
|
||||
uint256 tokenId,
|
||||
uint256,
|
||||
bytes calldata
|
||||
) external override returns (bytes4) {
|
||||
return IERC721Receiver.onERC721Received.selector;
|
||||
}
|
||||
|
||||
function _transferOutERC721(address to, uint256 index) internal {
|
||||
require(index<_TOKEN_IDS_.length, "INDEX_NOT_EXIST");
|
||||
uint256 tokenId = _TOKEN_IDS_[index];
|
||||
IERC721(_NFT_COLLECTION_).safeTransfer(to, tokenId);
|
||||
_TOKEN_IDS_[index] = _TOKEN_IDS_[_TOKEN_IDS_.length - 1];
|
||||
_TOKEN_IDS_.pop();
|
||||
require(index < _NFT_IDS_.length, "INDEX_NOT_EXIST");
|
||||
uint256 tokenId = _NFT_IDS_[index];
|
||||
IERC721(_NFT_COLLECTION_).safeTransferFrom(address(this), to, tokenId);
|
||||
_NFT_IDS_[index] = _NFT_IDS_[_NFT_IDS_.length - 1];
|
||||
_NFT_IDS_.pop();
|
||||
_NFT_RESERVE_[tokenId] = 0;
|
||||
}
|
||||
|
||||
@@ -166,89 +198,115 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
require(IControllerModel(controllerModel).getEmergencySwitch(address(this)), "NOT_OPEN");
|
||||
|
||||
for(uint256 i = 0; i< nftContract.length; i++) {
|
||||
if(_NFT_RESERVE_[tokenIds[i]] && nftContract[i]==_NFT_COLLECTION_){
|
||||
uint256 index = getNFTIndex(tokenIds[i]);
|
||||
_TOKEN_IDS_[index] = _TOKEN_IDS_[_TOKEN_IDS_.length - 1];
|
||||
_TOKEN_IDS_.pop();
|
||||
_NFT_RESERVE_[tokenId] = 0;
|
||||
if(_NFT_RESERVE_[tokenIds[i]] == 1 && nftContract[i] == _NFT_COLLECTION_){
|
||||
uint256 index = getNFTIndexById(tokenIds[i]);
|
||||
_NFT_IDS_[index] = _NFT_IDS_[_NFT_IDS_.length - 1];
|
||||
_NFT_IDS_.pop();
|
||||
_NFT_RESERVE_[tokenIds[i]] = 0;
|
||||
}
|
||||
IERC721(nftContract[i]).safeTransfer(to, tokenId);
|
||||
IERC721(nftContract[i]).safeTransferFrom(address(this), to, tokenIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ============ Math =============
|
||||
|
||||
function geometricCalc(uint256 base, uint256 ratio, uint256 times) internal view returns(uint256 newBase, uint256 sum) {
|
||||
sum = 0;
|
||||
for(uint256 i = 0; i < times; i++) {
|
||||
base = DecimalMath.mulFloor(base, ratio);
|
||||
sum = sum.add(base);
|
||||
}
|
||||
newBase = base;
|
||||
function geometricCalc(uint256 a1, uint256 q, uint256 start, uint256 end) internal view returns(uint256) {
|
||||
//Sn=a1*(q^n-1)/(q-1)
|
||||
//Sn-Sm = a1*(q^n-q^m)/(q-1)
|
||||
|
||||
//q^n
|
||||
uint256 qn = DecimalMath.powFloor(q, end);
|
||||
//q^m
|
||||
uint256 qm = DecimalMath.powFloor(q, start);
|
||||
return a1.mul(qn.sub(qm)).div(q.sub(DecimalMath.ONE));
|
||||
}
|
||||
|
||||
function getRandomOutId() external view returns (uint256 index) {
|
||||
uint256 nftAmount = _TOKEN_IDS_.length;
|
||||
function getRandomOutId() public view returns (uint256 index) {
|
||||
uint256 nftAmount = _NFT_IDS_.length;
|
||||
index = uint256(keccak256(abi.encodePacked(tx.origin, blockhash(block.number-1), gasleft()))) % nftAmount;
|
||||
}
|
||||
|
||||
|
||||
// ================= Ownable ================
|
||||
|
||||
function changeNFTInPrice(uint256 newGsStart, uint256 newCr, bool switch) external {
|
||||
function changeNFTInPrice(uint256 newGsStart, uint256 newCr, bool switchFlag) external {
|
||||
require(msg.sender == IFilterAdmin(_OWNER_)._OWNER_(), "ACCESS_RESTRICTED");
|
||||
if (!switch) {
|
||||
_changeNFTInPrice(newGsStart, newCr, switchFlag);
|
||||
}
|
||||
|
||||
function _changeNFTInPrice(uint256 newGsStart, uint256 newCr, bool switchFlag) internal {
|
||||
if (!switchFlag) {
|
||||
_NFT_IN_SWITCH_ = false;
|
||||
} else {
|
||||
require(newCr>DecimalMath.ONE, "CR_ZERO");
|
||||
require(newCr > DecimalMath.ONE, "CR_INVALID");
|
||||
_GS_START_IN_ = newGsStart;
|
||||
_CR_IN_ = newCr;
|
||||
_NFT_IN_SWITCH_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
function changeNFTRandomInPrice(uint256 newGsStart, uint256 newCr, bool switch) external {
|
||||
function changeNFTRandomInPrice(uint256 newGsStart, uint256 newCr, bool switchFlag) external {
|
||||
require(msg.sender == IFilterAdmin(_OWNER_)._OWNER_(), "ACCESS_RESTRICTED");
|
||||
if (!switch) {
|
||||
_NFT_RANDOM_OUT_SWITCH_ = false;
|
||||
_changeNFTRandomInPrice(newGsStart, newCr, switchFlag);
|
||||
}
|
||||
|
||||
function _changeNFTRandomInPrice(uint256 newGsStart, uint256 newCr, bool switchFlag) internal {
|
||||
if (!switchFlag) {
|
||||
_NFT_RANDOM_SWITCH_ = false;
|
||||
} else {
|
||||
require(newCr>DecimalMath.ONE, "CR_ZERO");
|
||||
require(newCr > DecimalMath.ONE, "CR_INVALID");
|
||||
_GS_START_RANDOM_OUT_ = newGsStart;
|
||||
_CR_RANDOM_OUT_ = newCr;
|
||||
_NFT_RANDOM_OUT_SWITCH_ = true;
|
||||
_NFT_RANDOM_SWITCH_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
function changeNFTTargetOutPrice(uint256 newGsStart, uint256 newCr, bool switch) external {
|
||||
function changeNFTTargetOutPrice(uint256 newGsStart, uint256 newCr, bool switchFlag) external {
|
||||
require(msg.sender == IFilterAdmin(_OWNER_)._OWNER_(), "ACCESS_RESTRICTED");
|
||||
if (!switch) {
|
||||
_NFT_TARGET_OUT_SWITCH_ = false;
|
||||
_changeNFTTargetOutPrice(newGsStart, newCr, switchFlag);
|
||||
}
|
||||
|
||||
function _changeNFTTargetOutPrice(uint256 newGsStart, uint256 newCr, bool switchFlag) internal {
|
||||
if (!switchFlag) {
|
||||
_NFT_TARGET_SWITCH_ = false;
|
||||
} else {
|
||||
require(newCr>DecimalMath.ONE, "CR_ZERO");
|
||||
require(newCr > DecimalMath.ONE, "CR_INVALID");
|
||||
_GS_START_TARGET_OUT_ = newGsStart;
|
||||
_CR_TARGET_OUT_ = newCr;
|
||||
_NFT_TARGET_OUT_SWITCH_ = true;
|
||||
_NFT_TARGET_SWITCH_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
function changeNFTAmount(uint256 maxNFTAmount, uint256 minNFTAmount) external {
|
||||
require(msg.sender == IFilterAdmin(_OWNER_)._OWNER_(), "ACCESS_RESTRICTED");
|
||||
_changeNFTAmount(maxNFTAmount, minNFTAmount);
|
||||
}
|
||||
|
||||
function _changeNFTAmount(uint256 maxNFTAmount, uint256 minNFTAmount) internal {
|
||||
require(maxNFTAmount >= minNFTAmount, "AMOUNT_INVALID");
|
||||
_MAX_NFT_AMOUNT_ = maxNFTAmount;
|
||||
_MIN_NFT_AMOUNT_ = minNFTAmount;
|
||||
}
|
||||
|
||||
function changeTokenIdRange(uint256 tokenIdStart, uint256 tokenIdEnd) external {
|
||||
function changeTokenIdRange(uint256 nftIdStart, uint256 nftIdEnd) external {
|
||||
require(msg.sender == IFilterAdmin(_OWNER_)._OWNER_(), "ACCESS_RESTRICTED");
|
||||
require(tokenIdStart <= tokenIdEnd, "TOKEN_RANGE_INVALID");
|
||||
_changeTokenIdRange(nftIdStart, nftIdEnd);
|
||||
}
|
||||
|
||||
function _changeTokenIdRange(uint256 nftIdStart, uint256 nftIdEnd) internal {
|
||||
require(nftIdStart <= nftIdEnd, "TOKEN_RANGE_INVALID");
|
||||
|
||||
_TOKEN_ID_START_ = tokenIdStart;
|
||||
_TOKEN_ID_END_ = tokenIdEnd;
|
||||
_NFT_ID_START_ = nftIdStart;
|
||||
_NFT_ID_END_ = nftIdEnd;
|
||||
}
|
||||
|
||||
function changeTokenIdMap(uint256[] memory tokenIds, bool[] memory isRegistrieds) external {
|
||||
require(msg.sender == IFilterAdmin(_OWNER_)._OWNER_(), "ACCESS_RESTRICTED");
|
||||
_changeTokenIdMap(tokenIds, isRegistrieds);
|
||||
}
|
||||
|
||||
function _changeTokenIdMap(uint256[] memory tokenIds, bool[] memory isRegistrieds) internal {
|
||||
require(tokenIds.length == isRegistrieds.length, "PARAM_NOT_MATCH");
|
||||
|
||||
for(uint256 i = 0; i < tokenIds.length; i++) {
|
||||
@@ -262,42 +320,8 @@ contract FilterModel01 is InitializableOwnable, IERC721Receiver {
|
||||
return interfaceId == type(IERC721Receiver).interfaceId;
|
||||
}
|
||||
|
||||
|
||||
function version() virtual external pure returns (string memory) {
|
||||
return "FILTER_1_ERC721 1.0.0";
|
||||
//TODO:
|
||||
function geometricCalc1(uint256 base, uint256 ratio, uint256 times) internal view returns(uint256 newBase, uint256 sum) {
|
||||
require(times > 0);
|
||||
//q^(n-1)
|
||||
uint256 general_coefficient = ratio.powFloor(times - 1);
|
||||
//an=a1*q^n-1
|
||||
newBase = base.mul(general_coefficient);
|
||||
|
||||
if(ratio == 1e18) {
|
||||
//na1
|
||||
sum = base.mul(times);
|
||||
} else {
|
||||
//a1(1-q^n)/(1-q)
|
||||
uint256 denominator = base.mul(1e18.sub(DecimalMath.mulFloor(general_coefficient, ratio)));
|
||||
sum = denominator.div(1e18.sub(ratio));
|
||||
}
|
||||
}
|
||||
|
||||
function removeTokenId(uint256 id) internal returns(bool){
|
||||
uint256[] memory tokenIds = _TOKEN_IDS_;
|
||||
uint256 i;
|
||||
for (; i < tokenIds.length; i++) {
|
||||
if (tokenIds[i] == id) {
|
||||
tokenIds[i] = tokenIds[tokenIds.length - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i < tokenIds.length) {
|
||||
_TOKEN_IDS_ = tokenIds;
|
||||
_TOKEN_IDS_.pop();
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,9 @@
|
||||
pragma solidity 0.6.9;
|
||||
|
||||
interface IControllerModel {
|
||||
function getNFTInFee(address filterAdminAddr, address user) external view returns(uint256);
|
||||
function getMintFee(address filterAdminAddr) external view returns (uint256);
|
||||
|
||||
function getNFTRandomOutFee(address filterAdminAddr, address user) external view returns(uint256);
|
||||
function getBurnFee(address filterAdminAddr) external view returns (uint256);
|
||||
|
||||
function getNFTTargetOutFee(address filterAdminAddr, address user) external view returns(uint256);
|
||||
|
||||
function getEmergencySwitch(address filter) external view returns(bool);
|
||||
function getEmergencySwitch(address filter) external view returns (bool);
|
||||
}
|
||||
@@ -13,27 +13,21 @@ interface IFilterAdmin {
|
||||
function _CONTROLLER_MODEL_() external returns (address);
|
||||
|
||||
function init(
|
||||
address _owner,
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address owner,
|
||||
uint256 initSupply,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
uint256 fee,
|
||||
address mtFeeModel,
|
||||
address defaultMaintainer,
|
||||
address[] memory filters
|
||||
) external;
|
||||
|
||||
function ERC721In(
|
||||
address filter,
|
||||
address nftContract,
|
||||
uint256[] memory tokenIds,
|
||||
uint256 minMintAmount
|
||||
) external returns (uint256 actualMintAmount);
|
||||
function mintFragTo(address to, uint256 rawAmount) external returns (uint256 received);
|
||||
|
||||
function mintFragTo(address to, uint256 rawAmount) external;
|
||||
function burnFragFrom(address from, uint256 rawAmount) external returns (uint256 paid);
|
||||
|
||||
function burnFragFrom(address from, uint256 rawAmount) external;
|
||||
function queryChargeMintFee(uint256 rawAmount) external view returns (uint256 poolFee, uint256 mtFee);
|
||||
|
||||
function queryChargeMintFee(uint256 rawAmount) external;
|
||||
|
||||
function queryChargeBurnFee(uint256 rawAmount) external;
|
||||
function queryChargeBurnFee(uint256 rawAmount) external view returns (uint256 poolFee, uint256 mtFee);
|
||||
}
|
||||
|
||||
@@ -8,35 +8,21 @@
|
||||
pragma solidity 0.6.9;
|
||||
|
||||
interface IFilterModel {
|
||||
function isFilterERC721Pass(address nftCollectionAddress, uint256 nftId) external view returns (bool);
|
||||
function isNFTValid(address nftCollectionAddress, uint256 nftId) external view returns (bool);
|
||||
|
||||
function _NFT_COLLECTION_() external view returns(address);
|
||||
|
||||
function isFilterERC1155Pass(address nftCollectionAddress, uint256 nftId, uint256 amount) external view returns (bool);
|
||||
function queryNFTIn(uint256 NFTInAmount) external view returns (uint256 rawReceive, uint256 received);
|
||||
|
||||
function getAvaliableNFTIn() external view returns(uint256);
|
||||
function queryNFTTargetOut(uint256 NFTOutAmount) external view returns (uint256 rawPay, uint256 pay);
|
||||
|
||||
function getAvaliableNFTOut() external view returns(uint256);
|
||||
function queryNFTRandomOut(uint256 NFTOutAmount) external view returns (uint256 rawPay, uint256 pay);
|
||||
|
||||
function _NFT_IN_SWITCH_() external view returns(bool);
|
||||
function ERC721In(uint256[] memory tokenIds, address to) external returns(uint256 received);
|
||||
|
||||
function _NFT_RANDOM_SWITCH_() external view returns(bool);
|
||||
function ERC721TargetOut(uint256[] memory indexes, address to) external returns(uint256 paid);
|
||||
|
||||
function _NFT_TARGET_SWITCH_() external view returns(bool);
|
||||
function ERC721RandomOut(uint256 amount, address to) external returns (uint256 paid);
|
||||
|
||||
|
||||
function getNFTInPrice(address nftCollectionAddress, uint256 nftId) external view returns (uint256);
|
||||
|
||||
function getNFTRandomOutPrice() external view returns (uint256);
|
||||
|
||||
function getNFTTargetOutPrice(address nftCollectionAddress, uint256 nftId) external view returns (uint256);
|
||||
|
||||
function getRandomOutId() external view returns (address nftCollection, uint256 nftId);
|
||||
|
||||
function transferOutERC721(address nftContract, address assetTo, uint256 nftId) external;
|
||||
|
||||
function transferInERC721(address nftContract, address assetFrom, uint256 nftId) external;
|
||||
|
||||
function transferOutERC1155(address nftContract, address assetTo, uint256 nftId, uint256 amount) external;
|
||||
|
||||
function transferBatchOutERC1155(address nftContract, address assetTo, uint256[] memory nftIds, uint256[] memory amounts) external;
|
||||
|
||||
function transferBatchInERC1155(address nftContract, address assetFrom, uint256[] memory nftIds, uint256[] memory amounts) external;
|
||||
}
|
||||
103
contracts/SmartRoute/DODONFTApprove.sol
Normal file
103
contracts/SmartRoute/DODONFTApprove.sol
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
|
||||
Copyright 2021 DODO ZOO.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.6.9;
|
||||
|
||||
import {IERC721} from "../intf/IERC721.sol";
|
||||
import {IERC1155} from "../intf/IERC1155.sol";
|
||||
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
|
||||
|
||||
/**
|
||||
* @title DODONFTApprove
|
||||
* @author DODO Breeder
|
||||
*
|
||||
* @notice Handle NFT authorizations in DODO platform
|
||||
*/
|
||||
contract DODONFTApprove is InitializableOwnable {
|
||||
|
||||
// ============ Storage ============
|
||||
uint256 private constant _TIMELOCK_DURATION_ = 3 days;
|
||||
mapping (address => bool) public _IS_ALLOWED_PROXY_;
|
||||
uint256 public _TIMELOCK_;
|
||||
address public _PENDING_ADD_DODO_PROXY_;
|
||||
|
||||
// ============ Events ============
|
||||
event AddDODOProxy(address dodoProxy);
|
||||
|
||||
// ============ Modifiers ============
|
||||
modifier notLocked() {
|
||||
require(
|
||||
_TIMELOCK_ <= block.timestamp,
|
||||
"SetProxy is timelocked"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function init(address owner, address[] memory proxies) external {
|
||||
initOwner(owner);
|
||||
for(uint i = 0; i < proxies.length; i++)
|
||||
_IS_ALLOWED_PROXY_[proxies[i]] = true;
|
||||
}
|
||||
|
||||
function unlockAddProxy(address newDodoProxy) public onlyOwner {
|
||||
_TIMELOCK_ = block.timestamp + _TIMELOCK_DURATION_;
|
||||
_PENDING_ADD_DODO_PROXY_ = newDodoProxy;
|
||||
}
|
||||
|
||||
function lockAddProxy() public onlyOwner {
|
||||
_PENDING_ADD_DODO_PROXY_ = address(0);
|
||||
_TIMELOCK_ = 0;
|
||||
}
|
||||
|
||||
|
||||
function addDODOProxy() external onlyOwner notLocked() {
|
||||
_IS_ALLOWED_PROXY_[_PENDING_ADD_DODO_PROXY_] = true;
|
||||
lockAddProxy();
|
||||
emit AddDODOProxy(_PENDING_ADD_DODO_PROXY_);
|
||||
}
|
||||
|
||||
function removeDODOProxy (address oldDodoProxy) public onlyOwner {
|
||||
_IS_ALLOWED_PROXY_[oldDodoProxy] = false;
|
||||
}
|
||||
|
||||
|
||||
function claimERC721(
|
||||
address nftContract,
|
||||
address who,
|
||||
address dest,
|
||||
uint256 tokenId
|
||||
) external {
|
||||
require(_IS_ALLOWED_PROXY_[msg.sender], "DODONFTApprove:Access restricted");
|
||||
IERC721(nftContract).safeTransferFrom(who, dest, tokenId);
|
||||
}
|
||||
|
||||
function claimERC1155(
|
||||
address nftContract,
|
||||
address who,
|
||||
address dest,
|
||||
uint256 tokenId,
|
||||
uint256 amount
|
||||
) external {
|
||||
require(_IS_ALLOWED_PROXY_[msg.sender], "DODONFTApprove:Access restricted");
|
||||
IERC1155(nftContract).safeTransferFrom(who, dest, tokenId, amount, "");
|
||||
}
|
||||
|
||||
function claimERC1155Batch(
|
||||
address nftContract,
|
||||
address who,
|
||||
address dest,
|
||||
uint256[] memory tokenIds,
|
||||
uint256[] memory amounts
|
||||
) external {
|
||||
require(_IS_ALLOWED_PROXY_[msg.sender], "DODONFTApprove:Access restricted");
|
||||
IERC1155(nftContract).safeBatchTransferFrom(who, dest, tokenIds, amounts, "");
|
||||
}
|
||||
|
||||
function isAllowedProxy(address _proxy) external view returns (bool) {
|
||||
return _IS_ALLOWED_PROXY_[_proxy];
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,13 @@ import {SafeMath} from "../../lib/SafeMath.sol";
|
||||
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
|
||||
import {ICloneFactory} from "../../lib/CloneFactory.sol";
|
||||
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
|
||||
import {IFilterModel} from "../../NFTPool/intf/IFilterModel.sol";
|
||||
import {IFilterAdmin} from "../../NFTPool/intf/IFilterAdmin.sol";
|
||||
import {IERC721} from "../../intf/IERC721.sol";
|
||||
import {IDODONFTApprove} from "../../intf/IDODONFTApprove.sol";
|
||||
import {IERC20} from "../../intf/IERC20.sol";
|
||||
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
||||
|
||||
interface IFilter01 {
|
||||
interface IFilterERC721V1 {
|
||||
function init(
|
||||
address filterAdmin,
|
||||
address nftCollection,
|
||||
@@ -35,8 +36,10 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
|
||||
mapping(uint256 => address) public _FILTER_TEMPLATES_;
|
||||
address public _FILTER_ADMIN_TEMPLATE_;
|
||||
address public _DEFAULT_MAINTAINER_;
|
||||
address public _NFT_POOL_FEE_MODEL_;
|
||||
address public _CONTROLLER_MODEL_;
|
||||
address public immutable _CLONE_FACTORY_;
|
||||
address public immutable _DODO_NFT_APPROVE_;
|
||||
address public immutable _DODO_APPROVE_;
|
||||
|
||||
|
||||
// ============ Event ==============
|
||||
@@ -45,16 +48,60 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
|
||||
constructor(
|
||||
address cloneFactory,
|
||||
address filterAdminTemplate,
|
||||
address nftPoolFeeModel,
|
||||
address defaultMaintainer
|
||||
address controllerModel,
|
||||
address defaultMaintainer,
|
||||
address dodoNftApprove,
|
||||
address dodoApprove
|
||||
) public {
|
||||
_CLONE_FACTORY_ = cloneFactory;
|
||||
_FILTER_ADMIN_TEMPLATE_ = filterAdminTemplate;
|
||||
_NFT_POOL_FEE_MODEL_ = nftPoolFeeModel;
|
||||
_CONTROLLER_MODEL_ = controllerModel;
|
||||
_DEFAULT_MAINTAINER_ = defaultMaintainer;
|
||||
_DODO_NFT_APPROVE_ = dodoNftApprove;
|
||||
_DODO_APPROVE_ = dodoApprove;
|
||||
}
|
||||
|
||||
// ================ NFT In and Out ===================
|
||||
function nftIn(
|
||||
address filter,
|
||||
address nftCollection,
|
||||
uint256[] memory tokenIds,
|
||||
address to,
|
||||
uint256 minMintAmount
|
||||
) external {
|
||||
for(uint256 i = 0; i < tokenIds.length; i++) {
|
||||
require(IFilterModel(filter).isNFTValid(nftCollection,tokenIds[i]), "NOT_REGISTRIED");
|
||||
IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC721(nftCollection, msg.sender, filter, tokenIds[i]);
|
||||
}
|
||||
uint256 received = IFilterModel(filter).ERC721In(tokenIds, to);
|
||||
require(received >= minMintAmount, "MINT_AMOUNT_NOT_ENOUGH");
|
||||
}
|
||||
|
||||
function nftTargetOut(
|
||||
address filter,
|
||||
uint256[] memory indexes,
|
||||
address to,
|
||||
uint256 maxBurnAmount
|
||||
) external {
|
||||
uint256 paid = IFilterModel(filter).ERC721TargetOut(indexes, to);
|
||||
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
|
||||
}
|
||||
|
||||
function nftRandomOut(
|
||||
address filter,
|
||||
uint256 amount,
|
||||
address to,
|
||||
uint256 maxBurnAmount
|
||||
) external {
|
||||
uint256 paid = IFilterModel(filter).ERC721RandomOut(amount, to);
|
||||
require(paid <= maxBurnAmount, "BURN_AMOUNT_EXCEED");
|
||||
}
|
||||
|
||||
|
||||
// ================== Create NFTPool ===================
|
||||
|
||||
function createNewNFTPool01(
|
||||
uint256 initSupply,
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
uint256 fee,
|
||||
@@ -67,7 +114,7 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
|
||||
) external returns(address newFilterAdmin) {
|
||||
newFilterAdmin = ICloneFactory(_CLONE_FACTORY_).clone(_FILTER_ADMIN_TEMPLATE_);
|
||||
|
||||
address filter01 = createFilter01(
|
||||
address filter01 = createFilterERC721V1(
|
||||
newFilterAdmin,
|
||||
nftCollection,
|
||||
switches,
|
||||
@@ -82,16 +129,19 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
|
||||
|
||||
IFilterAdmin(newFilterAdmin).init(
|
||||
msg.sender,
|
||||
initSupply,
|
||||
name,
|
||||
symbol,
|
||||
fee,
|
||||
_NFT_POOL_FEE_MODEL_,
|
||||
_CONTROLLER_MODEL_,
|
||||
_DEFAULT_MAINTAINER_,
|
||||
filters
|
||||
);
|
||||
}
|
||||
|
||||
function createFilter01(
|
||||
|
||||
// ================== Create Filter ===================
|
||||
function createFilterERC721V1(
|
||||
address filterAdmin,
|
||||
address nftCollection,
|
||||
bool[] memory switches,
|
||||
@@ -99,34 +149,42 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
|
||||
uint256[] memory nftAmounts,
|
||||
uint256[] memory priceRules,
|
||||
uint256[] memory spreadIds
|
||||
) public returns(address newFilter01) {
|
||||
newFilter01 = ICloneFactory(_CLONE_FACTORY_).clone(_FILTER_TEMPLATES_[1]);
|
||||
IFilter01(newFilter01).init(filterAdmin, nftCollection, switches, tokenRanges, nftAmounts, priceRules, spreadIds);
|
||||
) public returns(address newFilterERC721V1) {
|
||||
//key = 1 => FilterERC721V1
|
||||
newFilterERC721V1 = ICloneFactory(_CLONE_FACTORY_).clone(_FILTER_TEMPLATES_[1]);
|
||||
IFilterERC721V1(newFilterERC721V1).init(
|
||||
filterAdmin,
|
||||
nftCollection,
|
||||
switches,
|
||||
tokenRanges,
|
||||
nftAmounts,
|
||||
priceRules,
|
||||
spreadIds
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ================== NFT ERC20 Swap ======================
|
||||
function erc721ToErc20(
|
||||
address filterAdmin,
|
||||
address filter,
|
||||
address nftContract,
|
||||
uint256 tokenId,
|
||||
address toToken,
|
||||
address dodoApprove,
|
||||
address dodoProxy,
|
||||
bytes memory dodoSwapData
|
||||
)
|
||||
external
|
||||
preventReentrant
|
||||
{
|
||||
IERC721(nftContract).safeTransferFrom(msg.sender, address(this), tokenId);
|
||||
IERC721(nftContract).approve(filter, tokenId);
|
||||
IDODONFTApprove(_DODO_NFT_APPROVE_).claimERC721(nftContract, msg.sender, filter, tokenId);
|
||||
|
||||
uint256[] memory tokenIds = new uint256[](1);
|
||||
tokenIds[0] = tokenId;
|
||||
|
||||
//TODO:
|
||||
uint256 mintAmount = IFilterAdmin(filterAdmin).ERC721In(filter, nftContract, tokenIds, 0);
|
||||
uint256 receivedFragAmount = IFilterModel(filter).ERC721In(tokenIds, address(this));
|
||||
|
||||
_generalApproveMax(filterAdmin, dodoApprove, mintAmount);
|
||||
_generalApproveMax(filterAdmin, _DODO_APPROVE_, receivedFragAmount);
|
||||
|
||||
(bool success, ) = dodoProxy.call(dodoSwapData);
|
||||
require(success, "API_SWAP_FAILED");
|
||||
@@ -146,8 +204,8 @@ contract DODONFTPoolProxy is ReentrancyGuard, InitializableOwnable {
|
||||
_FILTER_ADMIN_TEMPLATE_ = newFilterAdminTemplate;
|
||||
}
|
||||
|
||||
function changeNftPoolFeeModel(address newNftPoolFeeModel) external onlyOwner {
|
||||
_NFT_POOL_FEE_MODEL_ = newNftPoolFeeModel;
|
||||
function changeControllerModel(address newControllerModel) external onlyOwner {
|
||||
_CONTROLLER_MODEL_ = newControllerModel;
|
||||
}
|
||||
|
||||
function setFilterTemplate(uint256 idx, address newFilterTemplate) external onlyOwner {
|
||||
|
||||
18
contracts/intf/IDODONFTApprove.sol
Normal file
18
contracts/intf/IDODONFTApprove.sol
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
|
||||
Copyright 2021 DODO ZOO.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.6.9;
|
||||
|
||||
interface IDODONFTApprove {
|
||||
function isAllowedProxy(address _proxy) external view returns (bool);
|
||||
|
||||
function claimERC721(address nftContract, address who, address dest, uint256 tokenId) external;
|
||||
|
||||
function claimERC1155(address nftContract, address who, address dest, uint256 tokenId, uint256 amount) external;
|
||||
|
||||
function claimERC1155Batch(address nftContract, address who, address dest, uint256[] memory tokenIds, uint256[] memory amounts) external;
|
||||
}
|
||||
Reference in New Issue
Block a user