Skip to content

Instantly share code, notes, and snippets.

@yann300
Last active March 1, 2022 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yann300/12d92796916c05712061cbe21717ccfa to your computer and use it in GitHub Desktop.
Save yann300/12d92796916c05712061cbe21717ccfa to your computer and use it in GitHub Desktop.
'{{\r\n "language": "Solidity",\r\n "sources": {\r\n "/contracts/BlindBox.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n// import \\"./GenerativeBB.sol\\";\\nimport \\"./NonGenerativeBB.sol\\";\\n\\ncontract BlindBox is NonGenerativeBB {\\n using Counters for Counters.Counter;\\n using SafeMath for uint256;\\n constructor() payable {\\n\\n }\\n\\n /** \\n @dev this function is to buy box of any type.\\n @param seriesId id of the series of whom box to bought.\\n @param isGenerative flag to show either blindbox to be bought is of Generative blindbox type or Non-Generative\\n \\n */\\n function buyBox(uint256 seriesId, bool isGenerative, uint256 currencyType, address collection, string memory ownerId, bytes32 user) public {\\n if(isGenerative){\\n // buyGenerativeBox(seriesId, currencyType);\\n } else {\\n buyNonGenBox(seriesId, currencyType, collection, ownerId, user);\\n }\\n }\\n function buyBoxPayable(uint256 seriesId, bool isGenerative, address collection, bytes32 user) payable public {\\n if(isGenerative){\\n // buyGenBoxPayable(seriesId);\\n } else {\\n buyNonGenBoxPayable(seriesId, collection, user);\\n }\\n }\\n\\n fallback() payable external {}\\n receive() payable external {}\\n}"\r\n },\r\n "/contracts/VRF/IRand.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n\\ninterface IRand {\\n function getRandomNumber() external returns (bytes32 requestId);\\n function getRandomVal() external view returns (uint256); \\n\\n}"\r\n },\r\n "/contracts/Utils.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\"./Proxy/BlindboxStorage.sol\\";\\nimport \'@openzeppelin/contracts/access/Ownable.sol\';\\nimport \'@openzeppelin/contracts/utils/math/SafeMath.sol\';\\n\\n\\ncontract Utils is Ownable, BlindboxStorage{\\n using Counters for Counters.Counter;\\n using SafeMath for uint256;\\n \\n function updateDexAddress(address _add) onlyOwner public {\\n dex = IDEX(_add);\\n }\\n function calculatePrice(uint256 _price, uint256 base, uint256 currencyType) public view returns(uint256 price) {\\n price = _price;\\n (uint112 _reserve0, uint112 _reserve1,) =LPMATIC.getReserves();\\n if(currencyType == 0 && base == 1){\\n price = SafeMath.div(SafeMath.mul(price,SafeMath.mul(_reserve1,1000000000000)),_reserve0);\\n } else if(currencyType == 1 && base == 0){\\n price = SafeMath.div(SafeMath.mul(price,_reserve0),SafeMath.mul(_reserve1,1000000000000));\\n }\\n \\n }\\n \\n}"\r\n },\r\n "/contracts/Proxy/BlindboxStorage.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n\\nimport \'@openzeppelin/contracts/utils/Counters.sol\';\\nimport \'@openzeppelin/contracts/utils/math/SafeMath.sol\';\\nimport \'../IERC20.sol\';\\nimport \'../VRF/IRand.sol\';\\nimport \'../INFT.sol\';\\nimport \'../IDEX.sol\';\\nimport \\"../LPInterface.sol\\";\\n\\n///////////////////////////////////////////////////////////////////////////////////////////////////\\n/**\\n * @title DexStorage\\n * @dev Defining dex storage for the proxy contract.\\n */\\n///////////////////////////////////////////////////////////////////////////////////////////////////\\n\\ncontract BlindboxStorage {\\n using Counters for Counters.Counter;\\n using SafeMath for uint256;\\n\\n address a;\\n address b;\\n address c;\\n\\n IRand vrf;\\n IERC20 ALIA;\\n IERC20 ETH;\\n IERC20 USD;\\n IERC20 MATIC;\\n INFT nft;\\n IDEX dex;\\n address platform;\\n IERC20 internal token;\\n \\n Counters.Counter internal _boxId;\\n\\n Counters.Counter public generativeSeriesId;\\n\\n struct Attribute {\\n string name;\\n string uri;\\n uint256 rarity;\\n }\\n\\n struct GenerativeBox {\\n string name;\\n string boxURI;\\n uint256 series; // to track start end Time\\n uint256 countNFTs;\\n // uint256[] attributes;\\n // uint256 attributesRarity;\\n bool isOpened;\\n }\\n\\n struct GenSeries {\\n string name;\\n string seriesURI;\\n string boxName;\\n string boxURI;\\n uint256 startTime;\\n uint256 endTime;\\n uint256 maxBoxes;\\n uint256 perBoxNftMint;\\n uint256 price; // in ALIA\\n Counters.Counter boxId; // to track series\'s boxId (upto minted so far)\\n Counters.Counter attrType; // attribute Type IDs\\n Counters.Counter attrId; // attribute\'s ID\\n // attributeType => attributeId => Attribute\\n mapping ( uint256 => mapping( uint256 => Attribute)) attributes;\\n // attributes combination hash => flag\\n mapping ( bytes32 => bool) blackList;\\n }\\n\\n struct NFT {\\n // attrType => attrId\\n mapping (uint256 => uint256) attribute;\\n }\\n\\n // seriesId => Series\\n mapping ( uint256 => GenSeries) public genSeries;\\n mapping ( uint256 => uint256) public genseriesRoyalty;\\n mapping ( uint256 => uint256[]) _allowedCurrenciesGen;\\n mapping ( uint256 => address) public bankAddressGen;\\n mapping ( uint256 => uint256) public baseCurrencyGen;\\n mapping (uint256=>string) public genCollection;\\n // boxId => attributeType => attributeId => Attribute\\n // mapping( uint256 => mapping ( uint256 => mapping( uint256 => Attribute))) public attributes;\\n // boxId => Box\\n mapping ( uint256 => GenerativeBox) public boxesGen;\\n // attributes combination => flag\\n // mapping ( bytes => bool) public blackList;\\n // boxId => boxOpener => array of combinations to be minted\\n // mapping ( uint256 => mapping ( address => bytes[] )) public nftToMint;\\n // boxId => owner\\n mapping ( uint256 => address ) public genBoxOwner;\\n // boxId => NFT index => attrType => attribute\\n mapping (uint256 => mapping( uint256 => mapping (uint256 => uint256))) public nftsToMint;\\n \\n\\n Counters.Counter public nonGenerativeSeriesId;\\n // mapping(address => Counters.Counter) public nonGenerativeSeriesIdByAddress;\\n struct URI {\\n string name;\\n string uri;\\n uint256 rarity;\\n uint256 copies;\\n }\\n\\n struct NonGenerativeBox {\\n string name;\\n string boxURI;\\n uint256 series; // to track start end Time\\n uint256 countNFTs;\\n // uint256[] attributes;\\n // uint256 attributesRarity;\\n bool isOpened;\\n }\\n\\n struct NonGenSeries {\\n string collection;\\n string name;\\n string seriesURI;\\n string boxName;\\n string boxURI;\\n uint256 startTime;\\n uint256 endTime;\\n uint256 maxBoxes;\\n uint256 perBoxNftMint;\\n uint256 price; \\n Counters.Counter boxId; // to track series\'s boxId (upto minted so far)\\n Counters.Counter attrId; \\n // uriId => URI \\n mapping ( uint256 => URI) uris;\\n }\\n\\n struct IDs {\\n Counters.Counter attrType;\\n Counters.Counter attrId;\\n }\\n\\n struct CopiesData{\\n \\n uint256 total;\\n mapping(uint256 => uint256) nftCopies;\\n }\\n mapping (uint256 => CopiesData) public _CopiesData;\\n \\n // seriesId => NonGenSeries\\n mapping ( uint256 => NonGenSeries) public nonGenSeries;\\n\\n mapping ( uint256 => uint256[]) _allowedCurrencies;\\n mapping ( uint256 => address) public bankAddress;\\n mapping ( uint256 => uint256) public nonGenseriesRoyalty;\\n mapping ( uint256 => uint256) public baseCurrency;\\n // boxId => IDs\\n // mapping (uint256 => IDs) boxIds;\\n // boxId => attributeType => attributeId => Attribute\\n // mapping( uint256 => mapping ( uint256 => mapping( uint256 => Attribute))) public attributes;\\n // boxId => Box\\n mapping ( uint256 => NonGenerativeBox) public boxesNonGen;\\n // attributes combination => flag\\n // mapping ( bytes => bool) public blackList;\\n // boxId => boxOpener => array of combinations to be minted\\n // mapping ( uint256 => mapping ( address => bytes[] )) public nftToMint;\\n // boxId => owner\\n mapping ( uint256 => address ) public nonGenBoxOwner;\\n // boxId => NFT index => attrType => attribute\\n // mapping (uint256 => mapping( uint256 => mapping (uint256 => uint256))) public nfts;\\n mapping(string => mapping(bool => uint256[])) seriesIdsByCollection;\\n uint256 deployTime;\\n LPInterface LPAlia;\\n LPInterface LPWETH;\\n LPInterface LPMATIC;\\n mapping(bytes32 => mapping(uint256 => bool)) _whitelisted;\\n mapping(uint256 => bool) _isWhiteListed;\\n mapping(address => mapping (uint256=>uint256)) _boxesCrytpoUser;\\n mapping( string => mapping (uint256=>uint256)) _boxesNoncryptoUser;\\n mapping (uint256 => uint256) _perBoxUserLimit;\\n mapping (uint256 => bool) _isCryptoAllowed;\\n mapping (uint256 => uint256) _registrationFee;\\n}"\r\n },\r\n "/contracts/NonGenerativeBB.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \'./GenerativeBB.sol\';\\n\\ncontract NonGenerativeBB is GenerativeBB {\\n using Counters for Counters.Counter;\\n using SafeMath for uint256;\\n \\n /** \\n @dev utility function to mint NonGenerative BlindBox\\n @param seriesId - id of NonGenerative Series whose box to be opened\\n @notice given series should not be ended or its max boxes already minted.\\n */\\n function mintNonGenBox(uint256 seriesId) private {\\n require(nonGenSeries[seriesId].startTime <= block.timestamp, \\"series not started\\");\\n require(nonGenSeries[seriesId].endTime >= block.timestamp, \\"series ended\\");\\n require(nonGenSeries[seriesId].maxBoxes > nonGenSeries[seriesId].boxId.current(),\\"max boxes minted of this series\\");\\n nonGenSeries[seriesId].boxId.increment(); // incrementing boxCount minted\\n _boxId.increment(); // incrementing to get boxId\\n\\n boxesNonGen[_boxId.current()].name = nonGenSeries[seriesId].boxName;\\n boxesNonGen[_boxId.current()].boxURI = nonGenSeries[seriesId].boxURI;\\n boxesNonGen[_boxId.current()].series = seriesId;\\n boxesNonGen[_boxId.current()].countNFTs = nonGenSeries[seriesId].perBoxNftMint;\\n \\n // uint256[] attributes; // attributes setting in another mapping per boxId. note: series should\'ve all attributes [Done]\\n // uint256 attributesRarity; // rarity should be 100, how to ensure ? \\n //from available attrubets fill them in 100 index of array as per their rarity. divide all available rarites into 100\\n emit BoxMintNonGen(_boxId.current(), seriesId);\\n\\n }\\n modifier validateCurrencyType(uint256 seriesId, uint256 currencyType, bool isPayable) {\\n bool isValid = false;\\n uint256[] storage allowedCurrencies = _allowedCurrencies[seriesId];\\n for (uint256 index = 0; index < allowedCurrencies.length; index++) {\\n if(allowedCurrencies[index] == currencyType){\\n isValid = true;\\n }\\n }\\n require(isValid, \\"123\\");\\n require((isPayable && currencyType == 1) || currencyType < 1, \\"126\\");\\n _;\\n }\\n \\n/** \\n @dev function to buy NonGenerative BlindBox\\n @param seriesId - id of NonGenerative Series whose box to be bought\\n @notice given series should not be ended or its max boxes already minted.\\n */\\n function buyNonGenBox(uint256 seriesId, uint256 currencyType, address collection, string memory ownerId, bytes32 user) validateCurrencyType(seriesId,currencyType, false) internal {\\n require(!_isWhiteListed[seriesId] || _whitelisted[user][seriesId], \\"not authorize\\");\\n require(abi.encodePacked(nonGenSeries[seriesId].name).length > 0,\\"Series doesn\'t exist\\"); \\n require(nonGenSeries[seriesId].maxBoxes > nonGenSeries[seriesId].boxId.current(),\\"boxes sold out\\");\\n mintNonGenBox(seriesId);\\n token = USD;\\n \\n uint256 price = calculatePrice(nonGenSeries[seriesId].price , baseCurrency[seriesId], currencyType);\\n // if(currencyType == 0){\\n price = price / 1000000000000;\\n // }\\n // escrow alia\\n token.transferFrom(msg.sender, bankAddress[seriesId], price);\\n // transfer box to buyer\\n nonGenBoxOwner[_boxId.current()] = msg.sender;\\n emitBuyBoxNonGen(seriesId, currencyType, price, collection, ownerId);\\n \\n }\\n\\n \\n function getUserBoxCount(uint256 seriesId, address _add, string memory ownerId) public view returns(uint256) {\\n return _boxesCrytpoUser[_add][seriesId];\\n }\\n function buyNonGenBoxPayable(uint256 seriesId, address collection, bytes32 user)validateCurrencyType(seriesId,1, true) internal {\\n require(!_isWhiteListed[seriesId] || _whitelisted[user][seriesId], \\"not authorize\\");\\n require(abi.encodePacked(nonGenSeries[seriesId].name).length > 0,\\"Series doesn\'t exist\\"); \\n require(nonGenSeries[seriesId].maxBoxes > nonGenSeries[seriesId].boxId.current(),\\"boxes sold out\\");\\n uint256 before_bal = MATIC.balanceOf(address(this));\\n MATIC.deposit{value : msg.value}();\\n uint256 after_bal = MATIC.balanceOf(address(this));\\n uint256 depositAmount = after_bal - before_bal;\\n uint256 price = calculatePrice(nonGenSeries[seriesId].price , baseCurrency[seriesId], 1);\\n require(price <= depositAmount, \\"NFT 108\\");\\n chainTransfer(bankAddress[seriesId], 1000, price);\\n if(depositAmount - price > 0) chainTransfer(msg.sender, 1000, (depositAmount - price));\\n mintNonGenBox(seriesId);\\n // transfer box to buyer\\n nonGenBoxOwner[_boxId.current()] = msg.sender;\\n emitBuyBoxNonGen(seriesId, 1, price, collection, \\"\\");\\n }\\n function emitBuyBoxNonGen(uint256 seriesId, uint256 currencyType, uint256 price, address collection, string memory ownerId) private{\\n require(_boxesCrytpoUser[msg.sender][seriesId] < _perBoxUserLimit[seriesId], \\"Limit reach\\" );\\n \\n _openNonGenBoxOffchain(_boxId.current(), collection);\\n _boxesCrytpoUser[msg.sender][seriesId]++;\\n _boxesNoncryptoUser[ownerId][seriesId]++;\\n\\n emit BuyBoxNonGen(_boxId.current(), seriesId, nonGenSeries[seriesId].price, currencyType, nonGenSeries[seriesId].collection, msg.sender, baseCurrency[seriesId], price);\\n }\\n// function chainTransfer(address _address, uint256 percentage, uint256 price) private {\\n// address payable newAddress = payable(_address);\\n// uint256 initialBalance;\\n// uint256 newBalance;\\n// initialBalance = address(this).balance;\\n// MATIC.withdraw(SafeMath.div(SafeMath.mul(price,percentage), 1000));\\n// newBalance = address(this).balance.sub(initialBalance);\\n// // newAddress.transfer(newBalance);\\n// (bool success, ) = newAddress.call{value: newBalance}(\\"\\");\\n// require(success, \\"Failed to send Ether\\");\\n// }\\n/** \\n @dev function to open NonGenerative BlindBox\\n @param boxId - id of blind box to be opened\\n @notice given box should not be already opened.\\n */\\n function openNonGenBox(uint256 boxId, address collection) public {\\n require(nonGenBoxOwner[boxId] == msg.sender, \\"Box not owned\\");\\n require(!boxesNonGen[boxId].isOpened, \\"Box already opened\\");\\n // _openNonGenBox(boxId);\\n _openNonGenBoxOffchain(boxId, collection);\\n\\n emit BoxOpenedNonGen(boxId);\\n }\\n function _openNonGenBoxOffchain(uint256 boxId, address collection) private {\\n uint256 sId = boxesGen[boxId].series;\\n // uint256 rand = getRand();\\n uint256 from;\\n uint256 to;\\n (from, to) =dex.mintBlindbox(collection, msg.sender, boxesNonGen[boxId].countNFTs, bankAddress[sId], nonGenseriesRoyalty[sId], sId); // this function should be implemented in DEX contract to return (uint256, uint256) tokenIds, for reference look into Collection.sol mint func. (can be found at Collection/Collection.sol of same repo)\\n boxesNonGen[boxId].isOpened = true;\\n emit NonGenNFTsMinted(sId, boxId, from, to, 0, boxesNonGen[boxId].countNFTs);\\n }\\n\\n function getNumberOfBoxes(uint256 seriesId) public view returns(uint256){\\n return nonGenSeries[seriesId].boxId.current();\\n }\\n function updateBoxPriceNonGen(uint256 seriesId, uint256 price, uint256 _baseCurrency, uint256[] memory allowedCurrecny) onlyOwner public {\\n baseCurrency[seriesId] = _baseCurrency;\\n _allowedCurrencies[seriesId] = allowedCurrecny;\\n nonGenSeries[seriesId].price = price;\\n }\\n\\n function updateBoxTimeNonGen(uint256 seriesId, uint256 endTime) onlyOwner public {\\n nonGenSeries[seriesId].endTime = endTime;\\n }\\n \\n // events\\n event BoxMintNonGen(uint256 boxId, uint256 seriesId);\\n // event AttributesAdded(uint256 indexed boxId, uint256 indexed attrType, uint256 fromm, uint256 to);\\n event BuyBoxNonGen(uint256 boxId, uint256 seriesId, uint256 orignalPrice, uint256 currencyType, string collection, address from,uint256 baseCurrency, uint256 calculated);\\n event BoxOpenedNonGen(uint256 indexed boxId);\\n // event BlackList(uint256 indexed seriesId, bytes32 indexed combHash, bool flag);\\n event NonGenNFTsMinted(uint256 seriesId, uint256 indexed boxId, uint256 from, uint256 to, uint256 rand, uint256 countNFTs);\\n \\n\\n}"\r\n },\r\n "/contracts/LPInterface.sol": {\r\n "content": "pragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\n */\\ninterface LPInterface {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\\n\\n \\n}"\r\n },\r\n "/contracts/INFT.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n\\ninterface INFT {\\n function mintWithTokenURI(address to, string calldata tokenURI) external returns (uint256);\\n function transferFrom(address owner, address to, uint256 tokenId) external;\\n function mint(address to_, uint256 countNFTs_) external returns (uint256, uint256);\\n}"\r\n },\r\n "/contracts/IERC20.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller\'s account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller\'s tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender\'s allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller\'s\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n function withdraw(uint) external;\\n function deposit() payable external;\\n}\\n"\r\n },\r\n "/contracts/IDEX.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n\\ninterface IDEX {\\n function calculatePrice(uint256 _price, uint256 base, uint256 currencyType, uint256 tokenId, address seller, address nft_a) external view returns(uint256);\\n function mintWithCollection(address collection, address to, string memory tokesnURI, uint256 royalty ) external returns(uint256);\\n function createCollection(string calldata name_, string calldata symbol_) external;\\n function transferCollectionOwnership(address collection, address newOwner) external;\\n function mintNFT(uint256 count) external returns(uint256,uint256);\\n function mintBlindbox(address collection, address to, uint256 quantity, address from, uint256 royalty, uint256 seriesId) external returns(uint256 fromIndex,uint256 toIndex);\\n}"\r\n },\r\n "/contracts/GenerativeBB.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \'./Utils.sol\';\\n/**\\n@title GenerativeBB \\n- this contract of blindbox\'s type Generative. which deals with all the operations of Generative blinboxes & series\\n */\\ncontract GenerativeBB is Utils {\\n \\n using Counters for Counters.Counter;\\n using SafeMath for uint256;\\n constructor() {\\n\\n }\\n\\n/** \\n @dev function to start new Generative Series\\n @param name - name of the series\\n @param seriesURI - series metadata tracking URI\\n @param boxName - name of the boxes to be created in this series\\n @param boxURI - blindbox\'s URI tracking its metadata\\n @param startTime - start time of the series, (from whom its boxes will be available to get bought)\\n @param endTime - end time of the series, (after whom its boxes will not be available to get bought)\\n\\n */ \\n function generativeSeries(string memory bCollection, string memory name, string memory seriesURI, string memory boxName, string memory boxURI, uint256 startTime, uint256 endTime, uint256 royalty) onlyOwner internal {\\n require(startTime < endTime, \\"invalid series endTime\\");\\n seriesIdsByCollection[bCollection][true].push(generativeSeriesId.current());\\n genCollection[generativeSeriesId.current()] = bCollection;\\n genSeries[generativeSeriesId.current()].name = name;\\n genSeries[generativeSeriesId.current()].seriesURI = seriesURI;\\n genSeries[generativeSeriesId.current()].boxName = boxName;\\n genSeries[generativeSeriesId.current()].boxURI = boxURI;\\n genSeries[generativeSeriesId.current()].startTime = startTime;\\n genSeries[generativeSeriesId.current()].endTime = endTime;\\n\\n emit NewGenSeries( generativeSeriesId.current(), name, startTime, endTime);\\n }\\n function setExtraParamsGen(uint256 _baseCurrency, uint256[] memory allowedCurrecny, address _bankAddress, uint256 boxPrice, uint256 maxBoxes, uint256 perBoxNftMint) internal {\\n baseCurrencyGen[generativeSeriesId.current()] = _baseCurrency;\\n _allowedCurrenciesGen[generativeSeriesId.current()] = allowedCurrecny;\\n bankAddressGen[generativeSeriesId.current()] = _bankAddress;\\n genSeries[generativeSeriesId.current()].price = boxPrice;\\n genSeries[generativeSeriesId.current()].maxBoxes = maxBoxes;\\n genSeries[generativeSeriesId.current()].perBoxNftMint = perBoxNftMint;\\n }\\n /** \\n @dev utility function to mint Generative BlindBox\\n @param seriesId - id of Generative Series whose box to be opened\\n @notice given series should not be ended or its max boxes already minted.\\n */\\n function mintGenBox(uint256 seriesId) private {\\n require(genSeries[seriesId].endTime >= block.timestamp, \\"series ended\\");\\n require(genSeries[seriesId].maxBoxes > genSeries[seriesId].boxId.current(),\\"max boxes minted of this series\\");\\n genSeries[seriesId].boxId.increment(); // incrementing boxCount minted\\n _boxId.increment(); // incrementing to get boxId\\n\\n boxesGen[_boxId.current()].name = genSeries[seriesId].boxName;\\n boxesGen[_boxId.current()].boxURI = genSeries[seriesId].boxURI;\\n boxesGen[_boxId.current()].series = seriesId;\\n boxesGen[_boxId.current()].countNFTs = genSeries[seriesId].perBoxNftMint;\\n \\n // uint256[] attributes; // attributes setting in another mapping per boxId. note: series should\'ve all attributes [Done]\\n // uint256 attributesRarity; // rarity should be 100, how to ensure ? \\n //from available attrubets fill them in 100 index of array as per their rarity. divide all available rarites into 100\\n emit BoxMintGen(_boxId.current(), seriesId);\\n\\n }\\n modifier validateCurrencyTypeGen(uint256 seriesId, uint256 currencyType, bool isPayable) {\\n bool isValid = false;\\n uint256[] storage allowedCurrencies = _allowedCurrenciesGen[seriesId];\\n for (uint256 index = 0; index < allowedCurrencies.length; index++) {\\n if(allowedCurrencies[index] == currencyType){\\n isValid = true;\\n }\\n }\\n require(isValid, \\"123\\");\\n require((isPayable && currencyType == 1) || currencyType < 1, \\"126\\");\\n _;\\n }\\n/** \\n @dev function to buy Generative BlindBox\\n @param seriesId - id of Generative Series whose box to be bought\\n @notice given series should not be ended or its max boxes already minted.\\n */\\n function buyGenerativeBox(uint256 seriesId, uint256 currencyType) validateCurrencyTypeGen(seriesId, currencyType, false) internal {\\n require(abi.encode(genSeries[seriesId].name).length > 0,\\"Series doesn\'t exist\\"); \\n require(genSeries[seriesId].maxBoxes > genSeries[seriesId].boxId.current(),\\"boxes sold out\\");\\n mintGenBox(seriesId);\\n token = USD; // skipping this for testing purposes\\n \\n uint256 price = dex.calculatePrice(genSeries[seriesId].price , baseCurrencyGen[seriesId], currencyType, 0, address(this), address(this));\\n // if(currencyType == 0){\\n price = price / 1000000000000;\\n // }\\n // escrow alia\\n token.transferFrom(msg.sender, bankAddressGen[seriesId], price);\\n genBoxOwner[_boxId.current()] = msg.sender;\\n\\n emit BuyBoxGen(_boxId.current(), seriesId);\\n }\\n function buyGenBoxPayable(uint256 seriesId) validateCurrencyTypeGen(seriesId,1, true) internal {\\n require(abi.encode(genSeries[seriesId].name).length > 0,\\"Series doesn\'t exist\\"); \\n require(genSeries[seriesId].maxBoxes > genSeries[seriesId].boxId.current(),\\"boxes sold out\\");\\n uint256 before_bal = MATIC.balanceOf(address(this));\\n MATIC.deposit{value : msg.value}();\\n uint256 after_bal = MATIC.balanceOf(address(this));\\n uint256 depositAmount = after_bal - before_bal;\\n uint256 price = dex.calculatePrice(genSeries[seriesId].price , baseCurrencyGen[seriesId], 1, 0, address(this), address(this));\\n require(price <= depositAmount, \\"NFT 108\\");\\n chainTransfer(bankAddressGen[seriesId], 1000, price);\\n if(depositAmount - price > 0) chainTransfer(msg.sender, 1000, (depositAmount - price));\\n mintGenBox(seriesId);\\n // transfer box to buyer\\n genBoxOwner[_boxId.current()] = msg.sender;\\n\\n emit BuyBoxGen(_boxId.current(), seriesId);\\n }\\n function chainTransfer(address _address, uint256 percentage, uint256 price) internal {\\n address payable newAddress = payable(_address);\\n uint256 initialBalance;\\n uint256 newBalance;\\n initialBalance = address(this).balance;\\n MATIC.withdraw(SafeMath.div(SafeMath.mul(price,percentage), 1000));\\n newBalance = address(this).balance.sub(initialBalance);\\n // newAddress.transfer(newBalance);\\n (bool success, ) = newAddress.call{value: newBalance}(\\"\\");\\n require(success, \\"Failed to send Ether\\");\\n }\\n/** \\n @dev function to open Generative BlindBox\\n @param boxId - id of blind box to be opened\\n @notice given box should not be already opened.\\n */\\n function openGenBox(uint256 boxId) internal {\\n require(genBoxOwner[boxId] == msg.sender, \\"Box not owned\\");\\n require(!boxesGen[boxId].isOpened, \\"Box already opened\\");\\n // _openGenBox(boxId);\\n _openGenBoxOffchain(boxId);\\n\\n emit BoxOpenedGen(boxId);\\n\\n }\\n function _openGenBoxOffchain(uint256 boxId) private {\\n // uint256 sId = boxesGen[boxId].series;\\n uint256 from;\\n uint256 to;\\n (from, to) =dex.mintNFT(boxesGen[boxId].countNFTs); // this function should be implemented in DEX contract to return (uint256, uint256) tokenIds, for reference look into Collection.sol mint func. (can be found at Collection/Collection.sol of same repo)\\n boxesGen[boxId].isOpened = true;\\n emit GenNFTsMinted( boxesGen[boxId].series, boxId, from, to, 0, boxesGen[boxId].countNFTs);\\n }\\n\\n \\n // events\\n event NewGenSeries(uint256 indexed seriesId, string name, uint256 startTime, uint256 endTime);\\n event BoxMintGen(uint256 boxId, uint256 seriesId);\\n event AttributesAdded(uint256 indexed seriesId, uint256 indexed attrType, uint256 from, uint256 to);\\n event BuyBoxGen(uint256 boxId, uint256 seriesId);\\n event BoxOpenedGen(uint256 indexed boxId);\\n event BlackList(uint256 indexed seriesId, bytes32 indexed combHash, bool flag);\\n event NFTsMinted(uint256 indexed boxId, address owner, uint256 countNFTs);\\n event GenNFTsMinted(uint256 seriesId, uint256 indexed boxId, uint256 from, uint256 to, uint256 rand, uint256 countNFTs);\\n \\n\\n}"\r\n },\r\n "@openzeppelin/contracts/utils/math/SafeMath.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n// CAUTION\\n// This version of SafeMath should only be used with Solidity 0.8 or later,\\n// because it relies on the compiler\'s built in overflow checks.\\n\\n/**\\n * @dev Wrappers over Solidity\'s arithmetic operations.\\n *\\n * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler\\n * now has built in overflow checking.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring \'a\' not being zero, but the\\n // benefit is lost if \'b\' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity\'s `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity\'s `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity\'s `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity\'s `/` operator.\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity\'s `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity\'s `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity\'s `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity\'s `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n }\\n}\\n"\r\n },\r\n "@openzeppelin/contracts/utils/Counters.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library\'s function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\"Counter: decrement overflow\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n"\r\n },\r\n "@openzeppelin/contracts/utils/Context.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n"\r\n },\r\n "@openzeppelin/contracts/access/Ownable.sol": {\r\n "content": "// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\"../utils/Context.sol\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\"Ownable: caller is not the owner\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\"Ownable: new owner is the zero address\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n"\r\n }\r\n },\r\n "settings": {\r\n "remappings": [],\r\n "optimizer": {\r\n "enabled": true,\r\n "runs": 200\r\n },\r\n "evmVersion": "istanbul",\r\n "libraries": {},\r\n "outputSelection": {\r\n "*": {\r\n "*": [\r\n "evm.bytecode",\r\n "evm.deployedBytecode",\r\n "devdoc",\r\n "userdoc",\r\n "metadata",\r\n "abi"\r\n ]\r\n }\r\n }\r\n }\r\n}}'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment