├── .dockerignore ├── .github └── workflows │ └── deploy-website.yaml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README-old.md ├── README.md ├── components.json ├── eslint.config.js ├── index.html ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── audits │ ├── EIP_2935_Audit_Report_Dedaub.pdf │ ├── EIP_7002_Audit_Report_Dedaub.pdf │ ├── EIP_7251_Audit_Report_Dedaub.pdf │ ├── Pectra_System_Contracts_Bytecode_Audit_Report_Blackthorn.pdf │ ├── Pectra_System_Contracts_Bytecode_Audit_Report_Plainshift.pdf │ └── Pectra_System_Contracts_Bytecode_Audit_Report_Sigma_Prime.pdf ├── events │ └── .gitkeep ├── images │ ├── andres.jpeg │ ├── bhargava.png │ ├── blackthorn.png │ ├── cantina.svg │ ├── david.jpeg │ ├── dedaub.png │ ├── ef.jpg │ ├── favicon.png │ ├── fredrik-large.jpg │ ├── fredrik.jpeg │ ├── immunefi.png │ ├── justin.png │ ├── plainshift.svg │ ├── sigp.png │ └── tyler.jpeg ├── instances │ ├── 0.bin │ ├── 1.bin │ ├── 2.bin │ ├── 3.bin │ ├── 4.bin │ └── test.bin ├── robots.txt ├── sitemap-0.xml └── sitemap.xml ├── src ├── App.css ├── App.tsx ├── components │ ├── Footer.tsx │ ├── Navbar.tsx │ ├── ThemeSwitch.tsx │ ├── theme-provider.tsx │ └── ui │ │ ├── button.tsx │ │ ├── input.tsx │ │ ├── sonner.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ └── tooltip.tsx ├── hooks │ ├── use-mobile.tsx │ └── use-toast.ts ├── index.css ├── lib │ └── utils.ts ├── main.tsx ├── pages │ ├── audits.tsx │ ├── blog.tsx │ ├── competitions.tsx │ ├── index.tsx │ ├── notFound.tsx │ ├── responsibilities.tsx │ ├── team.tsx │ └── wishlist.tsx └── vite-env.d.ts ├── tailwind.config.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.dockerignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | .pnp 4 | .pnp.js 5 | 6 | # Testing 7 | coverage 8 | 9 | # Next.js 10 | .next 11 | out 12 | 13 | # Production 14 | build 15 | 16 | # Misc 17 | .DS_Store 18 | *.pem 19 | 20 | # Debug 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # Local env files 26 | .env.local 27 | .env.development.local 28 | .env.test.local 29 | .env.production.local 30 | 31 | # Git 32 | .git 33 | .gitignore 34 | 35 | # IDE 36 | .idea 37 | .vscode 38 | *.swp 39 | *.swo 40 | 41 | # Project specific 42 | README.md 43 | README-old.md 44 | -------------------------------------------------------------------------------- /.github/workflows/deploy-website.yaml: -------------------------------------------------------------------------------- 1 | # .github/workflows/main.yml 2 | name: Build and Deploy 3 | on: 4 | push: 5 | tags: ["*"] 6 | branches: ["master"] 7 | 8 | permissions: 9 | contents: write 10 | env: 11 | # Use docker.io for Docker Hub if empty 12 | REGISTRY: ghcr.io 13 | # github.repository as / 14 | IMAGE_NAME: ${{ github.repository }} 15 | jobs: 16 | docker-build: 17 | permissions: 18 | packages: write 19 | id-token: write 20 | contents: read 21 | uses: ethdevops/workflows/.github/workflows/basic-docker-build-cypher.yaml@main 22 | secrets: 23 | cypher_client_id: ${{ secrets.CYPHER_CLIENT_ID }} 24 | cypher_client_secret: ${{ secrets.CYPHER_CLIENT_SECRET }} 25 | 26 | deploy-to-k8s: 27 | permissions: 28 | id-token: write 29 | if: startsWith(github.ref, 'refs/tags/') 30 | needs: 31 | - docker-build 32 | uses: ethdevops/workflows/.github/workflows/deploy-via-argocd.yaml@main 33 | with: 34 | team: security 35 | project: website 36 | secrets: 37 | cypher_client_id: ${{ secrets.CYPHER_CLIENT_ID }} 38 | cypher_client_secret: ${{ secrets.CYPHER_CLIENT_SECRET }} 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | /.pnp 4 | .pnp.js 5 | 6 | # Testing 7 | /coverage 8 | 9 | # Next.js 10 | /.next/ 11 | /out/ 12 | .swc/ 13 | 14 | # Production 15 | /build 16 | /dist 17 | 18 | # Misc 19 | .DS_Store 20 | *.pem 21 | .env.local 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | # Debug 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | 31 | # Local env files 32 | .env*.local 33 | 34 | # Vercel 35 | .vercel 36 | 37 | # TypeScript 38 | *.tsbuildinfo 39 | next-env.d.ts 40 | 41 | # IDE 42 | .idea/ 43 | .vscode/ 44 | *.sublime-project 45 | *.sublime-workspace 46 | *.code-workspace 47 | 48 | # Logs 49 | logs 50 | *.log 51 | 52 | # Cache 53 | .cache/ 54 | .npm/ 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional stylelint cache 60 | .stylelintcache 61 | 62 | # Yarn 63 | .yarn/* 64 | !.yarn/patches 65 | !.yarn/plugins 66 | !.yarn/releases 67 | !.yarn/sdks 68 | !.yarn/versions 69 | .pnp.* 70 | 71 | # macOS 72 | .DS_Store 73 | .AppleDouble 74 | .LSOverride 75 | Icon 76 | ._* 77 | .DocumentRevisions-V100 78 | .fseventsd 79 | .Spotlight-V100 80 | .TemporaryItems 81 | .Trashes 82 | .VolumeIcon.icns 83 | .com.apple.timemachine.donotpresent 84 | 85 | # Windows 86 | Thumbs.db 87 | Thumbs.db:encryptable 88 | ehthumbs.db 89 | ehthumbs_vista.db 90 | *.stackdump 91 | [Dd]esktop.ini 92 | $RECYCLE.BIN/ 93 | *.cab 94 | *.msi 95 | *.msix 96 | *.msm 97 | *.msp 98 | *.lnk 99 | 100 | # Linux 101 | *~ 102 | .fuse_hidden* 103 | .directory 104 | .Trash-* 105 | .nfs* 106 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | 3 | # Set working directory 4 | WORKDIR /app 5 | 6 | # Copy package files 7 | COPY package.json package-lock.json* ./ 8 | 9 | # Install dependencies 10 | RUN npm ci 11 | 12 | # Copy source files 13 | COPY . . 14 | 15 | # Expose the port the app runs on 16 | EXPOSE 3000 17 | 18 | # Start npm dev server 19 | CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3000"] 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Ethereum Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-old.md: -------------------------------------------------------------------------------- 1 | # Protocol Security Research Team 2 | logo 3 | 4 | The Protocol Security Research team is one piece of the large puzzle that helps safeguard Ethereum’s integrity. It is a public good team funded by the Ethereum Foundation with ~10 people who each possess different areas of expertise and experience. Through coordination, meticulous code reviews, developing and utilizing advanced tooling, and running real-world simulations, our focus is on securing the network and its critical components. Our hands-on approach includes managing the bug bounty program, continuously monitoring the network, and collaborating with client teams and many other teams in the ecosystem. We’re committed to identifying and mitigating risks to Ethereum network. The Protocol Security Research team is often not the most visible team in public, both due to the nature of what we work on, but also as we primarily try to help empower people in the ecosystem. 5 | 6 | 7 | ## Coordination & Collaboration 8 | We spend time coordinating and collaborating with many parts of the ecosystem in order to further help keep Ethereum safe. Some of the things we do are: 9 | - Vulnerability coordination and collaboration with L2s, L1s, critical dependencies and more for security issues 10 | - Protocol Security call series 11 | - Coordination and collaboration with external security auditors for protocol related audits 12 | - Security coordination and collaboration with client teams and critical dependencies 13 | - Coordination and collaboration with researchers from the Ethereum ecosystem, academia and security 14 | - Collaboration with teams such as EF Devops and EF Testing 15 | - Ongoing collaboration and support for grantees 16 | - Support public good projects related to security 17 | - Writing the "Secured" series on the [EF Blog](https://blog.ethereum.org) 18 | - Host security challenges such as the [Ethereum Protocol Attackathon](https://blog.ethereum.org/2024/07/08/attackathon) 19 | 20 | 21 | ## Bug Bounty Program 22 | The Protocol Security Research team manages the [Ethereum Foundation Bug Bounty Program](https://bounty.ethereum.org). We receive reports, triage, provide input, pay bounty rewards and coordinate public disclosures. The bug bounty program covers Ethereum specifications, Ethereum clients, the Solidity compiler and more. 23 | 24 | We also keep a public repository of [past results](https://github.com/ethereum/public-disclosures/) 25 | 26 | 27 | ## Grants 28 | We feel that providing resources and funding to security grants is impactful and valuable to the ecosystem. In our opinion, providing funding is often critical, however we also provide our own time as a resource in order to further help projects be successful. Some of the grants we work on are: 29 | - Provide and support Academic Grants through [funding and resources](https://blog.ethereum.org/2023/06/28/academic-grants-round-23) 30 | - We support the [Ethereum Protocol Fellowship](https://github.com/eth-protocol-fellows/cohort-five/blob/main/projects/project-ideas.md#protocol-security) by providing resources 31 | - We provide resources for the [Devcon(nect) Scholars](https://blog.ethereum.org/2023/06/26/devconnect-instanbul-scholars) 32 | - We provide funding and resources for General Security Grants 33 | - Grants for various security efforts, such as [The Red Guild](https://blog.theredguild.org/about/), [Security Alliance](https://securityalliance.org/), or fuzzers created by external people such as [Guido Vranken](https://guidovranken.com/) 34 | 35 | 36 | ## Fuzzing 37 | There is a finite amount of time for manual audits, so we build, maintain and use fuzzers to increase the likelihood of finding vulnerabilities. Many severe vulnerabilities have been found by these fuzzers, and then patched by client teams before they could be found and exploited by a malicious actor. 38 | - Execution Layer 39 | - [goevmlab](https://github.com/holiman/goevmlab/) 40 | - [tx-fuzz](https://github.com/MariusVanDerWijden/tx-fuzz) 41 | - [FuzzyVM](https://github.com/MariusVanDerWijden/FuzzyVM) 42 | - [merge-fuzz](https://github.com/MariusVanDerWijden/merge-fuzz) 43 | - [Nosy](https://github.com/infosecual/nosy) 44 | - Various cryptography & EVM fuzzers 45 | - Private fuzzers 46 | - Consensus Layer 47 | - [Nosy](https://github.com/infosecual/nosy) 48 | - Private fuzzers 49 | - Solidity Compiler 50 | - Private fuzzers 51 | - Network Layer (devp2p (discv4, discv5, ENR, RLP, ...), libp2p) 52 | - Private fuzzers 53 | - JSON-RPC 54 | - Private fuzzer 55 | - Account Abstraction 56 | - Private fuzzer 57 | - Full Stack 58 | - [Attacknet](https://github.com/crytic/attacknet) (built from grant) 59 | - [Antithesis]() (service provider) 60 | - Cryptographic libraries 61 | - [kzgfuzz](https://github.com/jtraglia/kzg-fuzz) 62 | - [kzg differential fuzzer](https://github.com/ethereum/c-kzg-4844/tree/main/fuzz) 63 | - Critical Dependencies 64 | - Private Fuzzers 65 | 66 | 67 | ## Manual Reviews 68 | We spend a lot of time manually reviewing specifications, clients and critical dependencies. Upcoming changes for hardforks are always being continually reviewed and prioritized. 69 | - Specifications ([EL](https://github.com/ethereum/execution-specs) / [CL](https://github.com/ethereum/consensus-specs)) 70 | - Clients 71 | - [Besu](https://github.com/hyperledger/besu/) 72 | - [Erigon](https://github.com/ledgerwatch/erigon) 73 | - [Geth](https://github.com/ethereum/go-ethereum/) 74 | - [Lighthouse](https://github.com/sigp/lighthouse/) 75 | - [Lodestar](https://github.com/ChainSafe/lodestar/) 76 | - [Nimbus](https://github.com/status-im/nimbus-eth2) 77 | - [Nethermind](https://github.com/NethermindEth/nethermind/) 78 | - [Prysm](https://github.com/prysmaticlabs/prysm/) 79 | - [Teku](https://github.com/Consensys/teku) 80 | - [Reth](https://github.com/paradigmxyz/reth/) 81 | - [Grandine](https://github.com/grandinetech/grandine) 82 | - Network libraries 83 | - [devp2p](https://github.com/ethereum/devp2p/) 84 | - [libp2p](https://github.com/libp2p) 85 | - Hardforks 86 | - CL / EL side 87 | - EIPs 88 | - EOF 89 | - 4444 90 | - PeerDAS 91 | - 7702 (txpool) 92 | - ... 93 | - Critical Dependencies 94 | - Static Analysis 95 | - Cryptographic libraries 96 | 97 | 98 | ### Research 99 | Many hours are spent on security research related to the Ethereum ecosystem. As a some of this research could potentially pose a threat, the specific research results may often not end up as public research, but the outcome of the research is rather used to help further secure the Ethereum ecosystem through improvements. A few examples of research topics are: 100 | - Client Diversity 101 | - /dev/random Diversity 102 | - ZK security research 103 | - Threat Analysis 104 | - Risk Assessments 105 | - L2s 106 | - Cryptography 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This directory holds the codebase to our website, [security.ethereum.org](https://security.ethereum.org). 2 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/index.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | } 20 | } -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import reactHooks from "eslint-plugin-react-hooks"; 4 | import reactRefresh from "eslint-plugin-react-refresh"; 5 | import tseslint from "typescript-eslint"; 6 | 7 | export default tseslint.config( 8 | { ignores: ["dist"] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ["**/*.{ts,tsx}"], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | "react-hooks": reactHooks, 18 | "react-refresh": reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | "react-refresh/only-export-components": [ 23 | "warn", 24 | { allowConstantExport: true }, 25 | ], 26 | "@typescript-eslint/no-unused-vars": "off", 27 | }, 28 | } 29 | ); 30 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Protocol Security Research Team 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | output: 'export', 4 | images: { 5 | unoptimized: true, 6 | }, 7 | basePath: '/', 8 | assetPrefix: '/assets/', 9 | } 10 | 11 | module.exports = nextConfig -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "predeploy": "npm run build", 11 | "deploy": "gh-pages -d dist", 12 | "lint": "eslint ." 13 | }, 14 | "homepage": "https://security.ethereum.org", 15 | "dependencies": { 16 | "@hookform/resolvers": "^3.9.0", 17 | "@radix-ui/react-accordion": "^1.2.0", 18 | "@radix-ui/react-alert-dialog": "^1.1.1", 19 | "@radix-ui/react-aspect-ratio": "^1.1.0", 20 | "@radix-ui/react-avatar": "^1.1.0", 21 | "@radix-ui/react-checkbox": "^1.1.1", 22 | "@radix-ui/react-collapsible": "^1.1.0", 23 | "@radix-ui/react-context-menu": "^2.2.1", 24 | "@radix-ui/react-dialog": "^1.1.2", 25 | "@radix-ui/react-dropdown-menu": "^2.1.1", 26 | "@radix-ui/react-hover-card": "^1.1.1", 27 | "@radix-ui/react-label": "^2.1.0", 28 | "@radix-ui/react-menubar": "^1.1.1", 29 | "@radix-ui/react-navigation-menu": "^1.2.0", 30 | "@radix-ui/react-popover": "^1.1.1", 31 | "@radix-ui/react-progress": "^1.1.0", 32 | "@radix-ui/react-radio-group": "^1.2.0", 33 | "@radix-ui/react-scroll-area": "^1.1.0", 34 | "@radix-ui/react-select": "^2.1.1", 35 | "@radix-ui/react-separator": "^1.1.0", 36 | "@radix-ui/react-slider": "^1.2.0", 37 | "@radix-ui/react-slot": "^1.1.0", 38 | "@radix-ui/react-switch": "^1.1.0", 39 | "@radix-ui/react-tabs": "^1.1.0", 40 | "@radix-ui/react-toast": "^1.2.1", 41 | "@radix-ui/react-toggle": "^1.1.0", 42 | "@radix-ui/react-toggle-group": "^1.1.0", 43 | "@radix-ui/react-tooltip": "^1.1.4", 44 | "@tanstack/react-query": "^5.56.2", 45 | "class-variance-authority": "^0.7.1", 46 | "clsx": "^2.1.1", 47 | "cmdk": "^1.0.0", 48 | "date-fns": "^3.6.0", 49 | "embla-carousel-react": "^8.3.0", 50 | "input-otp": "^1.2.4", 51 | "lucide-react": "^0.462.0", 52 | "next-themes": "^0.3.0", 53 | "react": "^18.3.1", 54 | "react-day-picker": "^8.10.1", 55 | "react-dom": "^18.3.1", 56 | "react-hook-form": "^7.53.0", 57 | "react-pdf": "^9.2.1", 58 | "react-resizable-panels": "^2.1.3", 59 | "react-router-dom": "^6.26.2", 60 | "recharts": "^2.12.7", 61 | "sonner": "^1.5.0", 62 | "tailwind-merge": "^2.5.2", 63 | "tailwindcss-animate": "^1.0.7", 64 | "vaul": "^0.9.3", 65 | "zod": "^3.23.8" 66 | }, 67 | "devDependencies": { 68 | "@eslint/js": "^9.9.0", 69 | "@tailwindcss/typography": "^0.5.15", 70 | "@types/node": "^22.5.5", 71 | "@types/react": "^18.3.3", 72 | "@types/react-dom": "^18.3.0", 73 | "@vitejs/plugin-react-swc": "^3.5.0", 74 | "autoprefixer": "^10.4.20", 75 | "eslint": "^9.9.0", 76 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 77 | "eslint-plugin-react-refresh": "^0.4.9", 78 | "gh-pages": "^6.3.0", 79 | "globals": "^15.9.0", 80 | "postcss": "^8.4.47", 81 | "tailwindcss": "^3.4.11", 82 | "typescript": "^5.5.3", 83 | "typescript-eslint": "^8.0.1", 84 | "vite": "^6.3.4" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/audits/EIP_2935_Audit_Report_Dedaub.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/audits/EIP_2935_Audit_Report_Dedaub.pdf -------------------------------------------------------------------------------- /public/audits/EIP_7002_Audit_Report_Dedaub.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/audits/EIP_7002_Audit_Report_Dedaub.pdf -------------------------------------------------------------------------------- /public/audits/EIP_7251_Audit_Report_Dedaub.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/audits/EIP_7251_Audit_Report_Dedaub.pdf -------------------------------------------------------------------------------- /public/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Blackthorn.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Blackthorn.pdf -------------------------------------------------------------------------------- /public/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Plainshift.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Plainshift.pdf -------------------------------------------------------------------------------- /public/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Sigma_Prime.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Sigma_Prime.pdf -------------------------------------------------------------------------------- /public/events/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/events/.gitkeep -------------------------------------------------------------------------------- /public/images/andres.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/andres.jpeg -------------------------------------------------------------------------------- /public/images/bhargava.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/bhargava.png -------------------------------------------------------------------------------- /public/images/blackthorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/blackthorn.png -------------------------------------------------------------------------------- /public/images/cantina.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /public/images/david.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/david.jpeg -------------------------------------------------------------------------------- /public/images/dedaub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/dedaub.png -------------------------------------------------------------------------------- /public/images/ef.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/ef.jpg -------------------------------------------------------------------------------- /public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/favicon.png -------------------------------------------------------------------------------- /public/images/fredrik-large.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/fredrik-large.jpg -------------------------------------------------------------------------------- /public/images/fredrik.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/fredrik.jpeg -------------------------------------------------------------------------------- /public/images/immunefi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/immunefi.png -------------------------------------------------------------------------------- /public/images/justin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/justin.png -------------------------------------------------------------------------------- /public/images/plainshift.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /public/images/sigp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/sigp.png -------------------------------------------------------------------------------- /public/images/tyler.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/images/tyler.jpeg -------------------------------------------------------------------------------- /public/instances/0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/instances/0.bin -------------------------------------------------------------------------------- /public/instances/1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/instances/1.bin -------------------------------------------------------------------------------- /public/instances/2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/instances/2.bin -------------------------------------------------------------------------------- /public/instances/3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/instances/3.bin -------------------------------------------------------------------------------- /public/instances/4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/instances/4.bin -------------------------------------------------------------------------------- /public/instances/test.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/protocol-security/0653cf9cb6cb72fee4acb27d1b25ad3dedffc492/public/instances/test.bin -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # * 2 | User-agent: * 3 | Allow: / 4 | 5 | # Host 6 | Host: https://security.ethereum.org 7 | 8 | # Sitemaps 9 | Sitemap: https://security.ethereum.org/sitemap.xml 10 | -------------------------------------------------------------------------------- /public/sitemap-0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://security.ethereum.orgdaily0.72025-01-14T21:42:24.561Z 4 | https://security.ethereum.org/blogdaily0.72025-01-14T21:42:24.562Z 5 | https://security.ethereum.org/competitionsdaily0.72025-01-14T21:42:24.562Z 6 | https://security.ethereum.org/eventsdaily0.72025-01-14T21:42:24.562Z 7 | https://security.ethereum.org/teamdaily0.72025-01-14T21:42:24.562Z 8 | -------------------------------------------------------------------------------- /public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://security.ethereum.org/sitemap-0.xml 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | 2 | /* Clean slate for our custom styles */ 3 | #root { 4 | max-width: 100%; 5 | margin: 0; 6 | padding: 0; 7 | text-align: left; 8 | } 9 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Toaster } from "@/components/ui/toaster"; 2 | import { Toaster as Sonner } from "@/components/ui/sonner"; 3 | import { TooltipProvider } from "@/components/ui/tooltip"; 4 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; 5 | import { BrowserRouter, Routes, Route } from "react-router-dom"; 6 | import { ThemeProvider } from "@/components/theme-provider"; 7 | import Index from "./pages/index"; 8 | import NotFound from "./pages/notFound"; 9 | import Team from "./pages/team"; 10 | import Responsibilities from "./pages/responsibilities"; 11 | import Competitions from "./pages/competitions"; 12 | import Blog from "./pages/blog"; 13 | import Audits from "./pages/audits"; 14 | import Wishlist from "./pages/wishlist"; 15 | const queryClient = new QueryClient(); 16 | 17 | const App = () => ( 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | } /> 26 | } /> 27 | } /> 28 | } /> 29 | } /> 30 | } /> 31 | } /> 32 | {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} 33 | } /> 34 | 35 | 36 | 37 | 38 | 39 | ); 40 | 41 | export default App; 42 | -------------------------------------------------------------------------------- /src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | export function Footer() { 2 | const currentYear = new Date().getFullYear(); 3 | 4 | return ( 5 |
6 |
7 |
8 |
9 | 10 | © {currentYear} Ethereum Foundation. All rights reserved. 11 | 12 |
13 |
14 |
15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/components/Navbar.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import { Link, useLocation } from 'react-router-dom'; 3 | import { cn } from '@/lib/utils'; 4 | import { ThemeSwitch } from './ThemeSwitch'; 5 | 6 | const links = [ 7 | { text: 'Team', href: '/team' }, 8 | { text: 'Responsibilities', href: '/responsibilities' }, 9 | { text: 'Competitions', href: '/competitions' }, 10 | { text: 'Audits', href: '/audits' }, 11 | { text: 'Blog', href: '/blog' }, 12 | { text: 'Wishlist', href: '/wishlist' }, 13 | ]; 14 | 15 | export function Navbar() { 16 | const [scrolled, setScrolled] = useState(false); 17 | const [mobileMenuOpen, setMobileMenuOpen] = useState(false); 18 | const location = useLocation(); 19 | 20 | useEffect(() => { 21 | const handleScroll = () => { 22 | const isScrolled = window.scrollY > 20; 23 | if (isScrolled !== scrolled) { 24 | setScrolled(isScrolled); 25 | } 26 | }; 27 | 28 | window.addEventListener('scroll', handleScroll); 29 | return () => window.removeEventListener('scroll', handleScroll); 30 | }, [scrolled]); 31 | 32 | return ( 33 |
41 |
42 | 46 | Home 47 | 48 | 49 | {/* Desktop Navigation */} 50 | 68 | 69 | {/* Mobile Menu Button */} 70 |
71 | 72 | 104 |
105 |
106 | 107 | {/* Mobile Navigation */} 108 | {mobileMenuOpen && ( 109 | 127 | )} 128 |
129 | ); 130 | } 131 | -------------------------------------------------------------------------------- /src/components/ThemeSwitch.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from "@/components/theme-provider"; 2 | import { Button } from "@/components/ui/button"; 3 | import { Moon, Sun } from "lucide-react"; 4 | 5 | export function ThemeSwitch() { 6 | const { theme, setTheme } = useTheme(); 7 | 8 | return ( 9 | 22 | ); 23 | } -------------------------------------------------------------------------------- /src/components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext, useEffect, useState } from "react" 2 | 3 | type Theme = "dark" | "light" | "system" 4 | 5 | type ThemeProviderProps = { 6 | children: React.ReactNode 7 | defaultTheme?: Theme 8 | storageKey?: string 9 | } 10 | 11 | type ThemeProviderState = { 12 | theme: Theme 13 | setTheme: (theme: Theme) => void 14 | } 15 | 16 | const initialState: ThemeProviderState = { 17 | theme: "system", 18 | setTheme: () => null, 19 | } 20 | 21 | const ThemeProviderContext = createContext(initialState) 22 | 23 | export function ThemeProvider({ 24 | children, 25 | defaultTheme = "system", 26 | storageKey = "vite-ui-theme", 27 | ...props 28 | }: ThemeProviderProps) { 29 | const [theme, setTheme] = useState( 30 | () => (localStorage.getItem(storageKey) as Theme) || defaultTheme 31 | ) 32 | 33 | useEffect(() => { 34 | const root = window.document.documentElement 35 | 36 | root.classList.remove("light", "dark") 37 | 38 | if (theme === "system") { 39 | const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") 40 | .matches 41 | ? "dark" 42 | : "light" 43 | 44 | root.classList.add(systemTheme) 45 | return 46 | } 47 | 48 | root.classList.add(theme) 49 | }, [theme]) 50 | 51 | const value = { 52 | theme, 53 | setTheme: (theme: Theme) => { 54 | localStorage.setItem(storageKey, theme) 55 | setTheme(theme) 56 | }, 57 | } 58 | 59 | return ( 60 | 61 | {children} 62 | 63 | ) 64 | } 65 | 66 | export const useTheme = () => { 67 | const context = useContext(ThemeProviderContext) 68 | 69 | if (context === undefined) 70 | throw new Error("useTheme must be used within a ThemeProvider") 71 | 72 | return context 73 | } -------------------------------------------------------------------------------- /src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", 9 | { 10 | variants: { 11 | variant: { 12 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 | destructive: 14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90", 15 | outline: 16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 17 | secondary: 18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 | ghost: "hover:bg-accent hover:text-accent-foreground", 20 | link: "text-primary underline-offset-4 hover:underline", 21 | }, 22 | size: { 23 | default: "h-10 px-4 py-2", 24 | sm: "h-9 rounded-md px-3", 25 | lg: "h-11 rounded-md px-8", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Input = React.forwardRef>( 6 | ({ className, type, ...props }, ref) => { 7 | return ( 8 | 17 | ) 18 | } 19 | ) 20 | Input.displayName = "Input" 21 | 22 | export { Input } 23 | -------------------------------------------------------------------------------- /src/components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from "next-themes" 2 | import { Toaster as Sonner } from "sonner" 3 | 4 | type ToasterProps = React.ComponentProps 5 | 6 | const Toaster = ({ ...props }: ToasterProps) => { 7 | const { theme = "system" } = useTheme() 8 | 9 | return ( 10 | 26 | ) 27 | } 28 | 29 | export { Toaster } 30 | -------------------------------------------------------------------------------- /src/components/ui/toast.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as ToastPrimitives from "@radix-ui/react-toast" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | import { X } from "lucide-react" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const ToastProvider = ToastPrimitives.Provider 9 | 10 | const ToastViewport = React.forwardRef< 11 | React.ElementRef, 12 | React.ComponentPropsWithoutRef 13 | >(({ className, ...props }, ref) => ( 14 | 22 | )) 23 | ToastViewport.displayName = ToastPrimitives.Viewport.displayName 24 | 25 | const toastVariants = cva( 26 | "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", 27 | { 28 | variants: { 29 | variant: { 30 | default: "border bg-background text-foreground", 31 | destructive: 32 | "destructive group border-destructive bg-destructive text-destructive-foreground", 33 | }, 34 | }, 35 | defaultVariants: { 36 | variant: "default", 37 | }, 38 | } 39 | ) 40 | 41 | const Toast = React.forwardRef< 42 | React.ElementRef, 43 | React.ComponentPropsWithoutRef & 44 | VariantProps 45 | >(({ className, variant, ...props }, ref) => { 46 | return ( 47 | 52 | ) 53 | }) 54 | Toast.displayName = ToastPrimitives.Root.displayName 55 | 56 | const ToastAction = React.forwardRef< 57 | React.ElementRef, 58 | React.ComponentPropsWithoutRef 59 | >(({ className, ...props }, ref) => ( 60 | 68 | )) 69 | ToastAction.displayName = ToastPrimitives.Action.displayName 70 | 71 | const ToastClose = React.forwardRef< 72 | React.ElementRef, 73 | React.ComponentPropsWithoutRef 74 | >(({ className, ...props }, ref) => ( 75 | 84 | 85 | 86 | )) 87 | ToastClose.displayName = ToastPrimitives.Close.displayName 88 | 89 | const ToastTitle = React.forwardRef< 90 | React.ElementRef, 91 | React.ComponentPropsWithoutRef 92 | >(({ className, ...props }, ref) => ( 93 | 98 | )) 99 | ToastTitle.displayName = ToastPrimitives.Title.displayName 100 | 101 | const ToastDescription = React.forwardRef< 102 | React.ElementRef, 103 | React.ComponentPropsWithoutRef 104 | >(({ className, ...props }, ref) => ( 105 | 110 | )) 111 | ToastDescription.displayName = ToastPrimitives.Description.displayName 112 | 113 | type ToastProps = React.ComponentPropsWithoutRef 114 | 115 | type ToastActionElement = React.ReactElement 116 | 117 | export { 118 | type ToastProps, 119 | type ToastActionElement, 120 | ToastProvider, 121 | ToastViewport, 122 | Toast, 123 | ToastTitle, 124 | ToastDescription, 125 | ToastClose, 126 | ToastAction, 127 | } 128 | -------------------------------------------------------------------------------- /src/components/ui/toaster.tsx: -------------------------------------------------------------------------------- 1 | import { useToast } from "@/hooks/use-toast" 2 | import { 3 | Toast, 4 | ToastClose, 5 | ToastDescription, 6 | ToastProvider, 7 | ToastTitle, 8 | ToastViewport, 9 | } from "@/components/ui/toast" 10 | 11 | export function Toaster() { 12 | const { toasts } = useToast() 13 | 14 | return ( 15 | 16 | {toasts.map(function ({ id, title, description, action, ...props }) { 17 | return ( 18 | 19 |
20 | {title && {title}} 21 | {description && ( 22 | {description} 23 | )} 24 |
25 | {action} 26 | 27 |
28 | ) 29 | })} 30 | 31 |
32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /src/components/ui/tooltip.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as TooltipPrimitive from "@radix-ui/react-tooltip" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const TooltipProvider = TooltipPrimitive.Provider 7 | 8 | const Tooltip = TooltipPrimitive.Root 9 | 10 | const TooltipTrigger = TooltipPrimitive.Trigger 11 | 12 | const TooltipContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, sideOffset = 4, ...props }, ref) => ( 16 | 25 | )) 26 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 27 | 28 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } 29 | -------------------------------------------------------------------------------- /src/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /src/hooks/use-toast.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import type { 4 | ToastActionElement, 5 | ToastProps, 6 | } from "@/components/ui/toast" 7 | 8 | const TOAST_LIMIT = 1 9 | const TOAST_REMOVE_DELAY = 1000000 10 | 11 | type ToasterToast = ToastProps & { 12 | id: string 13 | title?: React.ReactNode 14 | description?: React.ReactNode 15 | action?: ToastActionElement 16 | } 17 | 18 | const actionTypes = { 19 | ADD_TOAST: "ADD_TOAST", 20 | UPDATE_TOAST: "UPDATE_TOAST", 21 | DISMISS_TOAST: "DISMISS_TOAST", 22 | REMOVE_TOAST: "REMOVE_TOAST", 23 | } as const 24 | 25 | let count = 0 26 | 27 | function genId() { 28 | count = (count + 1) % Number.MAX_SAFE_INTEGER 29 | return count.toString() 30 | } 31 | 32 | type ActionType = typeof actionTypes 33 | 34 | type Action = 35 | | { 36 | type: ActionType["ADD_TOAST"] 37 | toast: ToasterToast 38 | } 39 | | { 40 | type: ActionType["UPDATE_TOAST"] 41 | toast: Partial 42 | } 43 | | { 44 | type: ActionType["DISMISS_TOAST"] 45 | toastId?: ToasterToast["id"] 46 | } 47 | | { 48 | type: ActionType["REMOVE_TOAST"] 49 | toastId?: ToasterToast["id"] 50 | } 51 | 52 | interface State { 53 | toasts: ToasterToast[] 54 | } 55 | 56 | const toastTimeouts = new Map>() 57 | 58 | const addToRemoveQueue = (toastId: string) => { 59 | if (toastTimeouts.has(toastId)) { 60 | return 61 | } 62 | 63 | const timeout = setTimeout(() => { 64 | toastTimeouts.delete(toastId) 65 | dispatch({ 66 | type: "REMOVE_TOAST", 67 | toastId: toastId, 68 | }) 69 | }, TOAST_REMOVE_DELAY) 70 | 71 | toastTimeouts.set(toastId, timeout) 72 | } 73 | 74 | export const reducer = (state: State, action: Action): State => { 75 | switch (action.type) { 76 | case "ADD_TOAST": 77 | return { 78 | ...state, 79 | toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), 80 | } 81 | 82 | case "UPDATE_TOAST": 83 | return { 84 | ...state, 85 | toasts: state.toasts.map((t) => 86 | t.id === action.toast.id ? { ...t, ...action.toast } : t 87 | ), 88 | } 89 | 90 | case "DISMISS_TOAST": { 91 | const { toastId } = action 92 | 93 | // ! Side effects ! - This could be extracted into a dismissToast() action, 94 | // but I'll keep it here for simplicity 95 | if (toastId) { 96 | addToRemoveQueue(toastId) 97 | } else { 98 | state.toasts.forEach((toast) => { 99 | addToRemoveQueue(toast.id) 100 | }) 101 | } 102 | 103 | return { 104 | ...state, 105 | toasts: state.toasts.map((t) => 106 | t.id === toastId || toastId === undefined 107 | ? { 108 | ...t, 109 | open: false, 110 | } 111 | : t 112 | ), 113 | } 114 | } 115 | case "REMOVE_TOAST": 116 | if (action.toastId === undefined) { 117 | return { 118 | ...state, 119 | toasts: [], 120 | } 121 | } 122 | return { 123 | ...state, 124 | toasts: state.toasts.filter((t) => t.id !== action.toastId), 125 | } 126 | } 127 | } 128 | 129 | const listeners: Array<(state: State) => void> = [] 130 | 131 | let memoryState: State = { toasts: [] } 132 | 133 | function dispatch(action: Action) { 134 | memoryState = reducer(memoryState, action) 135 | listeners.forEach((listener) => { 136 | listener(memoryState) 137 | }) 138 | } 139 | 140 | type Toast = Omit 141 | 142 | function toast({ ...props }: Toast) { 143 | const id = genId() 144 | 145 | const update = (props: ToasterToast) => 146 | dispatch({ 147 | type: "UPDATE_TOAST", 148 | toast: { ...props, id }, 149 | }) 150 | const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }) 151 | 152 | dispatch({ 153 | type: "ADD_TOAST", 154 | toast: { 155 | ...props, 156 | id, 157 | open: true, 158 | onOpenChange: (open) => { 159 | if (!open) dismiss() 160 | }, 161 | }, 162 | }) 163 | 164 | return { 165 | id: id, 166 | dismiss, 167 | update, 168 | } 169 | } 170 | 171 | function useToast() { 172 | const [state, setState] = React.useState(memoryState) 173 | 174 | React.useEffect(() => { 175 | listeners.push(setState) 176 | return () => { 177 | const index = listeners.indexOf(setState) 178 | if (index > -1) { 179 | listeners.splice(index, 1) 180 | } 181 | } 182 | }, [state]) 183 | 184 | return { 185 | ...state, 186 | toast, 187 | dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), 188 | } 189 | } 190 | 191 | export { useToast, toast } 192 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | :root { 7 | --background: 0 0% 100%; 8 | --foreground: 240 10% 3.9%; 9 | 10 | --card: 0 0% 100%; 11 | --card-foreground: 240 10% 3.9%; 12 | 13 | --popover: 0 0% 100%; 14 | --popover-foreground: 240 10% 3.9%; 15 | 16 | --primary: 240 5.9% 10%; 17 | --primary-foreground: 0 0% 98%; 18 | 19 | --secondary: 240 4.8% 95.9%; 20 | --secondary-foreground: 240 5.9% 10%; 21 | 22 | --muted: 240 4.8% 95.9%; 23 | --muted-foreground: 240 3.8% 46.1%; 24 | 25 | --accent: 240 4.8% 95.9%; 26 | --accent-foreground: 240 5.9% 10%; 27 | 28 | --destructive: 0 84.2% 60.2%; 29 | --destructive-foreground: 0 0% 98%; 30 | 31 | --border: 240 5.9% 90%; 32 | --input: 240 5.9% 90%; 33 | --ring: 240 5.9% 10%; 34 | 35 | --radius: 0.5rem; 36 | } 37 | 38 | .dark { 39 | --background: 240 10% 3.9%; 40 | --foreground: 0 0% 98%; 41 | 42 | --card: 240 10% 3.9%; 43 | --card-foreground: 0 0% 98%; 44 | 45 | --popover: 240 10% 3.9%; 46 | --popover-foreground: 0 0% 98%; 47 | 48 | --primary: 0 0% 98%; 49 | --primary-foreground: 240 5.9% 10%; 50 | 51 | --secondary: 240 3.7% 15.9%; 52 | --secondary-foreground: 0 0% 98%; 53 | 54 | --muted: 240 3.7% 15.9%; 55 | --muted-foreground: 240 5% 64.9%; 56 | 57 | --accent: 240 3.7% 15.9%; 58 | --accent-foreground: 0 0% 98%; 59 | 60 | --destructive: 0 62.8% 30.6%; 61 | --destructive-foreground: 0 0% 98%; 62 | 63 | --border: 240 3.7% 15.9%; 64 | --input: 240 3.7% 15.9%; 65 | --ring: 240 4.9% 83.9%; 66 | } 67 | } 68 | 69 | @layer base { 70 | * { 71 | @apply border-border; 72 | } 73 | body { 74 | @apply bg-background text-foreground; 75 | font-feature-settings: "rlig" 1, "calt" 1; } 76 | 77 | /* Custom scrollbar */ 78 | ::-webkit-scrollbar { 79 | width: 8px; 80 | } 81 | 82 | ::-webkit-scrollbar-track { 83 | background: hsl(var(--background)); 84 | } 85 | 86 | ::-webkit-scrollbar-thumb { 87 | background: hsl(var(--muted)); 88 | border-radius: 4px; 89 | } 90 | 91 | ::-webkit-scrollbar-thumb:hover { 92 | background: hsl(var(--accent)); 93 | } 94 | } 95 | 96 | @layer utilities { 97 | .hover-underline { 98 | @apply relative after:absolute after:bottom-0 after:left-0 after:h-[2px] after:w-0 after:bg-primary after:transition-all after:duration-300 hover:after:w-full; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client' 2 | import App from './App.tsx' 3 | import './index.css' 4 | 5 | createRoot(document.getElementById("root")!).render(); 6 | -------------------------------------------------------------------------------- /src/pages/audits.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from '@/components/Navbar'; 2 | import { Footer } from '@/components/Footer'; 3 | import { Calendar, FileText, ExternalLink } from 'lucide-react'; 4 | 5 | interface Finding { 6 | severity: 'critical' | 'high' | 'medium' | 'low' | 'info'; 7 | count: number; 8 | } 9 | 10 | interface Audit { 11 | name: string; 12 | auditor: string; 13 | auditorUrl?: string; 14 | logo: string; 15 | date: string; 16 | scope: string; 17 | findings: Finding[]; 18 | pdfUrl?: string; 19 | } 20 | 21 | const audits: Audit[] = [ 22 | { 23 | name: 'Pectra System Contracts Bytecode', 24 | auditor: 'Sigma Prime', 25 | auditorUrl: 'https://sigmaprime.io/', 26 | logo: '/images/sigp.png', 27 | date: 'January 2025', 28 | scope: 'Audit the bytecode of the system contracts involved in the Pectra upgrade', 29 | findings: [ 30 | {severity: 'medium', count: 1}, 31 | {severity: 'low', count: 1}, 32 | {severity: 'info', count: 4}, 33 | ], 34 | pdfUrl: '/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Sigma_Prime.pdf', 35 | }, 36 | { 37 | name: 'Pectra System Contracts Bytecode', 38 | auditor: 'Plainshift', 39 | auditorUrl: 'https://plainshift.io/', 40 | logo: '/images/plainshift.svg', 41 | date: 'December 2024', 42 | scope: 'Audit the bytecode of the system contracts involved in the Pectra upgrade', 43 | findings: [ 44 | {severity: 'low', count: 1}, 45 | {severity: 'info', count: 4}, 46 | ], 47 | pdfUrl: '/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Plainshift.pdf', 48 | }, 49 | { 50 | name: 'EIP 7251', 51 | auditor: 'Dedaub', 52 | auditorUrl: 'https://dedaub.com/', 53 | logo: '/images/dedaub.png', 54 | date: 'December 2024', 55 | scope: 'Audit the EIP 7251 implementation', 56 | findings: [ 57 | { severity: 'medium', count: 1}, 58 | { severity: 'info', count: 3} 59 | ], 60 | pdfUrl: '/audits/EIP_7251_Audit_Report_Dedaub.pdf', 61 | }, 62 | { 63 | name: 'EIP 7002', 64 | auditor: 'Dedaub', 65 | auditorUrl: 'https://dedaub.com/', 66 | logo: '/images/dedaub.png', 67 | date: 'December 2024', 68 | scope: 'Audit the EIP 7002 implementation', 69 | findings: [ 70 | { severity: 'medium', count: 1}, 71 | { severity: 'info', count: 2} 72 | ], 73 | pdfUrl: '/audits/EIP_7002_Audit_Report_Dedaub.pdf', 74 | }, 75 | { 76 | name: 'EIP 2935', 77 | auditor: 'Dedaub', 78 | auditorUrl: 'https://dedaub.com/', 79 | logo: '/images/dedaub.png', 80 | date: 'December 2024', 81 | scope: 'Audit the EIP 2935 implementation', 82 | findings: [ 83 | { severity: 'info', count: 1} 84 | ], 85 | pdfUrl: '/audits/EIP_2935_Audit_Report_Dedaub.pdf', 86 | }, 87 | { 88 | name: 'Pectra System Contracts Bytecode', 89 | auditor: 'Blackthorn', 90 | auditorUrl: 'https://blackthorn.xyz/', 91 | logo: '/images/blackthorn.png', 92 | date: 'December 2024', 93 | scope: 'Audit the bytecode of the system contracts involved in the Pectra upgrade', 94 | findings: [ 95 | { severity: 'medium', count: 1}, 96 | { severity: 'low', count: 16}, 97 | ], 98 | pdfUrl: '/audits/Pectra_System_Contracts_Bytecode_Audit_Report_Blackthorn.pdf', 99 | }, 100 | ]; 101 | 102 | export default function Audits() { 103 | return ( 104 |
105 | 106 |
107 |
108 |
109 |
110 | {audits.map((audit, index) => ( 111 |
115 |
116 |
117 | {audit.logo && ( 118 |
119 | {audit.auditor} 124 |
125 | )} 126 |
127 | 128 |
129 | 130 |
131 |

132 | {audit.name} 133 |

134 | 135 |

136 | {audit.auditorUrl ? ( 137 | 143 | {audit.auditor} 144 | 145 | 146 | ) : ( 147 | audit.auditor 148 | )} 149 |

150 | 151 |

152 | {audit.scope} 153 |

154 | 155 |
156 | {audit.findings.map((finding, idx) => ( 157 | finding.count > 0 && ( 158 | 168 | {finding.count} {finding.severity} 169 | 170 | ) 171 | ))} 172 |
173 | 174 |
175 | 176 | Completed: {audit.date} 177 |
178 | 179 | {audit.pdfUrl && ( 180 | 186 | 187 | View Report 188 | 189 | )} 190 |
191 |
192 |
193 | ))} 194 |
195 |
196 |
197 |
198 |
199 |
200 | ); 201 | } 202 | -------------------------------------------------------------------------------- /src/pages/blog.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Navbar } from '@/components/Navbar'; 3 | import { Footer } from '@/components/Footer'; 4 | import { Link } from 'react-router-dom'; 5 | import { FileText } from 'lucide-react'; 6 | 7 | interface InternalPostMeta { 8 | title: string; 9 | date: string; 10 | } 11 | 12 | interface InternalPost { 13 | slug: string; 14 | frontmatter: InternalPostMeta; 15 | } 16 | 17 | const externalLinks = [ 18 | { 19 | title: 'ETH Rangers Program', 20 | date: '2024-12-02', 21 | link: 'https://blog.ethereum.org/2024/12/02/ethrangers-public-goods' 22 | }, 23 | { 24 | title: 'Ethereum Protocol Attackathon Announcement', 25 | date: '2024-11-25', 26 | link: 'https://blog.ethereum.org/2024/11/25/ethereum-protocol-attackathon' 27 | }, 28 | { 29 | title: 'Secured #6 - Writing Robust C - Best Practices for Finding and Preventing Vulnerabilities', 30 | date: '2023-11-02', 31 | link: 'https://blog.ethereum.org/2023/11/02/writing-robust-c' 32 | }, 33 | { 34 | title: 'Secured #5 - Public Vulnerability Disclosures', 35 | date: '2023-05-03', 36 | link: 'https://blog.ethereum.org/2023/05/03/secured-5-disclosures-update' 37 | }, 38 | { 39 | title: 'Secured #4 - Bug Bounty Rewards to $250,000', 40 | date: '2022-05-16', 41 | link: 'https://blog.ethereum.org/2022/05/16/secured-no-4' 42 | }, 43 | { 44 | title: 'Secured #3 - Security Teams', 45 | date: '2022-04-22', 46 | link: 'https://blog.ethereum.org/2022/04/14/secured-no-3' 47 | }, 48 | { 49 | title: 'Secured #2 - Public Vulnerability Disclosures', 50 | date: '2022-03-09', 51 | link: 'https://blog.ethereum.org/2022/03/09/secured-no-2' 52 | }, 53 | { 54 | title: 'Secured #1 - BLS is Everywhere', 55 | date: '2021-09-09', 56 | link: 'https://blog.ethereum.org/2021/09/09/secured-no-1' 57 | }, 58 | ]; 59 | 60 | function sortByDate(a: { date: string }, b: { date: string }) { 61 | return new Date(b.date).getTime() - new Date(a.date).getTime(); 62 | } 63 | 64 | const Blog: React.FC = () => { 65 | const [internalPosts, setInternalPosts] = useState([]); 66 | const [hovered, setHovered] = useState(null); 67 | 68 | useEffect(() => { 69 | // Vite's import.meta.glob for markdown files 70 | const modules = import.meta.glob('/src/posts/*.md', { eager: true }); 71 | const posts: InternalPost[] = Object.entries(modules).map(([file, mod]: any) => { 72 | const slug = file.split('/').pop()?.replace('.md', '') || ''; 73 | const frontmatter = mod.frontmatter || {}; 74 | return { slug, frontmatter }; 75 | }); 76 | setInternalPosts(posts); 77 | }, []); 78 | 79 | const allPosts = [ 80 | ...internalPosts.map(post => ({ 81 | type: 'internal' as const, 82 | slug: post.slug, 83 | title: post.frontmatter.title, 84 | date: post.frontmatter.date, 85 | })), 86 | ...externalLinks.map(post => ({ 87 | type: 'external' as const, 88 | link: post.link, 89 | title: post.title, 90 | date: post.date, 91 | })), 92 | ].sort(sortByDate); 93 | 94 | return ( 95 |
96 | 97 |
98 |
99 | {allPosts.map((post, i) => { 100 | const iconColor = hovered === i ? "bg-red-500/10 text-red-500" : "bg-muted text-muted-foreground"; 101 | return ( 102 |
setHovered(i)} 105 | onMouseLeave={() => setHovered(null)} 106 | > 107 | {post.type === 'internal' ? ( 108 | 112 |
113 | 114 | 115 | 116 |
117 |
118 | {post.title} 119 |
120 |
{post.date}
121 |
122 |
123 | 124 | ) : ( 125 | 131 |
132 | 133 | 134 | 135 |
136 |
137 | {post.title} 138 |
139 |
{post.date}
140 |
141 |
142 |
143 | )} 144 |
145 | ); 146 | })} 147 |
148 |
149 |
150 |
151 | ); 152 | }; 153 | 154 | export default Blog; 155 | -------------------------------------------------------------------------------- /src/pages/competitions.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from '@/components/Navbar'; 2 | import { Footer } from '@/components/Footer'; 3 | import { Calendar } from 'lucide-react'; 4 | 5 | interface Competition { 6 | name: string; 7 | description: string; 8 | link: string; 9 | pool: string; 10 | startDate: string; 11 | endDate: string; 12 | platform: string; 13 | } 14 | 15 | const competitions: Competition[] = [ 16 | { 17 | name: 'Attackathon | Pectra', 18 | description: ' Competition targetting Pectra specific client code and specifications', 19 | link: 'https://cantina.xyz/competitions/pectra', 20 | pool: '2,000,000 USD', 21 | startDate: '21 February 2025', 22 | endDate: '21 March 2025', 23 | platform: '/images/cantina.svg', 24 | }, 25 | { 26 | name: 'Attackathon | Ethereum Protocol', 27 | description: ' Competition targetting the entire Ethereum protocol', 28 | link: 'https://immunefi.com/audit-competition/ethereum-protocol-attackathon/information/', 29 | pool: '1,500,000 USD', 30 | startDate: '25 November 2024', 31 | endDate: '20 January 2025', 32 | platform: '/images/immunefi.png', 33 | } 34 | ]; 35 | 36 | export default function Competitions() { 37 | return ( 38 |
39 | 40 |
41 |
42 |
43 |
44 | {competitions.map((competition, index) => ( 45 |
49 |
50 |
51 | {competition.platform && ( 52 |
53 | {competition.name} 58 |
59 | )} 60 |
61 | 62 |
63 | 64 |
65 |

66 | {competition.name} 67 |

68 | 69 |

70 | {competition.description} 71 |

72 | 73 |
74 | 77 | {competition.pool} 78 | 79 |
80 | 81 |
82 | 83 | Start: {competition.startDate} 84 |
85 | 86 |
87 | 88 | End: {competition.endDate} 89 |
90 | 91 | 97 | View Competition 98 | 99 |
100 |
101 |
102 | ))} 103 |
104 |
105 |
106 |
107 |
108 |
109 | ); 110 | } 111 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from '@/components/Navbar'; 2 | import { Footer } from '@/components/Footer'; 3 | 4 | export default function Index() { 5 | return ( 6 |
7 | 8 |
9 |
10 |
11 |
12 |

13 | The Protocol Security Research team is one piece of the large puzzle that helps safeguard Ethereum's integrity. 14 | It is a public good team funded by the Ethereum Foundation with ~10 people who each possess different areas 15 | of expertise and experience. 16 |

17 | 18 |

19 | Through coordination, meticulous code reviews, developing and utilizing advanced tooling, and running 20 | real-world simulations, our focus is on securing the network and its critical components. Our hands-on 21 | approach includes managing the bug bounty program, continuously monitoring the network, and collaborating 22 | with client teams and many other teams in the ecosystem. 23 |

24 | 25 |

26 | We're committed to identifying and mitigating risks to Ethereum network. The Protocol Security Research team is often not the most visible team in public, both due to the nature of what we work on, but also 27 | as we primarily try to help empower people in the ecosystem. 28 |

29 |
30 | 31 |
32 |

Contact

33 |

34 | For security-related inquiries or to report vulnerabilities, please contact us at: 35 |

36 | 40 | security@ethereum.org 41 | 42 |
43 |
44 |
45 |
46 |
47 |
48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /src/pages/notFound.tsx: -------------------------------------------------------------------------------- 1 | import { useLocation } from "react-router-dom"; 2 | import { useEffect } from "react"; 3 | 4 | const NotFound = () => { 5 | const location = useLocation(); 6 | 7 | useEffect(() => { 8 | console.error( 9 | "404 Error: User attempted to access non-existent route:", 10 | location.pathname 11 | ); 12 | }, [location.pathname]); 13 | 14 | return ( 15 |
16 |
17 |

404

18 |

Oops! Page not found

19 | 20 | Return to Home 21 | 22 |
23 |
24 | ); 25 | }; 26 | 27 | export default NotFound; 28 | -------------------------------------------------------------------------------- /src/pages/responsibilities.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from '@/components/Navbar'; 2 | import { Footer } from '@/components/Footer'; 3 | 4 | export default function Responsibilities() { 5 | 6 | return ( 7 |
8 | 9 |
10 |
11 |
12 | 13 |
14 |

Coordination & Collaboration

15 |

We spend time coordinating and collaborating with many parts of the ecosystem in order to further help keep Ethereum safe. Some of the things we do are:

16 |
    17 |
  • Vulnerability coordination and collaboration with L2s, L1s, critical dependencies and more for security issues
  • 18 |
  • Protocol Security call series
  • 19 |
  • Coordination and collaboration with external security auditors for protocol related audits
  • 20 |
  • Security coordination and collaboration with client teams and critical dependencies
  • 21 |
  • Coordination and collaboration with researchers from the Ethereum ecosystem, academia and security
  • 22 |
  • Collaboration with teams such as EF Devops and EF Testing
  • 23 |
  • Ongoing collaboration and support for grantees
  • 24 |
  • Support public good projects related to security
  • 25 |
  • Writing the "Secured" series on the EF Blog
  • 26 |
  • Host security challenges such as the Ethereum Protocol Attackathon
  • 27 |
28 |
29 | 30 |
31 |

Bug Bounty Program

32 |

The Protocol Security Research team manages the Ethereum Foundation Bug Bounty Program. We receive reports, triage, provide input, pay bounty rewards and coordinate public disclosures. The bug bounty program covers Ethereum specifications, Ethereum clients, the Solidity compiler and more.

33 |

We also keep a public repository of past results.

34 |
35 | 36 |
37 |

Grants

38 |

We feel that providing resources and funding to security grants is impactful and valuable to the ecosystem. In our opinion, providing funding is often critical, however we also provide our own time as a resource in order to further help projects be successful.

39 | 51 |
52 | 53 |
54 |

Fuzzing

55 |

There is a finite amount of time for manual audits, so we build, maintain and use fuzzers to increase the likelihood of finding vulnerabilities. Many severe vulnerabilities have been found by these fuzzers, and then patched by client teams before they could be found and exploited by a malicious actor.

56 | 57 |

Execution Layer

58 | 67 | 68 |

Consensus Layer

69 |
    70 |
  • Nosy
  • 71 |
  • Private fuzzers
  • 72 |
73 | 74 |

Full Stack

75 | 79 | 80 |

Cryptographic Libraries

81 | 85 |
86 | 87 |
88 |

Manual Reviews

89 |

We spend a lot of time manually reviewing specifications, clients and critical dependencies. Upcoming changes for hardforks are always being continually reviewed and prioritized.

90 | 91 |

Specifications

92 | 96 | 97 |

Clients

98 | 111 | 112 |

Network Libraries

113 | 117 |
118 | 119 |
120 |

Research

121 |

Many hours are spent on security research related to the Ethereum ecosystem. As some of this research could potentially pose a threat, the specific research results may often not end up as public research, but the outcome of the research is rather used to help further secure the Ethereum ecosystem through improvements.

122 |

Some examples of research topics include:

123 |
    124 |
  • Client Diversity
  • 125 |
  • /dev/random Diversity
  • 126 |
  • ZK security research
  • 127 |
  • Threat Analysis
  • 128 |
  • Risk Assessments
  • 129 |
  • L2s
  • 130 |
  • Cryptography
  • 131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | ); 139 | } 140 | -------------------------------------------------------------------------------- /src/pages/team.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from '@/components/Navbar'; 2 | import { Footer } from '@/components/Footer'; 3 | import { Github, Twitter, Globe, MessageCircle } from 'lucide-react'; 4 | 5 | interface TeamMember { 6 | name: string; 7 | description: string; 8 | github?: string; 9 | twitter?: string; 10 | website?: string; 11 | signal?: string; 12 | image: string; 13 | } 14 | 15 | const teamMembers: TeamMember[] = [ 16 | { 17 | name: 'Tyler Holmes', 18 | description: 'Ethereum testnet bootstrapper, multiaddr libraries, kurtosis, and chaos fuzzing.', 19 | github: 'https://github.com/0xTylerHolmes', 20 | twitter: 'https://x.com/0xTylerHolmes', 21 | signal: 'https://signal.me/#eu/qsVdOw5jn9jVo71b5UScjn7ZqaLOv84eceT3u2_Ic5JmoEt8x35K-bSXjdnGs5zs', 22 | image: '/images/tyler.jpeg', 23 | }, 24 | { 25 | name: 'Andrés Láinez', 26 | description: 'Execution layer clients and zkVMs.', 27 | github: 'https://github.com/nethoxa', 28 | twitter: 'https://x.com/nethoxa', 29 | website: 'https://nethoxa.github.io/', 30 | image: '/images/andres.jpeg', 31 | }, 32 | { 33 | name: 'Bhargava Shastry', 34 | description: 'Solidity compilers, fuzzing everything, and networking libraries.', 35 | github: 'https://github.com/bshastry', 36 | twitter: 'https://x.com/ibags', 37 | image: '/images/bhargava.png', 38 | }, 39 | { 40 | name: 'Fredrik Svantes', 41 | description: 'Team lead, all things coordination, bug bounty program, and grants.', 42 | github: 'https://github.com/fredriksvantes', 43 | twitter: 'https://x.com/fredriksvantes', 44 | image: '/images/fredrik.jpeg', 45 | }, 46 | { 47 | name: 'David Theodore', 48 | description: 'ZK security, automated fuzzing, Golang clients, validator safety, and holistic thinker.', 49 | github: 'https://github.com/infosecual', 50 | twitter: 'https://x.com/infosecual', 51 | image: '/images/david.jpeg', 52 | }, 53 | { 54 | name: 'Justin Traglia', 55 | description: 'Manual code review, consensus layer specs/clients, MEV-boost stack, and KZG libraries.', 56 | github: 'https://github.com/jtraglia', 57 | twitter: 'https://x.com/JustinTraglia', 58 | signal: 'https://signal.me/#eu/nFqTWX1iPknqfQa93CuYl6iLjGyKylI3gTPq__SeNTkhGd3w1TBFZ5cwoRH7hFzI', 59 | image: '/images/justin.png', 60 | }, 61 | ]; 62 | 63 | export default function Team() { 64 | return ( 65 |
66 | 67 |
68 |
69 |
70 |
71 | {teamMembers.map((member, index) => ( 72 |
76 |
77 |
78 | {member.name} 83 |
84 | 85 |
86 | 87 |
88 |

89 | {member.name} 90 |

91 | 92 |

93 | {member.description} 94 |

95 | 96 |
97 | {member.github && ( 98 | 99 | 100 | 101 | )} 102 | {member.twitter && ( 103 | 104 | 105 | 106 | )} 107 | {member.website && ( 108 | 109 | 110 | 111 | )} 112 | {member.signal && ( 113 | 114 | 115 | 116 | )} 117 |
118 |
119 |
120 |
121 | ))} 122 |
123 |
124 |
125 |
126 |
127 |
128 | ); 129 | } 130 | -------------------------------------------------------------------------------- /src/pages/wishlist.tsx: -------------------------------------------------------------------------------- 1 | import { Navbar } from '@/components/Navbar'; 2 | import { Footer } from '@/components/Footer'; 3 | 4 | interface WishlistItem { 5 | title: string; 6 | content: string; 7 | } 8 | 9 | const wishlistItems: WishlistItem[] = [ 10 | { 11 | title: "Differential LLMing", 12 | content: "A tool using LLMs to analyze implementations of EIPs and consensus-specs between the different clients to find differences in implementation." 13 | }, 14 | { 15 | title: "LLM Test Generation", 16 | content: "A tool using LLMs to generate relevant missing test cases for the EL and CL specs." 17 | } 18 | ]; 19 | 20 | export default function Wishlist() { 21 | return ( 22 |
23 | 24 |
25 |
26 |
27 |
28 |

29 | This isn't a public RFP document. This is purely a wishlist of tools that the team would find interesting. 30 |

31 |

32 | This repo is meant to hold ideas for tooling that we would love to see someday. 33 |

34 |
35 | 36 |
37 | {wishlistItems.map((item, index) => ( 38 |
42 |
43 |

44 | {item.title} 45 |

46 | 47 |

48 | {item.content} 49 |

50 |
51 |
52 | ))} 53 |
54 |
55 |
56 |
57 |
58 |
59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | import animate from "tailwindcss-animate"; 3 | 4 | export default { 5 | darkMode: ["class"], 6 | content: [ 7 | "./pages/**/*.{ts,tsx}", 8 | "./components/**/*.{ts,tsx}", 9 | "./app/**/*.{ts,tsx}", 10 | "./src/**/*.{ts,tsx}", 11 | ], 12 | prefix: "", 13 | theme: { 14 | container: { 15 | center: true, 16 | padding: '2rem', 17 | screens: { 18 | 'sm': '640px', 19 | 'md': '768px', 20 | 'lg': '1024px', 21 | 'xl': '1280px', 22 | '2xl': '1400px' 23 | } 24 | }, 25 | extend: { 26 | colors: { 27 | border: 'hsl(var(--border))', 28 | input: 'hsl(var(--input))', 29 | ring: 'hsl(var(--ring))', 30 | background: 'hsl(var(--background))', 31 | foreground: 'hsl(var(--foreground))', 32 | primary: { 33 | DEFAULT: 'hsl(var(--primary))', 34 | foreground: 'hsl(var(--primary-foreground))' 35 | }, 36 | secondary: { 37 | DEFAULT: 'hsl(var(--secondary))', 38 | foreground: 'hsl(var(--secondary-foreground))' 39 | }, 40 | destructive: { 41 | DEFAULT: 'hsl(var(--destructive))', 42 | foreground: 'hsl(var(--destructive-foreground))' 43 | }, 44 | muted: { 45 | DEFAULT: 'hsl(var(--muted))', 46 | foreground: 'hsl(var(--muted-foreground))' 47 | }, 48 | accent: { 49 | DEFAULT: 'hsl(var(--accent))', 50 | foreground: 'hsl(var(--accent-foreground))' 51 | }, 52 | popover: { 53 | DEFAULT: 'hsl(var(--popover))', 54 | foreground: 'hsl(var(--popover-foreground))' 55 | }, 56 | card: { 57 | DEFAULT: 'hsl(var(--card))', 58 | foreground: 'hsl(var(--card-foreground))' 59 | }, 60 | sidebar: { 61 | DEFAULT: 'hsl(var(--sidebar-background))', 62 | foreground: 'hsl(var(--sidebar-foreground))', 63 | primary: 'hsl(var(--sidebar-primary))', 64 | 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))', 65 | accent: 'hsl(var(--sidebar-accent))', 66 | 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))', 67 | border: 'hsl(var(--sidebar-border))', 68 | ring: 'hsl(var(--sidebar-ring))' 69 | } 70 | }, 71 | borderRadius: { 72 | lg: 'var(--radius)', 73 | md: 'calc(var(--radius) - 2px)', 74 | sm: 'calc(var(--radius) - 4px)' 75 | }, 76 | keyframes: { 77 | 'accordion-down': { 78 | from: { height: '0' }, 79 | to: { height: 'var(--radix-accordion-content-height)' } 80 | }, 81 | 'accordion-up': { 82 | from: { height: 'var(--radix-accordion-content-height)' }, 83 | to: { height: '0' } 84 | }, 85 | 'fade-in': { 86 | '0%': { opacity: '0', transform: 'translateY(10px)' }, 87 | '100%': { opacity: '1', transform: 'translateY(0)' } 88 | }, 89 | 'fade-out': { 90 | '0%': { opacity: '1', transform: 'translateY(0)' }, 91 | '100%': { opacity: '0', transform: 'translateY(10px)' } 92 | } 93 | }, 94 | animation: { 95 | 'accordion-down': 'accordion-down 0.2s ease-out', 96 | 'accordion-up': 'accordion-up 0.2s ease-out', 97 | 'fade-in': 'fade-in 0.3s ease-out', 98 | 'fade-out': 'fade-out 0.3s ease-out' 99 | } 100 | } 101 | }, 102 | plugins: [animate], 103 | } satisfies Config; 104 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noImplicitAny": true, 22 | "noFallthroughCasesInSwitch": true, 23 | 24 | "baseUrl": ".", 25 | "paths": { 26 | "@/*": ["./src/*"] 27 | } 28 | }, 29 | "include": ["src"] 30 | } 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ], 7 | "compilerOptions": { 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["./src/*"] 11 | }, 12 | "noImplicitAny": false, 13 | "noUnusedParameters": false, 14 | "skipLibCheck": true, 15 | "allowJs": true, 16 | "noUnusedLocals": false, 17 | "strictNullChecks": false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": ["ES2023"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | "noEmit": true, 14 | 15 | /* Linting */ 16 | "strict": true, 17 | "noUnusedLocals": false, 18 | "noUnusedParameters": false, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["vite.config.ts"] 22 | } 23 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react-swc"; 3 | import path from "path"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig(({ mode, command }) => ({ 7 | base: '/', 8 | build: { 9 | outDir: 'dist', 10 | assetsDir: 'assets', 11 | rollupOptions: { 12 | output: { 13 | manualChunks: undefined, 14 | assetFileNames: 'assets/[name].[hash].[ext]' 15 | } 16 | } 17 | }, 18 | server: { 19 | allowedHosts: ["localhost", "security.ethereum.org"], 20 | host: "0.0.0.0", 21 | port: 3000 22 | }, 23 | plugins: [react()], 24 | resolve: { 25 | alias: { 26 | "@": path.resolve(__dirname, "./src"), 27 | }, 28 | }, 29 | })); 30 | --------------------------------------------------------------------------------