This commit is contained in:
owen05
2021-09-07 15:56:37 +08:00
parent 3ef45bc799
commit 6a659a4b82
4 changed files with 149 additions and 38 deletions

View File

@@ -18,36 +18,52 @@ contract FilterERC721Model is InitializableOwnable, IFilterERC721Model {
//=================== 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_;
uint256 public _TIMELOCK_DURATION_;
struct LockFilterInfo {
address[] nftCollections;
uint256[] nftIds;
uint256[] prices;
uint256[] specPrices;
uint256 releaseTime;
}
mapping(bytes32 => LockFilterInfo) public _TIME_LOCKS_;
uint256 public _PENDING_LOTTERY_THRESHOLD_;
uint256 public _PENDING_TOTAL_NFT_AMOUNT_;
uint256 public _PENDING_SPEC_FACTOR_;
uint256 public _GLOBAL_TIME_LOCK_;
function init(
address owner
address owner,
uint256 specFactor,
uint256 lotteryThreshold,
uint256 totalNftAmount,
uint256 timeLockDuration
) external {
//TODO:
initOwner(owner);
_SPEC_FACTOR_ = specFactor;
_LOTTERY_THRESHOLD_ = lotteryThreshold;
_TOTAL_NFT_AMOUNT_ = totalNftAmount;
_TIMELOCK_DURATION_ = timeLockDuration;
}
//==================== View ==================
function isFilterERC721Pass(address nftCollectionAddress, uint256 nftId) override external view returns (bool) {
if(_PRICES_[nftCollectionAddress][nftId] == 0)
return false;
else
return true;
return _isInclude(nftCollectionAddress, nftId);
}
function saveNFTPrice(address nftCollectionAddress, uint256 nftId) override external view returns(uint256) {
@@ -73,7 +89,8 @@ contract FilterERC721Model is InitializableOwnable, IFilterERC721Model {
//============= Owner ===============
function setNFTFilter(
function addNFTFilter(
address[] memory nftCollections,
uint256[] memory nftIds,
uint256[] memory prices,
@@ -84,6 +101,8 @@ contract FilterERC721Model is InitializableOwnable, IFilterERC721Model {
require(nftCollections.length == specPrices.length, "PARAMS_INVALID");
for(uint256 i = 0; i < nftCollections.length; i++){
if(_isInclude(nftCollections[i], nftIds[i])) continue;
_PRICES_[nftCollections[i]][nftIds[i]] = prices[i];
if(specPrices[i] == 0){
@@ -94,36 +113,130 @@ contract FilterERC721Model is InitializableOwnable, IFilterERC721Model {
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");
}
}
_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 scheduleUpdateNftFilter(
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");
uint256 releaseTime = block.timestamp.add(_TIMELOCK_DURATION_);
bytes32 id = keccak256(abi.encode(nftCollections, nftIds, prices, specPrices, releaseTime));
LockFilterInfo memory lockFilterInfo = LockFilterInfo({
nftCollections: nftCollections,
nftIds: nftIds,
prices: prices,
specPrices: specPrices,
releaseTime: releaseTime
});
require(_TIME_LOCKS_[id].releaseTime == 0, "ALREADY_ADDED");
for(uint256 i = 0; i< nftCollections.length; i++) {
require(_isInclude(nftCollections[i],nftIds[i]));
}
_TIME_LOCKS_[id] = lockFilterInfo;
}
function setSpecFactor(uint256 newSpecFactor) external onlyOwner {
_SPEC_FACTOR_ = newSpecFactor;
function executeUpdateNftFilter(
bytes32 id
) external onlyOwner {
LockFilterInfo memory lockFilterInfo = _TIME_LOCKS_[id];
uint256 releaseTime = lockFilterInfo.releaseTime;
require(releaseTime != 0 && releaseTime !=1 && block.timestamp > releaseTime, "TIMELOCKED");
address[] memory nftCollections = lockFilterInfo.nftCollections;
uint256[] memory nftIds = lockFilterInfo.nftIds;
uint256[] memory prices = lockFilterInfo.prices;
uint256[] memory specPrices = lockFilterInfo.specPrices;
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];
}
}
lockFilterInfo.releaseTime = 1;
_TIME_LOCKS_[id] = lockFilterInfo;
}
function setTotalNFTAmount(uint256 newTotalNFTAmount) external onlyOwner {
_TOTAL_NFT_AMOUNT_ = newTotalNFTAmount;
//TODO:价格修改为0是否是同样的效果
function scheduleRemoveNFTFilter(
address[] memory nftCollections,
uint256[] memory nftIds
) external onlyOwner {
require(nftCollections.length == nftIds.length, "PARAMS_INVALID");
}
function executeRemoveNFTFilter(
bytes32 id
) external onlyOwner {
}
function scheduleUpdateGlobalState(
uint256 newLotteryThreshold,
uint256 newSpecFactor,
uint256 newTotalNFTAmount
) external onlyOwner {
require(newTotalNFTAmount >= _CURRENT_NFT_AMOUNT_, "NFT_ALREADY_EXCEED");
require(newSpecFactor > 100, "SPEC_FACTOR_TOO_LOW");
_PENDING_LOTTERY_THRESHOLD_ = newLotteryThreshold;
_PENDING_TOTAL_NFT_AMOUNT_ = newSpecFactor;
_PENDING_SPEC_FACTOR_ = newTotalNFTAmount;
_GLOBAL_TIME_LOCK_ = block.timestamp.add(_TIMELOCK_DURATION_);
}
function executeUpdateGlobalState() external onlyOwner {
require(block.timestamp > _GLOBAL_TIME_LOCK_ && _GLOBAL_TIME_LOCK_ !=0, "TIMELOCKED");
require(_PENDING_TOTAL_NFT_AMOUNT_ >= _CURRENT_NFT_AMOUNT_, "NFT_ALREADY_EXCEED");
require(_PENDING_SPEC_FACTOR_ > 100, "SPEC_FACTOR_TOO_LOW");
_LOTTERY_THRESHOLD_ = _PENDING_LOTTERY_THRESHOLD_;
_SPEC_FACTOR_ = _PENDING_SPEC_FACTOR_;
_TOTAL_NFT_AMOUNT_ = _PENDING_TOTAL_NFT_AMOUNT_;
lockGlobalState();
}
function lockGlobalState() public onlyOwner {
_PENDING_LOTTERY_THRESHOLD_ = 0;
_PENDING_TOTAL_NFT_AMOUNT_ = 0;
_PENDING_SPEC_FACTOR_ = 0;
_GLOBAL_TIME_LOCK_ = 0;
}
//==================== internal ===================
function _isInclude(address nftCollection, uint256 nftId) internal view returns (bool) {
uint256[] memory ids = _NFT_COLLECTION_IDS_[nftCollection];
uint256 i = 0;
for(;i < ids.length; i++) {
if(nftId == i) break;
}
if(i == ids.length)
return false;
else
return true;
}
}

View File

@@ -8,9 +8,8 @@
pragma solidity 0.6.9;
import {SafeMath} from "../../lib/SafeMath.sol";
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
contract InitializableInternalMintableERC20 is InitializableOwnable {
contract InitializableInternalMintableERC20 {
using SafeMath for uint256;
string public name;
@@ -33,7 +32,6 @@ contract InitializableInternalMintableERC20 is InitializableOwnable {
string memory _symbol,
uint8 _decimals
) public {
initOwner(_creator);
name = _name;
symbol = _symbol;
decimals = _decimals;