├── wallet ├── __init__.py ├── migrations │ ├── __init__.py │ ├── 0002_auto_20210221_0856.py │ └── 0001_initial.py ├── tests.py ├── admin.py ├── apps.py ├── urls.py ├── models.py └── views.py ├── tutorial ├── __init__.py ├── asgi.py ├── wsgi.py ├── views.py ├── urls.py ├── utils.py └── settings.py ├── db.sqlite3 ├── content ├── demo1.mp4 ├── demo2.mp4 └── demo3.mp4 ├── static ├── images │ ├── nft.png │ ├── main_icon.png │ └── icon_upload.png ├── fonts │ ├── iconfont.eot │ ├── iconfont.ttf │ ├── iconfont.woff │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── css │ ├── shuvo.css │ ├── owl.carousel.min.css │ ├── isotop.css │ ├── responsive.css.map │ ├── style.css │ └── magnific-popup.css └── js │ ├── jquery.appear.min.js │ ├── main.js │ ├── wow.min.js │ └── centerprime.js ├── contract ├── netflix-libs │ ├── utils │ │ ├── UQ112x112.sol │ │ ├── Strings.sol │ │ └── Address.sol │ ├── token │ │ ├── erc1155 │ │ │ ├── IERC1155MetadataURI.sol │ │ │ ├── IERC1155Receiver.sol │ │ │ └── IERC1155.sol │ │ ├── erc721 │ │ │ ├── IERC721Metadata.sol │ │ │ ├── IERC721Receiver.sol │ │ │ └── IERC721.sol │ │ ├── erc165 │ │ │ ├── IERC165.sol │ │ │ └── ERC165.sol │ │ ├── erc20 │ │ │ └── IERC20.sol │ │ └── bep20 │ │ │ ├── IBEP20.sol │ │ │ ├── SafeBEP20.sol │ │ │ └── BEP20.sol │ ├── gsn │ │ └── Context.sol │ ├── access │ │ └── Ownable.sol │ └── math │ │ └── SafeMath.sol ├── pool │ ├── interfaces │ │ ├── INetflixSwapFactory.sol │ │ ├── INetflixSwapBEP721.sol │ │ ├── INetflixSwapBEP20.sol │ │ └── INetflixSwapPair.sol │ ├── NetflixSwapFactory.sol │ ├── NetflixSwapBEP20.sol │ ├── ContentLiquiditySalesPool.sol │ ├── NetflixSwapBEP721.sol │ └── NetflixSwapPair.sol ├── Netflix_NFT.sol ├── SellerNFTToken_BEP20.sol ├── SellerNFTToken_ERC20.sol ├── SellerNFTToken_ERC721.sol └── farm │ └── NetflixNFTFarm.sol ├── manage.py ├── requirements.txt ├── README.md └── templates ├── detail.html └── index.html /wallet/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutorial/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wallet/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/db.sqlite3 -------------------------------------------------------------------------------- /wallet/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /content/demo1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/content/demo1.mp4 -------------------------------------------------------------------------------- /content/demo2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/content/demo2.mp4 -------------------------------------------------------------------------------- /content/demo3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/content/demo3.mp4 -------------------------------------------------------------------------------- /wallet/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /static/images/nft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/images/nft.png -------------------------------------------------------------------------------- /static/fonts/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/iconfont.eot -------------------------------------------------------------------------------- /static/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/iconfont.ttf -------------------------------------------------------------------------------- /static/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/iconfont.woff -------------------------------------------------------------------------------- /static/images/main_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/images/main_icon.png -------------------------------------------------------------------------------- /static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /static/images/icon_upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/images/icon_upload.png -------------------------------------------------------------------------------- /wallet/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class WalletConfig(AppConfig): 5 | name = 'wallet' 6 | -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/centerprime/NETFLIX-NFT/HEAD/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /static/css/shuvo.css: -------------------------------------------------------------------------------- 1 | .ts-venue-feature .single-venue-content i { 2 | font-size: 72px; 3 | color: #fff; } 4 | 5 | .ts-venue-feature .single-venue-content .ts-venue-title { 6 | font-size: 30px; 7 | color: #fff; } 8 | -------------------------------------------------------------------------------- /wallet/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import * 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | url(r'uploadImage', views.uploadImage, name='uploadImage'), 7 | url(r'getFiles', views.getFiles, name='getFiles'), 8 | ] 9 | -------------------------------------------------------------------------------- /tutorial/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for tutorial project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /tutorial/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for tutorial project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /wallet/migrations/0002_auto_20210221_0856.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.7 on 2021-02-21 08:56 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('wallet', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='user', 15 | name='fileType', 16 | field=models.CharField(max_length=100), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /contract/netflix-libs/utils/UQ112x112.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 4 | 5 | // range: [0, 2**112 - 1] 6 | // resolution: 1 / 2**112 7 | 8 | library UQ112x112 { 9 | uint224 constant Q112 = 2**112; 10 | 11 | // encode a uint112 as a UQ112x112 12 | function encode(uint112 y) internal pure returns (uint224 z) { 13 | z = uint224(y) * Q112; // never overflows 14 | } 15 | 16 | // divide a UQ112x112 by a uint112, returning a UQ112x112 17 | function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { 18 | z = x / uint224(y); 19 | } 20 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc1155/IERC1155MetadataURI.sol: -------------------------------------------------------------------------------- 1 | 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity ^0.8.0; 5 | 6 | import "./IERC1155.sol"; 7 | 8 | /** 9 | * @dev Interface of the optional ERC1155MetadataExtension interface, as defined 10 | * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. 11 | * 12 | * _Available since v3.1._ 13 | */ 14 | interface IERC1155MetadataURI is IERC1155 { 15 | /** 16 | * @dev Returns the URI for token type `id`. 17 | * 18 | * If the `\{id\}` substring is present in the URI, it must be replaced by 19 | * clients with the actual token type ID. 20 | */ 21 | function uri(uint256 id) external view returns (string memory); 22 | } -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /contract/pool/interfaces/INetflixSwapFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface INetflixSwapFactory { 4 | event PairCreated(address indexed token0, address indexed token1, address pair, uint256); 5 | 6 | function feeTo() external view returns (address); 7 | 8 | function feeToSetter() external view returns (address); 9 | 10 | function getPair(address tokenA, address tokenB) external view returns (address pair); 11 | 12 | function allPairs(uint256) external view returns (address pair); 13 | 14 | function allPairsLength() external view returns (uint256); 15 | 16 | function createPair(address tokenA, address tokenB) external returns (address pair); 17 | 18 | function setFeeTo(address) external; 19 | 20 | function setFeeToSetter(address) external; 21 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc721/IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Metadata is IERC721 { 12 | 13 | /** 14 | * @dev Returns the token collection name. 15 | */ 16 | function name() external view returns (string memory); 17 | 18 | /** 19 | * @dev Returns the token collection symbol. 20 | */ 21 | function symbol() external view returns (string memory); 22 | 23 | /** 24 | * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. 25 | */ 26 | function tokenURI(uint256 tokenId) external view returns (string memory); 27 | } 28 | -------------------------------------------------------------------------------- /wallet/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | # Create your models here. 5 | class User(models.Model): 6 | address = models.CharField(max_length=100) 7 | fileType = models.CharField(max_length=100) 8 | fileName = models.CharField(max_length=100, blank=True) 9 | fileId = models.CharField(max_length=250, unique=True) 10 | created_at = models.DateTimeField(auto_now_add=True) 11 | updated_at = models.DateTimeField(auto_now=True) 12 | 13 | class Meta: 14 | db_table = "user" 15 | 16 | 17 | class File(models.Model): 18 | token_id = models.IntegerField(max_length=10) 19 | token_portion = models.TextField() 20 | fileId = models.CharField(max_length=250) 21 | created_at = models.DateTimeField(auto_now_add=True) 22 | updated_at = models.DateTimeField(auto_now=True) 23 | 24 | class Meta: 25 | db_table = "file" 26 | -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc165/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | /** 6 | * @dev Interface of the ERC165 standard, as defined in the 7 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 8 | * 9 | * Implementers can declare support of contract interfaces, which can then be 10 | * queried by others ({ERC165Checker}). 11 | * 12 | * For an implementation, see {ERC165}. 13 | */ 14 | interface IERC165 { 15 | /** 16 | * @dev Returns true if this contract implements the interface defined by 17 | * `interfaceId`. See the corresponding 18 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 19 | * to learn more about how these ids are created. 20 | * 21 | * This function call must use less than 30 000 gas. 22 | */ 23 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 24 | } 25 | -------------------------------------------------------------------------------- /static/js/jquery.appear.min.js: -------------------------------------------------------------------------------- 1 | !function(p){var n=[],o=!1,f=!1,s={interval:250,force_process:!1},u=p(window),c=[];function d(){f=!1;for(var e=0,r=n.length;e=a&&o-(r.data("appear-top-offset")||0)<=a+u.height()&&n+r.width()>=t&&n-(r.data("appear-left-offset")||0)<=t+u.width()},p.fn.extend({appear:function(e,r){return p.appear(this,r),this}}),p.extend({appear:function(e,r){var t,a=p.extend({},s,r||{});if(!o){var i=function(){f||(f=!0,setTimeout(d,a.interval))};p(window).scroll(i).resize(i),o=!0}a.force_process&&setTimeout(d,a.interval),t=e,n.push(t),c.push()},force_appear:function(){return!!o&&(d(),!0)}})}("undefined"!=typeof module?require("jquery"):jQuery); -------------------------------------------------------------------------------- /static/js/main.js: -------------------------------------------------------------------------------- 1 | let box = document.querySelector(".box"); 2 | let output = document.querySelector(".output"); 3 | let fill = document.querySelector(".fill"); 4 | let click = document.querySelector("button"); 5 | let upload_text = document.querySelector(".upload_text"); 6 | let count_area = document.querySelector(".count_area"); 7 | 8 | click.addEventListener('click',()=>{ 9 | var a = 0; 10 | var run =setInterval(frames,30); 11 | function frames(){ 12 | a = a+1; 13 | if(a == 101){ 14 | clearInterval(run); 15 | box.style.display = "none"; 16 | output.style.display = "block"; 17 | 18 | } 19 | else{ 20 | var counter = document.querySelector(".counter"); 21 | counter.textContent = a + "%"; 22 | fill.style.width = a + "%"; 23 | upload_text.style.display = "none" 24 | count_area.style.display = "block" 25 | } 26 | } 27 | }) -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc721/IERC721Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | /** 6 | * @title erc721 token receiver interface 7 | * @dev Interface for any contract that wants to support safeTransfers 8 | * from erc721 asset contracts. 9 | */ 10 | interface IERC721Receiver { 11 | /** 12 | * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} 13 | * by `operator` from `from`, this function is called. 14 | * 15 | * It must return its Solidity selector to confirm the token transfer. 16 | * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. 17 | * 18 | * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. 19 | */ 20 | function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); 21 | } 22 | -------------------------------------------------------------------------------- /contract/netflix-libs/gsn/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc165/ERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "./IERC165.sol"; 6 | 7 | /** 8 | * @dev Implementation of the {IERC165} interface. 9 | * 10 | * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check 11 | * for the additional interface id that will be supported. For example: 12 | * 13 | * ```solidity 14 | * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 15 | * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); 16 | * } 17 | * ``` 18 | * 19 | * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. 20 | */ 21 | abstract contract ERC165 is IERC165 { 22 | /** 23 | * @dev See {IERC165-supportsInterface}. 24 | */ 25 | function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 26 | return interfaceId == type(IERC165).interfaceId; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contract/Netflix_NFT.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | import "./netflix-libs/token/erc721/ERC721.sol"; 3 | 4 | contract NETFLIX_NFT is ERC721 { 5 | 6 | mapping (uint256 => string ) public tokenIdFiles; 7 | uint256 public last_token_id; 8 | 9 | function getLastTokenId() public view returns (uint256){ 10 | return last_token_id; 11 | } 12 | 13 | constructor (string memory _name, string memory _symbol) public 14 | ERC721(_name, _symbol) 15 | {} 16 | 17 | 18 | function batchCreate(address _to , uint256[] memory _tokenIds , string[] memory _strs) public { 19 | FileItem[] memory fileItems; 20 | 21 | for (uint256 i =0; i< _tokenIds.length; i++ ){ 22 | createItem(_strs[i], _to , _tokenIds[i]); 23 | } 24 | 25 | } 26 | 27 | 28 | 29 | function createItem( string memory _str, address _to , uint256 _tokenId) public { 30 | last_token_id = _tokenId; 31 | tokenIdFiles[_tokenId] = _str; 32 | super._mint(_to,_tokenId); // Assigns the Token to the Ethereum Address that is specified 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | appdirs==1.4.4 2 | asgiref==3.3.1 3 | attrs==20.3.0 4 | base58==2.0.1 5 | bitarray==1.2.2 6 | certifi==2018.11.29 7 | chardet==3.0.4 8 | cytoolz==0.11.0 9 | distlib==0.3.0 10 | Django==3.1.7 11 | django-restframework==0.0.1 12 | djangorestframework==3.12.2 13 | eth-abi==2.1.1 14 | eth-account==0.5.4 15 | eth-hash==0.2.0 16 | eth-keyfile==0.5.1 17 | eth-keys==0.3.3 18 | eth-rlp==0.2.1 19 | eth-typing==2.2.2 20 | eth-utils==1.9.5 21 | filelock==3.0.12 22 | gspread==3.1.0 23 | hexbytes==0.2.1 24 | httplib2==0.15.0 25 | idna==2.8 26 | importlib-metadata==1.6.1 27 | ipfshttpclient==0.7.0a1 28 | jsonschema==3.2.0 29 | lru-dict==1.1.6 30 | multiaddr==0.0.9 31 | netaddr==0.8.0 32 | oauth2client==4.1.3 33 | parsimonious==0.8.1 34 | pipenv==2020.6.2 35 | protobuf==3.14.0 36 | pyasn1==0.4.8 37 | pyasn1-modules==0.2.7 38 | pycryptodome==3.9.9 39 | pyrsistent==0.17.3 40 | pytz==2021.1 41 | requests==2.22.0 42 | rlp==2.0.1 43 | rsa==4.0 44 | six==1.13.0 45 | sqlparse==0.4.1 46 | toolz==0.11.1 47 | typing-extensions==3.7.4.3 48 | urllib3==1.25.7 49 | varint==1.0.2 50 | virtualenv==20.0.23 51 | virtualenv-clone==0.5.4 52 | web3==5.13.1 53 | websockets==8.1 54 | zipp==3.1.0 55 | -------------------------------------------------------------------------------- /tutorial/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | from wallet.models import User, File 4 | 5 | 6 | def index(request): 7 | return render(request, 'index.html') 8 | 9 | 10 | def myfiles(request, address): 11 | listOfFiles = [] 12 | fileLists = User.objects.filter(address=address) 13 | for file in fileLists: 14 | mapFileData = {} 15 | filePortions = File.objects.filter(fileId=file.fileId).order_by('-token_id') 16 | mapFileData['fileName'] = file.fileName 17 | mapFileData['fileType'] = file.fileType 18 | mapFileData['fileId'] = file.fileId 19 | listOfFilePortions = [] 20 | for filePor in filePortions: 21 | mapFilePorData = {} 22 | mapFilePorData['token_id'] = filePor.token_id 23 | mapFilePorData['token_portion'] = filePor.token_portion 24 | listOfFilePortions.append(mapFilePorData) 25 | mapFileData['filePortions'] = listOfFilePortions 26 | listOfFiles.append(mapFileData) 27 | 28 | context = { 29 | 'address' : address, 30 | 'items': listOfFiles 31 | } 32 | return render(request, 'detail.html', context=context) 33 | -------------------------------------------------------------------------------- /tutorial/urls.py: -------------------------------------------------------------------------------- 1 | """tutorial URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | from django.urls import path, include 19 | from tutorial.views import * 20 | from django.conf.urls.static import static 21 | from tutorial import settings 22 | from wallet import urls as apiEndpoint 23 | 24 | urlpatterns = [ 25 | path('admin/', admin.site.urls), 26 | path('', index), 27 | path('myfiles//', myfiles), 28 | url(r'api/v1/', include(apiEndpoint)), 29 | ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 30 | -------------------------------------------------------------------------------- /contract/pool/interfaces/INetflixSwapBEP721.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface INetflixSwapBEP721 { 4 | event Approval(address indexed owner, address indexed spender, uint256 tokenId); 5 | event Transfer(address indexed from, address indexed to, uint256 tokenId); 6 | 7 | function name() external pure returns (string memory); 8 | 9 | function symbol() external pure returns (string memory); 10 | 11 | function totalSupply() external view returns (uint256); 12 | 13 | function balanceOf(address owner) external view returns (uint256); 14 | 15 | function allowance(address owner, address spender) external view returns (uint256); 16 | 17 | function approve(address spender, uint256 tokenId) external returns (bool); 18 | 19 | function transfer(address to, uint256 tokenId) external returns (bool); 20 | 21 | function transferFrom( 22 | address from, 23 | address to, 24 | uint256 value 25 | ) external returns (bool); 26 | 27 | function DOMAIN_SEPARATOR() external view returns (bytes32); 28 | 29 | function PERMIT_TYPEHASH() external pure returns (bytes32); 30 | 31 | function nonces(address owner) external view returns (uint256); 32 | 33 | function permit( 34 | address owner, 35 | address spender, 36 | uint256 value, 37 | uint256 deadline, 38 | uint8 v, 39 | bytes32 r, 40 | bytes32 s 41 | ) external; 42 | } -------------------------------------------------------------------------------- /contract/pool/interfaces/INetflixSwapBEP20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface INetflixSwapBEP20 { 4 | event Approval(address indexed owner, address indexed spender, uint256 value); 5 | event Transfer(address indexed from, address indexed to, uint256 value); 6 | 7 | function name() external pure returns (string memory); 8 | 9 | function symbol() external pure returns (string memory); 10 | 11 | function decimals() external pure returns (uint8); 12 | 13 | function totalSupply() external view returns (uint256); 14 | 15 | function balanceOf(address owner) external view returns (uint256); 16 | 17 | function allowance(address owner, address spender) external view returns (uint256); 18 | 19 | function approve(address spender, uint256 value) external returns (bool); 20 | 21 | function transfer(address to, uint256 value) external returns (bool); 22 | 23 | function transferFrom( 24 | address from, 25 | address to, 26 | uint256 value 27 | ) external returns (bool); 28 | 29 | function DOMAIN_SEPARATOR() external view returns (bytes32); 30 | 31 | function PERMIT_TYPEHASH() external pure returns (bytes32); 32 | 33 | function nonces(address owner) external view returns (uint256); 34 | 35 | function permit( 36 | address owner, 37 | address spender, 38 | uint256 value, 39 | uint256 deadline, 40 | uint8 v, 41 | bytes32 r, 42 | bytes32 s 43 | ) external; 44 | } -------------------------------------------------------------------------------- /wallet/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.7 on 2021-02-21 08:26 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='File', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('token_id', models.IntegerField(max_length=10)), 19 | ('token_portion', models.TextField()), 20 | ('fileId', models.CharField(max_length=250)), 21 | ('created_at', models.DateTimeField(auto_now_add=True)), 22 | ('updated_at', models.DateTimeField(auto_now=True)), 23 | ], 24 | options={ 25 | 'db_table': 'file', 26 | }, 27 | ), 28 | migrations.CreateModel( 29 | name='User', 30 | fields=[ 31 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 32 | ('address', models.CharField(max_length=100)), 33 | ('fileType', models.CharField(max_length=100, unique=True)), 34 | ('fileName', models.CharField(blank=True, max_length=100)), 35 | ('fileId', models.CharField(max_length=250, unique=True)), 36 | ('created_at', models.DateTimeField(auto_now_add=True)), 37 | ('updated_at', models.DateTimeField(auto_now=True)), 38 | ], 39 | options={ 40 | 'db_table': 'user', 41 | }, 42 | ), 43 | ] 44 | -------------------------------------------------------------------------------- /tutorial/utils.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import json 3 | 4 | from web3 import Web3, HTTPProvider 5 | 6 | 7 | def imageToBase64String(): 8 | with open("../image1.jpg", "rb") as image_file: 9 | encoded_string = base64.b64encode(image_file.read()) 10 | return encoded_string 11 | 12 | 13 | def videoToBase64String(): 14 | with open("../demo.mp4", "rb") as videoFile: 15 | encoded_string = base64.b64encode(videoFile.read()) 16 | return encoded_string 17 | 18 | 19 | def base64StringToImage(img_data): 20 | with open("../imageToSave.png", "wb") as fh: 21 | fh.write(base64.decodebytes(img_data)) 22 | 23 | 24 | def size(b64string): 25 | # x = (n * (3/4)) - y 26 | return (len(b64string) * 3) / 4 - b64string.count('=', -2) 27 | 28 | 29 | def splitStringEveryKb(str, kb_size): 30 | list_of_strings = [] 31 | kb_size = kb_size * 1024 32 | counter = 0 33 | temp_str = '' 34 | for s in str: 35 | if counter == kb_size: 36 | print("Temp Sttr : " + temp_str) 37 | list_of_strings.append(temp_str) 38 | counter = 0 39 | temp_str = '' 40 | else: 41 | counter += 1 42 | temp_str += s 43 | return list_of_strings 44 | 45 | 46 | def splitStringEveryCharacter(line, n): 47 | return [line[i:i + n] for i in range(0, len(line), n)] 48 | 49 | 50 | def collectListOfStrings(strs): 51 | string = '' 52 | counter = 0 53 | for s in strs: 54 | counter += 1 55 | print("[ No." + str(counter) + " size : " + str(len(s)) + " bytes" + " ]" + " -> " + s) 56 | string += s 57 | return string 58 | 59 | 60 | 61 | 62 | 63 | if __name__ == '__main__': 64 | img_data = videoToBase64String() 65 | das = img_data.decode('utf-8') 66 | print("Text Bytes : " + str(len(das))) 67 | splittedStrs = splitStringEveryCharacter(das, 1024 * 2) 68 | collectedStr = collectListOfStrings(splittedStrs) 69 | print(collectedStr) 70 | # base64StringToImage(collectedStr.encode('utf-8')) 71 | # print() 72 | # uploadToNFT(splittedStrs, "0x38C1E1204C10C8be90ecA671Da8Ea8a9AEb16031") 73 | -------------------------------------------------------------------------------- /contract/pool/NetflixSwapFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | import './interfaces/INetflixSwapFactory.sol'; 4 | import './NetflixSwapPair.sol'; 5 | 6 | contract NetflixSwapFactory is INetflixSwapFactory { 7 | address public feeTo; 8 | address public feeToSetter; 9 | 10 | mapping(address => mapping(address => address)) public getPair; 11 | address[] public allPairs; 12 | 13 | event PairCreated(address indexed token0, address indexed token1, address pair, uint256); 14 | 15 | constructor(address _feeToSetter) public { 16 | feeToSetter = _feeToSetter; 17 | // default feeTo is feeToSetter 18 | feeTo = feeToSetter; 19 | } 20 | 21 | function allPairsLength() external view returns (uint256) { 22 | return allPairs.length; 23 | } 24 | 25 | function createPair(address tokenA, address tokenB) external returns (address pair) { 26 | require(tokenA != tokenB, 'NetflixSwapFactory: IDENTICAL_ADDRESSES'); 27 | (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 28 | require(token0 != address(0), 'NetflixSwapFactory: ZERO_ADDRESS'); 29 | require(getPair[token0][token1] == address(0), 'NetflixSwapFactory: PAIR_EXISTS'); // single check is sufficient 30 | bytes memory bytecode = type(NetflixSwapPair).creationCode; 31 | bytes32 salt = keccak256(abi.encodePacked(token0, token1)); 32 | assembly { 33 | pair := create2(0, add(bytecode, 32), mload(bytecode), salt) 34 | } 35 | INetflixSwapPair(pair).initialize(token0, token1); 36 | getPair[token0][token1] = pair; 37 | getPair[token1][token0] = pair; // populate mapping in the reverse direction 38 | allPairs.push(pair); 39 | emit PairCreated(token0, token1, pair, allPairs.length); 40 | } 41 | 42 | function setFeeTo(address _feeTo) external { 43 | require(msg.sender == feeToSetter, 'NetflixSwapFactory: FORBIDDEN'); 44 | feeTo = _feeTo; 45 | } 46 | 47 | function setFeeToSetter(address _feeToSetter) external { 48 | require(msg.sender == feeToSetter, 'NetflixSwapFactory: FORBIDDEN'); 49 | feeToSetter = _feeToSetter; 50 | } 51 | } -------------------------------------------------------------------------------- /contract/netflix-libs/utils/Strings.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | /** 6 | * @dev String operations. 7 | */ 8 | library Strings { 9 | bytes16 private constant alphabet = "0123456789abcdef"; 10 | 11 | /** 12 | * @dev Converts a `uint256` to its ASCII `string` decimal representation. 13 | */ 14 | function toString(uint256 value) internal pure returns (string memory) { 15 | // Inspired by OraclizeAPI's implementation - MIT licence 16 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 17 | 18 | if (value == 0) { 19 | return "0"; 20 | } 21 | uint256 temp = value; 22 | uint256 digits; 23 | while (temp != 0) { 24 | digits++; 25 | temp /= 10; 26 | } 27 | bytes memory buffer = new bytes(digits); 28 | while (value != 0) { 29 | digits -= 1; 30 | buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); 31 | value /= 10; 32 | } 33 | return string(buffer); 34 | } 35 | 36 | /** 37 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. 38 | */ 39 | function toHexString(uint256 value) internal pure returns (string memory) { 40 | if (value == 0) { 41 | return "0x00"; 42 | } 43 | uint256 temp = value; 44 | uint256 length = 0; 45 | while (temp != 0) { 46 | length++; 47 | temp >>= 8; 48 | } 49 | return toHexString(value, length); 50 | } 51 | 52 | /** 53 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. 54 | */ 55 | function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 56 | bytes memory buffer = new bytes(2 * length + 2); 57 | buffer[0] = "0"; 58 | buffer[1] = "x"; 59 | for (uint256 i = 2 * length + 1; i > 1; --i) { 60 | buffer[i] = alphabet[value & 0xf]; 61 | value >>= 4; 62 | } 63 | require(value == 0, "Strings: hex length insufficient"); 64 | return string(buffer); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /contract/netflix-libs/access/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | import "./gsn/Context.sol"; 6 | /** 7 | * @dev Contract module which provides a basic access control mechanism, where 8 | * there is an account (an owner) that can be granted exclusive access to 9 | * specific functions. 10 | * 11 | * By default, the owner account will be the one that deploys the contract. This 12 | * can later be changed with {transferOwnership}. 13 | * 14 | * This module is used through inheritance. It will make available the modifier 15 | * `onlyOwner`, which can be applied to your functions to restrict their use to 16 | * the owner. 17 | */ 18 | abstract contract Ownable is Context { 19 | address payable private _owner; 20 | 21 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 22 | 23 | /** 24 | * @dev Initializes the contract setting the deployer as the initial owner. 25 | */ 26 | constructor () internal { 27 | address payable msgSender = _msgSender(); 28 | _owner = msgSender; 29 | emit OwnershipTransferred(address(0), msgSender); 30 | } 31 | 32 | /** 33 | * @dev Returns the address of the current owner. 34 | */ 35 | function owner() public view returns (address payable) { 36 | return _owner; 37 | } 38 | 39 | /** 40 | * @dev Throws if called by any account other than the owner. 41 | */ 42 | modifier onlyOwner() { 43 | require(_owner == _msgSender(), "Ownable: caller is not the owner"); 44 | _; 45 | } 46 | 47 | /** 48 | * @dev Leaves the contract without owner. It will not be possible to call 49 | * `onlyOwner` functions anymore. Can only be called by the current owner. 50 | * 51 | * NOTE: Renouncing ownership will leave the contract without an owner, 52 | * thereby removing any functionality that is only available to the owner. 53 | */ 54 | function renounceOwnership() public virtual onlyOwner { 55 | emit OwnershipTransferred(_owner, address(0)); 56 | _owner = address(0); 57 | } 58 | 59 | /** 60 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 61 | * Can only be called by the current owner. 62 | */ 63 | function transferOwnership(address payable newOwner) public virtual onlyOwner { 64 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 65 | emit OwnershipTransferred(_owner, newOwner); 66 | _owner = newOwner; 67 | } 68 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Binance Hackathon: The Future Is Now - Introducing NETFLIX NFT from Team CenterPrime. 2 |

3 | 4 | ## Overview 5 | Our project contributes to the content industry by converting various content 6 | formats (movies, music, photographs, documents) into NFT tokens. 7 | Until now, the blockchain industry has been represented by financial services. 8 | However, in the real economy, content services are also important. To date, content 9 | services using NFT tokens have been stored on or linked to other chain networks, 10 | making it difficult to assess their actual value. Therefore, we have created a 11 | technology that can easily make content usable in the blockchain network. We also 12 | want to make changes to the NFT by tokenizing the actual content, not simply 13 | storing or exchanging FT or NFT tokens. 14 |

15 | 16 | ## Challenges 17 | We have set six challenges for the revolution of the new blockchain content industry. 18 | 19 | 1. Distribution of data issued per each NFT token 20 | 2. Data re-decode per each NFT token 21 | 3. Purchase an NFT token by exchanging it with an FT token 22 | 4. NFT token pricing and fundraising using liquidity pool 23 | 5. Streaming pool to which NFT token content can be streamed 24 | 6. NFT token streaming service that be spent on Netflix content 25 | 26 |

27 |

28 |

29 |

30 | 31 | ## Future 32 | The technology we provide will provide the following benefits in the future. 33 | 34 | 1. Expansion of the blockchain content industry 35 | 2. Transparent content value calculation through NFT tokens 36 | 3. Expansion of the fund-raising market for content development 37 | 4. Consumer management systems of content platforms 38 | 5. Profit diversification through NFT token liquidity 39 | 6. Providing a variety of payment services 40 | 41 | ## Demo 42 | [NETFLIX NFT Demo website](http://13.124.28.86) 43 | -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc1155/IERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "../../token/erc165/ERC165.sol"; 6 | 7 | /** 8 | * _Available since v3.1._ 9 | */ 10 | interface IERC1155Receiver is IERC165 { 11 | 12 | /** 13 | @dev Handles the receipt of a single ERC1155 token type. This function is 14 | called at the end of a `safeTransferFrom` after the balance has been updated. 15 | To accept the transfer, this must return 16 | `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 17 | (i.e. 0xf23a6e61, or its own function selector). 18 | @param operator The address which initiated the transfer (i.e. msg.sender) 19 | @param from The address which previously owned the token 20 | @param id The ID of the token being transferred 21 | @param value The amount of tokens being transferred 22 | @param data Additional data with no specified format 23 | @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed 24 | */ 25 | function onERC1155Received( 26 | address operator, 27 | address from, 28 | uint256 id, 29 | uint256 value, 30 | bytes calldata data 31 | ) 32 | external 33 | returns(bytes4); 34 | 35 | /** 36 | @dev Handles the receipt of a multiple ERC1155 token types. This function 37 | is called at the end of a `safeBatchTransferFrom` after the balances have 38 | been updated. To accept the transfer(s), this must return 39 | `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 40 | (i.e. 0xbc197c81, or its own function selector). 41 | @param operator The address which initiated the batch transfer (i.e. msg.sender) 42 | @param from The address which previously owned the token 43 | @param ids An array containing ids of each token being transferred (order and length must match values array) 44 | @param values An array containing amounts of each token being transferred (order and length must match ids array) 45 | @param data Additional data with no specified format 46 | @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed 47 | */ 48 | function onERC1155BatchReceived( 49 | address operator, 50 | address from, 51 | uint256[] calldata ids, 52 | uint256[] calldata values, 53 | bytes calldata data 54 | ) 55 | external 56 | returns(bytes4); 57 | } -------------------------------------------------------------------------------- /contract/SellerNFTToken_BEP20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.0 <0.8.0; 3 | 4 | import "./netflix-libs/access/Ownable.sol"; 5 | import "./netflix-libs/gsn/Context.sol"; 6 | import "./netflix-libs/math/SafeMath.sol"; 7 | import "./netflix-libs/token/bep20/BEP20.sol"; 8 | 9 | 10 | contract SellerNFTToken_ERC20 is BEP20 { 11 | 12 | struct RECORD { 13 | address owner; 14 | string fileId; 15 | uint256 startTokenId; 16 | uint256 lastTokenId; 17 | bool isExpired; 18 | } 19 | 20 | struct TimeLock { 21 | address owner; 22 | uint startDateTime; 23 | uint endDateTime; 24 | } 25 | 26 | // mapping start and last token id based on address 27 | mapping (address => mapping (string => RECORD)) internal recordMap; 28 | mapping (address => mapping (string => TimeLock)) internal timeLockMap; 29 | 30 | // constructor 31 | constructor (string name,string symbol) public ERC20 (name,symbol) { 32 | } 33 | 34 | // _receiver : Receiver address 35 | // _RECORD_START_TOKEN_ID : Start token id in NFT token 36 | // _RECORD_LAST_TOKEN_ID : Last token id in NFT token 37 | function NETFLIX_NFT_RECORD_ADD ( string _fileId, 38 | address _receiver, 39 | uint256 _RECORD_START_TOKEN_ID, 40 | uint256 _RECORD_LAST_TOKEN_ID) public { 41 | // map _fileId to RECORD 42 | recordMap[_receiver][_fileId] = RECORD(_receiver,_fileId, _RECORD_START_TOKEN_ID,_RECORD_LAST_TOKEN_ID); 43 | // send SellerNFTToken 44 | _mint(_receiver, 1 * (10 ** uint256(decimals()))); 45 | // check _receiver has exipred NFT tokens 46 | // get TimeLock 47 | TimeLock timeLock = timeLockMap[_receiver][_fileId]; 48 | // get RECORD 49 | RECORD record = recordMap[_receiver][_fileId]; 50 | // check diff 51 | uint diff = (endDate - startDate) / 60 / 60 / 24; 52 | if (diff == 0 && !record.isExpired){ 53 | // burn token because time is expired 54 | _burnFrom(_receiver , address(0) , 1 * (10 ** uint256(decimals()))); 55 | // make as expired 56 | record.isExpired = true; 57 | } 58 | } 59 | 60 | // ADD NETFLIX_NFT_FIXEDTERM 61 | function NETFLIX_NFT_FIXEDTERM (address ownerOfTokenId, string _fileId, uint _START_DATETIME, uint _LAST_DATETIME) public { 62 | // map _fileId to TimeLock 63 | timeLockMap[ownerOfTokenId][_fileId] = TimeLock(ownerOfTokenId , _START_DATETIME, _LAST_DATETIME); 64 | } 65 | 66 | // Get RECORD 67 | function getRECORD(string _fileId) public virtual returns (RECORD) { 68 | return recordMap[msg.sender][_fileId]; 69 | } 70 | 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /contract/SellerNFTToken_ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.0 <0.8.0; 3 | 4 | import "./netflix-libs/access/Ownable.sol"; 5 | import "./netflix-libs/gsn/Context.sol"; 6 | import "./netflix-libs/token/erc20/ERC20.sol"; 7 | import "./netflix-libs/math/SafeMath.sol"; 8 | 9 | 10 | contract SellerNFTToken_ERC20 is ERC20 { 11 | 12 | struct RECORD { 13 | address owner; 14 | string fileId; 15 | uint256 startTokenId; 16 | uint256 lastTokenId; 17 | bool isExpired; 18 | } 19 | 20 | struct TimeLock { 21 | address owner; 22 | uint startDateTime; 23 | uint endDateTime; 24 | } 25 | 26 | // mapping start and last token id based on address 27 | mapping (address => mapping (string => RECORD)) internal recordMap; 28 | mapping (address => mapping (string => TimeLock)) internal timeLockMap; 29 | 30 | // constructor 31 | constructor (string name,string symbol) public ERC20 (name,symbol) { 32 | } 33 | 34 | // _receiver : Receiver address 35 | // _RECORD_START_TOKEN_ID : Start token id in NFT token 36 | // _RECORD_LAST_TOKEN_ID : Last token id in NFT token 37 | function NETFLIX_NFT_RECORD_ADD ( string _fileId, 38 | address _receiver, 39 | uint256 _RECORD_START_TOKEN_ID, 40 | uint256 _RECORD_LAST_TOKEN_ID) public { 41 | // map _fileId to RECORD 42 | recordMap[_receiver][_fileId] = RECORD(_receiver,_fileId, _RECORD_START_TOKEN_ID,_RECORD_LAST_TOKEN_ID); 43 | // send SellerNFTToken 44 | _mint(_receiver, 1 * (10 ** uint256(decimals()))); 45 | // check _receiver has exipred NFT tokens 46 | // get TimeLock 47 | TimeLock timeLock = timeLockMap[_receiver][_fileId]; 48 | // get RECORD 49 | RECORD record = recordMap[_receiver][_fileId]; 50 | // check diff 51 | uint diff = (endDate - startDate) / 60 / 60 / 24; 52 | if (diff == 0 && !record.isExpired){ 53 | // burn token because time is expired 54 | _burnFrom(_receiver , address(0) , 1 * (10 ** uint256(decimals()))); 55 | // make as expired 56 | record.isExpired = true; 57 | } 58 | } 59 | 60 | // ADD NETFLIX_NFT_FIXEDTERM 61 | function NETFLIX_NFT_FIXEDTERM (address ownerOfTokenId, string _fileId, uint _START_DATETIME, uint _LAST_DATETIME) public { 62 | // map _fileId to TimeLock 63 | timeLockMap[ownerOfTokenId][_fileId] = TimeLock(ownerOfTokenId , _START_DATETIME, _LAST_DATETIME); 64 | } 65 | 66 | // Get RECORD 67 | function getRECORD(string _fileId) public virtual returns (RECORD) { 68 | return recordMap[msg.sender][_fileId]; 69 | } 70 | 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /contract/SellerNFTToken_ERC721.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.0 <0.8.0; 3 | 4 | import "./netflix-libs/token/erc721/ERC721.sol"; 5 | 6 | 7 | contract SellerNFTToken_ERC721 is ERC721 { 8 | 9 | struct RECORD { 10 | address owner; 11 | string fileId; 12 | uint256 startTokenId; 13 | uint256 lastTokenId; 14 | bool isExpired; 15 | } 16 | 17 | struct TimeLock { 18 | address owner; 19 | uint startDateTime; 20 | uint endDateTime; 21 | } 22 | 23 | // mapping start and last token id based on address 24 | mapping (address => mapping (string => RECORD)) internal recordMap; 25 | mapping (address => mapping (string => TimeLock)) internal timeLockMap; 26 | // last token id 27 | uint256 public last_token_id; 28 | 29 | 30 | constructor (string memory _name, string memory _symbol) public 31 | ERC721(_name, _symbol) 32 | {} 33 | 34 | // _receiver : Receiver address 35 | // _RECORD_START_TOKEN_ID : Start token id in NFT token 36 | // _RECORD_LAST_TOKEN_ID : Last token id in NFT token 37 | function NETFLIX_NFT_RECORD_ADD ( string _fileId, 38 | address _receiver, 39 | uint256 _RECORD_START_TOKEN_ID, 40 | uint256 _RECORD_LAST_TOKEN_ID) public { 41 | // map _fileId to RECORD 42 | recordMap[_receiver][_fileId] = RECORD(_receiver,_fileId, _RECORD_START_TOKEN_ID,_RECORD_LAST_TOKEN_ID); 43 | // send SellerNFTToken 44 | last_token_id +=1; 45 | // Assigns the Token to the Ethereum Address that is specified 46 | super._mint(_receiver, last_token_id); 47 | // check _receiver has exipred NFT tokens 48 | // get TimeLock 49 | TimeLock timeLock = timeLockMap[_receiver][_fileId]; 50 | // get RECORD 51 | RECORD record = recordMap[_receiver][_fileId]; 52 | // check diff 53 | uint diff = (endDate - startDate) / 60 / 60 / 24; 54 | if (diff == 0 && !record.isExpired){ 55 | // burn token because time is expired 56 | _burn(_receiver , address(0) , 1 * (10 ** uint256(decimals()))); 57 | // make as expired 58 | record.isExpired = true; 59 | } 60 | } 61 | 62 | // ADD NETFLIX_NFT_FIXEDTERM 63 | function NETFLIX_NFT_FIXEDTERM (address ownerOfTokenId, string _fileId, uint _START_DATETIME, uint _LAST_DATETIME) public { 64 | // map _fileId to TimeLock 65 | timeLockMap[ownerOfTokenId][_fileId] = TimeLock(ownerOfTokenId , _START_DATETIME, _LAST_DATETIME); 66 | } 67 | 68 | // Get RECORD 69 | function getRECORD(string _fileId) public virtual returns (RECORD) { 70 | return recordMap[msg.sender][_fileId]; 71 | } 72 | 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /static/css/owl.carousel.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Owl Carousel v2.2.1 3 | * Copyright 2013-2017 David Deutsch 4 | * Licensed under () 5 | */ 6 | .owl-carousel,.owl-carousel .owl-item{-webkit-tap-highlight-color:transparent;position:relative}.owl-carousel{display:none;width:100%;z-index:1}.owl-carousel .owl-stage{position:relative;-ms-touch-action:pan-Y;-moz-backface-visibility:hidden}.owl-carousel .owl-stage:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.owl-carousel .owl-stage-outer{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0)}.owl-carousel .owl-item,.owl-carousel .owl-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.owl-carousel .owl-item{min-height:1px;float:left;-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.owl-carousel .owl-item img{display:block;width:100%}.owl-carousel .owl-dots.disabled,.owl-carousel .owl-nav.disabled{display:none}.no-js .owl-carousel,.owl-carousel.owl-loaded{display:block}.owl-carousel .owl-dot,.owl-carousel .owl-nav .owl-next,.owl-carousel .owl-nav .owl-prev{cursor:pointer;cursor:hand;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-loading{opacity:0;display:block}.owl-carousel.owl-hidden{opacity:0}.owl-carousel.owl-refresh .owl-item{visibility:hidden}.owl-carousel.owl-drag .owl-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-grab{cursor:move;cursor:grab}.owl-carousel.owl-rtl{direction:rtl}.owl-carousel.owl-rtl .owl-item{float:right}.owl-carousel .animated{animation-duration:1s;animation-fill-mode:both}.owl-carousel .owl-animated-in{z-index:0}.owl-carousel .owl-animated-out{z-index:1}.owl-carousel .fadeOut{animation-name:fadeOut}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.owl-height{transition:height .5s ease-in-out}.owl-carousel .owl-item .owl-lazy{opacity:0;transition:opacity .4s ease}.owl-carousel .owl-item img.owl-lazy{transform-style:preserve-3d}.owl-carousel .owl-video-wrapper{position:relative;height:100%;background:#000}.owl-carousel .owl-video-play-icon{position:absolute;height:80px;width:80px;left:50%;top:50%;margin-left:-40px;margin-top:-40px;background:url(owl.video.play.png) no-repeat;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;transition:transform .1s ease}.owl-carousel .owl-video-play-icon:hover{-ms-transform:scale(1.3,1.3);transform:scale(1.3,1.3)}.owl-carousel .owl-video-playing .owl-video-play-icon,.owl-carousel .owl-video-playing .owl-video-tn{display:none}.owl-carousel .owl-video-tn{opacity:0;height:100%;background-position:center center;background-repeat:no-repeat;background-size:contain;transition:opacity .4s ease}.owl-carousel .owl-video-frame{position:relative;z-index:1;height:100%;width:100%} -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc20/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 standard as defined in the EIP. 7 | */ 8 | interface IERC20 { 9 | /** 10 | * @dev Returns the amount of tokens in existence. 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the amount of tokens owned by `account`. 16 | */ 17 | function balanceOf(address account) external view returns (uint256); 18 | 19 | /** 20 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 21 | * 22 | * Returns a boolean value indicating whether the operation succeeded. 23 | * 24 | * Emits a {Transfer} event. 25 | */ 26 | function transfer(address recipient, uint256 amount) external returns (bool); 27 | 28 | /** 29 | * @dev Returns the remaining number of tokens that `spender` will be 30 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 31 | * zero by default. 32 | * 33 | * This value changes when {approve} or {transferFrom} are called. 34 | */ 35 | function allowance(address owner, address spender) external view returns (uint256); 36 | 37 | /** 38 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 39 | * 40 | * Returns a boolean value indicating whether the operation succeeded. 41 | * 42 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 43 | * that someone may use both the old and the new allowance by unfortunate 44 | * transaction ordering. One possible solution to mitigate this race 45 | * condition is to first reduce the spender's allowance to 0 and set the 46 | * desired value afterwards: 47 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 48 | * 49 | * Emits an {Approval} event. 50 | */ 51 | function approve(address spender, uint256 amount) external returns (bool); 52 | 53 | /** 54 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 55 | * allowance mechanism. `amount` is then deducted from the caller's 56 | * allowance. 57 | * 58 | * Returns a boolean value indicating whether the operation succeeded. 59 | * 60 | * Emits a {Transfer} event. 61 | */ 62 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 63 | 64 | /** 65 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 66 | * another (`to`). 67 | * 68 | * Note that `value` may be zero. 69 | */ 70 | event Transfer(address indexed from, address indexed to, uint256 value); 71 | 72 | /** 73 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 74 | * a call to {approve}. `value` is the new allowance. 75 | */ 76 | event Approval(address indexed owner, address indexed spender, uint256 value); 77 | } -------------------------------------------------------------------------------- /contract/pool/interfaces/INetflixSwapPair.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface INetflixSwapPair { 4 | event Approval(address indexed owner, address indexed spender, uint256 value); 5 | event Transfer(address indexed from, address indexed to, uint256 value); 6 | 7 | function name() external pure returns (string memory); 8 | 9 | function symbol() external pure returns (string memory); 10 | 11 | function decimals() external pure returns (uint8); 12 | 13 | function totalSupply() external view returns (uint256); 14 | 15 | function balanceOf(address owner) external view returns (uint256); 16 | 17 | function allowance(address owner, address spender) external view returns (uint256); 18 | 19 | function approve(address spender, uint256 value) external returns (bool); 20 | 21 | function transfer(address to, uint256 value) external returns (bool); 22 | 23 | function transferFrom( 24 | address from, 25 | address to, 26 | uint256 value 27 | ) external returns (bool); 28 | 29 | function DOMAIN_SEPARATOR() external view returns (bytes32); 30 | 31 | function PERMIT_TYPEHASH() external pure returns (bytes32); 32 | 33 | function nonces(address owner) external view returns (uint256); 34 | 35 | function permit( 36 | address owner, 37 | address spender, 38 | uint256 value, 39 | uint256 deadline, 40 | uint8 v, 41 | bytes32 r, 42 | bytes32 s 43 | ) external; 44 | 45 | event Mint(address indexed sender, uint256 amount0, uint256 amount1); 46 | event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); 47 | event Swap( 48 | address indexed sender, 49 | uint256 amount0In, 50 | uint256 amount1In, 51 | uint256 amount0Out, 52 | uint256 amount1Out, 53 | address indexed to 54 | ); 55 | event Sync(uint112 reserve0, uint112 reserve1); 56 | 57 | function MINIMUM_LIQUIDITY() external pure returns (uint256); 58 | 59 | function factory() external view returns (address); 60 | 61 | function token0() external view returns (address); 62 | 63 | function token1() external view returns (address); 64 | 65 | function getReserves() 66 | external 67 | view 68 | returns ( 69 | uint112 reserve0, 70 | uint112 reserve1, 71 | uint32 blockTimestampLast 72 | ); 73 | 74 | function price0CumulativeLast() external view returns (uint256); 75 | 76 | function price1CumulativeLast() external view returns (uint256); 77 | 78 | function kLast() external view returns (uint256); 79 | 80 | function mint(address to) external returns (uint256 liquidity); 81 | 82 | function burn(address to) external returns (uint256 amount0, uint256 amount1); 83 | 84 | function swap( 85 | uint256 amount0Out, 86 | uint256 amount1Out, 87 | address to 88 | ) external; 89 | 90 | function skim(address to) external; 91 | 92 | function sync() external; 93 | 94 | function initialize(address, address) external; 95 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/bep20/IBEP20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.4.0; 4 | 5 | interface IBEP20 { 6 | /** 7 | * @dev Returns the amount of tokens in existence. 8 | */ 9 | function totalSupply() external view returns (uint256); 10 | 11 | /** 12 | * @dev Returns the token decimals. 13 | */ 14 | function decimals() external view returns (uint8); 15 | 16 | /** 17 | * @dev Returns the token symbol. 18 | */ 19 | function symbol() external view returns (string memory); 20 | 21 | /** 22 | * @dev Returns the token name. 23 | */ 24 | function name() external view returns (string memory); 25 | 26 | /** 27 | * @dev Returns the bep token owner. 28 | */ 29 | function getOwner() external view returns (address); 30 | 31 | /** 32 | * @dev Returns the amount of tokens owned by `account`. 33 | */ 34 | function balanceOf(address account) external view returns (uint256); 35 | 36 | /** 37 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 38 | * 39 | * Returns a boolean value indicating whether the operation succeeded. 40 | * 41 | * Emits a {Transfer} event. 42 | */ 43 | function transfer(address recipient, uint256 amount) external returns (bool); 44 | 45 | /** 46 | * @dev Returns the remaining number of tokens that `spender` will be 47 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 48 | * zero by default. 49 | * 50 | * This value changes when {approve} or {transferFrom} are called. 51 | */ 52 | function allowance(address _owner, address spender) external view returns (uint256); 53 | 54 | /** 55 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 56 | * 57 | * Returns a boolean value indicating whether the operation succeeded. 58 | * 59 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 60 | * that someone may use both the old and the new allowance by unfortunate 61 | * transaction ordering. One possible solution to mitigate this race 62 | * condition is to first reduce the spender's allowance to 0 and set the 63 | * desired value afterwards: 64 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 65 | * 66 | * Emits an {Approval} event. 67 | */ 68 | function approve(address spender, uint256 amount) external returns (bool); 69 | 70 | /** 71 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 72 | * allowance mechanism. `amount` is then deducted from the caller's 73 | * allowance. 74 | * 75 | * Returns a boolean value indicating whether the operation succeeded. 76 | * 77 | * Emits a {Transfer} event. 78 | */ 79 | function transferFrom( 80 | address sender, 81 | address recipient, 82 | uint256 amount 83 | ) external returns (bool); 84 | 85 | /** 86 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 87 | * another (`to`). 88 | * 89 | * Note that `value` may be zero. 90 | */ 91 | event Transfer(address indexed from, address indexed to, uint256 value); 92 | 93 | /** 94 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 95 | * a call to {approve}. `value` is the new allowance. 96 | */ 97 | event Approval(address indexed owner, address indexed spender, uint256 value); 98 | } -------------------------------------------------------------------------------- /tutorial/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for tutorial project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.1.7. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.1/ref/settings/ 11 | """ 12 | import os 13 | from pathlib import Path 14 | 15 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 16 | BASE_DIR = Path(__file__).resolve().parent.parent 17 | 18 | # Quick-start development settings - unsuitable for production 19 | # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ 20 | 21 | # SECURITY WARNING: keep the secret key used in production secret! 22 | SECRET_KEY = '@ad%i349!ikqu@k53i*3p39mfz*1*_y3&3=4u&n%^8p$2*x4cv' 23 | 24 | # SECURITY WARNING: don't run with debug turned on in production! 25 | DEBUG = True 26 | 27 | ALLOWED_HOSTS = ['*'] 28 | 29 | # Application definition 30 | 31 | INSTALLED_APPS = [ 32 | 'django.contrib.admin', 33 | 'django.contrib.auth', 34 | 'django.contrib.contenttypes', 35 | 'django.contrib.sessions', 36 | 'django.contrib.messages', 37 | 'django.contrib.staticfiles', 38 | 'rest_framework', 39 | 'wallet', 40 | ] 41 | 42 | MIDDLEWARE = [ 43 | 'django.middleware.security.SecurityMiddleware', 44 | 'django.contrib.sessions.middleware.SessionMiddleware', 45 | 'django.middleware.common.CommonMiddleware', 46 | 'django.middleware.csrf.CsrfViewMiddleware', 47 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 48 | 'django.contrib.messages.middleware.MessageMiddleware', 49 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 50 | ] 51 | 52 | ROOT_URLCONF = 'tutorial.urls' 53 | 54 | TEMPLATES = [ 55 | { 56 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 57 | 'DIRS': [os.path.join(BASE_DIR, 'templates')] 58 | , 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'tutorial.wsgi.application' 72 | 73 | # Database 74 | # https://docs.djangoproject.com/en/3.1/ref/settings/#databases 75 | 76 | DATABASES = { 77 | 'default': { 78 | 'ENGINE': 'django.db.backends.sqlite3', 79 | 'NAME': BASE_DIR / 'db.sqlite3', 80 | } 81 | } 82 | 83 | # Password validation 84 | # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators 85 | 86 | AUTH_PASSWORD_VALIDATORS = [ 87 | { 88 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 89 | }, 90 | { 91 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 92 | }, 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 98 | }, 99 | ] 100 | 101 | # Internationalization 102 | # https://docs.djangoproject.com/en/3.1/topics/i18n/ 103 | 104 | LANGUAGE_CODE = 'en-us' 105 | 106 | TIME_ZONE = 'UTC' 107 | 108 | USE_I18N = True 109 | 110 | USE_L10N = True 111 | 112 | USE_TZ = True 113 | 114 | # Static files (CSS, JavaScript, Images) 115 | # https://docs.djangoproject.com/en/3.1/howto/static-files/ 116 | 117 | STATIC_URL = '/static/' 118 | STATICFILES_DIRS = ( 119 | os.path.join(BASE_DIR, 'static'), 120 | ) 121 | 122 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 123 | 124 | TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),) 125 | 126 | SESSION_EXPIRE_AT_BROWSER_CLOSE = False 127 | SESSION_COOKIE_AGE = 3 * 60 # 128 | 129 | MEDIA_URL = '/media/' 130 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 131 | -------------------------------------------------------------------------------- /contract/pool/NetflixSwapBEP20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | import './interfaces/INetflixSwapBEP20.sol'; 4 | import "../netflix-libs/math/SafeMath.sol"; 5 | 6 | contract NetflixSwapBEP20 is INetflixSwapBEP20 { 7 | using SafeMath for uint256; 8 | 9 | string public constant name = 'Netflix LPs'; 10 | string public constant symbol = 'BLP'; 11 | uint8 public constant decimals = 18; 12 | uint256 public totalSupply; 13 | mapping(address => uint256) public balanceOf; 14 | mapping(address => mapping(address => uint256)) public allowance; 15 | 16 | bytes32 public DOMAIN_SEPARATOR; 17 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 18 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 19 | mapping(address => uint256) public nonces; 20 | 21 | event Approval(address indexed owner, address indexed spender, uint256 value); 22 | event Transfer(address indexed from, address indexed to, uint256 value); 23 | 24 | constructor() public { 25 | uint256 chainId; 26 | assembly { 27 | chainId := chainid 28 | } 29 | DOMAIN_SEPARATOR = keccak256( 30 | abi.encode( 31 | keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), 32 | keccak256(bytes(name)), 33 | keccak256(bytes('1')), 34 | chainId, 35 | address(this) 36 | ) 37 | ); 38 | } 39 | 40 | function _mint(address to, uint256 value) internal { 41 | totalSupply = totalSupply.add(value); 42 | balanceOf[to] = balanceOf[to].add(value); 43 | emit Transfer(address(0), to, value); 44 | } 45 | 46 | function _burn(address from, uint256 value) internal { 47 | balanceOf[from] = balanceOf[from].sub(value); 48 | totalSupply = totalSupply.sub(value); 49 | emit Transfer(from, address(0), value); 50 | } 51 | 52 | function _approve( 53 | address owner, 54 | address spender, 55 | uint256 value 56 | ) private { 57 | allowance[owner][spender] = value; 58 | emit Approval(owner, spender, value); 59 | } 60 | 61 | function _transfer( 62 | address from, 63 | address to, 64 | uint256 value 65 | ) private { 66 | balanceOf[from] = balanceOf[from].sub(value); 67 | balanceOf[to] = balanceOf[to].add(value); 68 | emit Transfer(from, to, value); 69 | } 70 | 71 | function approve(address spender, uint256 value) external returns (bool) { 72 | _approve(msg.sender, spender, value); 73 | return true; 74 | } 75 | 76 | function transfer(address to, uint256 value) external returns (bool) { 77 | _transfer(msg.sender, to, value); 78 | return true; 79 | } 80 | 81 | function transferFrom( 82 | address from, 83 | address to, 84 | uint256 value 85 | ) external returns (bool) { 86 | if (allowance[from][msg.sender] != uint256(-1)) { 87 | allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); 88 | } 89 | _transfer(from, to, value); 90 | return true; 91 | } 92 | 93 | function permit( 94 | address owner, 95 | address spender, 96 | uint256 value, 97 | uint256 deadline, 98 | uint8 v, 99 | bytes32 r, 100 | bytes32 s 101 | ) external { 102 | require(deadline >= block.timestamp, 'NetflixSwapBEP20: EXPIRED'); 103 | bytes32 digest = keccak256( 104 | abi.encodePacked( 105 | '\x19\x01', 106 | DOMAIN_SEPARATOR, 107 | keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) 108 | ) 109 | ); 110 | address recoveredAddress = ecrecover(digest, v, r, s); 111 | require(recoveredAddress != address(0) && recoveredAddress == owner, 'NetflixSwapBEP20: INVALID_SIGNATURE'); 112 | _approve(owner, spender, value); 113 | } 114 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc1155/IERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "../../token/erc165/ERC165.sol"; 6 | 7 | /** 8 | * @dev Required interface of an ERC1155 compliant contract, as defined in the 9 | * https://eips.ethereum.org/EIPS/eip-1155[EIP]. 10 | * 11 | * _Available since v3.1._ 12 | */ 13 | interface IERC1155 is IERC165 { 14 | /** 15 | * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. 16 | */ 17 | event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); 18 | 19 | /** 20 | * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all 21 | * transfers. 22 | */ 23 | event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); 24 | 25 | /** 26 | * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to 27 | * `approved`. 28 | */ 29 | event ApprovalForAll(address indexed account, address indexed operator, bool approved); 30 | 31 | /** 32 | * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. 33 | * 34 | * If an {URI} event was emitted for `id`, the standard 35 | * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value 36 | * returned by {IERC1155MetadataURI-uri}. 37 | */ 38 | event URI(string value, uint256 indexed id); 39 | 40 | /** 41 | * @dev Returns the amount of tokens of token type `id` owned by `account`. 42 | * 43 | * Requirements: 44 | * 45 | * - `account` cannot be the zero address. 46 | */ 47 | function balanceOf(address account, uint256 id) external view returns (uint256); 48 | 49 | /** 50 | * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. 51 | * 52 | * Requirements: 53 | * 54 | * - `accounts` and `ids` must have the same length. 55 | */ 56 | function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); 57 | 58 | /** 59 | * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, 60 | * 61 | * Emits an {ApprovalForAll} event. 62 | * 63 | * Requirements: 64 | * 65 | * - `operator` cannot be the caller. 66 | */ 67 | function setApprovalForAll(address operator, bool approved) external; 68 | 69 | /** 70 | * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. 71 | * 72 | * See {setApprovalForAll}. 73 | */ 74 | function isApprovedForAll(address account, address operator) external view returns (bool); 75 | 76 | /** 77 | * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. 78 | * 79 | * Emits a {TransferSingle} event. 80 | * 81 | * Requirements: 82 | * 83 | * - `to` cannot be the zero address. 84 | * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. 85 | * - `from` must have a balance of tokens of type `id` of at least `amount`. 86 | * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the 87 | * acceptance magic value. 88 | */ 89 | function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; 90 | 91 | /** 92 | * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. 93 | * 94 | * Emits a {TransferBatch} event. 95 | * 96 | * Requirements: 97 | * 98 | * - `ids` and `amounts` must have the same length. 99 | * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the 100 | * acceptance magic value. 101 | */ 102 | function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; 103 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/bep20/SafeBEP20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | import './IBEP20.sol'; 6 | import "https://github.com/centerprime/CPXToken/tree/master/v0.6/contracts/math/SafeMath.sol"; 7 | 8 | /** 9 | * @title SafeBEP20 10 | * @dev Wrappers around BEP20 operations that throw on failure (when the token 11 | * contract returns false). Tokens that return no value (and instead revert or 12 | * throw on failure) are also supported, non-reverting calls are assumed to be 13 | * successful. 14 | * To use this library you can add a `using SafeBEP20 for IBEP20;` statement to your contract, 15 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 16 | */ 17 | library SafeBEP20 { 18 | using SafeMath for uint256; 19 | using Address for address; 20 | 21 | function safeTransfer( 22 | IBEP20 token, 23 | address to, 24 | uint256 value 25 | ) internal { 26 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 27 | } 28 | 29 | function safeTransferFrom( 30 | IBEP20 token, 31 | address from, 32 | address to, 33 | uint256 value 34 | ) internal { 35 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 36 | } 37 | 38 | /** 39 | * @dev Deprecated. This function has issues similar to the ones found in 40 | * {IBEP20-approve}, and its usage is discouraged. 41 | * 42 | * Whenever possible, use {safeIncreaseAllowance} and 43 | * {safeDecreaseAllowance} instead. 44 | */ 45 | function safeApprove( 46 | IBEP20 token, 47 | address spender, 48 | uint256 value 49 | ) internal { 50 | // safeApprove should only be called when setting an initial allowance, 51 | // or when resetting it to zero. To increase and decrease it, use 52 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 53 | // solhint-disable-next-line max-line-length 54 | require( 55 | (value == 0) || (token.allowance(address(this), spender) == 0), 56 | 'SafeBEP20: approve from non-zero to non-zero allowance' 57 | ); 58 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 59 | } 60 | 61 | function safeIncreaseAllowance( 62 | IBEP20 token, 63 | address spender, 64 | uint256 value 65 | ) internal { 66 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 67 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 68 | } 69 | 70 | function safeDecreaseAllowance( 71 | IBEP20 token, 72 | address spender, 73 | uint256 value 74 | ) internal { 75 | uint256 newAllowance = token.allowance(address(this), spender).sub( 76 | value, 77 | 'SafeBEP20: decreased allowance below zero' 78 | ); 79 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 80 | } 81 | 82 | /** 83 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 84 | * on the return value: the return value is optional (but if data is returned, it must not be false). 85 | * @param token The token targeted by the call. 86 | * @param data The call data (encoded using abi.encode or one of its variants). 87 | */ 88 | function _callOptionalReturn(IBEP20 token, bytes memory data) private { 89 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 90 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 91 | // the target address contains contract code and also asserts for success in the low-level call. 92 | 93 | bytes memory returndata = address(token).functionCall(data, 'SafeBEP20: low-level call failed'); 94 | if (returndata.length > 0) { 95 | // Return data is optional 96 | // solhint-disable-next-line max-line-length 97 | require(abi.decode(returndata, (bool)), 'SafeBEP20: BEP20 operation did not succeed'); 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /contract/pool/ContentLiquiditySalesPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.0 <0.8.0; 3 | 4 | import "../netflix-libs/gsn/Context.sol"; 5 | import "../netflix-libs/token/erc20/ERC20.sol"; 6 | import "../netflix-libs/token/erc721/ERC721.sol"; 7 | import "../netflix-libs/math/SafeMath.sol"; 8 | import "../netflix-libs/access/Ownable.sol"; 9 | 10 | contract ContentLiquiditySalesPool is Ownable { 11 | 12 | event Sent(address indexed payee, uint256 amount, uint256 balance); 13 | event Received(address indexed payer, uint256 tokenId, uint256 amount, uint256 balance); 14 | 15 | // ERC721 nftTokenAddress 16 | ERC721 public nftTokenAddress; 17 | // ERC20 erc20TokenAddress 18 | ERC20 public erc20TokenAddress; 19 | // tokenId price 20 | uint256 public tokenIdPrice; 21 | // mapping tokenId based on address 22 | mapping(uint256 => address) public tokenSeller; 23 | 24 | /** 25 | * @dev Contract Constructor 26 | * @param _nftTokenAddress address for non-fungible token contract 27 | * @param _currentPrice initial price 28 | */ 29 | constructor(address _nftTokenAddress, address _erc20TokenAddress, uint256 _tokenIdPrice , uint256 _tokenId) public { 30 | // check _nftTokenAddress address validation 31 | require(_nftTokenAddress != address(0) && _nftTokenAddress != address(this)); 32 | // check tokenId price 33 | require(_tokenIdPrice > 0); 34 | // init nftTokenAddress 35 | nftTokenAddress = ERC721(_nftTokenAddress); 36 | // init erc20TokenAddress 37 | erc20TokenAddress = ERC20(_erc20TokenAddress); 38 | // init tokenIdPrice 39 | tokenIdPrice = _tokenIdPrice; 40 | // transfer tokenId to contract address 41 | nftAddress.transferFrom(msg.sender, address(this), _tokenId); 42 | // mapping tokenId based on address 43 | tokenSeller[_tokenId] = msg.sender; 44 | } 45 | 46 | 47 | /** 48 | * Purchase NFT token ID by BNB 49 | * @dev Purchase _tokenId 50 | * @param _tokenId uint256 token ID 51 | */ 52 | function purchaseTokenByBNB(uint256 _tokenId) public payable { 53 | // check msg.sender address validation 54 | require(msg.sender != address(0) && msg.sender != address(this),"wrong addresses interaction"); 55 | // check balance enough 56 | require(msg.value >= tokenIdPrice,"not enough ETH funds"); 57 | // get tokenId owner address 58 | address temp = tokenSeller[_tokenId]; 59 | // get payable address 60 | address payable Seller = address(uint160(temp)); 61 | // transfer BNB to owner address 62 | Seller.transfer(msg.value); 63 | // tokenId transfer to the msg.sender 64 | nftTokenAddress.transferFrom(address(this), msg.sender, _tokenId); 65 | // publish event 66 | emit Received(msg.sender, _tokenId, msg.value, address(this).balance); 67 | } 68 | 69 | /** 70 | * @dev Purchase _tokenId by ERC20 Token 71 | * @param _tokenId uint256 token ID 72 | * @param _amount uint256 amount of ERC20 Tooken 73 | */ 74 | function purchaseTokenByERC20Token(uint256 _tokenId,uint256 _amount) public returns (bool) { 75 | // check msg.sender address validation 76 | require(msg.sender != address(0) && msg.sender != address(this),"wrong addresses interaction"); 77 | // check balance enough 78 | require(_amount >= currentPrice,"not enough ERC20 token funds"); 79 | // approve _tokenId to msg.sender 80 | nftAddress.approve(msg.sender,_tokenId); 81 | // get tokenId owner address 82 | address temp = tokenSeller[_tokenId]; 83 | // transfer ERC20 token to owner of tokenId 84 | require(erc20TokenAddress.transferFrom(msg.sender, temp, _amount),"Not Enough tokens Transfered"); 85 | // transfer tokenId to msg.sender 86 | nftTokenAddress.transferFrom(address(this), msg.sender, _tokenId); 87 | // publish event 88 | emit Received(msg.sender, _tokenId, _amount, address(this).balance); 89 | return true; 90 | } 91 | 92 | /** 93 | * @dev withdraw BNB _amount 94 | */ 95 | function withdraw (address payable _payee, uint256 _amount) public onlyOwner { 96 | // check _payee address validation 97 | require(_payee != address(0) && _payee != address(this)); 98 | // check balance enough 99 | require(_amount > 0 && _amount <= address(this).balance); 100 | // transfer BNB funds 101 | _payee.transfer(_amount); 102 | // publish event 103 | emit Sent(_payee, _amount, address(this).balance); 104 | } 105 | 106 | /** 107 | * @dev set _tokenIdPrice 108 | */ 109 | function setTokenIdPrice(uint256 _tokenIdPrice) public onlyOwner { 110 | require(_tokenIdPrice >= 0); 111 | tokenIdPrice = _tokenIdPrice; 112 | } 113 | 114 | /** 115 | * @dev get tokenIdPrice 116 | */ 117 | function getTokenIdPrice() public view returns (uint256) { 118 | return tokenIdPrice; 119 | } 120 | 121 | 122 | } -------------------------------------------------------------------------------- /contract/netflix-libs/token/erc721/IERC721.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "../../introspection/IERC165.sol"; 6 | 7 | /** 8 | * @dev Required interface of an erc721 compliant contract. 9 | */ 10 | interface IERC721 is IERC165 { 11 | /** 12 | * @dev Emitted when `tokenId` token is transferred from `from` to `to`. 13 | */ 14 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 15 | 16 | /** 17 | * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. 18 | */ 19 | event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); 20 | 21 | /** 22 | * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. 23 | */ 24 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 25 | 26 | /** 27 | * @dev Returns the number of tokens in ``owner``'s account. 28 | */ 29 | function balanceOf(address owner) external view returns (uint256 balance); 30 | 31 | /** 32 | * @dev Returns the owner of the `tokenId` token. 33 | * 34 | * Requirements: 35 | * 36 | * - `tokenId` must exist. 37 | */ 38 | function ownerOf(uint256 tokenId) external view returns (address owner); 39 | 40 | /** 41 | * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients 42 | * are aware of the erc721 protocol to prevent tokens from being forever locked. 43 | * 44 | * Requirements: 45 | * 46 | * - `from` cannot be the zero address. 47 | * - `to` cannot be the zero address. 48 | * - `tokenId` token must exist and be owned by `from`. 49 | * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. 50 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 51 | * 52 | * Emits a {Transfer} event. 53 | */ 54 | function safeTransferFrom(address from, address to, uint256 tokenId) external; 55 | 56 | /** 57 | * @dev Transfers `tokenId` token from `from` to `to`. 58 | * 59 | * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. 60 | * 61 | * Requirements: 62 | * 63 | * - `from` cannot be the zero address. 64 | * - `to` cannot be the zero address. 65 | * - `tokenId` token must be owned by `from`. 66 | * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 67 | * 68 | * Emits a {Transfer} event. 69 | */ 70 | function transferFrom(address from, address to, uint256 tokenId) external; 71 | 72 | /** 73 | * @dev Gives permission to `to` to transfer `tokenId` token to another account. 74 | * The approval is cleared when the token is transferred. 75 | * 76 | * Only a single account can be approved at a time, so approving the zero address clears previous approvals. 77 | * 78 | * Requirements: 79 | * 80 | * - The caller must own the token or be an approved operator. 81 | * - `tokenId` must exist. 82 | * 83 | * Emits an {Approval} event. 84 | */ 85 | function approve(address to, uint256 tokenId) external; 86 | 87 | /** 88 | * @dev Returns the account approved for `tokenId` token. 89 | * 90 | * Requirements: 91 | * 92 | * - `tokenId` must exist. 93 | */ 94 | function getApproved(uint256 tokenId) external view returns (address operator); 95 | 96 | /** 97 | * @dev Approve or remove `operator` as an operator for the caller. 98 | * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. 99 | * 100 | * Requirements: 101 | * 102 | * - The `operator` cannot be the caller. 103 | * 104 | * Emits an {ApprovalForAll} event. 105 | */ 106 | function setApprovalForAll(address operator, bool _approved) external; 107 | 108 | /** 109 | * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. 110 | * 111 | * See {setApprovalForAll} 112 | */ 113 | function isApprovedForAll(address owner, address operator) external view returns (bool); 114 | 115 | /** 116 | * @dev Safely transfers `tokenId` token from `from` to `to`. 117 | * 118 | * Requirements: 119 | * 120 | * - `from` cannot be the zero address. 121 | * - `to` cannot be the zero address. 122 | * - `tokenId` token must exist and be owned by `from`. 123 | * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 124 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 125 | * 126 | * Emits a {Transfer} event. 127 | */ 128 | function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; 129 | } 130 | -------------------------------------------------------------------------------- /contract/farm/NetflixNFTFarm.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.0; 2 | 3 | import "../netflix-libs/access/Ownable.sol"; 4 | import "../netflix-libs/gsn/Context.sol"; 5 | import "../netflix-libs/token/bep20/BEP20.sol"; 6 | import "../netflix-libs/token/bep20/IBEP20.sol"; 7 | import "../netflix-libs/token/bep20/SafeBep20.sol"; 8 | import "../netflix-libs/math/SafeMath.sol"; 9 | import "../netflix-libs/token/erc1155/IERC1155.sol"; 10 | 11 | contract NetflixNFTFarm is Ownable { 12 | 13 | struct UserInfo { 14 | // current staked LP 15 | uint256 amount; 16 | // unix timestamp for last details update (when pointsDebt calculated) 17 | uint256 lastUpdateAt; 18 | // total points collected before latest deposit 19 | uint256 pointsDebt; 20 | } 21 | 22 | struct NFTInfo { 23 | address contractAddress; 24 | // NFT id 25 | uint256 id; 26 | // NFTs remaining to farm 27 | uint256 remaining; 28 | // points required to claim NFT 29 | uint256 price; 30 | } 31 | 32 | // safe math 33 | using SafeMath for uint256; 34 | // BEP20 token 35 | using SafeBEP20 for IBEP20; 36 | // points generated per LP token per second staked 37 | uint256 public emissionRate; 38 | // staked token 39 | IBEP20 lpToken; 40 | // list of NFTInfo 41 | NFTInfo[] public nftInfo; 42 | // mapping address based on UserInfo 43 | mapping(address => UserInfo) public userInfo; 44 | 45 | // constructor 46 | constructor(uint256 _emissionRate, IBEP20 _lpToken) public { 47 | emissionRate = _emissionRate; 48 | lpToken = _lpToken; 49 | } 50 | 51 | // addNFT 52 | function addNFT( 53 | address contractAddress, // Only ERC-1155 NFT Supported! 54 | uint256 id, 55 | uint256 total, 56 | uint256 price 57 | ) external onlyOwner { 58 | IERC1155(contractAddress).safeTransferFrom( 59 | msg.sender, 60 | address(this), 61 | id, 62 | total, 63 | "" 64 | ); 65 | nftInfo.push(NFTInfo({ 66 | contractAddress : contractAddress, 67 | id : id, 68 | remaining : total, 69 | price : price 70 | })); 71 | } 72 | 73 | // deposit 74 | function deposit(uint256 _amount) external { 75 | lpToken.safeTransferFrom( 76 | msg.sender, 77 | address(this), 78 | _amount 79 | ); 80 | // get UserInfo based on address 81 | UserInfo storage user = userInfo[msg.sender]; 82 | 83 | if (user.amount != 0) { 84 | user.pointsDebt = pointsBalance(msg.sender); 85 | } 86 | user.amount = user.amount.add(_amount); 87 | user.lastUpdateAt = now; 88 | } 89 | 90 | // get reward nft token 91 | function getReward(uint256 _nftIndex, uint256 _quantity) public { 92 | NFTInfo storage nft = nftInfo[_nftIndex]; 93 | require(nft.remaining > 0, "All NFTs farmed"); 94 | require(pointsBalance(msg.sender) >= nft.price.mul(_quantity), "Insufficient Points"); 95 | UserInfo storage user = userInfo[msg.sender]; 96 | 97 | // deduct points 98 | user.pointsDebt = pointsBalance(msg.sender).sub(nft.price.mul(_quantity)); 99 | user.lastUpdateAt = now; 100 | 101 | // transfer NFT token 102 | IERC1155(nft.contractAddress).safeTransferFrom( 103 | address(this), 104 | msg.sender, 105 | nft.id, 106 | _quantity, 107 | "" 108 | ); 109 | 110 | nft.remaining = nft.remaining.sub(_quantity); 111 | } 112 | 113 | // get multiple reward nft token 114 | function getMultipleReward(uint256[] calldata _nftIndex, uint256[] calldata _quantity) external { 115 | require(_nftIndex.length == _quantity.length, "Incorrect array length"); 116 | for (uint64 i = 0; i < _nftIndex.length; i++) { 117 | claim(_nftIndex[i], _quantity[i]); 118 | } 119 | } 120 | 121 | // withdraw 122 | function withdraw(uint256 _amount) public { 123 | UserInfo storage user = userInfo[msg.sender]; 124 | require(user.amount >= _amount, "Insufficient staked"); 125 | 126 | // update userInfo 127 | user.pointsDebt = pointsBalance(msg.sender); 128 | user.amount = user.amount.sub(_amount); 129 | user.lastUpdateAt = now; 130 | 131 | lpToken.safeTransfer( 132 | msg.sender, 133 | _amount 134 | ); 135 | } 136 | 137 | // withdraw all LP tokens 138 | function exit() external { 139 | withdraw(userInfo[msg.sender].amount); 140 | } 141 | 142 | // get points balance based on address 143 | function pointsBalance(address userAddress) public view returns (uint256) { 144 | UserInfo memory user = userInfo[userAddress]; 145 | return user.pointsDebt.add(_unDebitedPoints(user)); 146 | } 147 | 148 | function _unDebitedPoints(UserInfo memory user) internal view returns (uint256) { 149 | return now.sub(user.lastUpdateAt).mul(emissionRate).mul(user.amount); 150 | } 151 | 152 | function nftCount() public view returns (uint256) { 153 | return nftInfo.length; 154 | } 155 | 156 | // required function to allow receiving ERC-1155 157 | function onERC1155Received( 158 | address operator, 159 | address from, 160 | uint256 id, 161 | uint256 value, 162 | bytes calldata data 163 | ) 164 | external 165 | returns (bytes4) 166 | { 167 | return bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)")); 168 | } 169 | } -------------------------------------------------------------------------------- /static/css/isotop.css: -------------------------------------------------------------------------------- 1 | /* Start: Recommended Isotope styles */ 2 | 3 | /**** Isotope Filtering ****/ 4 | 5 | .isotope-item { 6 | z-index: 2; 7 | } 8 | 9 | .isotope-hidden.isotope-item { 10 | pointer-events: none; 11 | z-index: 1; 12 | } 13 | 14 | /**** Isotope CSS3 transitions ****/ 15 | 16 | .isotope, 17 | .isotope .isotope-item { 18 | -webkit-transition-duration: 0.8s; 19 | -moz-transition-duration: 0.8s; 20 | -ms-transition-duration: 0.8s; 21 | -o-transition-duration: 0.8s; 22 | transition-duration: 0.8s; 23 | } 24 | 25 | .isotope { 26 | -webkit-transition-property: height, width; 27 | -moz-transition-property: height, width; 28 | -ms-transition-property: height, width; 29 | -o-transition-property: height, width; 30 | transition-property: height, width; 31 | } 32 | 33 | .isotope .isotope-item { 34 | -webkit-transition-property: -webkit-transform, opacity; 35 | -moz-transition-property: -moz-transform, opacity; 36 | -ms-transition-property: -ms-transform, opacity; 37 | -o-transition-property: -o-transform, opacity; 38 | transition-property: transform, opacity; 39 | } 40 | 41 | /**** disabling Isotope CSS3 transitions ****/ 42 | 43 | .isotope.no-transition, 44 | .isotope.no-transition .isotope-item, 45 | .isotope .isotope-item.no-transition { 46 | -webkit-transition-duration: 0s; 47 | -moz-transition-duration: 0s; 48 | -ms-transition-duration: 0s; 49 | -o-transition-duration: 0s; 50 | transition-duration: 0s; 51 | } 52 | 53 | /* End: Recommended Isotope styles */ 54 | 55 | 56 | 57 | /* disable CSS transitions for containers with infinite scrolling*/ 58 | .isotope.infinite-scrolling { 59 | -webkit-transition: none; 60 | -moz-transition: none; 61 | -ms-transition: none; 62 | -o-transition: none; 63 | transition: none; 64 | } 65 | 66 | 67 | 68 | /**** Isotope styles ****/ 69 | 70 | /* required for containers to inherit vertical size from window */ 71 | /*html, 72 | body { 73 | height: 100%; 74 | } 75 | */ 76 | #container { 77 | padding: 20px 0px; 78 | } 79 | 80 | .height-01{ 81 | height: 250px; 82 | width: 28%; 83 | } 84 | .height-02,{ 85 | height: 250px; 86 | width: 25%; 87 | } 88 | .height-03{ 89 | width: 180px; 90 | height: 180px; 91 | } 92 | .element { 93 | margin: 1px; 94 | float: left; 95 | overflow: hidden; 96 | position: relative; 97 | color: #222; 98 | } 99 | 100 | /*.element.web { background: #F00 url("../images/zoom.png") no-repeat center center; 101 | background: hsl( 0, 100%, 50%) url("../images/zoom.png") no-repeat center center; } 102 | .element.branding { background: #F80 url("../images/zoom.png") no-repeat center center; background: hsl( 36, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 103 | .element.print { background: #0F0 url("../images/zoom.png") no-repeat center center; background: hsl( 108, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 104 | .element.creative { background: #0FF url("../images/zoom.png") no-repeat center center; background: hsl( 180, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 105 | .element.modern { background: #08F url("../images/zoom.png") no-repeat center center; background: hsl( 216, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 106 | .element.other { background: #00F url("../images/zoom.png") no-repeat center center;; background: hsl( 252, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 107 | .element.ecommerce { background: #F0F url("../images/zoom.png") no-repeat center center;background: hsl( 288, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 108 | .element.digital { background: #F08 url("../images/zoom.png") no-repeat center center; background: hsl( 324, 100%, 50%) url("../images/zoom.png") no-repeat center center;} 109 | 110 | */ 111 | .element * { 112 | position: absolute; 113 | margin: 0; 114 | } 115 | 116 | .element .symbol { 117 | left: 0.2em; 118 | top: 0.4em; 119 | font-size: 3.8em; 120 | line-height: 1.0em; 121 | color: #FFF; 122 | } 123 | .element.large .symbol { 124 | font-size: 4.5em; 125 | } 126 | 127 | .element.fake .symbol { 128 | color: #000; 129 | } 130 | 131 | .element .name { 132 | left: 0.5em; 133 | bottom: 1.6em; 134 | font-size: 1.05em; 135 | } 136 | 137 | .element .weight { 138 | font-size: 0.9em; 139 | left: 0.5em; 140 | bottom: 0.5em; 141 | } 142 | 143 | .element .number { 144 | font-size: 1.25em; 145 | font-weight: bold; 146 | color: hsla(0,0%,0%,.5); 147 | right: 0.5em; 148 | top: 0.5em; 149 | } 150 | 151 | .variable-sizes .element.width2 { width: 230px; } 152 | 153 | .variable-sizes .element.height2 { height: 230px; } 154 | 155 | .variable-sizes .element.width2.height2 { 156 | font-size: 2.0em; 157 | } 158 | 159 | .element.large, 160 | .variable-sizes .element.large, 161 | .variable-sizes .element.large.width2.height2 { 162 | font-size: 3.0em; 163 | width: 350px; 164 | height: 350px; 165 | z-index: 100; 166 | } 167 | 168 | .clickable .element:hover { 169 | cursor: pointer; 170 | } 171 | 172 | .clickable .element:hover h3 { 173 | text-shadow: 174 | 0 0 10px white, 175 | 0 0 10px white 176 | ; 177 | } 178 | 179 | .clickable .element:hover h2 { 180 | color: white; 181 | } 182 | 183 | /**** Filters ****/ 184 | 185 | #filters{ 186 | margin: 5px 0px; 187 | padding: 0px; 188 | list-style: none; 189 | } 190 | 191 | #filters li { 192 | display: inline-block; 193 | margin-right: -1px; 194 | } 195 | -------------------------------------------------------------------------------- /static/css/responsive.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["..\\sass\\responsive.scss"],"names":[],"mappings":"AAAA;;6BAE6B;AAC7B;EAGG;IAEM,gBAAe;IACf,gBAAe,EACjB;EAIJ;IACG,gBAAe,EACjB;EAED;IAOM,kBAAiB,EAKnB;IAZJ;MAGS,aAAY;MACZ,cAAa,EACf;IALP;MAUS,gBAAe,EACjB;EAIP;IACG,qBAAoB,EACtB;EAGD;IACG,aAAY;IACZ,cAAa,EACf;EAED;IAEM,gBAAe,EACjB;EAIJ;IACG,cAAa,EACf;EAED;IACG,kBAAiB,EACnB;EAED;IACG,aAAY;IACZ,cAAa,EAEf;EAGD;IACG,aAAY;IACZ,cAAa,EAMf;IARD;MAKM,gBAAe;MACf,oBAAmB,EACrB;EAIJ;IACG,gBAAe,EACjB;EAGD;IACG,gBAAe;IACf,kBAAiB,EACnB;EAED;IACG,gBAAe,EACjB;EAGD;IACG,gBAAe,EACjB,EAAA;;AAIJ;;6BAE6B;AAE7B;EAEG;IACG,eAAc,EAChB;EAGD;IACG,oBAAmB,EACrB;EAED;IACG,8BAA6B,EAC/B;EAGD;;IAEG,gBAAe,EACjB;EAGD;IACG,uBAAsB,EACxB;EAED;IACG,aAAY;IACZ,gBAAe,EACjB;EAED;IACG,YAAW;IACX,aAAY,EACd;EAED;IAEM,oBAAmB;IACnB,YAAW;IACX,sBAAqB,EACvB;EALJ;IAUY,6BAA4B,EAM9B;IAhBV;MAae,aAAY;MACZ,kBAAiB,EACnB;EAfb;IAmBY,wBAAuB;IACvB,yBAAgB;IAAhB,iBAAgB,EAClB;EAKV;IACG,gBAAe,EACjB;EAED;IAEM,oBAAmB;IACnB,YAAW,EACb;EAJJ;IAOM,iBAAgB;IAChB,gBAAe,EAWjB;IAnBJ;MAckB,uBAAsB,EACxB;EAOhB;IACG,gBAAe,EACjB;EAED;IACG,gBAAe,EAKjB;IAND;MAIM,eAAc,EAChB;EAIJ;IACG,cAAa,EACf;EAED;IACG,kBAAiB,EAQnB;IATD;MAKS,gBAAe;MACf,kBAAiB,EACnB;EAKP;IAGS,gBAAe,EACjB;EAJP;IASM,YAAW;IACX,aAAY,EAQd;IAlBJ;MAaS,gBAAe;MACf,SAAQ;MACR,SAAQ;MACR,aAAY,EACd;EAKP,yBAAyB;EACzB;IAIY,oBAAmB,EACrB;EALV;IAUM,cAAa,EACf;EAIJ;IACG,UAAS;IACT,oBAAmB,EAKrB;IAPD;MAKM,iBAAgB,EAClB;EAIJ;IAGS,mBAAkB,EACpB;EAIP;IACG,iBAAgB;IAChB,oBAAmB,EAKrB;IAPD;MAKM,gBAAe,EACjB;EAIJ;IACG,iBAAgB,EAClB;EAGD;IACG,kBAAiB;IACjB,aAAY;IACZ,cAAa,EACf;EAED;IACG,qBAAoB,EACtB;EAED;;IAEG,oBAAmB,EACrB;EAED;IACG,kBAAiB,EACnB;EAGD;IACG,oBAAmB,EACrB;EAED;IACG,qBAAoB,EAKtB;IAND;MAIM,oBAAmB,EACrB;EAIJ;IACG,qBAAoB,EACtB;EAED;IACG,oBAAmB,EACrB;EAGD;IAEM,iBAAgB;IAChB,kBAAiB,EAgCnB;IAnCJ;MAOY,mBAAkB;MAClB,gBAAe;MACf,aAAY;MACZ,cAAa;MACb,cAAa,EACf;IAZV;MAiBY,QAAO;MACP,OAAM,EACR;IAnBV;MAwBY,QAAO;MACP,OAAM,EACR;IA1BV;MA+BY,QAAO;MACP,OAAM,EACR;EAMV;IACG,iBAAgB,EAClB;EAGD;IACG,qBAAoB,EACtB;EAED;;IAEG,oBAAmB,EACrB;EAGD;IACG,cAAa,EACf;EAGD;IACG,qBAAoB,EACtB;EAED;IACG,oBAAmB,EACrB;EAED;IACG,qBAAoB,EACtB;EAED;IACG,aAAY,EACd;EAED;IACG,oBAAmB,EACrB;EAGD;IACG,mBAAkB,EACpB;EAGD;IAGS,cAAa,EACf;EAIP,iBAAiB;EACjB;IACG,oBAAmB,EACrB;EAED;IAEM,YAAW,EACb;EAKJ;IACG,gBAAe,EAMjB;IAPD;MAIM,gBAAe,EAEjB;EAIJ;IACG,gBAAe;IACf,kBAAiB,EACnB;EAGD;IACG,8BAA6B;IAC7B,iBAAgB;IAChB,uBAAsB,EACxB;EAED;IACG,iBAAgB,EAClB;EAGD;IACG,oBAAmB,EACrB;EAED;IAKG,oBAAmB,EACrB;IAND;MAEM,YAAW,EACb;EAKJ;IACG,oBAAmB,EACrB;EAED;IAEM,oBAAmB,EACrB;EAIJ;;IAEG,YAAW;IACX,uBAAsB;IACtB,cAAa,EACf;EAGD;IACG,gBAAe,EACjB;EAGD;IAEM,gBAAe,EACjB;EAIJ;IAEM,UAAS,EACX;EAHJ;IAMM,YAAW,EACb;EAIJ;;;IAKM,8BAA6B,EAC/B;EANJ;IASM,iBAAgB,EAClB;EAIJ;IACG,kBAAiB;IACjB,gBAAe;IACf,eAAc;IACd,uBAAsB;IACtB,uBAAsB;IACtB,aAAY;IACZ,UAAQ,EACX;EAEA;IACG,iBAAgB;IAChB,YAAW,EACb,EAAA;;AAIJ;;6BAE6B;AAC7B;EAEG;IACG,eAAc,EAChB;EAED;IACG,oBAAmB,EACrB;EAED;IACG,gBAAe,EACjB;EAED;IACG,kBAAiB,EACnB;EAED;IACG,8BAA6B,EAC/B;EAED;IACG,uBAAsB,EACxB;EAED;IACG,gBAAe,EACjB;EAED;IAEM,oBAAmB;IACnB,YAAW;IACX,sBAAqB,EACvB;EALJ;IAUY,6BAA4B,EAM9B;IAhBV;MAae,aAAY;MACZ,kBAAiB,EACnB;EAfb;IAmBY,yBAAgB;IAAhB,iBAAgB,EAClB;EApBV;IA+BkB,YAAW;IACX,iBAAgB,EAKlB;IArChB;MAkCqB,aAAY;MACZ,kBAAiB,EACnB;EASnB;IACG,gBAAe,EACjB;EAED;IACG,gBAAe,EACjB;EAED;IACG,aAAY;IACZ,gBAAe,EACjB;EAED;IACG,YAAW;IACX,aAAY,EACd;EAED;IAEM,iBAAgB,EAClB;EAGJ;IAEM,oBAAmB;IACnB,YAAW,EACb;EAJJ;IAOM,iBAAgB;IAChB,gBAAe,EACjB;EATJ;IAYM,wBAAuB;IACvB,oCAA2B;IAA3B,4BAA2B;IAC3B,mBAAkB,EAOpB;IArBJ;MAkBY,uBAAsB,EACxB;EAKV;IACG,gBAAe,EAKjB;IAND;MAIM,eAAc,EAChB;EAMJ;IACG,cAAa,EACf;EAED;IACG,kBAAiB,EAmCnB;IApCD;MAIM,uBAAsB,EA+BxB;MAnCJ;QAOS,gBAAe,EACjB;MARP;QAWS,gBAAe;QACf,gBAAe;QACf,oBAAmB;QACnB,kBAAiB,EACnB;MAfP;QAkBS,oBAAmB,EAKrB;QAvBP;UAqBY,oBAAmB,EACrB;MAtBV;QA2BY,oBAAmB;QACnB,mBAAkB,EAKpB;QAjCV;UA+Be,eAAc,EAChB;EAMb;IAIY,gBAAe;IACf,iBAAgB,EAClB;EAGN;IAIW,oBAAmB,EACrB;EALT;IASW,YAAW;IACX,cAAa,EACf;EAKb;IAGS,gBAAe;IACf,iBAAgB,EAClB;EAKP;IAEM,kBAAiB,EAmBnB;IArBJ;MAKS,aAAY;MACZ,cAAa,EACf;IAPP;MAUS,gBAAe,EAMjB;MAhBP;QAaY,gBAAe;QACf,kBAAiB,EACnB;IAfV;MAmBS,oBAAmB,EACrB;EAOP;IAEM,kBAAiB,EAWnB;IAbJ;MAMY,WAAU,EACZ;IAPV;MAUY,oBAAmB,EACrB;EAXV;IAgBM,cAAa,EACf;EAIJ;IAEM,qBAAoB,EAqBtB;IAvBJ;MAKS,WAAU;MACV,kBAAiB,EAgBnB;MAtBP;QASY,gBAAe,EACjB;MAVV;QAaY,aAAY,EAEd;MAfV;QAmBe,cAAa,EACf;EAOb;IAEM,UAAS;IACT,oBAAmB,EAKrB;IARJ;MAMS,qBAAoB,EACtB;EAKP;IAGS,mBAAkB,EACpB;EAIP;IACG,iBAAgB;IAChB,oBAAmB,EAKrB;IAPD;MAKM,gBAAe,EACjB;EAKJ;IACG,gBAAe,EAYjB;IAbD;MAIM,oBAAmB,EACrB;IALJ;MAQM,YAAW;MACX,aAAY;MACZ,eAAc;MACd,iBAAgB,EAClB;EAGJ;IACG,oBAAmB,EACrB;EAED;IAGS,iBAAgB,EAClB;EAIP;IACG,gBAAe,EACjB;EAED;IACG,kBAAiB,EACnB;EAGD;IACG,mBAAkB;IAClB,qBAAoB,EAMtB;IARD;MAKM,uBAAsB,EAExB;EAGJ;IACG,qBAAoB,EACtB;EAED;IACG,oBAAmB,EASrB;IAVD;MAOS,YAAW,EACb;EAKP;IACG,qBAAoB,EACtB;EAED;IACG,iBAAgB;IAChB,mBAAkB;IAClB,oBAAmB,EAMrB;IATD;MAMM,aAAY;MACZ,SAAQ,EACV;EAIJ;IACG,iBAAgB,EAClB;EAED;IACG,qBAAoB,EAOtB;IARD;MAKS,0DAAiD;MAAjD,kDAAiD,EACnD;EAKP;IACG,UAAS;IACT,kBAAiB,EACnB;EAED;IACG,gBAAe,EACjB;EAGD;;;IAGG,gBAAe,EACjB;EAED;IACG,qBAAoB,EACtB;EAED;;IAEG,oBAAmB;IACnB,gBAAe;IACf,kBAAiB,EACnB;EAED;;IAEG,oBAAmB,EACrB;EAGD;IACG,cAAa,EACf;EAED;IACG,kBAAiB,EAKnB;IAND;MAIM,mBAAkB,EACpB;EAIJ;IACG,iBAAgB;IAChB,oBAAmB,EA2CrB;IA7CD;MAKM,kBAAiB,EAuCnB;MA5CJ;QASY,aAAY;QACZ,cAAa;QACb,gBAAe,EAWjB;QAtBV;UAce,gBAAe;UACf,iBAAgB,EAClB;QAhBb;UAmBe,2BAA0B;UAC1B,gBAAe,EACjB;MArBb;QA0Be,UAAS,EACX;MA3Bb;QAgCe,WAAU,EACZ;MAjCb;QAsCe,UAAS;QACT,YAAW;QACX,YAAW,EACb;EAOb;IACG,6BAAsB;IAAtB,8BAAsB;IAAtB,2BAAsB;IAAtB,uBAAsB,EAgBxB;IAjBD;MAIM,oBAAc;MAAd,mBAAc;MAAd,eAAc;MACd,gBAAe;MACf,mBAAkB,EACpB;IAPJ;MAUM,6BAA4B;MAC5B,gCAA+B,EAKjC;MAhBJ;QAcS,cAAa,EACf;EAIP;IACG,iBAAgB,EAClB;EAGD;IACG,oBAAmB,EAWrB;IAZD;MAMY,sBAAqB;MACrB,mBAAkB;MAClB,cAAa,EACf;EAKV;IAKS,cAAa,EACf;EANP;IASS,cAAa;IACb,0BAAyB,EAC3B;EAXP;IAcS,4BAA2B;IAC3B,oBAAmB,EACrB;EAhBP;IAmBS,SAAQ,EACV;EAIP;IACG,qBAAoB,EAMtB;IAPD;MAIM,gBAAe;MACf,oBAAmB,EACrB;EAIJ;IAEM,iBAAgB,EAOlB;IATJ;MAKS,YAAW;MACX,cAAa;MACb,iBAAgB,EAClB;EAIP;IACG,mBAAkB,EACpB;EAED;IACG,gBAAe,EACjB;EAGD;IACG,sBAAqB,EACvB;EAED;IACG,iBAAgB,EAClB;EAED;;IAIM,mBAAkB,EACpB;EALJ;IAQM,8BAA6B,EAC/B;EAGJ;IAEM,gBAAe;IACf,gBAAe,EACjB;EAGJ;IACG,sBAAqB;IACrB,iBAAgB,EAClB;EAGD;IAEM,oBAAmB,EACrB;EAHJ;IAMM,kBAAiB;IACjB,oBAAmB,EACrB;EARJ;IAaY,gBAAe,EACjB;EAOV,gBAAgB;EAChB;IACG,qBAAoB,EACtB;EAED;IACG,4BAA2B;IAC3B,eAAc,EAChB;EAED;IACG,eAAc,EAChB;EAED,iBAAiB;EACjB;IACG,oBAAmB,EACrB;EAED,cAAc;EACd;IAGS,iBAAgB;IAChB,mBAAkB,EACpB;EAIP,eAAe;EACf;IAGS,aAAY;IACZ,cAAa,EACf;EAKP;IACG,kBAAiB,EACnB;EAED;IACG,gBAAe,EAMjB;IAPD;MAIM,gBAAe,EAEjB;EAIJ;IAGS,iBAAgB,EAClB;EAIP;IAGS,YAAW,EACb;EAJP;IAQM,UAAS,EACX;EAKJ;IAGS,aAAY;IACZ,kBAAiB;IACjB,6BAA4B,EAK9B;IAVP;MAQY,UAAS,EACX;EAKV;IACG,eAAc,EAChB;EAGD;IACG,cAAa,EASf;IAVD;MAMY,gBAAe,EACjB;EAKV;IAEM,iBAAgB,EAClB;EAIJ;IACG,oBAAmB,EACrB;EAED;IAKG,oBAAmB,EACrB;IAND;MAEM,YAAW,EACb;EAKJ;IACG,oBAAmB,EACrB;EAED;IACG,qBAAoB,EACtB;EAED;IAEM,iBAAgB,EAElB;EAIJ;IACG,gBAAe,EACjB;EAGD;IAEM,WAAU,EAKZ;IAPJ;MAKS,gBAAe,EACjB;EANP;IAUM,eAAc,EAChB;EAXJ;IAeS,WAAU,EACZ;EAhBP;IAoBM,YAAW,EAKb;IAzBJ;MAuBS,oBAAmB,EACrB;EAxBP;IA4BM,uBAAsB;IACtB,YAAW;IACX,eAAc,EAChB;EAGJ;IACG,cAAa,EAWf;IAZD;MAIM,YAAW;MACX,aAAY;MACZ,mBAAkB,EACpB;IAPJ;MAUM,mBAAkB,EACpB;EAUJ;IACG,eAAc,EAChB;EAGD;IACG,gBAAe;IACf,gBAAe,EACjB;EAED;IACG,oBAAmB,EACrB;EAGD;IACG,kBAAiB;IACjB,gBAAe;IACf,eAAc;IACd,uBAAsB;IACtB,uBAAsB;IACtB,aAAY;IACZ,UAAQ,EACX;EAEA;IACG,iBAAgB;IAChB,YAAW,EACb,EAAA"} -------------------------------------------------------------------------------- /contract/pool/NetflixSwapBEP721.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | import './interfaces/INetflixSwapBEP721.sol'; 4 | import "../netflix-libs/math/SafeMath.sol"; 5 | 6 | contract NetflixSwapBEP721 is INetflixSwapBEP721 { 7 | using SafeMath for uint256; 8 | 9 | string public constant name = 'Netflix LPs'; 10 | string public constant symbol = 'NLP'; 11 | uint256 public totalSupply; 12 | // Mapping from token ID to owner address 13 | mapping(uint256 => address) private _owners; 14 | 15 | // Mapping owner address to token count 16 | mapping(address => uint256) private _balances; 17 | 18 | // Mapping from token ID to approved address 19 | mapping(uint256 => address) private _tokenApprovals; 20 | 21 | bytes32 public DOMAIN_SEPARATOR; 22 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 23 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 24 | mapping(address => uint256) public nonces; 25 | 26 | event Approval(address indexed owner, address indexed spender, uint256 indexed tokenId); 27 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 28 | 29 | constructor() public { 30 | uint256 chainId; 31 | assembly { 32 | chainId := chainid 33 | } 34 | DOMAIN_SEPARATOR = keccak256( 35 | abi.encode( 36 | keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), 37 | keccak256(bytes(name)), 38 | keccak256(bytes('1')), 39 | chainId, 40 | address(this) 41 | ) 42 | ); 43 | } 44 | 45 | function _mint(address to, uint256 tokenId) internal { 46 | 47 | require(to != address(0), "ERC721: mint to the zero address"); 48 | require(!_exists(tokenId), "ERC721: token already minted"); 49 | 50 | _beforeTokenTransfer(address(0), to, tokenId); 51 | 52 | _balances[to] += 1; 53 | _owners[tokenId] = to; 54 | 55 | emit Transfer(address(0), to, tokenId); 56 | } 57 | 58 | /** 59 | * @dev Returns whether `tokenId` exists. 60 | * 61 | * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. 62 | * 63 | * Tokens start existing when they are minted (`_mint`), 64 | * and stop existing when they are burned (`_burn`). 65 | */ 66 | function _exists(uint256 tokenId) internal view virtual returns (bool) { 67 | return _owners[tokenId] != address(0); 68 | } 69 | 70 | 71 | function _burn(address from, uint256 tokenId) internal { 72 | address owner = ERC721.ownerOf(tokenId); 73 | 74 | _beforeTokenTransfer(owner, address(0), tokenId); 75 | 76 | // Clear approvals 77 | _approve(address(0), tokenId); 78 | 79 | _balances[owner] -= 1; 80 | delete _owners[tokenId]; 81 | 82 | emit Transfer(owner, address(0), tokenId); 83 | } 84 | 85 | /** 86 | * @dev Approve `to` to operate on `tokenId` 87 | * 88 | * Emits a {Approval} event. 89 | */ 90 | function _approve(address to, uint256 tokenId) internal virtual { 91 | _tokenApprovals[tokenId] = to; 92 | emit Approval(ERC721.ownerOf(tokenId), to, tokenId); 93 | } 94 | 95 | /** 96 | * @dev Transfers `tokenId` from `from` to `to`. 97 | * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. 98 | * 99 | * Requirements: 100 | * 101 | * - `to` cannot be the zero address. 102 | * - `tokenId` token must be owned by `from`. 103 | * 104 | * Emits a {Transfer} event. 105 | */ 106 | function _transfer(address from, address to, uint256 tokenId) internal virtual { 107 | require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); 108 | require(to != address(0), "ERC721: transfer to the zero address"); 109 | 110 | _beforeTokenTransfer(from, to, tokenId); 111 | 112 | // Clear approvals from the previous owner 113 | _approve(address(0), tokenId); 114 | 115 | _balances[from] -= 1; 116 | _balances[to] += 1; 117 | _owners[tokenId] = to; 118 | 119 | emit Transfer(from, to, tokenId); 120 | } 121 | 122 | 123 | function approve(address spender, uint256 value) external returns (bool) { 124 | _approve(msg.sender, spender, value); 125 | return true; 126 | } 127 | 128 | function transfer(address to, uint256 value) external returns (bool) { 129 | _transfer(msg.sender, to, value); 130 | return true; 131 | } 132 | 133 | function transferFrom( 134 | address from, 135 | address to, 136 | uint256 tokenId 137 | ) external returns (bool) { 138 | require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); 139 | _transfer(from, to, tokenId); 140 | return true; 141 | } 142 | 143 | /** 144 | * @dev Returns whether `spender` is allowed to manage `tokenId`. 145 | * 146 | * Requirements: 147 | * 148 | * - `tokenId` must exist. 149 | */ 150 | function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { 151 | require(_exists(tokenId), "ERC721: operator query for nonexistent token"); 152 | address owner = ERC721.ownerOf(tokenId); 153 | return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); 154 | } 155 | 156 | function permit( 157 | address owner, 158 | address spender, 159 | uint256 value, 160 | uint256 deadline, 161 | uint8 v, 162 | bytes32 r, 163 | bytes32 s 164 | ) external { 165 | require(deadline >= block.timestamp, 'NetflixSwapBEP20: EXPIRED'); 166 | bytes32 digest = keccak256( 167 | abi.encodePacked( 168 | '\x19\x01', 169 | DOMAIN_SEPARATOR, 170 | keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) 171 | ) 172 | ); 173 | address recoveredAddress = ecrecover(digest, v, r, s); 174 | require(recoveredAddress != address(0) && recoveredAddress == owner, 'NetflixSwapBEP20: INVALID_SIGNATURE'); 175 | _approve(owner, spender, value); 176 | } 177 | 178 | /** 179 | * @dev Hook that is called before any token transfer. This includes minting 180 | * and burning. 181 | * 182 | * Calling conditions: 183 | * 184 | * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be 185 | * transferred to `to`. 186 | * - When `from` is zero, `tokenId` will be minted for `to`. 187 | * - When `to` is zero, ``from``'s `tokenId` will be burned. 188 | * - `from` cannot be the zero address. 189 | * - `to` cannot be the zero address. 190 | * 191 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 192 | */ 193 | function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual {} 194 | } -------------------------------------------------------------------------------- /contract/netflix-libs/math/SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | // CAUTION 6 | // This version of SafeMath should only be used with Solidity 0.8 or later, 7 | // because it relies on the compiler's built in overflow checks. 8 | 9 | /** 10 | * @dev Wrappers over Solidity's arithmetic operations. 11 | */ 12 | library SafeMath { 13 | /** 14 | * @dev Returns the addition of two unsigned integers, with an overflow flag. 15 | * 16 | * _Available since v3.4._ 17 | */ 18 | function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { 19 | unchecked { 20 | uint256 c = a + b; 21 | if (c < a) return (false, 0); 22 | return (true, c); 23 | } 24 | } 25 | 26 | /** 27 | * @dev Returns the substraction of two unsigned integers, with an overflow flag. 28 | * 29 | * _Available since v3.4._ 30 | */ 31 | function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { 32 | unchecked { 33 | if (b > a) return (false, 0); 34 | return (true, a - b); 35 | } 36 | } 37 | 38 | /** 39 | * @dev Returns the multiplication of two unsigned integers, with an overflow flag. 40 | * 41 | * _Available since v3.4._ 42 | */ 43 | function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { 44 | unchecked { 45 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 46 | // benefit is lost if 'b' is also tested. 47 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 48 | if (a == 0) return (true, 0); 49 | uint256 c = a * b; 50 | if (c / a != b) return (false, 0); 51 | return (true, c); 52 | } 53 | } 54 | 55 | /** 56 | * @dev Returns the division of two unsigned integers, with a division by zero flag. 57 | * 58 | * _Available since v3.4._ 59 | */ 60 | function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { 61 | unchecked { 62 | if (b == 0) return (false, 0); 63 | return (true, a / b); 64 | } 65 | } 66 | 67 | /** 68 | * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. 69 | * 70 | * _Available since v3.4._ 71 | */ 72 | function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { 73 | unchecked { 74 | if (b == 0) return (false, 0); 75 | return (true, a % b); 76 | } 77 | } 78 | 79 | /** 80 | * @dev Returns the addition of two unsigned integers, reverting on 81 | * overflow. 82 | * 83 | * Counterpart to Solidity's `+` operator. 84 | * 85 | * Requirements: 86 | * 87 | * - Addition cannot overflow. 88 | */ 89 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 90 | return a + b; 91 | } 92 | 93 | /** 94 | * @dev Returns the subtraction of two unsigned integers, reverting on 95 | * overflow (when the result is negative). 96 | * 97 | * Counterpart to Solidity's `-` operator. 98 | * 99 | * Requirements: 100 | * 101 | * - Subtraction cannot overflow. 102 | */ 103 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 104 | return a - b; 105 | } 106 | 107 | /** 108 | * @dev Returns the multiplication of two unsigned integers, reverting on 109 | * overflow. 110 | * 111 | * Counterpart to Solidity's `*` operator. 112 | * 113 | * Requirements: 114 | * 115 | * - Multiplication cannot overflow. 116 | */ 117 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 118 | return a * b; 119 | } 120 | 121 | /** 122 | * @dev Returns the integer division of two unsigned integers, reverting on 123 | * division by zero. The result is rounded towards zero. 124 | * 125 | * Counterpart to Solidity's `/` operator. 126 | * 127 | * Requirements: 128 | * 129 | * - The divisor cannot be zero. 130 | */ 131 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 132 | return a / b; 133 | } 134 | 135 | /** 136 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 137 | * reverting when dividing by zero. 138 | * 139 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 140 | * opcode (which leaves remaining gas untouched) while Solidity uses an 141 | * invalid opcode to revert (consuming all remaining gas). 142 | * 143 | * Requirements: 144 | * 145 | * - The divisor cannot be zero. 146 | */ 147 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 148 | return a % b; 149 | } 150 | 151 | /** 152 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 153 | * overflow (when the result is negative). 154 | * 155 | * CAUTION: This function is deprecated because it requires allocating memory for the error 156 | * message unnecessarily. For custom revert reasons use {trySub}. 157 | * 158 | * Counterpart to Solidity's `-` operator. 159 | * 160 | * Requirements: 161 | * 162 | * - Subtraction cannot overflow. 163 | */ 164 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 165 | unchecked { 166 | require(b <= a, errorMessage); 167 | return a - b; 168 | } 169 | } 170 | 171 | /** 172 | * @dev Returns the integer division of two unsigned integers, reverting with custom message on 173 | * division by zero. The result is rounded towards zero. 174 | * 175 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 176 | * opcode (which leaves remaining gas untouched) while Solidity uses an 177 | * invalid opcode to revert (consuming all remaining gas). 178 | * 179 | * Counterpart to Solidity's `/` operator. Note: this function uses a 180 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 181 | * uses an invalid opcode to revert (consuming all remaining gas). 182 | * 183 | * Requirements: 184 | * 185 | * - The divisor cannot be zero. 186 | */ 187 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 188 | unchecked { 189 | require(b > 0, errorMessage); 190 | return a / b; 191 | } 192 | } 193 | 194 | /** 195 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 196 | * reverting with custom message when dividing by zero. 197 | * 198 | * CAUTION: This function is deprecated because it requires allocating memory for the error 199 | * message unnecessarily. For custom revert reasons use {tryMod}. 200 | * 201 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 202 | * opcode (which leaves remaining gas untouched) while Solidity uses an 203 | * invalid opcode to revert (consuming all remaining gas). 204 | * 205 | * Requirements: 206 | * 207 | * - The divisor cannot be zero. 208 | */ 209 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 210 | unchecked { 211 | require(b > 0, errorMessage); 212 | return a % b; 213 | } 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /static/js/wow.min.js: -------------------------------------------------------------------------------- 1 | /*! WOW wow.js - v1.3.0 - 2016-10-04 2 | * https://wowjs.uk 3 | * Copyright (c) 2016 Thomas Grainger; Licensed MIT */!function(a,b){if("function"==typeof define&&define.amd)define(["module","exports"],b);else if("undefined"!=typeof exports)b(module,exports);else{var c={exports:{}};b(c,c.exports),a.WOW=c.exports}}(this,function(a,b){"use strict";function c(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function d(a,b){return b.indexOf(a)>=0}function e(a,b){for(var c in b)if(null==a[c]){var d=b[c];a[c]=d}return a}function f(a){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(a)}function g(a){var b=arguments.length<=1||void 0===arguments[1]?!1:arguments[1],c=arguments.length<=2||void 0===arguments[2]?!1:arguments[2],d=arguments.length<=3||void 0===arguments[3]?null:arguments[3],e=void 0;return null!=document.createEvent?(e=document.createEvent("CustomEvent"),e.initCustomEvent(a,b,c,d)):null!=document.createEventObject?(e=document.createEventObject(),e.eventType=a):e.eventName=a,e}function h(a,b){null!=a.dispatchEvent?a.dispatchEvent(b):b in(null!=a)?a[b]():"on"+b in(null!=a)&&a["on"+b]()}function i(a,b,c){null!=a.addEventListener?a.addEventListener(b,c,!1):null!=a.attachEvent?a.attachEvent("on"+b,c):a[b]=c}function j(a,b,c){null!=a.removeEventListener?a.removeEventListener(b,c,!1):null!=a.detachEvent?a.detachEvent("on"+b,c):delete a[b]}function k(){return"innerHeight"in window?window.innerHeight:document.documentElement.clientHeight}Object.defineProperty(b,"__esModule",{value:!0});var l,m,n=function(){function a(a,b){for(var c=0;c=0){var b=a.target||a.srcElement;b.className=b.className.replace(this.config.animateClass,"").trim()}}},{key:"customStyle",value:function(a,b,c,d,e){return b&&this.cacheAnimationName(a),a.style.visibility=b?"hidden":"visible",c&&this.vendorSet(a.style,{animationDuration:c}),d&&this.vendorSet(a.style,{animationDelay:d}),e&&this.vendorSet(a.style,{animationIterationCount:e}),this.vendorSet(a.style,{animationName:b?"none":this.cachedAnimationName(a)}),a}},{key:"vendorSet",value:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];a[""+c]=d;for(var e=0;e=e&&f>=c}},{key:"disabled",value:function(){return!this.config.mobile&&f(navigator.userAgent)}}]),a}();b["default"]=r,a.exports=b["default"]}); -------------------------------------------------------------------------------- /templates/detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% load static %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Hackathon 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 | 119 | 120 |
121 | 122 |
123 |
124 |
125 |

{{ address }}

126 |
127 |
128 | 129 | {# {% for item in items %}#} 130 | {#
#} 131 | {#
#} 132 | {#

item.fileId

#} 133 | {#
#} 134 | {#
#} 135 | {#

item.fileType

#} 136 | {#
#} 137 | {#
#} 138 | {#

view file

#} 139 | {#
#} 140 | {#
#} 141 | {# {% endfor %}#} 142 | 143 |
144 |
145 | 146 | 147 | 148 | 149 | 171 | 172 |
173 |
174 | 175 |
176 | 177 |
178 |
179 | 180 | 181 |
182 | 183 | 184 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /contract/netflix-libs/utils/Address.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | /** 6 | * @dev Collection of functions related to the address type 7 | */ 8 | library Address { 9 | /** 10 | * @dev Returns true if `account` is a contract. 11 | * 12 | * [IMPORTANT] 13 | * ==== 14 | * It is unsafe to assume that an address for which this function returns 15 | * false is an externally-owned account (EOA) and not a contract. 16 | * 17 | * Among others, `isContract` will return false for the following 18 | * types of addresses: 19 | * 20 | * - an externally-owned account 21 | * - a contract in construction 22 | * - an address where a contract will be created 23 | * - an address where a contract lived, but was destroyed 24 | * ==== 25 | */ 26 | function isContract(address account) internal view returns (bool) { 27 | // This method relies on extcodesize, which returns 0 for contracts in 28 | // construction, since the code is only stored at the end of the 29 | // constructor execution. 30 | 31 | uint256 size; 32 | // solhint-disable-next-line no-inline-assembly 33 | assembly { size := extcodesize(account) } 34 | return size > 0; 35 | } 36 | 37 | /** 38 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 39 | * `recipient`, forwarding all available gas and reverting on errors. 40 | * 41 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 42 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 43 | * imposed by `transfer`, making them unable to receive funds via 44 | * `transfer`. {sendValue} removes this limitation. 45 | * 46 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 47 | * 48 | * IMPORTANT: because control is transferred to `recipient`, care must be 49 | * taken to not create reentrancy vulnerabilities. Consider using 50 | * {ReentrancyGuard} or the 51 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 52 | */ 53 | function sendValue(address payable recipient, uint256 amount) internal { 54 | require(address(this).balance >= amount, "Address: insufficient balance"); 55 | 56 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 57 | (bool success, ) = recipient.call{ value: amount }(""); 58 | require(success, "Address: unable to send value, recipient may have reverted"); 59 | } 60 | 61 | /** 62 | * @dev Performs a Solidity function call using a low level `call`. A 63 | * plain`call` is an unsafe replacement for a function call: use this 64 | * function instead. 65 | * 66 | * If `target` reverts with a revert reason, it is bubbled up by this 67 | * function (like regular Solidity function calls). 68 | * 69 | * Returns the raw returned data. To convert to the expected return value, 70 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 71 | * 72 | * Requirements: 73 | * 74 | * - `target` must be a contract. 75 | * - calling `target` with `data` must not revert. 76 | * 77 | * _Available since v3.1._ 78 | */ 79 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 80 | return functionCall(target, data, "Address: low-level call failed"); 81 | } 82 | 83 | /** 84 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 85 | * `errorMessage` as a fallback revert reason when `target` reverts. 86 | * 87 | * _Available since v3.1._ 88 | */ 89 | function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 90 | return functionCallWithValue(target, data, 0, errorMessage); 91 | } 92 | 93 | /** 94 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 95 | * but also transferring `value` wei to `target`. 96 | * 97 | * Requirements: 98 | * 99 | * - the calling contract must have an ETH balance of at least `value`. 100 | * - the called Solidity function must be `payable`. 101 | * 102 | * _Available since v3.1._ 103 | */ 104 | function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { 105 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 106 | } 107 | 108 | /** 109 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 110 | * with `errorMessage` as a fallback revert reason when `target` reverts. 111 | * 112 | * _Available since v3.1._ 113 | */ 114 | function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { 115 | require(address(this).balance >= value, "Address: insufficient balance for call"); 116 | require(isContract(target), "Address: call to non-contract"); 117 | 118 | // solhint-disable-next-line avoid-low-level-calls 119 | (bool success, bytes memory returndata) = target.call{ value: value }(data); 120 | return _verifyCallResult(success, returndata, errorMessage); 121 | } 122 | 123 | /** 124 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 125 | * but performing a static call. 126 | * 127 | * _Available since v3.3._ 128 | */ 129 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 130 | return functionStaticCall(target, data, "Address: low-level static call failed"); 131 | } 132 | 133 | /** 134 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 135 | * but performing a static call. 136 | * 137 | * _Available since v3.3._ 138 | */ 139 | function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { 140 | require(isContract(target), "Address: static call to non-contract"); 141 | 142 | // solhint-disable-next-line avoid-low-level-calls 143 | (bool success, bytes memory returndata) = target.staticcall(data); 144 | return _verifyCallResult(success, returndata, errorMessage); 145 | } 146 | 147 | /** 148 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 149 | * but performing a delegate call. 150 | * 151 | * _Available since v3.4._ 152 | */ 153 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 154 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 155 | } 156 | 157 | /** 158 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 159 | * but performing a delegate call. 160 | * 161 | * _Available since v3.4._ 162 | */ 163 | function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 164 | require(isContract(target), "Address: delegate call to non-contract"); 165 | 166 | // solhint-disable-next-line avoid-low-level-calls 167 | (bool success, bytes memory returndata) = target.delegatecall(data); 168 | return _verifyCallResult(success, returndata, errorMessage); 169 | } 170 | 171 | function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { 172 | if (success) { 173 | return returndata; 174 | } else { 175 | // Look for revert reason and bubble it up if present 176 | if (returndata.length > 0) { 177 | // The easiest way to bubble the revert reason is using memory via assembly 178 | 179 | // solhint-disable-next-line no-inline-assembly 180 | assembly { 181 | let returndata_size := mload(returndata) 182 | revert(add(32, returndata), returndata_size) 183 | } 184 | } else { 185 | revert(errorMessage); 186 | } 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /static/css/style.css: -------------------------------------------------------------------------------- 1 | /* Table of Content 2 | ================================================== 3 | 1. Typography 4 | 2. Global Styles (body, link color, gap, ul, section-title, overlay etc) 5 | 3. Header area 6 | 4. Banner area 7 | 8 | 9 | */ 10 | 11 | @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;600;700;800&display=swap'); 12 | /* ============================== */ 13 | 14 | html { 15 | min-width: 100%; 16 | min-height: 100%; 17 | } 18 | 19 | body { 20 | align-items: center; 21 | justify-content: center; 22 | background: black; 23 | /* overflow: auto; */ 24 | } 25 | 26 | .banner_area { 27 | width: 20%; 28 | height: 100%; 29 | background: url(../images/nft.png); 30 | background-repeat: no-repeat; 31 | background-size: cover; 32 | } 33 | 34 | .select_area { 35 | width: 65%; 36 | margin-left: auto; 37 | margin-right: auto; 38 | padding: 40px 0; 39 | } 40 | .select_area_footer{ 41 | text-align: center; 42 | color: white; 43 | font-size: 13px; 44 | margin-top: 45px; 45 | } 46 | .download_file_type_title { 47 | color: white; 48 | font-size: 20px; 49 | font-weight: 600; 50 | margin-top: 20px; 51 | } 52 | 53 | .download_file_type_text { 54 | display: flex; 55 | } 56 | 57 | .download_file_type_text ul { 58 | list-style: none; 59 | padding: 0; 60 | width: 120px; 61 | } 62 | 63 | .download_file_type_text ul li { 64 | font-size: 15px; 65 | font-weight: 400; 66 | color: white; 67 | line-height: 30px; 68 | cursor: pointer; 69 | } 70 | .download_file_type_text ul li:hover{ 71 | color: red; 72 | } 73 | .download_file_type hr { 74 | margin-top: 0; 75 | margin-bottom: 0; 76 | border: 0; 77 | border-top: 4px solid #b81f25; 78 | width: 15px; 79 | position: absolute; 80 | } 81 | 82 | .nft_title { 83 | color: #b81f25; 84 | text-align: center; 85 | } 86 | 87 | .box { 88 | /* width: 70%; */ 89 | margin-left: auto; 90 | margin-right: auto; 91 | border-radius: 10px; 92 | text-align: center; 93 | font-weight: 800; 94 | padding: 10px 0; 95 | } 96 | 97 | .bar { 98 | background: #000000; 99 | height: 40px; 100 | padding: 6px; 101 | margin: 85px auto 20px; 102 | border-radius: 50px; 103 | overflow: hidden; 104 | border: 1px solid #b81f25; 105 | } 106 | 107 | .upload_text { 108 | position: absolute; 109 | left: 0; 110 | right: 0; 111 | color: white; 112 | font-size: 18px; 113 | font-weight: 600; 114 | } 115 | 116 | .fill { 117 | height: 100%; 118 | width: 0%; 119 | background: linear-gradient(to right, #000000, #b81f25); 120 | border-radius: 50px; 121 | } 122 | 123 | .timer { 124 | display: flex; 125 | justify-content: center; 126 | flex-direction: column; 127 | } 128 | 129 | button { 130 | font-size: 18px; 131 | font-weight: 500; 132 | width: 100%; 133 | align-self: center; 134 | justify-self: center; 135 | color: #fff; 136 | background: #b81f25; 137 | padding: 15px 10px; 138 | outline: none; 139 | border: 2px solid #b81f25; 140 | border-radius: 5px; 141 | cursor: pointer; 142 | } 143 | 144 | button:hover { 145 | background: white; 146 | color: #b81f25; 147 | } 148 | .close{ 149 | width: auto; 150 | } 151 | .modal-body{ 152 | text-align: center; 153 | justify-content: center; 154 | } 155 | .modal-dialog{ 156 | max-width: 900px !important; 157 | } 158 | .output { 159 | width: 100%; 160 | display: none; 161 | } 162 | .transactions{ 163 | align-items: center; 164 | vertical-align: middle; 165 | } 166 | .tx-hash-output{ 167 | border-radius: 6px; 168 | border: 1px solid #b81f25; 169 | text-align: start; 170 | margin-top: 5px; 171 | padding: 10px 10px; 172 | color: white; 173 | font-weight: 600; 174 | word-wrap: break-word; 175 | } 176 | .view_address{ 177 | border-radius: 6px; 178 | border: 1px solid #b81f25; 179 | text-align: start; 180 | margin-top: 5px; 181 | padding: 10px 10px; 182 | color: white; 183 | font-weight: 600; 184 | overflow: hidden; 185 | text-overflow: ellipsis; 186 | white-space: nowrap; 187 | } 188 | .tx-hash-output a:hover{ 189 | color: #b81f25; 190 | } 191 | .tx-hash { 192 | color: white; 193 | font-weight: 600; 194 | 195 | } 196 | .tokken-id-output{ 197 | border-radius: 6px; 198 | border: 1px solid #b81f25; 199 | text-align: start; 200 | padding: 10px 10px; 201 | height: 200px; 202 | overflow-y: scroll; 203 | overflow-x: hidden; 204 | margin-top: 20px; 205 | } 206 | p{ 207 | margin-bottom: 0 !important; 208 | } 209 | .Token_id{ 210 | margin-bottom: 15px; 211 | } 212 | .tokken_name{ 213 | color: #b81f25; 214 | font-size: 18px; 215 | } 216 | .tokken_hash_id{ 217 | word-wrap: break-word; 218 | color: white; 219 | font-size: 15px; 220 | } 221 | /* Scrollbar Styling */ 222 | ::-webkit-scrollbar { 223 | width: 10px; 224 | } 225 | 226 | ::-webkit-scrollbar-track { 227 | background: rgba(255, 255, 255, 0.1); 228 | -webkit-border-radius: 10px; 229 | border-radius: 10px; 230 | } 231 | 232 | ::-webkit-scrollbar-thumb { 233 | -webkit-border-radius: 10px; 234 | border-radius: 10px; 235 | background: #b81f25; 236 | } 237 | 238 | 239 | .count_area{ 240 | margin-top: 40px; 241 | position: absolute; 242 | left: 0; 243 | right: 0; 244 | color: white; 245 | text-align: center; 246 | margin-right: auto; 247 | margin-left: auto; 248 | display: nonef; 249 | } 250 | .counter { 251 | color: #d5161d; 252 | font-size: 18px; 253 | font-weight: 500; 254 | width: 60px; 255 | } 256 | 257 | .error_messeg { 258 | color: #d5161d; 259 | font-size: 18px; 260 | font-weight: 600; 261 | margin-top: 20px; 262 | } 263 | 264 | @keyframes animate {} 265 | 266 | .body_area { 267 | width: 80%; 268 | background-color: #000000; 269 | } 270 | 271 | .body_area_title { 272 | margin: 15px 0; 273 | color: white; 274 | font-size: 25px; 275 | font-weight: 700; 276 | text-align: center; 277 | } 278 | 279 | .finished_alert { 280 | color: #08A474; 281 | font-size: 18px; 282 | } 283 | 284 | .file_upload_place { 285 | background: rgba(255, 255, 255, 0.1); 286 | text-align: center; 287 | border: 2px solid white; 288 | border-radius: 5px; 289 | align-items: center; 290 | vertical-align: middle; 291 | justify-content: center; 292 | justify-items: center; 293 | padding: 100px; 294 | /* width: 70%; */ 295 | margin-left: auto; 296 | margin-right: auto; 297 | } 298 | .wallet_adress{ 299 | align-items: center; 300 | vertical-align: middle; 301 | justify-content: center; 302 | justify-items: center; 303 | background: rgba(255, 255, 255, 0.1); 304 | text-align: center; 305 | color: white; 306 | border-radius: 50px; 307 | padding: 8px; 308 | margin-top: 40px; 309 | } 310 | .wallet_adress_002{ 311 | align-items: center; 312 | vertical-align: middle; 313 | justify-content: center; 314 | justify-items: center; 315 | background: rgba(255, 255, 255, 0.1); 316 | text-align: center; 317 | color: white; 318 | border-radius: 50px; 319 | padding: 8px; 320 | margin-top: 20px; 321 | } 322 | .connect_wallet{ 323 | text-align: center; 324 | font-size: 15px; 325 | font-weight: 500; 326 | width: 10%; 327 | align-self: center; 328 | justify-self: center; 329 | color: #fff; 330 | background: #b81f25; 331 | padding: 8px 10px; 332 | outline: none; 333 | border: 2px solid #b81f25; 334 | border-radius: 5px; 335 | cursor: pointer; 336 | position: absolute; 337 | right: 0; 338 | margin-top: 40px; 339 | margin-right: 20px; 340 | } 341 | .copy_base64{ 342 | text-align: center; 343 | font-size: 15px; 344 | font-weight: 500; 345 | width: 100%; 346 | align-self: center; 347 | justify-self: center; 348 | color: #fff; 349 | background: #b81f25; 350 | padding: 8px 10px; 351 | outline: none; 352 | border: 2px solid #b81f25; 353 | border-radius: 5px; 354 | cursor: pointer; 355 | margin-top: 20px; 356 | } 357 | .connect_wallet_002{ 358 | text-align: center; 359 | font-size: 15px; 360 | font-weight: 500; 361 | width: 10%; 362 | align-self: center; 363 | justify-self: center; 364 | color: #fff; 365 | background: #b81f25; 366 | padding: 8px 10px; 367 | outline: none; 368 | border: 2px solid #b81f25; 369 | border-radius: 5px; 370 | cursor: pointer; 371 | position: absolute; 372 | right: 0; 373 | margin-top: 100px; 374 | margin-right: 20px; 375 | } 376 | .view_file_name{ 377 | align-items: center; 378 | vertical-align: middle; 379 | justify-content: center; 380 | justify-items: center; 381 | justify-self: center; 382 | background: rgba(255, 255, 255, 0.1); 383 | text-align: center; 384 | color: white; 385 | border-radius: 50px; 386 | padding: 8px; 387 | } 388 | .files{ 389 | margin-top: 10px; 390 | } 391 | .view_file{ 392 | text-align: center; 393 | font-size: 15px; 394 | font-weight: 500; 395 | width: 10%; 396 | align-self: center; 397 | justify-self: center; 398 | color: #fff; 399 | background: #b81f25; 400 | padding: 8px 10px; 401 | outline: none; 402 | border: 2px solid #b81f25; 403 | border-radius: 5px; 404 | cursor: pointer; 405 | } 406 | 407 | .connect_wallet:hover, .connect_wallet_002:hover, .copy_base64:hover { 408 | background: white; 409 | color: #b81f25; 410 | } 411 | 412 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% load static %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | NETFLIX NFT 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |
40 | 119 |
120 |
121 | Connect Wallet 122 |
123 | {# #} 124 | {#
#} 125 | {# My files#} 126 | {#
#} 127 | {#
#} 128 |
129 |
130 |
131 |

132 |
133 |
134 | Try converting the file to NFT format.
135 | You can meet a free world. 136 |
137 |
138 |
139 |
140 |
141 | 145 | 147 |
148 |
149 |
150 |

NFT transformation is complete. 151 |

152 |
153 | 154 |
155 |
Upload your files, and soon you'll have a free world!
156 |
157 |
158 |
159 | 160 |
161 | 162 |
163 |
164 |
165 |
166 |
Transaction Hash
167 |
168 |

169 |
170 |
171 |
172 |
173 |
Test For img
174 | 175 | 181 |
182 |
183 |
Test For video
184 | 185 | 191 |
192 | 193 | 194 |
195 | Copy Base64 196 |
197 |
198 | 199 |
200 |
201 |
202 | 203 |
204 |
205 | 206 |
207 | 208 |
209 | 210 | 211 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /static/js/centerprime.js: -------------------------------------------------------------------------------- 1 | var selectedFile; 2 | window.addEventListener('load', async () => { 3 | 4 | // Modern dapp browsers... 5 | if (window.ethereum) { 6 | initCrossAjax(); 7 | window.web3 = new Web3(ethereum); 8 | try { 9 | console.log("KKKKK") 10 | // Request account access if needed 11 | await ethereum.enable(); 12 | // Acccounts now exposed 13 | let accounts = await web3.eth.getAccounts(); 14 | if (accounts.length !== 0) { 15 | // update balances 16 | await updateUI(accounts[0]); 17 | // start account change listener 18 | checkAccountChange(); 19 | // // start metamask locked/unlocked listener 20 | // checkMetamaskUnlocked(); 21 | // check ethereum network 22 | checkEthereumNetwork(); 23 | } else { 24 | // Metamask is locked need to login again 25 | disconnectMetamask(); 26 | } 27 | } catch (error) { 28 | console.log(error); 29 | // User denied account access... 30 | } 31 | } 32 | // Legacy dapp browsers... 33 | else if (window.web3) { 34 | window.web3 = new Web3(web3.currentProvider); 35 | } 36 | // Non-dapp browsers... 37 | else { 38 | console.log('Non-Ethereum browser detected. You should consider trying MetaMask!'); 39 | } 40 | 41 | 42 | // file selector 43 | checkBrowserIsSupportFileSelect(); 44 | 45 | document.getElementById("keystoreFile").addEventListener("change", function () { 46 | var file = this.files[0]; 47 | selectedFile = file; 48 | if (file) { 49 | var reader = new FileReader(); 50 | reader.onload = function (evt) { 51 | console.log(evt); 52 | $('#selectedImg').attr('src', evt.target.result); 53 | }; 54 | reader.onerror = function (evt) { 55 | console.error("An error ocurred reading the file", evt); 56 | }; 57 | reader.readAsDataURL(file); 58 | 59 | var fileName = $('#keystoreFile').val(); 60 | console.log(fileName) 61 | 62 | console.log(file) 63 | 64 | $("#selectedFile").text(file.name); 65 | 66 | console.log(reader) 67 | var filename = $('input[type=file]').val().split('\\').pop(); 68 | console.log(filename); 69 | 70 | $('#fileName').text(filename); 71 | } 72 | }, false); 73 | 74 | 75 | }); 76 | 77 | 78 | function checkBrowserIsSupportFileSelect() { 79 | if (window.File && window.FileReader && window.FileList && window.Blob) { 80 | // Read files 81 | } else { 82 | alert('The File APIs are not fully supported by your browser.'); 83 | } 84 | } 85 | 86 | function initCrossAjax() { 87 | // This function gets cookie with a given name 88 | function getCookie(name) { 89 | var cookieValue = null; 90 | if (document.cookie && document.cookie != '') { 91 | var cookies = document.cookie.split(';'); 92 | for (var i = 0; i < cookies.length; i++) { 93 | var cookie = jQuery.trim(cookies[i]); 94 | // Does this cookie string begin with the name we want? 95 | if (cookie.substring(0, name.length + 1) == (name + '=')) { 96 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 97 | break; 98 | } 99 | } 100 | } 101 | return cookieValue; 102 | } 103 | 104 | var csrftoken = getCookie('csrftoken'); 105 | 106 | /* 107 | The functions below will create a header with csrftoken 108 | */ 109 | 110 | function csrfSafeMethod(method) { 111 | // these HTTP methods do not require CSRF protection 112 | return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 113 | } 114 | 115 | function sameOrigin(url) { 116 | // test that a given url is a same-origin URL 117 | // url could be relative or scheme relative or absolute 118 | var host = document.location.host; // host + port 119 | var protocol = document.location.protocol; 120 | var sr_origin = '//' + host; 121 | var origin = protocol + sr_origin; 122 | // Allow absolute or scheme relative URLs to same origin 123 | return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 124 | (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 125 | // or any other URL that isn't scheme relative or absolute i.e relative. 126 | !(/^(\/\/|http:|https:).*/.test(url)); 127 | } 128 | 129 | $.ajaxSetup({ 130 | beforeSend: function (xhr, settings) { 131 | if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { 132 | // Send the token to same-origin, relative URLs only. 133 | // Send the token only if the method warrants CSRF protection 134 | // Using the CSRFToken value acquired earlier 135 | xhr.setRequestHeader("X-CSRFToken", csrftoken); 136 | } 137 | } 138 | }); 139 | 140 | } 141 | 142 | function disconnectMetamask() { 143 | $("#connectBtnDiv").show(); 144 | $("#walletAddressDiv").hide(); 145 | window.location.href = '/'; 146 | } 147 | 148 | 149 | async function getAccount() { 150 | return web3.eth.getAccounts(); 151 | } 152 | 153 | async function checkAccountChange() { 154 | var account = await getAccount(); 155 | console.log("checkAccountChange is started") 156 | setInterval(async () => { 157 | var tempAccount = await getAccount(); 158 | if (tempAccount === undefined || tempAccount === null) { 159 | // if account changed to undefined, that means metamask is now locked 160 | disconnectMetamask() 161 | } 162 | if (tempAccount.toString().toUpperCase() !== account.toString().toUpperCase()) { 163 | account = await getAccount(); 164 | await updateUI(account[0]) 165 | } 166 | }, 1000); 167 | } 168 | 169 | async function updateUI(walletAddress) { 170 | if (walletAddress === undefined || walletAddress === null) { 171 | disconnectMetamask(); 172 | } 173 | // set wallet address 174 | $("#connectBtnDiv").hide(); 175 | $("#walletAddressDiv").show(); 176 | $("#walletAddress").text(walletAddress); 177 | $("#myfilesUrl").attr("href", "/myfiles/" + walletAddress) 178 | console.log(walletAddress) 179 | } 180 | 181 | async function checkEthereumNetwork() { 182 | if (web3) { 183 | console.log("network id : " + await web3.eth.net.getNetworkType()); 184 | switch (await web3.eth.net.getNetworkType()) { 185 | case 'main': 186 | console.log('This is mainnet'); 187 | break; 188 | default: 189 | console.log('This is an unknown network.'); 190 | } 191 | const desiredNetwork = 'ropsten'; 192 | if (await web3.eth.net.getNetworkType() !== desiredNetwork) { 193 | // ask user to switch to desired network 194 | // alert('Please switch to ropsten network.'); 195 | } 196 | } 197 | } 198 | 199 | 200 | upload_image = function (event) { 201 | if (selectedFile !== undefined) { 202 | var walletAddress = $('#walletAddress').text() 203 | var data = { 204 | 'wallet_address': walletAddress, 205 | }; 206 | var formData = new FormData(); 207 | formData.append('file', selectedFile); 208 | const data_ = JSON.stringify(data); 209 | formData.append('data', data_); 210 | $.ajax({ 211 | type: 'POST', 212 | cache: false, 213 | processData: false, 214 | contentType: false, 215 | url: '/api/v1/wallet/uploadImage/', 216 | data: formData, 217 | success: function (result) { 218 | console.log("Ssdff") 219 | if (result['status_code'] === 200) { 220 | console.log(result['data']) 221 | showNFTFiles(result['data']) 222 | } else { 223 | var message = result['message']; 224 | $('#errorMessage').text(message); 225 | } 226 | }, 227 | error: function (error) { 228 | console.log(error); 229 | } 230 | }); 231 | } else { 232 | console.log("Please select file") 233 | } 234 | return false 235 | } 236 | 237 | 238 | function showNFTFiles(nftFiles) { 239 | $("#nftContainer").empty(); 240 | let txHash = nftFiles['txHash'] 241 | let fullBase64 = nftFiles['fullBase64'] 242 | $("#copyTarget").val(fullBase64); 243 | let tokenIds = nftFiles['tokenIds'] 244 | let filePortions = nftFiles['filePortions'] 245 | let testnetUrl = 'https://testnet.bscscan.com/tx/' + txHash; 246 | $("#txHashA").attr("href", testnetUrl) 247 | $("#txHashP").text(testnetUrl) 248 | 249 | var jjs = '
' + 250 | '
' + 'Token ID : ' + 3 + '
\n' + 251 | +'
' + '

' + txHash + '

' + '
' + 252 | '
' 253 | for (var i = 0; i < tokenIds.length; i++) { 254 | var ht = '
' + 255 | '
' + 'Token ID : ' + tokenIds[i] + '
\n' + 256 | '
' + '

' + filePortions[i] + '

' + '
' + 257 | '
' 258 | $("#nftContainer").append(ht); 259 | } 260 | } 261 | 262 | function copyBase64() { 263 | var clipboardText = ""; 264 | clipboardText = $('#copyTarget').val(); 265 | console.log(clipboardText); 266 | copyToClipboard(clipboardText); 267 | alert("Copied to Clipboard"); 268 | } 269 | 270 | function copyToClipboard(text) { 271 | 272 | var textArea = document.createElement("textarea"); 273 | textArea.value = text; 274 | document.body.appendChild(textArea); 275 | textArea.select(); 276 | 277 | try { 278 | var successful = document.execCommand('copy'); 279 | var msg = successful ? 'successful' : 'unsuccessful'; 280 | console.log('Copying text command was ' + msg); 281 | } catch (err) { 282 | console.log('Oops, unable to copy', err); 283 | } 284 | document.body.removeChild(textArea); 285 | } -------------------------------------------------------------------------------- /static/css/magnific-popup.css: -------------------------------------------------------------------------------- 1 | :focus { 2 | outline: 0; 3 | } 4 | 5 | /* Magnific Popup CSS */ 6 | .mfp-bg { 7 | top: 0; 8 | left: 0; 9 | width: 100%; 10 | height: 100%; 11 | z-index: 1042; 12 | overflow: hidden; 13 | position: fixed; 14 | background: #0b0b0b; 15 | opacity: 0.8; } 16 | 17 | .mfp-wrap { 18 | top: 0; 19 | left: 0; 20 | width: 100%; 21 | height: 100%; 22 | z-index: 1043; 23 | position: fixed; 24 | outline: none !important; 25 | -webkit-backface-visibility: hidden; } 26 | 27 | .mfp-container { 28 | text-align: center; 29 | position: absolute; 30 | width: 100%; 31 | height: 100%; 32 | left: 0; 33 | top: 0; 34 | padding: 0 8px; 35 | box-sizing: border-box; } 36 | 37 | .mfp-container:before { 38 | content: ''; 39 | display: inline-block; 40 | height: 100%; 41 | vertical-align: middle; } 42 | 43 | .mfp-align-top .mfp-container:before { 44 | display: none; } 45 | 46 | .mfp-content { 47 | position: relative; 48 | display: inline-block; 49 | vertical-align: middle; 50 | margin: 0 auto; 51 | text-align: left; 52 | z-index: 1045; } 53 | 54 | .mfp-inline-holder .mfp-content, 55 | .mfp-ajax-holder .mfp-content { 56 | width: 100%; 57 | cursor: auto; } 58 | 59 | .mfp-ajax-cur { 60 | cursor: progress; } 61 | 62 | .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { 63 | cursor: -moz-zoom-out; 64 | cursor: -webkit-zoom-out; 65 | cursor: zoom-out; } 66 | 67 | .mfp-zoom { 68 | cursor: pointer; 69 | cursor: -webkit-zoom-in; 70 | cursor: -moz-zoom-in; 71 | cursor: zoom-in; } 72 | 73 | .mfp-auto-cursor .mfp-content { 74 | cursor: auto; } 75 | 76 | .mfp-close, 77 | .mfp-arrow, 78 | .mfp-preloader, 79 | .mfp-counter { 80 | -webkit-user-select: none; 81 | -moz-user-select: none; 82 | user-select: none; } 83 | 84 | .mfp-loading.mfp-figure { 85 | display: none; } 86 | 87 | .mfp-hide { 88 | display: none !important; } 89 | 90 | .mfp-preloader { 91 | color: #CCC; 92 | position: absolute; 93 | top: 50%; 94 | width: auto; 95 | text-align: center; 96 | margin-top: -0.8em; 97 | left: 8px; 98 | right: 8px; 99 | z-index: 1044; } 100 | .mfp-preloader a { 101 | color: #CCC; } 102 | .mfp-preloader a:hover { 103 | color: #FFF; } 104 | 105 | .mfp-s-ready .mfp-preloader { 106 | display: none; } 107 | 108 | .mfp-s-error .mfp-content { 109 | display: none; } 110 | 111 | button.mfp-close, 112 | button.mfp-arrow { 113 | overflow: visible; 114 | cursor: pointer; 115 | background: transparent; 116 | border: 0; 117 | -webkit-appearance: none; 118 | display: block; 119 | outline: none; 120 | padding: 0; 121 | z-index: 1046; 122 | box-shadow: none; 123 | touch-action: manipulation; } 124 | 125 | button::-moz-focus-inner { 126 | padding: 0; 127 | border: 0; } 128 | 129 | .mfp-close { 130 | width: 44px; 131 | height: 44px; 132 | line-height: 44px; 133 | position: absolute; 134 | right: 0; 135 | top: 0; 136 | text-decoration: none; 137 | text-align: center; 138 | opacity: 0.65; 139 | padding: 0 0 18px 10px; 140 | color: #FFF; 141 | font-style: normal; 142 | font-size: 28px; 143 | font-family: Arial, Baskerville, monospace; } 144 | .mfp-close:hover, 145 | .mfp-close:focus { 146 | opacity: 1; } 147 | .mfp-close:active { 148 | top: 1px; } 149 | 150 | .mfp-close-btn-in .mfp-close { 151 | color: #333; } 152 | 153 | .mfp-image-holder .mfp-close, 154 | .mfp-iframe-holder .mfp-close { 155 | color: #FFF; 156 | right: -6px; 157 | text-align: right; 158 | padding-right: 6px; 159 | width: 100%; } 160 | 161 | .mfp-counter { 162 | position: absolute; 163 | top: 0; 164 | right: 0; 165 | color: #CCC; 166 | font-size: 12px; 167 | line-height: 18px; 168 | white-space: nowrap; } 169 | 170 | .mfp-arrow { 171 | position: absolute; 172 | opacity: 0.65; 173 | margin: 0; 174 | top: 50%; 175 | margin-top: -55px; 176 | padding: 0; 177 | width: 90px; 178 | height: 110px; 179 | -webkit-tap-highlight-color: transparent; } 180 | .mfp-arrow:active { 181 | margin-top: -54px; } 182 | .mfp-arrow:hover, 183 | .mfp-arrow:focus { 184 | opacity: 1; } 185 | .mfp-arrow:before, 186 | .mfp-arrow:after { 187 | content: ''; 188 | display: block; 189 | width: 0; 190 | height: 0; 191 | position: absolute; 192 | left: 0; 193 | top: 0; 194 | margin-top: 35px; 195 | margin-left: 35px; 196 | border: medium inset transparent; } 197 | .mfp-arrow:after { 198 | border-top-width: 13px; 199 | border-bottom-width: 13px; 200 | top: 8px; } 201 | .mfp-arrow:before { 202 | border-top-width: 21px; 203 | border-bottom-width: 21px; 204 | opacity: 0.7; } 205 | 206 | .mfp-arrow-left { 207 | left: 0; } 208 | .mfp-arrow-left:after { 209 | border-right: 17px solid #FFF; 210 | margin-left: 31px; } 211 | .mfp-arrow-left:before { 212 | margin-left: 25px; 213 | border-right: 27px solid #3F3F3F; } 214 | 215 | .mfp-arrow-right { 216 | right: 0; } 217 | .mfp-arrow-right:after { 218 | border-left: 17px solid #FFF; 219 | margin-left: 39px; } 220 | .mfp-arrow-right:before { 221 | border-left: 27px solid #3F3F3F; } 222 | 223 | .mfp-iframe-holder { 224 | padding-top: 40px; 225 | padding-bottom: 40px; } 226 | .mfp-iframe-holder .mfp-content { 227 | line-height: 0; 228 | width: 100%; 229 | max-width: 900px; } 230 | .mfp-iframe-holder .mfp-close { 231 | top: -40px; } 232 | 233 | .mfp-iframe-scaler { 234 | width: 100%; 235 | height: 0; 236 | overflow: hidden; 237 | padding-top: 56.25%; } 238 | .mfp-iframe-scaler iframe { 239 | position: absolute; 240 | display: block; 241 | top: 0; 242 | left: 0; 243 | width: 100%; 244 | height: 100%; 245 | box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); 246 | background: #000; } 247 | 248 | /* Main image in popup */ 249 | img.mfp-img { 250 | width: auto; 251 | max-width: 100%; 252 | height: auto; 253 | display: block; 254 | line-height: 0; 255 | box-sizing: border-box; 256 | padding: 40px 0 40px; 257 | margin: 0 auto; } 258 | 259 | /* The shadow behind the image */ 260 | .mfp-figure { 261 | line-height: 0; } 262 | .mfp-figure:after { 263 | content: ''; 264 | position: absolute; 265 | left: 0; 266 | top: 40px; 267 | bottom: 40px; 268 | display: block; 269 | right: 0; 270 | width: auto; 271 | height: auto; 272 | z-index: -1; 273 | box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); 274 | background: #444; } 275 | .mfp-figure small { 276 | color: #BDBDBD; 277 | display: block; 278 | font-size: 12px; 279 | line-height: 14px; } 280 | .mfp-figure figure { 281 | margin: 0; } 282 | 283 | .mfp-bottom-bar { 284 | margin-top: -36px; 285 | position: absolute; 286 | top: 100%; 287 | left: 0; 288 | width: 100%; 289 | cursor: auto; } 290 | 291 | .mfp-title { 292 | text-align: left; 293 | line-height: 18px; 294 | color: #F3F3F3; 295 | word-wrap: break-word; 296 | padding-right: 36px; } 297 | 298 | .mfp-image-holder .mfp-content { 299 | max-width: 100%; } 300 | 301 | .mfp-gallery .mfp-image-holder .mfp-figure { 302 | cursor: pointer; } 303 | 304 | @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { 305 | /** 306 | * Remove all paddings around the image on small screen 307 | */ 308 | .mfp-img-mobile .mfp-image-holder { 309 | padding-left: 0; 310 | padding-right: 0; } 311 | .mfp-img-mobile img.mfp-img { 312 | padding: 0; } 313 | .mfp-img-mobile .mfp-figure:after { 314 | top: 0; 315 | bottom: 0; } 316 | .mfp-img-mobile .mfp-figure small { 317 | display: inline; 318 | margin-left: 5px; } 319 | .mfp-img-mobile .mfp-bottom-bar { 320 | background: rgba(0, 0, 0, 0.6); 321 | bottom: 0; 322 | margin: 0; 323 | top: auto; 324 | padding: 3px 5px; 325 | position: fixed; 326 | box-sizing: border-box; } 327 | .mfp-img-mobile .mfp-bottom-bar:empty { 328 | padding: 0; } 329 | .mfp-img-mobile .mfp-counter { 330 | right: 5px; 331 | top: 3px; } 332 | .mfp-img-mobile .mfp-close { 333 | top: 0; 334 | right: 0; 335 | width: 35px; 336 | height: 35px; 337 | line-height: 35px; 338 | background: rgba(0, 0, 0, 0.6); 339 | position: fixed; 340 | text-align: center; 341 | padding: 0; } } 342 | 343 | @media all and (max-width: 900px) { 344 | .mfp-arrow { 345 | -webkit-transform: scale(0.75); 346 | transform: scale(0.75); } 347 | .mfp-arrow-left { 348 | -webkit-transform-origin: 0; 349 | transform-origin: 0; } 350 | .mfp-arrow-right { 351 | -webkit-transform-origin: 100%; 352 | transform-origin: 100%; } 353 | .mfp-container { 354 | padding-left: 6px; 355 | padding-right: 6px; } } 356 | 357 | 358 | /** 359 | * Simple fade transition, 360 | */ 361 | .mfp-fade.mfp-bg { 362 | opacity: 0; 363 | -webkit-transition: all 0.15s ease-out; 364 | -moz-transition: all 0.15s ease-out; 365 | transition: all 0.15s ease-out; 366 | } 367 | .mfp-fade.mfp-bg.mfp-ready { 368 | opacity: 0.8; 369 | } 370 | .mfp-fade.mfp-bg.mfp-removing { 371 | opacity: 0; 372 | } 373 | 374 | .mfp-fade.mfp-wrap .mfp-content { 375 | opacity: 0; 376 | -webkit-transition: all 0.15s ease-out; 377 | -moz-transition: all 0.15s ease-out; 378 | transition: all 0.15s ease-out; 379 | } 380 | .mfp-fade.mfp-wrap.mfp-ready .mfp-content { 381 | opacity: 1; 382 | } 383 | .mfp-fade.mfp-wrap.mfp-removing .mfp-content { 384 | opacity: 0; 385 | } 386 | /* 387 | 388 | ====== Zoom effect ====== 389 | 390 | */ 391 | .mfp-zoom-in { 392 | /* start state */ 393 | /* animate in */ 394 | /* animate out */ 395 | } 396 | .mfp-zoom-in .mfp-with-anim { 397 | opacity: 0; 398 | transition: all 0.2s ease-in-out; 399 | transform: scale(0.8); 400 | } 401 | .mfp-zoom-in.mfp-bg { 402 | opacity: 0; 403 | transition: all 0.3s ease-out; 404 | } 405 | .mfp-zoom-in.mfp-ready .mfp-with-anim { 406 | opacity: 1; 407 | transform: scale(1); 408 | } 409 | .mfp-zoom-in.mfp-ready.mfp-bg { 410 | opacity: 0.8; 411 | } 412 | .mfp-zoom-in.mfp-removing .mfp-with-anim { 413 | transform: scale(0.8); 414 | opacity: 0; 415 | } 416 | .mfp-zoom-in.mfp-removing.mfp-bg { 417 | opacity: 0; 418 | } -------------------------------------------------------------------------------- /contract/pool/NetflixSwapPair.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.5.16; 2 | 3 | import './interfaces/INetflixSwapPair.sol'; 4 | import './Neflix.sol'; 5 | import './interfaces/INetflixSwapFactory.sol'; 6 | import "../netflix-libs/access/Ownable.sol"; 7 | import "../netflix-libs/gsn/Context.sol"; 8 | import "../netflix-libs/token/erc20/ERC20.sol"; 9 | import "../netflix-libs/utils/UQ112x112.sol"; 10 | import "../netflix-libs/math/SafeMath.sol"; 11 | 12 | contract NetflixSwapPair is INetflixSwapPair, NetflixSwapBEP20 { 13 | using SafeMath for uint256; 14 | using UQ112x112 for uint224; 15 | 16 | uint256 public constant MINIMUM_LIQUIDITY = 10**3; 17 | bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)'))); 18 | 19 | address public factory; 20 | address public token0; 21 | address public token1; 22 | 23 | uint112 private reserve0; // uses single storage slot, accessible via getReserves 24 | uint112 private reserve1; // uses single storage slot, accessible via getReserves 25 | uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves 26 | 27 | uint256 public price0CumulativeLast; 28 | uint256 public price1CumulativeLast; 29 | uint256 public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event 30 | 31 | uint256 private unlocked = 1; 32 | modifier lock() { 33 | require(unlocked == 1, 'NetflixSwapPair: LOCKED'); 34 | unlocked = 0; 35 | _; 36 | unlocked = 1; 37 | } 38 | 39 | function getReserves() 40 | public 41 | view 42 | returns ( 43 | uint112 _reserve0, 44 | uint112 _reserve1, 45 | uint32 _blockTimestampLast 46 | ) 47 | { 48 | _reserve0 = reserve0; 49 | _reserve1 = reserve1; 50 | _blockTimestampLast = blockTimestampLast; 51 | } 52 | 53 | function _safeTransfer( 54 | address token, 55 | address to, 56 | uint256 value 57 | ) private { 58 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); 59 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'NetflixSwapPair: TRANSFER_FAILED'); 60 | } 61 | 62 | event Mint(address indexed sender, uint256 amount0, uint256 amount1); 63 | event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); 64 | event Swap( 65 | address indexed sender, 66 | uint256 amount0In, 67 | uint256 amount1In, 68 | uint256 amount0Out, 69 | uint256 amount1Out, 70 | address indexed to 71 | ); 72 | event Sync(uint112 reserve0, uint112 reserve1); 73 | 74 | constructor() public { 75 | factory = msg.sender; 76 | } 77 | 78 | // called once by the factory at time of deployment 79 | function initialize(address _token0, address _token1) external { 80 | require(msg.sender == factory, 'NetflixSwapPair: FORBIDDEN'); // sufficient check 81 | token0 = _token0; 82 | token1 = _token1; 83 | } 84 | 85 | // update reserves and, on the first call per block, price accumulators 86 | function _update( 87 | uint256 balance0, 88 | uint256 balance1, 89 | uint112 _reserve0, 90 | uint112 _reserve1 91 | ) private { 92 | require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'NetflixSwapPair: OVERFLOW'); 93 | uint32 blockTimestamp = uint32(block.timestamp % 2**32); 94 | uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired 95 | if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { 96 | // * never overflows, and + overflow is desired 97 | price0CumulativeLast += uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; 98 | price1CumulativeLast += uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed; 99 | } 100 | reserve0 = uint112(balance0); 101 | reserve1 = uint112(balance1); 102 | blockTimestampLast = blockTimestamp; 103 | emit Sync(reserve0, reserve1); 104 | } 105 | 106 | // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k) 107 | function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) { 108 | address feeTo = INetflixSwapFactory(factory).feeTo(); 109 | feeOn = feeTo != address(0); 110 | uint256 _kLast = kLast; // gas savings 111 | if (feeOn) { 112 | if (_kLast != 0) { 113 | uint256 rootK = SafeMath.sqrt(uint256(_reserve0).mul(_reserve1)); 114 | uint256 rootKLast = SafeMath.sqrt(_kLast); 115 | if (rootK > rootKLast) { 116 | uint256 numerator = totalSupply.mul(rootK.sub(rootKLast)); 117 | uint256 denominator = rootK.mul(5).add(rootKLast); 118 | uint256 liquidity = numerator / denominator; 119 | if (liquidity > 0) _mint(feeTo, liquidity); 120 | } 121 | } 122 | } else if (_kLast != 0) { 123 | kLast = 0; 124 | } 125 | } 126 | 127 | // this low-level function should be called from a contract which performs important safety checks 128 | function mint(address to) external lock returns (uint256 liquidity) { 129 | (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings 130 | uint256 balance0 = IBEP20(token0).balanceOf(address(this)); 131 | uint256 balance1 = IBEP20(token1).balanceOf(address(this)); 132 | uint256 amount0 = balance0.sub(_reserve0); 133 | uint256 amount1 = balance1.sub(_reserve1); 134 | 135 | bool feeOn = _mintFee(_reserve0, _reserve1); 136 | uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee 137 | if (_totalSupply == 0) { 138 | liquidity = SafeMath.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY); 139 | _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens 140 | } else { 141 | liquidity = SafeMath.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); 142 | } 143 | require(liquidity > 0, 'NetflixSwapPair: INSUFFICIENT_LIQUIDITY_MINTED'); 144 | _mint(to, liquidity); 145 | 146 | _update(balance0, balance1, _reserve0, _reserve1); 147 | if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date 148 | emit Mint(msg.sender, amount0, amount1); 149 | } 150 | 151 | // this low-level function should be called from a contract which performs important safety checks 152 | function burn(address to) external lock returns (uint256 amount0, uint256 amount1) { 153 | (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings 154 | address _token0 = token0; // gas savings 155 | address _token1 = token1; // gas savings 156 | uint256 balance0 = IBEP20(_token0).balanceOf(address(this)); 157 | uint256 balance1 = IBEP20(_token1).balanceOf(address(this)); 158 | uint256 liquidity = balanceOf[address(this)]; 159 | 160 | bool feeOn = _mintFee(_reserve0, _reserve1); 161 | uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee 162 | amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution 163 | amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution 164 | require(amount0 > 0 && amount1 > 0, 'NetflixSwapPair: INSUFFICIENT_LIQUIDITY_BURNED'); 165 | _burn(address(this), liquidity); 166 | _safeTransfer(_token0, to, amount0); 167 | _safeTransfer(_token1, to, amount1); 168 | balance0 = IBEP20(_token0).balanceOf(address(this)); 169 | balance1 = IBEP20(_token1).balanceOf(address(this)); 170 | 171 | _update(balance0, balance1, _reserve0, _reserve1); 172 | if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date 173 | emit Burn(msg.sender, amount0, amount1, to); 174 | } 175 | 176 | // this low-level function should be called from a contract which performs important safety checks 177 | function swap( 178 | uint256 amount0Out, 179 | uint256 amount1Out, 180 | address to 181 | ) external lock { 182 | require(amount0Out > 0 || amount1Out > 0, 'NetflixSwapPair: INSUFFICIENT_OUTPUT_AMOUNT'); 183 | (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings 184 | require(amount0Out < _reserve0 && amount1Out < _reserve1, 'NetflixSwapPair: INSUFFICIENT_LIQUIDITY'); 185 | 186 | uint256 balance0; 187 | uint256 balance1; 188 | { 189 | // scope for _token{0,1}, avoids stack too deep errors 190 | address _token0 = token0; 191 | address _token1 = token1; 192 | require(to != _token0 && to != _token1, 'NetflixSwapPair: INVALID_TO'); 193 | if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens 194 | if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens 195 | balance0 = IBEP20(_token0).balanceOf(address(this)); 196 | balance1 = IBEP20(_token1).balanceOf(address(this)); 197 | } 198 | uint256 amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; 199 | uint256 amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; 200 | require(amount0In > 0 || amount1In > 0, 'NetflixSwapPair: INSUFFICIENT_INPUT_AMOUNT'); 201 | { 202 | // scope for reserve{0,1}Adjusted, avoids stack too deep errors 203 | uint256 balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); 204 | uint256 balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); 205 | require( 206 | balance0Adjusted.mul(balance1Adjusted) >= uint256(_reserve0).mul(_reserve1).mul(1000**2), 207 | 'NetflixSwapPair: K' 208 | ); 209 | } 210 | 211 | _update(balance0, balance1, _reserve0, _reserve1); 212 | emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); 213 | } 214 | 215 | // force balances to match reserves 216 | function skim(address to) external lock { 217 | address _token0 = token0; // gas savings 218 | address _token1 = token1; // gas savings 219 | _safeTransfer(_token0, to, IBEP20(_token0).balanceOf(address(this)).sub(reserve0)); 220 | _safeTransfer(_token1, to, IBEP20(_token1).balanceOf(address(this)).sub(reserve1)); 221 | } 222 | 223 | // force reserves to match balances 224 | function sync() external lock { 225 | _update(IBEP20(token0).balanceOf(address(this)), IBEP20(token1).balanceOf(address(this)), reserve0, reserve1); 226 | } 227 | } -------------------------------------------------------------------------------- /wallet/views.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import json 3 | import uuid 4 | 5 | from django.http import JsonResponse 6 | from django.shortcuts import render 7 | 8 | # Create your views here. 9 | from django.views.decorators.csrf import csrf_exempt 10 | from rest_framework import status 11 | from rest_framework.decorators import api_view 12 | from web3 import Web3, HTTPProvider 13 | 14 | from tutorial.utils import splitStringEveryCharacter, collectListOfStrings, base64StringToImage 15 | from wallet.models import File, User 16 | 17 | 18 | def uploadToNFT(list_of_arrays, walletAddress): 19 | web3 = Web3(HTTPProvider('https://data-seed-prebsc-1-s2.binance.org:8545/')) 20 | ERC20_ABI = json.loads( 21 | '[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"_strs","type":"string[]"}],"name":"batchCreate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_str","type":"string"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"createItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"last_token_id","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapAccounts","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"filePortion","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdFiles","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]') 22 | tokenContract = '0x2A768003c2F300a617f4b3bB3b6c7C1DE8F2d016' 23 | tokenContract = web3.toChecksumAddress(tokenContract) 24 | 25 | walletAddress = web3.toChecksumAddress(walletAddress) 26 | 27 | public_key = '0x38C1E1204C10C8be90ecA671Da8Ea8a9AEb16031' 28 | public_key = web3.toChecksumAddress(public_key) 29 | private_key = '59a48bac86bffca9695153d414aafdcaacd960dac9a6306779b42cc9699503e6' 30 | 31 | myContract = web3.eth.contract(address=tokenContract, abi=ERC20_ABI) 32 | chainID = 97 33 | defaultGasLimit = 1612917 * len(list_of_arrays) 34 | defaultGasPrice = web3.toWei('20', 'gwei') 35 | 36 | lastTokenId = myContract.functions.getLastTokenId().call() 37 | lastTokenId += 1 38 | 39 | list_of_token_ids = [] 40 | 41 | for i in range(len(list_of_arrays)): 42 | list_of_token_ids.append(lastTokenId + i) 43 | 44 | txn_data = myContract.functions.batchCreate( 45 | walletAddress, 46 | list_of_token_ids, 47 | list_of_arrays, 48 | ).buildTransaction({ 49 | 'chainId': chainID, 50 | 'gas': defaultGasLimit, 51 | 'gasPrice': defaultGasPrice, 52 | 'nonce': web3.eth.getTransactionCount(public_key), 53 | }) 54 | 55 | # Signing transaction with private key 56 | signed_txn = web3.eth.account.signTransaction(txn_data, private_key=private_key) 57 | 58 | # send transaction to blockchain 59 | web3.eth.sendRawTransaction(signed_txn.rawTransaction) 60 | 61 | # Transaction hash of the transaction which must be returned to client 62 | print(web3.toHex(web3.sha3(signed_txn.rawTransaction))) 63 | 64 | txHash = web3.toHex(web3.sha3(signed_txn.rawTransaction)) 65 | 66 | data = { 67 | 'txHash': txHash, 68 | 'tokenIds': list_of_token_ids, 69 | } 70 | 71 | return data 72 | 73 | @csrf_exempt 74 | @api_view(['POST']) 75 | def uploadImage(request): 76 | try: 77 | body = json.loads(request.POST.get('data')) 78 | walletAddress = body["wallet_address"] 79 | files = request.FILES 80 | keystoreFile = files.get('file', None) 81 | image_file = keystoreFile.read() 82 | encoded_string = base64.b64encode(image_file) 83 | das = encoded_string.decode('utf-8') 84 | splittedStrs = splitStringEveryCharacter(das, 1024 * 2) 85 | 86 | uploadData = uploadToNFT(splittedStrs, walletAddress) 87 | 88 | list_of_token_ids = uploadData['tokenIds'] 89 | 90 | # uniqueFileId = uuid.uuid4() 91 | # userModel = User(address=walletAddress, fileType="IMAGE", fileName="D", fileId=uniqueFileId) 92 | # userModel.save() 93 | # 94 | # for i in range(len(list_of_token_ids)): 95 | # fileModel = File(token_id=list_of_token_ids[i], token_portion=splittedStrs[i], fileId=uniqueFileId) 96 | # fileModel.save() 97 | 98 | collectedStr = collectListOfStrings(splittedStrs) 99 | 100 | # base64StringToImage(collectedStr.encode('utf-8')) 101 | message = { 102 | 'message': None, 103 | 'data': { 104 | 'txHash': uploadData['txHash'], 105 | 'tokenIds': uploadData['tokenIds'], 106 | 'filePortions': splittedStrs, 107 | 'fullBase64': collectedStr 108 | }, 109 | 'status_code': status.HTTP_200_OK 110 | } 111 | return JsonResponse(message, status=status.HTTP_200_OK) 112 | except Exception as e: 113 | print(str(e)) 114 | message = { 115 | 'message': str(e), 116 | 'data': None, 117 | 'status_code': status.HTTP_500_INTERNAL_SERVER_ERROR 118 | } 119 | return JsonResponse(message, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 120 | 121 | 122 | @csrf_exempt 123 | @api_view(['POST']) 124 | def getFiles(request): 125 | try: 126 | body = request.data 127 | walletAddress = body["wallet_address"] 128 | 129 | listOfFiles = [] 130 | fileLists = User.objects.filter(address=walletAddress) 131 | 132 | for file in fileLists: 133 | mapFileData = {} 134 | filePortions = File.objects.filter(fileId=file.fileId).order_by('-token_id') 135 | mapFileData['fileName'] = file.fileName 136 | mapFileData['fileType'] = file.fileType 137 | mapFileData['fileId'] = file.fileId 138 | listOfFilePortions = [] 139 | for filePor in filePortions: 140 | mapFilePorData = {} 141 | mapFilePorData['token_id'] = filePor.token_id 142 | mapFilePorData['token_portion'] = filePor.token_portion 143 | listOfFilePortions.append(mapFilePorData) 144 | mapFileData['filePortions'] = listOfFilePortions 145 | listOfFiles.append(mapFileData) 146 | 147 | message = { 148 | 'message': None, 149 | 'data': { 150 | 'address': walletAddress, 151 | 'files': listOfFiles, 152 | }, 153 | 'status_code': status.HTTP_200_OK 154 | } 155 | return JsonResponse(message, status=status.HTTP_200_OK) 156 | except Exception as e: 157 | message = { 158 | 'message': str(e), 159 | 'data': None, 160 | 'status_code': status.HTTP_500_INTERNAL_SERVER_ERROR 161 | } 162 | return JsonResponse(message, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 163 | -------------------------------------------------------------------------------- /contract/netflix-libs/token/bep20/BEP20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.4.0; 4 | 5 | import "https://github.com/centerprime/CPXToken/tree/master/v0.6/contracts/access/Ownable.sol"; 6 | import "https://github.com/centerprime/CPXToken/tree/master/v0.6/contracts/gsn/Context.sol"; 7 | import "https://github.com/centerprime/CPXToken/tree/master/v0.6/contracts/token/ERC20.sol"; 8 | import "https://github.com/centerprime/CPXToken/tree/master/v0.6/contracts/math/SafeMath.sol"; 9 | import "./IBEP20.sol"; 10 | /** 11 | * @dev Implementation of the {IBEP20} interface. 12 | * 13 | * This implementation is agnostic to the way tokens are created. This means 14 | * that a supply mechanism has to be added in a derived contract using {_mint}. 15 | * For a generic mechanism see {BEP20PresetMinterPauser}. 16 | * 17 | * TIP: For a detailed writeup see our guide 18 | * https://forum.zeppelin.solutions/t/how-to-implement-BEP20-supply-mechanisms/226[How 19 | * to implement supply mechanisms]. 20 | * 21 | * We have followed general OpenZeppelin guidelines: functions revert instead 22 | * of returning `false` on failure. This behavior is nonetheless conventional 23 | * and does not conflict with the expectations of BEP20 applications. 24 | * 25 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 26 | * This allows applications to reconstruct the allowance for all accounts just 27 | * by listening to said events. Other implementations of the EIP may not emit 28 | * these events, as it isn't required by the specification. 29 | * 30 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 31 | * functions have been added to mitigate the well-known issues around setting 32 | * allowances. See {IBEP20-approve}. 33 | */ 34 | contract BEP20 is Context, IBEP20, Ownable { 35 | using SafeMath for uint256; 36 | using Address for address; 37 | 38 | mapping(address => uint256) private _balances; 39 | 40 | mapping(address => mapping(address => uint256)) private _allowances; 41 | 42 | uint256 private _totalSupply; 43 | 44 | string private _name; 45 | string private _symbol; 46 | uint8 private _decimals; 47 | 48 | /** 49 | * @dev Sets the values for {name} and {symbol}, initializes {decimals} with 50 | * a default value of 18. 51 | * 52 | * To select a different value for {decimals}, use {_setupDecimals}. 53 | * 54 | * All three of these values are immutable: they can only be set once during 55 | * construction. 56 | */ 57 | constructor(string memory name, string memory symbol) public { 58 | _name = name; 59 | _symbol = symbol; 60 | _decimals = 18; 61 | } 62 | 63 | /** 64 | * @dev Returns the bep token owner. 65 | */ 66 | function getOwner() external override view returns (address) { 67 | return owner(); 68 | } 69 | 70 | /** 71 | * @dev Returns the token name. 72 | */ 73 | function name() public override view returns (string memory) { 74 | return _name; 75 | } 76 | 77 | /** 78 | * @dev Returns the token decimals. 79 | */ 80 | function decimals() public override view returns (uint8) { 81 | return _decimals; 82 | } 83 | 84 | /** 85 | * @dev Returns the token symbol. 86 | */ 87 | function symbol() public override view returns (string memory) { 88 | return _symbol; 89 | } 90 | 91 | /** 92 | * @dev See {BEP20-totalSupply}. 93 | */ 94 | function totalSupply() public override view returns (uint256) { 95 | return _totalSupply; 96 | } 97 | 98 | /** 99 | * @dev See {BEP20-balanceOf}. 100 | */ 101 | function balanceOf(address account) public override view returns (uint256) { 102 | return _balances[account]; 103 | } 104 | 105 | /** 106 | * @dev See {BEP20-transfer}. 107 | * 108 | * Requirements: 109 | * 110 | * - `recipient` cannot be the zero address. 111 | * - the caller must have a balance of at least `amount`. 112 | */ 113 | function transfer(address recipient, uint256 amount) public override returns (bool) { 114 | _transfer(_msgSender(), recipient, amount); 115 | return true; 116 | } 117 | 118 | /** 119 | * @dev See {BEP20-allowance}. 120 | */ 121 | function allowance(address owner, address spender) public override view returns (uint256) { 122 | return _allowances[owner][spender]; 123 | } 124 | 125 | /** 126 | * @dev See {BEP20-approve}. 127 | * 128 | * Requirements: 129 | * 130 | * - `spender` cannot be the zero address. 131 | */ 132 | function approve(address spender, uint256 amount) public override returns (bool) { 133 | _approve(_msgSender(), spender, amount); 134 | return true; 135 | } 136 | 137 | /** 138 | * @dev See {BEP20-transferFrom}. 139 | * 140 | * Emits an {Approval} event indicating the updated allowance. This is not 141 | * required by the EIP. See the note at the beginning of {BEP20}; 142 | * 143 | * Requirements: 144 | * - `sender` and `recipient` cannot be the zero address. 145 | * - `sender` must have a balance of at least `amount`. 146 | * - the caller must have allowance for `sender`'s tokens of at least 147 | * `amount`. 148 | */ 149 | function transferFrom( 150 | address sender, 151 | address recipient, 152 | uint256 amount 153 | ) public override returns (bool) { 154 | _transfer(sender, recipient, amount); 155 | _approve( 156 | sender, 157 | _msgSender(), 158 | _allowances[sender][_msgSender()].sub(amount, 'BEP20: transfer amount exceeds allowance') 159 | ); 160 | return true; 161 | } 162 | 163 | /** 164 | * @dev Atomically increases the allowance granted to `spender` by the caller. 165 | * 166 | * This is an alternative to {approve} that can be used as a mitigation for 167 | * problems described in {BEP20-approve}. 168 | * 169 | * Emits an {Approval} event indicating the updated allowance. 170 | * 171 | * Requirements: 172 | * 173 | * - `spender` cannot be the zero address. 174 | */ 175 | function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { 176 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 177 | return true; 178 | } 179 | 180 | /** 181 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 182 | * 183 | * This is an alternative to {approve} that can be used as a mitigation for 184 | * problems described in {BEP20-approve}. 185 | * 186 | * Emits an {Approval} event indicating the updated allowance. 187 | * 188 | * Requirements: 189 | * 190 | * - `spender` cannot be the zero address. 191 | * - `spender` must have allowance for the caller of at least 192 | * `subtractedValue`. 193 | */ 194 | function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { 195 | _approve( 196 | _msgSender(), 197 | spender, 198 | _allowances[_msgSender()][spender].sub(subtractedValue, 'BEP20: decreased allowance below zero') 199 | ); 200 | return true; 201 | } 202 | 203 | /** 204 | * @dev Creates `amount` tokens and assigns them to `msg.sender`, increasing 205 | * the total supply. 206 | * 207 | * Requirements 208 | * 209 | * - `msg.sender` must be the token owner 210 | */ 211 | function mint(uint256 amount) public onlyOwner returns (bool) { 212 | _mint(_msgSender(), amount); 213 | return true; 214 | } 215 | 216 | /** 217 | * @dev Moves tokens `amount` from `sender` to `recipient`. 218 | * 219 | * This is internal function is equivalent to {transfer}, and can be used to 220 | * e.g. implement automatic token fees, slashing mechanisms, etc. 221 | * 222 | * Emits a {Transfer} event. 223 | * 224 | * Requirements: 225 | * 226 | * - `sender` cannot be the zero address. 227 | * - `recipient` cannot be the zero address. 228 | * - `sender` must have a balance of at least `amount`. 229 | */ 230 | function _transfer( 231 | address sender, 232 | address recipient, 233 | uint256 amount 234 | ) internal { 235 | require(sender != address(0), 'BEP20: transfer from the zero address'); 236 | require(recipient != address(0), 'BEP20: transfer to the zero address'); 237 | 238 | _balances[sender] = _balances[sender].sub(amount, 'BEP20: transfer amount exceeds balance'); 239 | _balances[recipient] = _balances[recipient].add(amount); 240 | emit Transfer(sender, recipient, amount); 241 | } 242 | 243 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 244 | * the total supply. 245 | * 246 | * Emits a {Transfer} event with `from` set to the zero address. 247 | * 248 | * Requirements 249 | * 250 | * - `to` cannot be the zero address. 251 | */ 252 | function _mint(address account, uint256 amount) internal { 253 | require(account != address(0), 'BEP20: mint to the zero address'); 254 | 255 | _totalSupply = _totalSupply.add(amount); 256 | _balances[account] = _balances[account].add(amount); 257 | emit Transfer(address(0), account, amount); 258 | } 259 | 260 | /** 261 | * @dev Destroys `amount` tokens from `account`, reducing the 262 | * total supply. 263 | * 264 | * Emits a {Transfer} event with `to` set to the zero address. 265 | * 266 | * Requirements 267 | * 268 | * - `account` cannot be the zero address. 269 | * - `account` must have at least `amount` tokens. 270 | */ 271 | function _burn(address account, uint256 amount) internal { 272 | require(account != address(0), 'BEP20: burn from the zero address'); 273 | 274 | _balances[account] = _balances[account].sub(amount, 'BEP20: burn amount exceeds balance'); 275 | _totalSupply = _totalSupply.sub(amount); 276 | emit Transfer(account, address(0), amount); 277 | } 278 | 279 | /** 280 | * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. 281 | * 282 | * This is internal function is equivalent to `approve`, and can be used to 283 | * e.g. set automatic allowances for certain subsystems, etc. 284 | * 285 | * Emits an {Approval} event. 286 | * 287 | * Requirements: 288 | * 289 | * - `owner` cannot be the zero address. 290 | * - `spender` cannot be the zero address. 291 | */ 292 | function _approve( 293 | address owner, 294 | address spender, 295 | uint256 amount 296 | ) internal { 297 | require(owner != address(0), 'BEP20: approve from the zero address'); 298 | require(spender != address(0), 'BEP20: approve to the zero address'); 299 | 300 | _allowances[owner][spender] = amount; 301 | emit Approval(owner, spender, amount); 302 | } 303 | 304 | /** 305 | * @dev Destroys `amount` tokens from `account`.`amount` is then deducted 306 | * from the caller's allowance. 307 | * 308 | * See {_burn} and {_approve}. 309 | */ 310 | function _burnFrom(address account, uint256 amount) internal { 311 | _burn(account, amount); 312 | _approve( 313 | account, 314 | _msgSender(), 315 | _allowances[account][_msgSender()].sub(amount, 'BEP20: burn amount exceeds allowance') 316 | ); 317 | } 318 | } --------------------------------------------------------------------------------