# Rédiger Son Premier Rapport d'Audit Smart Contract — Guide Étape par Étape
Vous avez terminé votre premier audit de smart contract. Maintenant, il faut le présenter de manière professionnelle. Voici comment rédiger un rapport qui fera bonne impression.
Structure Standard d'un Rapport
Un rapport d'audit professionnel suit cette structure :
Durée typique : 10-30 pages selon la complexité.
1. Executive Summary
Objectif
Permettre au client (souvent non-technique) de comprendre l'état global en 1 page.
Contenu
## Executive Summary
Project: DeFi Lending Protocol
Audit Period: March 10-20, 2026
Auditors: [Your Name / Company]
Total Issues Found: 12
Severity Breakdown
- Critical: 1
- High: 2
- Medium: 4
- Low: 3
- Informational: 2
Key Findings
The protocol contains one critical vulnerability related to reentrancy
in the withdraw function (Finding C-01). This must be fixed before deployment.
Two high-severity issues related to access control and oracle manipulation
were also identified (H-01, H-02).
Overall Assessment
The codebase shows good development practices with comprehensive tests
(95% coverage). However, critical issues must be addressed immediately.
A follow-up audit is recommended after fixes.
Risk Rating: HIGH (before fixes) → MEDIUM (after fixes)
Ton : Factuel, pas alarmiste. Évitez "le code est nul", préférez "plusieurs améliorations sont recommandées".
2. Scope & Methodology
Scope
Listez exactement ce qui a été audité :
## Audit Scope
In Scope
The following contracts were reviewed:
LendingPool.sol (250 lines)
InterestRateModel.sol (120 lines)
PriceOracle.sol (180 lines)
Governance.sol (200 lines)
Total: 750 lines of code
Commit: abc123def456
Repository: https://github.com/client/defi-protocol
Out of Scope
- Frontend code
- Deployment scripts
- Third-party dependencies (OpenZeppelin, Chainlink)
Important : être précis sur le commit hash audité. Le code peut changer après l'audit.
Methodology
## Methodology
1. Automated Analysis
- Slither: Static analysis for common vulnerabilities
- Aderyn: Rust-based analyzer for gas optimizations
- Mythril: Symbolic execution for edge cases
2. Manual Review
- Line-by-line code review
- Architecture analysis
- Business logic verification
- Access control validation
3. Testing
- Unit test review (95% coverage achieved)
- Integration test creation (5 new scenarios)
- Fork testing against mainnet state
4. Tools Used
- Foundry v0.2.0
- Slither v0.10.0
- Aderyn v0.5.2
- VSCode + Solidity extension
3. Findings — Comment Classer la Sévérité
Échelle de Sévérité Standard
| Sévérité | Impact | Likelihood | Exemples |
|----------|--------|------------|----------|
| Critical | Perte de fonds directe | Facile à exploiter | Reentrancy, unprotected selfdestruct |
| High | Perte de fonds partielle | Exploitable | Access control bugs, oracle manipulation |
| Medium | Comportement inattendu | Conditions spécifiques | Front-running, timestamp dependence |
| Low | Problème mineur | Impact faible | Gas inefficiency, code quality |
| Informational | Best practices | Pas d'impact direct | Missing events, outdated dependencies |
Formule CVSS-like
Certains auditeurs utilisent une formule :
Sévérité = Impact × Likelihood
Impact: 1-5 (1 = cosmétique, 5 = perte totale de fonds)
Likelihood: 1-5 (1 = improbable, 5 = trivial à exploiter)
Score 20-25: Critical
Score 15-19: High
Score 10-14: Medium
Score 5-9: Low
Score 1-4: Informational
Format d'un Finding
Chaque finding suit ce template :
## [C-01] Reentrancy Vulnerability in withdraw()
Severity
Critical
Status
🔴 Unresolved
Description
The withdraw() function in LendingPool.sol performs an external
call before updating the user's balance, allowing for a classic reentrancy attack.
Location
solidity
// LendingPool.sol:45-52
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
(bool success,) = msg.sender.call{value: amount}(""); // ❌ External call first
require(success, "Transfer failed");
balances[msg.sender] -= amount; // ❌ State change after
}
### Impact
An attacker can drain the entire contract balance by recursively calling
withdraw() before their balance is updated.
Proof of Concept
solidity
contract Attacker {
LendingPool pool;
uint256 public attackCount;
constructor(LendingPool _pool) {
pool = _pool;
}
function attack() public payable {
pool.deposit{value: 1 ether}();
pool.withdraw(1 ether);
}
receive() external payable {
if (attackCount < 5) {
attackCount++;
pool.withdraw(1 ether); // Reenter
}
}
}
Result: With 1 ETH deposit, attacker withdraws 5 ETH.
Recommendation
Apply the Checks-Effects-Interactions pattern:
solidity
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount; // ✅ State change first
(bool success,) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
Alternatively, use OpenZeppelin's ReentrancyGuard:solidity
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract LendingPool is ReentrancyGuard {
function withdraw(uint256 amount) public nonReentrant {
// ...
}
}
### References
Éléments Clés
Exemple de Finding Medium
## [M-02] Front-Running Risk in Token Swap
Severity
Medium
Description
The swap() function accepts a user-defined minAmountOut but most
users will use frontend-suggested values, making them vulnerable to
sandwich attacks.
Location
solidity
// DEX.sol:78
function swap(uint amountIn, uint minAmountOut) public {
uint amountOut = calculateSwapOutput(amountIn);
require(amountOut >= minAmountOut, "Slippage too high");
// ...
}
### Impact
Attackers can observe pending swaps in the mempool and front-run with
large trades to manipulate price, then backrun after the victim's swap.
Expected loss: 1-3% per transaction in high-volume periods.
Recommendation
Add a deadline parameter (prevent stale transactions)
Recommend users set slippage to 0.5% max
Consider integrating Flashbots RPC for frontrun protection solidity
function swap(uint amountIn, uint minAmountOut, uint deadline) public {
require(block.timestamp <= deadline, "Transaction too old");
// ...
}
4. Recommendations — Au-delà des Fixes
Cette section contient des conseils généraux :
## General Recommendations
1. Implement Comprehensive Events
Many state-changing functions lack events. Add:
solidity
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount);
### 2. Upgrade to Solidity 0.8.28
The project uses 0.8.20. Version 0.8.28 includes:
- Improved optimizer
- Bug fixes for edge cases
- Better error messages
3. Add NatSpec Documentation
Only 40% of functions have NatSpec comments. Document:
- @notice for external functions
- @param for all parameters
- @return for return values
4. Consider Upgradeability
The protocol is immutable. For future flexibility, consider:
- UUPS proxy pattern (cheaper than Transparent proxy)
- Or deploy with governance-controlled pause mechanism
5. Increase Test Coverage
Current coverage: 95%. Missing coverage:
emergencyWithdraw() edge cases
- Multi-user interaction scenarios
- Fork tests against real Chainlink oracles
5. Annexes
Test Coverage Report
## Annex A: Test Coverage
| Contract | Statements | Branches | Functions |
|----------|------------|----------|-----------|
| LendingPool.sol | 98% | 92% | 100% |
| InterestRateModel.sol | 100% | 100% | 100% |
| PriceOracle.sol | 88% | 75% | 90% |
| Governance.sol | 92% | 85% | 95% |
Overall: 95% statement coverage
Missing Coverage
PriceOracle.sol:125: Edge case when Chainlink returns stale price
Governance.sol:78: Quorum not reached scenario
Tools Output
## Annex B: Automated Tool Results
Slither
15 issues found:
- High: 2 (reentrancy, tx.origin)
- Medium: 5 (timestamp dependence, etc.)
- Low: 8 (gas optimizations)
Full report: slither-report.json
Aderyn
8 issues found:
- Medium: 2
- Low: 6
Full report: aderyn-report.md
Template Complet (Markdown)
Voici un template GitHub à copier :
# Smart Contract Audit Report
Project: [Project Name]
Audit Period: [Start Date] - [End Date]
Auditors: [Your Name / Company]
Version: 1.0
---
Executive Summary
[High-level overview, severity breakdown, key findings, overall assessment]
---
Audit Scope
In Scope
- Contract 1 (X lines)
- Contract 2 (Y lines)
Commit: hash
Out of Scope
- Frontend
- Scripts
---
Methodology
Automated analysis (tools)
Manual review
Testing
---
Findings
Critical
[C-01] Title
- Severity: Critical
- Status: 🔴 Unresolved
- Description: ...
- Location: ...
- Impact: ...
- PoC: ...
- Recommendation: ...
High
[H-01] Title
...
Medium
[M-01] Title
...
Low
[L-01] Title
...
Informational
[I-01] Title
...
---
General Recommendations
Recommendation 1
Recommendation 2
---
Annexes
Annex A: Test Coverage
...
Annex B: Tool Reports
...
Ton et Style
À Faire
✅ Être factuel et précis
✅ Donner du code concret
✅ Citer des sources (SWC, CVE, audits similaires)
✅ Proposer plusieurs solutions quand possible
✅ Utiliser des émojis de status (🔴 Unresolved, 🟢 Resolved, 🟡 Partially Fixed)
À Éviter
❌ Être condescendant ("any junior dev would know this")
❌ Sur-dramatiser ("this will 100% get hacked")
❌ Être vague ("there might be a problem somewhere")
❌ Donner des conseils non-Solidity ("you should fire your dev")
Après l'Audit : Follow-up
Après que le client a corrigé les bugs :
## Follow-Up Report (v1.1)
Re-audit Date: March 25, 2026
Fixes Verification
| Finding | Status | Comment |
|---------|--------|---------|
| C-01 | 🟢 Fixed | ReentrancyGuard added correctly |
| H-01 | 🟢 Fixed | Access control implemented |
| H-02 | 🟡 Partially | Chainlink timeout added, but no fallback oracle |
| M-01 | 🔴 Unresolved | Client decided to accept the risk |
New Issues Introduced
- [L-05] Gas inefficiency in new ReentrancyGuard usage
Final Recommendation
APPROVED for mainnet deployment with noted risk (M-01 accepted by client).
Combien Facturer ?
Prix typiques en 2026 (freelance junior/mid) :
- Solo audit : $5,000 - $15,000 (1-2 semaines)
- Petit protocole : $15,000 - $50,000 (2-4 semaines)
- Protocole DeFi : $50,000 - $200,000+ (4-8 semaines, équipe)
Calcul : ~$500-1500 / jour selon expérience.
Conclusion
Un bon rapport d'audit doit être :
Utilisez ce guide comme template pour votre premier rapport, puis affinez selon votre style.
Et rappelez-vous : un audit ne trouve jamais 100% des bugs. Restez humble, documentez vos limitations (scope), et recommandez toujours des audits multiples pour les protocoles critiques.
Bonne chasse aux bugs.