init nftPool

This commit is contained in:
owen05
2021-09-06 19:15:17 +08:00
parent a1f377b6a7
commit 3ef45bc799
7 changed files with 555 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableInternalMintableERC20} from "../../external/ERC20/InitializableInternalMintableERC20.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {IFilterERC721Model} from "../intf/IFilterERC721Model.sol";
import {IFilterERC1155Model} from "../intf/IFilterERC1155Model.sol";
import {IERC721} from "../../intf/IERC721.sol";
import {IERC721Receiver} from "../../intf/IERC721Receiver.sol";
import {IERC1155} from "../../intf/IERC1155.sol";
import {IERC1155Receiver} from "../../intf/IERC1155Receiver.sol";
contract FilterAdmin is InitializableInternalMintableERC20, IERC721Receiver, IERC1155Receiver {
using SafeMath for uint256;
// ============ Storage ============
address public _ERC721_FILTER_MODEL_;
address public _ERC1155_FILTER_MODEL_;
function init(
address _owner,
uint256 _initSupply,
string memory _name,
string memory _symbol,
uint8 _decimals,
address _erc721FilterModel,
address _erc1155FilterModel
) external {
super.init(_owner, _initSupply, _name, _symbol, _decimals);
_ERC721_FILTER_MODEL_ = _erc721FilterModel;
_ERC1155_FILTER_MODEL_ = _erc1155FilterModel;
}
// ============ Event ============
event RemoveNftToken(address nftContract, uint256 tokenId, uint256 amount);
event AddNftToken(address nftContract, uint256 tokenId, uint256 amount);
function depositERC721(address nftContract, uint256[] memory tokenIds) public {
require(nftContract != address(0), "ZERO_ADDRESS");
for(uint256 i = 0; i < tokenIds.length; i++) {
uint256 price = IFilterERC721Model(_ERC721_FILTER_MODEL_).saveNFTPrice(nftContract, tokenIds[i]);
_mint(msg.sender, price);
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), "ZERO_ADDRESS");
require(tokenIds.length == amounts.length, "PARAMS_NOT_MATCH");
for(uint256 i = 0; i < tokenIds.length; i++) {
uint256 price = IFilterERC1155Model(_ERC1155_FILTER_MODEL_).saveNFTPrice(nftContract, tokenIds[i], amounts[i]);
_mint(msg.sender, price);
emit AddNftToken(nftContract, tokenIds[i], amounts[i]);
}
IERC1155(nftContract).safeBatchTransferFrom(msg.sender, address(this), tokenIds, amounts, "");
}
function doLotteryERC721() external {
uint256 lotteryPrice = IFilterERC721Model(_ERC721_FILTER_MODEL_).buyLotteryNFTPrice();
_burn(msg.sender, lotteryPrice);
(address nftContract, uint256 tokenId) = IFilterERC721Model(_ERC721_FILTER_MODEL_).lottery();
IERC721(nftContract).safeTransferFrom(address(this), msg.sender, tokenId);
emit RemoveNftToken(nftContract, tokenId, 1);
}
function doLotteryERC1155() external {
uint256 lotteryPrice = IFilterERC1155Model(_ERC1155_FILTER_MODEL_).buyLotteryNFTPrice();
_burn(msg.sender, lotteryPrice);
(address nftContract, uint256 tokenId) = IFilterERC1155Model(_ERC721_FILTER_MODEL_).lottery();
//TODO: amount
IERC1155(nftContract).safeTransferFrom(address(this), msg.sender, tokenId, 1, "");
emit RemoveNftToken(nftContract, tokenId, 1);
}
function buySpecERC721(address nftContract, uint256 tokenId) external {
uint256 price = IFilterERC721Model(_ERC721_FILTER_MODEL_).buySpecNFTPrice(nftContract, tokenId);
_burn(msg.sender, price);
IERC721(nftContract).safeTransferFrom(address(this), msg.sender, tokenId);
emit RemoveNftToken(nftContract, tokenId, 1);
}
function buySpecERC1155(address nftContract, uint256 tokenId, uint256 amount) external {
uint256 price = IFilterERC1155Model(_ERC1155_FILTER_MODEL_).buySpecNFTPrice(nftContract, tokenId, amount);
_burn(msg.sender, price);
IERC1155(nftContract).safeTransferFrom(address(this), msg.sender, tokenId, amount, "");
emit RemoveNftToken(nftContract, tokenId, amount);
}
function supportsInterface(bytes4 interfaceId) public override view returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId
|| interfaceId == type(IERC721Receiver).interfaceId;
}
// ============ Callback ============
function onERC721Received(
address,
address,
uint256 tokenId,
bytes calldata
) external override returns (bytes4) {
emit AddNftToken(msg.sender, tokenId, 1);
return IERC721Receiver.onERC721Received.selector;
}
function onERC1155Received(
address,
address,
uint256 id,
uint256 value,
bytes calldata
) external override returns (bytes4){
emit AddNftToken(msg.sender, id, value);
return IERC1155Receiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata
) external override returns (bytes4){
require(ids.length == values.length, "PARAMS_NOT_MATCH");
for(uint256 i = 0; i < ids.length; i++) {
emit AddNftToken(msg.sender, ids[i], values[i]);
}
return IERC1155Receiver.onERC1155BatchReceived.selector;
}
}

View File

@@ -0,0 +1,130 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {IFilterERC1155Model} from "../intf/IFilterERC1155Model.sol";
contract FilterERC1155Model is InitializableOwnable, IFilterERC1155Model {
using SafeMath for uint256;
//=================== Storage =====================
// nftCollection -> nftId -> price(frag)
mapping(address => mapping(uint256 => uint256)) public _PRICES_;
// nftCollection -> nftId -> amount
mapping(address => mapping(uint256 => uint256)) public _ERC1155_AMOUNT_;
// nftCollection -> nftId -> specPrice(frag)
mapping(address => mapping(uint256 => uint256)) public _SPEC_PRICES_;
uint256 public _SPEC_FACTOR_ = 200;
// nftColletcion -> nftIds
mapping(address => uint256[]) public _NFT_COLLECTION_IDS_;
address[] public _NFT_COLLECTIONS_;
uint256 public _LOTTERY_THRESHOLD_;
uint256 public _TOTAL_NFT_AMOUNT_;
uint256 public _CURRENT_NFT_AMOUNT_;
function init(
address owner
) external {
//TODO:
initOwner(owner);
}
//================== View ======================
function isFilterERC1155Pass(address nftCollectionAddress, uint256 nftId, uint256 amount) override external view returns (bool) {
if(_PRICES_[nftCollectionAddress][nftId] == 0)
return false;
else {
if(_ERC1155_AMOUNT_[nftCollectionAddress][nftId] >= amount)
return true;
else
return false;
}
}
//TODO: nftInCap
//TODO: nftOutCap
function saveNFTPrice(address nftCollectionAddress, uint256 nftId, uint256 amount) override external view returns(uint256) {
return _PRICES_[nftCollectionAddress][nftId].mul(amount);
}
function buySpecNFTPrice(address nftCollectionAddress, uint256 nftId, uint256 amount) override external view returns(uint256) {
require(_ERC1155_AMOUNT_[nftCollectionAddress][nftId] >= amount, "BUY_OVERFLOW");
return _SPEC_PRICES_[nftCollectionAddress][nftId].mul(amount);
}
//TODO: amount = 1
function buyLotteryNFTPrice() override external view returns(uint256) {
return _LOTTERY_THRESHOLD_;
}
function lottery() override external view returns(address nftCollection, uint256 nftId) {
//random
}
//================== Owner =====================
function setNFTFilter(
address[] memory nftCollections,
uint256[] memory nftIds,
uint256[] memory amounts,
uint256[] memory prices,
uint256[] memory specPrices
) external onlyOwner {
require(nftCollections.length == nftIds.length, "PARAMS_INVALID");
require(nftCollections.length == amounts.length, "PARAMS_INVALID");
require(nftCollections.length == prices.length, "PARAMS_INVALID");
require(nftCollections.length == specPrices.length, "PARAMS_INVALID");
for(uint256 i = 0; i < nftCollections.length; i++){
_PRICES_[nftCollections[i]][nftIds[i]] = prices[i];
_PRICES_[nftCollections[i]][nftIds[i]] = amounts[i];
if(specPrices[i] == 0){
_SPEC_PRICES_[nftCollections[i]][nftIds[i]] = prices[i].mul(_SPEC_FACTOR_).div(100);
}else {
_SPEC_PRICES_[nftCollections[i]][nftIds[i]] = specPrices[i];
}
if(_NFT_COLLECTION_IDS_[nftCollections[i]].length == 0) {
_NFT_COLLECTIONS_.push(nftCollections[i]);
_NFT_COLLECTION_IDS_[nftCollections[i]] = [nftIds[i]];
require(++_CURRENT_NFT_AMOUNT_ <= _TOTAL_NFT_AMOUNT_, "OVERFLOW_NFT_AMOUNT");
} else {
uint256 j = 0;
for(; j < _NFT_COLLECTION_IDS_[nftCollections[i]].length; i++) {
if(_NFT_COLLECTION_IDS_[nftCollections[i]][j] == nftIds[i]) {
break;
}
}
if(j == _NFT_COLLECTION_IDS_[nftCollections[i]].length) {
_NFT_COLLECTION_IDS_[nftCollections[i]].push(nftIds[i]);
require(++_CURRENT_NFT_AMOUNT_ <= _TOTAL_NFT_AMOUNT_, "OVERFLOW_NFT_AMOUNT");
}
}
}
}
function setLotteryThreshold(uint256 newLotteryThreshold) external onlyOwner {
_LOTTERY_THRESHOLD_ = newLotteryThreshold;
}
function setSpecFactor(uint256 newSpecFactor) external onlyOwner {
_SPEC_FACTOR_ = newSpecFactor;
}
}

View File

@@ -0,0 +1,129 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {IFilterERC721Model} from "../intf/IFilterERC721Model.sol";
contract FilterERC721Model is InitializableOwnable, IFilterERC721Model {
using SafeMath for uint256;
//=================== Storage ===================
// nftCollection -> nftId -> price(frag)
mapping(address => mapping(uint256 => uint256)) public _PRICES_;
// nftCollection -> nftId -> specPrice(frag)
mapping(address => mapping(uint256 => uint256)) public _SPEC_PRICES_;
uint256 public _SPEC_FACTOR_ = 200;
// nftColletcion -> nftIds
mapping(address => uint256[]) public _NFT_COLLECTION_IDS_;
address[] public _NFT_COLLECTIONS_;
uint256 public _LOTTERY_THRESHOLD_;
uint256 public _TOTAL_NFT_AMOUNT_;
uint256 public _CURRENT_NFT_AMOUNT_;
function init(
address owner
) external {
//TODO:
initOwner(owner);
}
//==================== View ==================
function isFilterERC721Pass(address nftCollectionAddress, uint256 nftId) override external view returns (bool) {
if(_PRICES_[nftCollectionAddress][nftId] == 0)
return false;
else
return true;
}
function saveNFTPrice(address nftCollectionAddress, uint256 nftId) override external view returns(uint256) {
return _PRICES_[nftCollectionAddress][nftId];
}
function buySpecNFTPrice(address nftCollectionAddress, uint256 nftId) override external view returns(uint256) {
return _SPEC_PRICES_[nftCollectionAddress][nftId];
}
function buyLotteryNFTPrice() override external view returns(uint256) {
return _LOTTERY_THRESHOLD_;
}
function lottery() override external view returns(address nftCollection, uint256 nftId) {
//random
}
//TODO: nftInCap
//TODO: nftOutCap
//============= Owner ===============
function setNFTFilter(
address[] memory nftCollections,
uint256[] memory nftIds,
uint256[] memory prices,
uint256[] memory specPrices
) external onlyOwner {
require(nftCollections.length == nftIds.length, "PARAMS_INVALID");
require(nftCollections.length == prices.length, "PARAMS_INVALID");
require(nftCollections.length == specPrices.length, "PARAMS_INVALID");
for(uint256 i = 0; i < nftCollections.length; i++){
_PRICES_[nftCollections[i]][nftIds[i]] = prices[i];
if(specPrices[i] == 0){
_SPEC_PRICES_[nftCollections[i]][nftIds[i]] = prices[i].mul(_SPEC_FACTOR_).div(100);
}else {
_SPEC_PRICES_[nftCollections[i]][nftIds[i]] = specPrices[i];
}
if(_NFT_COLLECTION_IDS_[nftCollections[i]].length == 0) {
_NFT_COLLECTIONS_.push(nftCollections[i]);
_NFT_COLLECTION_IDS_[nftCollections[i]] = [nftIds[i]];
require(++_CURRENT_NFT_AMOUNT_ <= _TOTAL_NFT_AMOUNT_, "OVERFLOW_NFT_AMOUNT");
} else {
uint256 j = 0;
for(; j < _NFT_COLLECTION_IDS_[nftCollections[i]].length; i++) {
if(_NFT_COLLECTION_IDS_[nftCollections[i]][j] == nftIds[i]) {
break;
}
}
if(j == _NFT_COLLECTION_IDS_[nftCollections[i]].length) {
_NFT_COLLECTION_IDS_[nftCollections[i]].push(nftIds[i]);
require(++_CURRENT_NFT_AMOUNT_ <= _TOTAL_NFT_AMOUNT_, "OVERFLOW_NFT_AMOUNT");
}
}
}
}
function setLotteryThreshold(uint256 newLotteryThreshold) external onlyOwner {
_LOTTERY_THRESHOLD_ = newLotteryThreshold;
}
function setSpecFactor(uint256 newSpecFactor) external onlyOwner {
_SPEC_FACTOR_ = newSpecFactor;
}
function setTotalNFTAmount(uint256 newTotalNFTAmount) external onlyOwner {
_TOTAL_NFT_AMOUNT_ = newTotalNFTAmount;
}
}

View File

@@ -0,0 +1,20 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
interface IFilterERC1155Model {
function isFilterERC1155Pass(address nftCollectionAddress, uint256 nftId, uint256 amount) external view returns (bool);
function saveNFTPrice(address nftCollectionAddress, uint256 nftId, uint256 amount) external view returns(uint256);
function buySpecNFTPrice(address nftCollectionAddress, uint256 nftId, uint256 amount) external view returns(uint256);
function buyLotteryNFTPrice() external view returns(uint256);
function lottery() external view returns(address nftCollection, uint256 nftId);
}

View File

@@ -0,0 +1,20 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
interface IFilterERC721Model {
function isFilterERC721Pass(address nftCollectionAddress, uint256 nftId) external view returns (bool);
function saveNFTPrice(address nftCollectionAddress, uint256 nftId) external view returns(uint256);
function buySpecNFTPrice(address nftCollectionAddress, uint256 nftId) external view returns(uint256);
function buyLotteryNFTPrice() external view returns(uint256);
function lottery() external view returns(address nftCollection, uint256 nftId);
}

View File

@@ -132,4 +132,16 @@ interface IDODOV2Proxy01 {
uint256 deadLine
) external payable returns (uint256 returnAmount);
// function mixSwap(
// address fromToken,
// address toToken,
// uint256 fromTokenAmount,
// uint256 minReturnAmount,
// address[] memory mixAdapters,
// address[] memory mixPairs,
// address[] memory assetTo,
// uint256 directions,
// bool isIncentive,
// uint256 deadLine
// ) external payable returns (uint256 returnAmount);
}

View File

@@ -0,0 +1,98 @@
/*
Copyright 2021 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
import {SafeMath} from "../../lib/SafeMath.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
contract InitializableInternalMintableERC20 is InitializableOwnable {
using SafeMath for uint256;
string public name;
uint8 public decimals;
string public symbol;
uint256 public totalSupply;
mapping(address => uint256) internal balances;
mapping(address => mapping(address => uint256)) internal allowed;
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
event Mint(address indexed user, uint256 value);
event Burn(address indexed user, uint256 value);
function init(
address _creator,
uint256 _initSupply,
string memory _name,
string memory _symbol,
uint8 _decimals
) public {
initOwner(_creator);
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _initSupply;
balances[_creator] = _initSupply;
emit Transfer(address(0), _creator, _initSupply);
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
require(to != address(0), "TO_ADDRESS_IS_EMPTY");
require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH");
balances[msg.sender] = balances[msg.sender].sub(amount);
balances[to] = balances[to].add(amount);
emit Transfer(msg.sender, to, amount);
return true;
}
function balanceOf(address owner) public view returns (uint256 balance) {
return balances[owner];
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
require(to != address(0), "TO_ADDRESS_IS_EMPTY");
require(amount <= balances[from], "BALANCE_NOT_ENOUGH");
require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH");
balances[from] = balances[from].sub(amount);
balances[to] = balances[to].add(amount);
allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);
emit Transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowed[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return allowed[owner][spender];
}
function _mint(address user, uint256 value) internal {
balances[user] = balances[user].add(value);
totalSupply = totalSupply.add(value);
emit Mint(user, value);
emit Transfer(address(0), user, value);
}
function _burn(address user, uint256 value) internal {
balances[user] = balances[user].sub(value);
totalSupply = totalSupply.sub(value);
emit Burn(user, value);
emit Transfer(user, address(0), value);
}
}