solidity-argus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +37 -0
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/package.json +43 -0
- package/skills/INVENTORY.md +79 -0
- package/skills/README.md +56 -0
- package/skills/checklists/cyfrin-best-practices-runtime/SKILL.md +424 -0
- package/skills/checklists/cyfrin-best-practices-upgrades/SKILL.md +157 -0
- package/skills/checklists/cyfrin-defi-core/SKILL.md +373 -0
- package/skills/checklists/cyfrin-defi-integrations/SKILL.md +412 -0
- package/skills/checklists/cyfrin-gas/SKILL.md +55 -0
- package/skills/checklists/general-audit/SKILL.md +433 -0
- package/skills/methodology/audit-workflow/SKILL.md +129 -0
- package/skills/methodology/report-template/SKILL.md +190 -0
- package/skills/methodology/severity-classification/SKILL.md +179 -0
- package/skills/protocol-patterns/amm-dex/SKILL.md +229 -0
- package/skills/protocol-patterns/bridges-cross-chain/SKILL.md +317 -0
- package/skills/protocol-patterns/dao-governance/SKILL.md +281 -0
- package/skills/protocol-patterns/lending-borrowing/SKILL.md +221 -0
- package/skills/protocol-patterns/staking-vesting/SKILL.md +247 -0
- package/skills/references/exploit-reference/SKILL.md +259 -0
- package/skills/references/smartbugs-examples/SKILL.md +296 -0
- package/skills/vulnerability-patterns/access-control/SKILL.md +298 -0
- package/skills/vulnerability-patterns/arbitrary-storage-location/SKILL.md +59 -0
- package/skills/vulnerability-patterns/assert-violation/SKILL.md +59 -0
- package/skills/vulnerability-patterns/asserting-contract-from-code-size/SKILL.md +61 -0
- package/skills/vulnerability-patterns/authorization-txorigin/SKILL.md +55 -0
- package/skills/vulnerability-patterns/default-visibility/SKILL.md +62 -0
- package/skills/vulnerability-patterns/delegatecall-untrusted-callee/SKILL.md +60 -0
- package/skills/vulnerability-patterns/dos-gas-limit/SKILL.md +59 -0
- package/skills/vulnerability-patterns/dos-revert/SKILL.md +72 -0
- package/skills/vulnerability-patterns/flash-loan-attacks/SKILL.md +249 -0
- package/skills/vulnerability-patterns/floating-pragma/SKILL.md +51 -0
- package/skills/vulnerability-patterns/hash-collision/SKILL.md +52 -0
- package/skills/vulnerability-patterns/inadherence-to-standards/SKILL.md +61 -0
- package/skills/vulnerability-patterns/incorrect-constructor/SKILL.md +60 -0
- package/skills/vulnerability-patterns/incorrect-inheritance-order/SKILL.md +59 -0
- package/skills/vulnerability-patterns/insufficient-gas-griefing/SKILL.md +61 -0
- package/skills/vulnerability-patterns/lack-of-precision/SKILL.md +61 -0
- package/skills/vulnerability-patterns/logic-errors/SKILL.md +333 -0
- package/skills/vulnerability-patterns/missing-protection-signature-replay/SKILL.md +60 -0
- package/skills/vulnerability-patterns/msgvalue-loop/SKILL.md +66 -0
- package/skills/vulnerability-patterns/off-by-one/SKILL.md +67 -0
- package/skills/vulnerability-patterns/oracle-manipulation/SKILL.md +252 -0
- package/skills/vulnerability-patterns/outdated-compiler-version/SKILL.md +65 -0
- package/skills/vulnerability-patterns/overflow-underflow/SKILL.md +61 -0
- package/skills/vulnerability-patterns/reentrancy/SKILL.md +266 -0
- package/skills/vulnerability-patterns/shadowing-state-variables/SKILL.md +72 -0
- package/skills/vulnerability-patterns/signature-malleability/SKILL.md +59 -0
- package/skills/vulnerability-patterns/unbounded-return-data/SKILL.md +63 -0
- package/skills/vulnerability-patterns/unchecked-return-values/SKILL.md +52 -0
- package/skills/vulnerability-patterns/unencrypted-private-data-on-chain/SKILL.md +65 -0
- package/skills/vulnerability-patterns/unexpected-ecrecover-null-address/SKILL.md +61 -0
- package/skills/vulnerability-patterns/uninitialized-storage-pointer/SKILL.md +63 -0
- package/skills/vulnerability-patterns/unsafe-low-level-call/SKILL.md +56 -0
- package/skills/vulnerability-patterns/unsecure-signatures/SKILL.md +80 -0
- package/skills/vulnerability-patterns/unsupported-opcodes/SKILL.md +69 -0
- package/skills/vulnerability-patterns/unused-variables/SKILL.md +70 -0
- package/skills/vulnerability-patterns/use-of-deprecated-functions/SKILL.md +81 -0
- package/skills/vulnerability-patterns/weak-sources-randomness/SKILL.md +77 -0
- package/skills/vulnerability-patterns/weird-tokens/SKILL.md +294 -0
- package/src/agents/argus-prompt.ts +407 -0
- package/src/agents/pythia-prompt.ts +134 -0
- package/src/agents/scribe-prompt.ts +87 -0
- package/src/agents/sentinel-prompt.ts +133 -0
- package/src/cli/cli-program.ts +67 -0
- package/src/cli/commands/doctor.ts +83 -0
- package/src/cli/commands/init.ts +46 -0
- package/src/cli/commands/install.ts +55 -0
- package/src/cli/index.ts +13 -0
- package/src/cli/tui-prompts.ts +75 -0
- package/src/cli/types.ts +9 -0
- package/src/config/index.ts +3 -0
- package/src/config/loader.ts +36 -0
- package/src/config/schema.ts +82 -0
- package/src/config/types.ts +4 -0
- package/src/constants/defaults.ts +6 -0
- package/src/create-hooks.ts +84 -0
- package/src/create-managers.ts +26 -0
- package/src/create-tools.ts +30 -0
- package/src/features/audit-enforcer/audit-enforcer.ts +34 -0
- package/src/features/audit-enforcer/index.ts +1 -0
- package/src/features/background-agent/background-manager.ts +200 -0
- package/src/features/background-agent/index.ts +1 -0
- package/src/features/context-monitor/context-monitor.ts +48 -0
- package/src/features/context-monitor/index.ts +4 -0
- package/src/features/context-monitor/tool-output-truncator.ts +17 -0
- package/src/features/error-recovery/index.ts +2 -0
- package/src/features/error-recovery/session-recovery.ts +27 -0
- package/src/features/error-recovery/tool-error-recovery.ts +35 -0
- package/src/features/index.ts +5 -0
- package/src/features/persistent-state/audit-state-manager.ts +121 -0
- package/src/features/persistent-state/index.ts +1 -0
- package/src/hooks/compaction-hook.ts +50 -0
- package/src/hooks/config-handler.ts +116 -0
- package/src/hooks/event-hook-v2.ts +93 -0
- package/src/hooks/event-hook.ts +74 -0
- package/src/hooks/hook-system.ts +9 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/knowledge-sync-hook.ts +57 -0
- package/src/hooks/safe-create-hook.ts +15 -0
- package/src/hooks/system-prompt-hook.ts +126 -0
- package/src/hooks/tool-tracking-hook.ts +234 -0
- package/src/hooks/types.ts +16 -0
- package/src/index.ts +36 -0
- package/src/knowledge/scvd-client.ts +242 -0
- package/src/knowledge/scvd-index.ts +183 -0
- package/src/knowledge/scvd-sync.ts +85 -0
- package/src/managers/index.ts +1 -0
- package/src/managers/types.ts +85 -0
- package/src/plugin-interface.ts +38 -0
- package/src/shared/binary-utils.ts +63 -0
- package/src/shared/deep-merge.ts +71 -0
- package/src/shared/file-utils.ts +56 -0
- package/src/shared/index.ts +5 -0
- package/src/shared/jsonc-parser.ts +39 -0
- package/src/shared/logger.ts +36 -0
- package/src/state/audit-state.ts +27 -0
- package/src/state/finding-store.ts +126 -0
- package/src/state/plugin-state.ts +14 -0
- package/src/state/types.ts +61 -0
- package/src/tools/contract-analyzer-tool.ts +184 -0
- package/src/tools/forge-fuzz-tool.ts +311 -0
- package/src/tools/forge-test-tool.ts +397 -0
- package/src/tools/pattern-checker-tool.ts +337 -0
- package/src/tools/report-generator-tool.ts +308 -0
- package/src/tools/slither-tool.ts +465 -0
- package/src/tools/solodit-search-tool.ts +131 -0
- package/src/tools/sync-knowledge-tool.ts +116 -0
- package/src/utils/project-detector.ts +133 -0
- package/src/utils/solidity-parser.ts +174 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: report-template
|
|
3
|
+
description: Reusable smart contract audit report structure with severity IDs, finding sections, and appendices.
|
|
4
|
+
---
|
|
5
|
+
<!-- Source: DeFiFoFum/fofum-solidity-skills (MIT) -->
|
|
6
|
+
|
|
7
|
+
# Audit Report Template
|
|
8
|
+
|
|
9
|
+
## Header
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
# Security Audit Report
|
|
13
|
+
|
|
14
|
+
**Protocol:** [Protocol Name]
|
|
15
|
+
**Version:** [Commit Hash / Version]
|
|
16
|
+
**Auditor:** [Your Name / Firm]
|
|
17
|
+
**Date:** [YYYY-MM-DD]
|
|
18
|
+
**Review Period:** [Start Date] - [End Date]
|
|
19
|
+
|
|
20
|
+
## Scope
|
|
21
|
+
|
|
22
|
+
| Contract | SLOC | Purpose |
|
|
23
|
+
|----------|------|---------|
|
|
24
|
+
| Vault.sol | 245 | Main vault logic |
|
|
25
|
+
| Oracle.sol | 89 | Price feed wrapper |
|
|
26
|
+
|
|
27
|
+
**Out of Scope:**
|
|
28
|
+
- Test files
|
|
29
|
+
- Deployment scripts
|
|
30
|
+
- External dependencies (OpenZeppelin)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Executive Summary
|
|
36
|
+
|
|
37
|
+
```markdown
|
|
38
|
+
## Executive Summary
|
|
39
|
+
|
|
40
|
+
[Protocol Name] is a [brief description]. This audit reviewed [X] contracts
|
|
41
|
+
totaling [Y] lines of code.
|
|
42
|
+
|
|
43
|
+
### Findings Summary
|
|
44
|
+
|
|
45
|
+
| Severity | Count |
|
|
46
|
+
|----------|-------|
|
|
47
|
+
| Critical | 0 |
|
|
48
|
+
| High | 2 |
|
|
49
|
+
| Medium | 3 |
|
|
50
|
+
| Low | 5 |
|
|
51
|
+
| Informational | 4 |
|
|
52
|
+
|
|
53
|
+
### Key Observations
|
|
54
|
+
|
|
55
|
+
- [Positive observation about code quality]
|
|
56
|
+
- [Main concern or risk area]
|
|
57
|
+
- [Recommendation summary]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Finding Format
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
## [H-01] Title Describing the Vulnerability
|
|
66
|
+
|
|
67
|
+
### Severity
|
|
68
|
+
**High**
|
|
69
|
+
|
|
70
|
+
### Location
|
|
71
|
+
`src/Vault.sol:142-156`
|
|
72
|
+
|
|
73
|
+
### Description
|
|
74
|
+
[Clear explanation of the vulnerability, what's wrong, and why it matters]
|
|
75
|
+
|
|
76
|
+
The `withdraw()` function sends ETH to the user before updating their balance,
|
|
77
|
+
creating a reentrancy vulnerability:
|
|
78
|
+
|
|
79
|
+
```solidity
|
|
80
|
+
function withdraw(uint256 amount) external {
|
|
81
|
+
require(balances[msg.sender] >= amount, "Insufficient");
|
|
82
|
+
|
|
83
|
+
(bool success,) = msg.sender.call{value: amount}(""); // External call
|
|
84
|
+
require(success, "Transfer failed");
|
|
85
|
+
|
|
86
|
+
balances[msg.sender] -= amount; // State update AFTER call
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Impact
|
|
91
|
+
An attacker can drain all ETH from the contract by recursively calling
|
|
92
|
+
`withdraw()` before the balance is updated.
|
|
93
|
+
|
|
94
|
+
**Funds at Risk:** All ETH in contract (~$X at time of audit)
|
|
95
|
+
|
|
96
|
+
### Proof of Concept
|
|
97
|
+
|
|
98
|
+
```solidity
|
|
99
|
+
contract Attacker {
|
|
100
|
+
Vault vault;
|
|
101
|
+
|
|
102
|
+
function attack() external payable {
|
|
103
|
+
vault.deposit{value: 1 ether}();
|
|
104
|
+
vault.withdraw(1 ether);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
receive() external payable {
|
|
108
|
+
if (address(vault).balance >= 1 ether) {
|
|
109
|
+
vault.withdraw(1 ether);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Recommendation
|
|
116
|
+
|
|
117
|
+
Apply the Checks-Effects-Interactions (CEI) pattern:
|
|
118
|
+
|
|
119
|
+
```solidity
|
|
120
|
+
function withdraw(uint256 amount) external {
|
|
121
|
+
require(balances[msg.sender] >= amount, "Insufficient");
|
|
122
|
+
|
|
123
|
+
balances[msg.sender] -= amount; // State update BEFORE call
|
|
124
|
+
|
|
125
|
+
(bool success,) = msg.sender.call{value: amount}("");
|
|
126
|
+
require(success, "Transfer failed");
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Alternatively, use OpenZeppelin's `ReentrancyGuard`.
|
|
131
|
+
|
|
132
|
+
### Developer Response
|
|
133
|
+
[Leave space for protocol team to respond]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Finding ID Convention
|
|
139
|
+
|
|
140
|
+
- `[C-XX]` - Critical
|
|
141
|
+
- `[H-XX]` - High
|
|
142
|
+
- `[M-XX]` - Medium
|
|
143
|
+
- `[L-XX]` - Low
|
|
144
|
+
- `[I-XX]` - Informational
|
|
145
|
+
- `[G-XX]` - Gas Optimization
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Appendix Sections
|
|
150
|
+
|
|
151
|
+
```markdown
|
|
152
|
+
## Appendix A: Methodology
|
|
153
|
+
|
|
154
|
+
This audit followed a structured approach:
|
|
155
|
+
1. **Reconnaissance:** Architecture mapping, entry point identification
|
|
156
|
+
2. **Static Analysis:** Slither, compiler warnings
|
|
157
|
+
3. **Manual Review:** Line-by-line review against checklist
|
|
158
|
+
4. **Testing:** Foundry tests for findings
|
|
159
|
+
|
|
160
|
+
## Appendix B: Tools Used
|
|
161
|
+
|
|
162
|
+
- Slither v0.10.0
|
|
163
|
+
- Foundry (forge 0.2.0)
|
|
164
|
+
- VS Code with Solidity extensions
|
|
165
|
+
|
|
166
|
+
## Appendix C: Scope Verification
|
|
167
|
+
|
|
168
|
+
All in-scope contracts were reviewed. The following were explicitly excluded:
|
|
169
|
+
- [List excluded items]
|
|
170
|
+
|
|
171
|
+
## Appendix D: Disclaimer
|
|
172
|
+
|
|
173
|
+
This audit does not guarantee the absence of vulnerabilities. Smart contract
|
|
174
|
+
security is a continuous process, and we recommend ongoing security practices
|
|
175
|
+
including bug bounties, monitoring, and incident response planning.
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Quick Checklist for Report Quality
|
|
181
|
+
|
|
182
|
+
- [ ] All findings have clear titles
|
|
183
|
+
- [ ] Severity is justified
|
|
184
|
+
- [ ] Location includes file:line
|
|
185
|
+
- [ ] Description is understandable by non-experts
|
|
186
|
+
- [ ] Impact quantifies risk where possible
|
|
187
|
+
- [ ] PoC is provided for High/Critical
|
|
188
|
+
- [ ] Recommendation is actionable
|
|
189
|
+
- [ ] Executive summary is concise
|
|
190
|
+
- [ ] Scope is clearly defined
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: severity-classification
|
|
3
|
+
description: Impact-versus-likelihood rubric to classify Solidity findings from informational through critical severity.
|
|
4
|
+
---
|
|
5
|
+
<!-- Source: DeFiFoFum/fofum-solidity-skills (MIT) -->
|
|
6
|
+
|
|
7
|
+
# Severity Classification Guide
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Severity is determined by **Impact × Likelihood**.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
LIKELIHOOD
|
|
15
|
+
Low Medium High
|
|
16
|
+
┌────────┬─────────┬─────────┐
|
|
17
|
+
High │ Medium │ High │Critical │
|
|
18
|
+
IMPACT Med│ Low │ Medium │ High │
|
|
19
|
+
Low │ Info │ Low │ Medium │
|
|
20
|
+
└────────┴─────────┴─────────┘
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Critical
|
|
26
|
+
|
|
27
|
+
**Definition:** Direct, immediate loss of significant funds without requiring user action.
|
|
28
|
+
|
|
29
|
+
**Criteria:**
|
|
30
|
+
- Attacker can drain protocol funds
|
|
31
|
+
- No user interaction required
|
|
32
|
+
- Exploit is profitable and repeatable
|
|
33
|
+
- Funds at risk > $100k (or significant % of TVL)
|
|
34
|
+
|
|
35
|
+
**Examples:**
|
|
36
|
+
- Unprotected withdrawal allowing anyone to drain
|
|
37
|
+
- Price oracle manipulation enabling undercollateralized borrows
|
|
38
|
+
- Reentrancy allowing multiple withdrawals
|
|
39
|
+
|
|
40
|
+
**Required for Report:**
|
|
41
|
+
- Working Foundry PoC
|
|
42
|
+
- Exact funds at risk calculation
|
|
43
|
+
- Step-by-step attack path
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## High
|
|
48
|
+
|
|
49
|
+
**Definition:** Loss of funds requiring specific conditions or user action, OR protocol insolvency risk.
|
|
50
|
+
|
|
51
|
+
**Criteria:**
|
|
52
|
+
- Attacker can steal user funds (with user action)
|
|
53
|
+
- Protocol can become insolvent
|
|
54
|
+
- Permanent freezing of funds
|
|
55
|
+
- Governance takeover
|
|
56
|
+
|
|
57
|
+
**Examples:**
|
|
58
|
+
- Frontrunning user transactions for profit
|
|
59
|
+
- Flash loan attack requiring specific market conditions
|
|
60
|
+
- Permanent DOS of critical functions
|
|
61
|
+
- Missing access control on privileged functions
|
|
62
|
+
|
|
63
|
+
**Required for Report:**
|
|
64
|
+
- PoC or detailed attack scenario
|
|
65
|
+
- Conditions required for exploit
|
|
66
|
+
- Estimated impact
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Medium
|
|
71
|
+
|
|
72
|
+
**Definition:** Conditional loss of funds, protocol disruption, or violation of core invariants.
|
|
73
|
+
|
|
74
|
+
**Criteria:**
|
|
75
|
+
- Loss of funds under unlikely conditions
|
|
76
|
+
- Temporary DOS of non-critical functions
|
|
77
|
+
- Griefing attacks (cost attacker money too)
|
|
78
|
+
- Breaking of stated invariants
|
|
79
|
+
|
|
80
|
+
**Examples:**
|
|
81
|
+
- Rounding errors that leak small amounts over time
|
|
82
|
+
- Incorrect fee calculations
|
|
83
|
+
- Missing slippage protection (user can set it)
|
|
84
|
+
- Stale oracle data used briefly
|
|
85
|
+
|
|
86
|
+
**Required for Report:**
|
|
87
|
+
- Clear explanation of conditions
|
|
88
|
+
- Impact assessment
|
|
89
|
+
- Recommended fix
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Low
|
|
94
|
+
|
|
95
|
+
**Definition:** Minor issues with limited impact, best practice violations.
|
|
96
|
+
|
|
97
|
+
**Criteria:**
|
|
98
|
+
- No direct loss of funds
|
|
99
|
+
- Code quality issues
|
|
100
|
+
- Missing events
|
|
101
|
+
- Inconsistent behavior (not exploitable)
|
|
102
|
+
- Edge cases with minimal impact
|
|
103
|
+
|
|
104
|
+
**Examples:**
|
|
105
|
+
- Missing zero-address validation (with no exploit path)
|
|
106
|
+
- Unlocked compiler version
|
|
107
|
+
- Inconsistent naming conventions
|
|
108
|
+
- Missing natspec documentation
|
|
109
|
+
|
|
110
|
+
**Required for Report:**
|
|
111
|
+
- Issue description
|
|
112
|
+
- Recommended fix
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Informational
|
|
117
|
+
|
|
118
|
+
**Definition:** Gas optimizations, code style, suggestions.
|
|
119
|
+
|
|
120
|
+
**Criteria:**
|
|
121
|
+
- No security impact
|
|
122
|
+
- Potential improvements
|
|
123
|
+
- Gas savings
|
|
124
|
+
|
|
125
|
+
**Examples:**
|
|
126
|
+
- Using `++i` instead of `i++`
|
|
127
|
+
- Caching array length in loops
|
|
128
|
+
- Using `calldata` instead of `memory`
|
|
129
|
+
- Redundant checks
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Special Categories
|
|
134
|
+
|
|
135
|
+
### Centralization Risk
|
|
136
|
+
|
|
137
|
+
**Severity:** Depends on trust model
|
|
138
|
+
|
|
139
|
+
- Single admin key → High (if not disclosed)
|
|
140
|
+
- Multisig + timelock → Low/Info
|
|
141
|
+
- Documented and accepted → Info
|
|
142
|
+
|
|
143
|
+
### Compiler/Dependency Issues
|
|
144
|
+
|
|
145
|
+
**Severity:** Depends on exploitability
|
|
146
|
+
|
|
147
|
+
- Known vulnerable dependency → Medium-Critical
|
|
148
|
+
- Outdated but not vulnerable → Info
|
|
149
|
+
|
|
150
|
+
### Gas Griefing
|
|
151
|
+
|
|
152
|
+
**Severity:** Usually Medium
|
|
153
|
+
|
|
154
|
+
- Can cause transaction failures
|
|
155
|
+
- Can force users to pay more gas
|
|
156
|
+
- Doesn't result in loss of principal
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Severity Comparison: Industry Standards
|
|
161
|
+
|
|
162
|
+
| This Guide | Code4rena | Sherlock | Immunefi |
|
|
163
|
+
|------------|-----------|----------|----------|
|
|
164
|
+
| Critical | High (3) | High | Critical |
|
|
165
|
+
| High | High (2) | High | High |
|
|
166
|
+
| Medium | Medium | Medium | Medium |
|
|
167
|
+
| Low | Low/QA | Low | Low |
|
|
168
|
+
| Info | Gas/QA | Info | None |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Disputes & Edge Cases
|
|
173
|
+
|
|
174
|
+
When severity is unclear:
|
|
175
|
+
|
|
176
|
+
1. **Default to higher severity** when uncertain
|
|
177
|
+
2. **Consider worst-case scenario**
|
|
178
|
+
3. **Account for composability** (other protocols building on top)
|
|
179
|
+
4. **Time-sensitivity** (can it be fixed before exploit?)
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: amm-dex
|
|
3
|
+
description: AMM and DEX security patterns covering pricing, LP accounting, MEV, and swap invariants.
|
|
4
|
+
---
|
|
5
|
+
<!-- Source: DeFiFoFum/fofum-solidity-skills (MIT) -->
|
|
6
|
+
|
|
7
|
+
# AMM (Automated Market Maker) Security Guide
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
AMMs (Uniswap, Curve, Balancer) enable permissionless token swaps via liquidity pools. Core security concerns: price manipulation, MEV, impermanent loss, and LP token accounting.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
19
|
+
│ AMM POOL │
|
|
20
|
+
├─────────────────────────────────────────────────────────────┤
|
|
21
|
+
│ │
|
|
22
|
+
│ x * y = k (Constant Product) │
|
|
23
|
+
│ │
|
|
24
|
+
│ ┌─────────┐ ┌─────────┐ │
|
|
25
|
+
│ │ Token A │ ◄─────► │ Token B │ │
|
|
26
|
+
│ │ Reserve │ │ Reserve │ │
|
|
27
|
+
│ └─────────┘ └─────────┘ │
|
|
28
|
+
│ ▲ ▲ │
|
|
29
|
+
│ │ │ │
|
|
30
|
+
│ ┌─────────────────────────────┐ │
|
|
31
|
+
│ │ LP Token Holders │ │
|
|
32
|
+
│ └─────────────────────────────┘ │
|
|
33
|
+
│ │
|
|
34
|
+
└─────────────────────────────────────────────────────────────┘
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Critical Security Areas
|
|
40
|
+
|
|
41
|
+
### 1. Price Manipulation
|
|
42
|
+
|
|
43
|
+
**Attack Vectors:**
|
|
44
|
+
- Flash loan price manipulation
|
|
45
|
+
- Sandwich attacks
|
|
46
|
+
- JIT (Just-In-Time) liquidity
|
|
47
|
+
|
|
48
|
+
**Checklist:**
|
|
49
|
+
- [ ] Is spot price used for anything critical? (Don't!)
|
|
50
|
+
- [ ] Are there TWAP implementations? Are windows sufficient?
|
|
51
|
+
- [ ] Can price be moved significantly in one transaction?
|
|
52
|
+
- [ ] Is slippage protection enforced?
|
|
53
|
+
|
|
54
|
+
```solidity
|
|
55
|
+
// VULNERABLE: Spot price for external use
|
|
56
|
+
function getPrice() external view returns (uint256) {
|
|
57
|
+
return reserve1 * 1e18 / reserve0; // Manipulatable!
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// SECURE: Accumulator-based TWAP
|
|
61
|
+
function updateTWAP() internal {
|
|
62
|
+
uint32 timeElapsed = block.timestamp - lastUpdate;
|
|
63
|
+
if (timeElapsed > 0) {
|
|
64
|
+
priceAccumulator += getSpotPrice() * timeElapsed;
|
|
65
|
+
lastUpdate = block.timestamp;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 2. Slippage & MEV
|
|
71
|
+
|
|
72
|
+
**Attack Vectors:**
|
|
73
|
+
- User sets 0 slippage tolerance
|
|
74
|
+
- Sandwich attacks when slippage is high
|
|
75
|
+
- Deadline not enforced
|
|
76
|
+
|
|
77
|
+
**Checklist:**
|
|
78
|
+
- [ ] Is minAmountOut enforced?
|
|
79
|
+
- [ ] Is deadline parameter checked?
|
|
80
|
+
- [ ] Are there reasonable slippage bounds?
|
|
81
|
+
- [ ] Is there MEV protection guidance for users?
|
|
82
|
+
|
|
83
|
+
```solidity
|
|
84
|
+
// VULNERABLE: No deadline check
|
|
85
|
+
function swap(uint256 amountIn, uint256 minAmountOut) external {
|
|
86
|
+
// Missing deadline check - tx can be held and executed later
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// SECURE
|
|
90
|
+
function swap(
|
|
91
|
+
uint256 amountIn,
|
|
92
|
+
uint256 minAmountOut,
|
|
93
|
+
uint256 deadline
|
|
94
|
+
) external {
|
|
95
|
+
require(block.timestamp <= deadline, "Expired");
|
|
96
|
+
// ...
|
|
97
|
+
require(amountOut >= minAmountOut, "Slippage");
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3. LP Token Accounting
|
|
102
|
+
|
|
103
|
+
**Attack Vectors:**
|
|
104
|
+
- First depositor inflation attack
|
|
105
|
+
- LP token value manipulation
|
|
106
|
+
- Donation attacks
|
|
107
|
+
|
|
108
|
+
**Checklist:**
|
|
109
|
+
- [ ] Is first LP protected from inflation attack?
|
|
110
|
+
- [ ] Are LP tokens calculated correctly with proper rounding?
|
|
111
|
+
- [ ] Can direct token transfers manipulate LP value?
|
|
112
|
+
- [ ] Is minimum liquidity locked (Uniswap pattern)?
|
|
113
|
+
|
|
114
|
+
```solidity
|
|
115
|
+
// Uniswap V2 first deposit protection
|
|
116
|
+
uint256 public constant MINIMUM_LIQUIDITY = 1000;
|
|
117
|
+
|
|
118
|
+
function mint() external returns (uint256 liquidity) {
|
|
119
|
+
uint256 _totalSupply = totalSupply;
|
|
120
|
+
if (_totalSupply == 0) {
|
|
121
|
+
liquidity = Math.sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY;
|
|
122
|
+
_mint(address(0), MINIMUM_LIQUIDITY); // Lock minimum
|
|
123
|
+
} else {
|
|
124
|
+
liquidity = Math.min(
|
|
125
|
+
amount0 * _totalSupply / _reserve0,
|
|
126
|
+
amount1 * _totalSupply / _reserve1
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 4. Swap Calculations
|
|
133
|
+
|
|
134
|
+
**Attack Vectors:**
|
|
135
|
+
- Rounding errors favoring trader
|
|
136
|
+
- Fee bypass
|
|
137
|
+
- Incorrect constant product maintenance
|
|
138
|
+
|
|
139
|
+
**Checklist:**
|
|
140
|
+
- [ ] Is k always maintained or increasing (k_after ≥ k_before)?
|
|
141
|
+
- [ ] Are fees correctly deducted?
|
|
142
|
+
- [ ] Does rounding favor the pool?
|
|
143
|
+
- [ ] Are there precision issues with small amounts?
|
|
144
|
+
|
|
145
|
+
```solidity
|
|
146
|
+
// VULNERABLE: k can decrease due to rounding
|
|
147
|
+
function swap(uint256 amountIn, uint256 amountOut) external {
|
|
148
|
+
// ... transfer tokens ...
|
|
149
|
+
require(reserve0 * reserve1 >= k, "Invalid k"); // Should be >=
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 5. Reentrancy in Swaps
|
|
154
|
+
|
|
155
|
+
**Attack Vectors:**
|
|
156
|
+
- Callback reentrancy (flash swaps)
|
|
157
|
+
- ERC777/hooks during transfer
|
|
158
|
+
|
|
159
|
+
**Checklist:**
|
|
160
|
+
- [ ] Is reentrancy guard in place?
|
|
161
|
+
- [ ] Are state updates before external calls?
|
|
162
|
+
- [ ] Are callbacks properly restricted?
|
|
163
|
+
- [ ] Is there ERC777 token support? If so, is it safe?
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## AMM-Specific Vulnerabilities
|
|
168
|
+
|
|
169
|
+
### Curve: Read-Only Reentrancy
|
|
170
|
+
|
|
171
|
+
```solidity
|
|
172
|
+
// Curve's virtual_price can be manipulated during reentrancy
|
|
173
|
+
// Attack: Enter pool → in callback, read virtual_price → it's wrong
|
|
174
|
+
|
|
175
|
+
// VULNERABLE: Reading Curve virtual_price during callback
|
|
176
|
+
function deposit(uint256 amount) external {
|
|
177
|
+
uint256 price = curvePool.get_virtual_price(); // Can be manipulated
|
|
178
|
+
uint256 value = amount * price / 1e18;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Uniswap V3: Concentrated Liquidity
|
|
183
|
+
|
|
184
|
+
**Additional concerns:**
|
|
185
|
+
- Tick manipulation
|
|
186
|
+
- Position NFT security
|
|
187
|
+
- Fee calculation across ticks
|
|
188
|
+
|
|
189
|
+
### Balancer: Weighted Pools
|
|
190
|
+
|
|
191
|
+
**Additional concerns:**
|
|
192
|
+
- Weight manipulation in managed pools
|
|
193
|
+
- Complex math (power functions)
|
|
194
|
+
- Multiple token interactions
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Testing Checklist
|
|
199
|
+
|
|
200
|
+
### Unit Tests
|
|
201
|
+
- [ ] Swap calculations match expected output
|
|
202
|
+
- [ ] LP mint/burn accounting
|
|
203
|
+
- [ ] Fee collection accurate
|
|
204
|
+
- [ ] Slippage enforcement
|
|
205
|
+
|
|
206
|
+
### Integration Tests
|
|
207
|
+
- [ ] Multi-hop swaps
|
|
208
|
+
- [ ] Flash swap callbacks
|
|
209
|
+
- [ ] Oracle integrations
|
|
210
|
+
|
|
211
|
+
### Invariant Tests
|
|
212
|
+
- [ ] k_after ≥ k_before (constant product)
|
|
213
|
+
- [ ] Sum of LP tokens = totalSupply
|
|
214
|
+
- [ ] Reserves match actual balances
|
|
215
|
+
- [ ] No tokens created from nothing
|
|
216
|
+
|
|
217
|
+
### Attack Simulations
|
|
218
|
+
- [ ] Sandwich attack simulation
|
|
219
|
+
- [ ] Flash loan manipulation
|
|
220
|
+
- [ ] First depositor attack
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## References
|
|
225
|
+
|
|
226
|
+
- [Uniswap V2 Core](https://github.com/Uniswap/v2-core)
|
|
227
|
+
- [Uniswap V3 Security](https://github.com/Uniswap/v3-core/tree/main/audits)
|
|
228
|
+
- [Curve Read-Only Reentrancy](https://chainsecurity.com/heartbeats/curve-lp-oracle-manipulation/)
|
|
229
|
+
- [Balancer V2 Security](https://docs.balancer.fi/concepts/security/audits.html)
|