Proof of Concept
Demonstration code that proves a vulnerability exists and can be exploited, typically used in security audits and bug bounty submissions.
A Proof of Concept (PoC) is executable code that demonstrates a security vulnerability can be exploited in practice, not just in theory. In smart contract security, PoCs are essential for validating findings, communicating risks to development teams, and substantiating bug bounty submissions. A well-crafted PoC transforms an abstract vulnerability description into concrete, undeniable evidence.
Why PoCs Matter
Security auditors identify potential vulnerabilities through code review, but theoretical issues don't always translate to practical exploits. A PoC bridges this gap by showing exactly how an attacker could exploit the vulnerability, what preconditions are required, and what damage would result.
For bug bounty submissions and competitive audits, PoCs often determine whether a finding is accepted and how it's rated. A vulnerability without a working PoC may be dismissed as theoretical or downgraded in severity. Conversely, a clear PoC demonstrating fund loss or protocol manipulation provides irrefutable evidence of impact.
Development teams benefit from PoCs because they clarify exactly what needs to be fixed. Rather than interpreting a vulnerability description, developers can examine working exploit code and understand the precise attack path. This reduces back-and-forth communication and accelerates remediation.
Anatomy of a Good PoC
Effective PoCs share several characteristics that make them valuable for security communication:
Minimal complexity: The PoC should demonstrate the vulnerability with the least possible code. Extra complexity obscures the core issue and makes the exploit harder to understand. Strip away everything that isn't essential to the attack.
Clear setup and execution: Document the initial state required for the exploit, the sequence of transactions or calls, and the final state proving the vulnerability. Readers should be able to follow the attack step by step.
Realistic conditions: The PoC should work under conditions that could plausibly occur in production. An exploit requiring impossible states or astronomical gas costs isn't practically exploitable.
Measurable impact: Quantify the damage—funds stolen, protocol state corrupted, access controls bypassed. Vague impact statements weaken the finding.
Writing PoCs in Foundry
Foundry has become the preferred framework for writing smart contract PoCs due to its speed and Solidity-native testing. A typical PoC test follows this structure:
1function testExploit() public {2 // Setup: Initialize protocol state3 // Often includes pranking as different users45 // Attack: Execute the exploit6 // Document each step with comments78 // Verify: Assert the vulnerability impact9 // Show funds stolen, state corrupted, etc.10}
Foundry's cheat codes enable powerful PoC capabilities. The vm.prank() function simulates transactions from arbitrary addresses. vm.warp() and vm.roll() manipulate time and block numbers. deal() sets token balances for testing. These tools allow auditors to construct precise attack scenarios.
PoC Best Practices
When creating PoCs for audit submissions or bug bounties, follow these guidelines:
Fork mainnet when relevant: For protocols interacting with existing DeFi infrastructure, fork the actual mainnet state. This proves the exploit works against real contracts, not just test deployments.
Use meaningful variable names: Name variables to clarify their role in the attack. attacker, victim, stolenFunds communicate more than addr1, addr2, amount.
Add console logging: Strategic console.log statements help readers follow the attack flow and verify intermediate states.
Include before/after assertions: Show the relevant state before and after the exploit. This clearly demonstrates the impact.
Test edge cases: If the vulnerability involves boundary conditions, test multiple scenarios to show the full scope of the issue.
PoCs in Bug Bounty Programs
Bug bounty platforms like Immunefi, Code4rena, and CodeHawks have specific requirements for PoC submissions. Most require working PoCs for high and critical severity findings. Some accept theoretical write-ups for lower severity issues, but PoCs always strengthen submissions.
When submitting to bug bounties, ensure your PoC runs against the exact contract versions in scope. Use the correct compiler version and test against the deployed bytecode when possible. Discrepancies between your test environment and production can invalidate otherwise valid findings.
From PoC to Fix Verification
After developers implement a fix, the original PoC becomes a regression test. Run the PoC against the patched code to verify the vulnerability is actually resolved. This verification step catches incomplete fixes and ensures the same attack vector won't reappear.
Many security teams maintain libraries of PoCs from past audits. These serve as educational resources, regression tests, and templates for identifying similar vulnerabilities in future projects. A well-organized PoC archive becomes a valuable asset for any security practice.
Articles Using This Term
Learn more about Proof of Concept in these articles:
Related Terms
Bug Bounty
Reward program incentivizing security researchers to find and report vulnerabilities before malicious exploitation.
Fuzzing
Automated testing technique using randomly generated inputs to discover edge cases and vulnerabilities in smart contracts.
Invariant Testing
Property-based testing approach verifying that critical protocol conditions remain true across all possible execution paths.
Competitive Audit
Public security review where multiple auditors compete to find vulnerabilities with rewards based on severity and discovery priority.
Need expert guidance on Proof of Concept?
Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.
Get a Quote

