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,424 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cyfrin-best-practices-runtime
|
|
3
|
+
description: Cyfrin best-practice checklist focused on runtime heuristics, cross-chain concerns, and timelock controls
|
|
4
|
+
---
|
|
5
|
+
<!-- Source: Cyfrin/audit-checklist -->
|
|
6
|
+
<!-- Auto-generated from https://github.com/Cyfrin/audit-checklist -->
|
|
7
|
+
|
|
8
|
+
# Cyfrin Audit Checklist — Best Practices (Runtime & Cross-chain)
|
|
9
|
+
|
|
10
|
+
### Basics > Version Issues > Solidity Version Issues
|
|
11
|
+
|
|
12
|
+
- [ ] **[SOL-Basics-VI-SVI-1]** Does the contract encode storage structs or arrays with types under 32 bytes directly using experimental ABIEncoderV2? (version 0.5.0~0.5.6)
|
|
13
|
+
- Storage structs and arrays with types shorter than 32 bytes can cause data corruption if encoded directly from storage using the experimental ABIEncoderV2.
|
|
14
|
+
- **Remediation:** Use the latest Solidity version.
|
|
15
|
+
- **References:**
|
|
16
|
+
- https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/
|
|
17
|
+
|
|
18
|
+
- [ ] **[SOL-Basics-VI-SVI-2]** Are there any instances where empty strings are directly passed to function calls? (version ~0.4.11)
|
|
19
|
+
- If an empty string is used in a function call, the following function arguments will not be correctly passed to the function.
|
|
20
|
+
- **Remediation:** Use the latest Solidity version.
|
|
21
|
+
|
|
22
|
+
- [ ] **[SOL-Basics-VI-SVI-3]** Does the optimizer replace specific constants with alternative computations? (version ~0.4.10)
|
|
23
|
+
- In some situations, the optimizer replaces certain numbers in the code with routines that compute different numbers.
|
|
24
|
+
- **Remediation:** Use the latest Solidity version.
|
|
25
|
+
- **References:**
|
|
26
|
+
- https://blog.soliditylang.org/2017/05/03/solidity-optimizer-bug/
|
|
27
|
+
|
|
28
|
+
- [ ] **[SOL-Basics-VI-SVI-4]** Does the contract use `abi.encodePacked`, especially in hash generation? (version >= 0.8.17)
|
|
29
|
+
- If you use `keccak256(abi.encodePacked(a, b))` and both `a` and `b` are dynamic types, it is easy to craft collisions in the hash value by moving parts of `a` into `b` and vice-versa. More specifically, `abi.encodePacked(\'a\', \'bc\') == abi.encodePacked(\'ab\', \'c\').
|
|
30
|
+
- **Remediation:** Use `abi.encode` instead of `abi.encodePacked`.
|
|
31
|
+
- **References:**
|
|
32
|
+
- https://solodit.xyz/issues/m-1-abiencodepacked-allows-hash-collision-sherlock-nftport-nftport-git
|
|
33
|
+
- https://docs.soliditylang.org/en/v0.8.17/abi-spec.html?highlight=collisions#non-standard-packed-mode
|
|
34
|
+
|
|
35
|
+
- [ ] **[SOL-Basics-VI-SVI-5]** BUILD: Is the contract optimized using sequences containing FullInliner with non-expression-split code? (version 0.6.7~0.8.20)
|
|
36
|
+
- Optimizer sequences containing FullInliner do not preserve the evaluation order of arguments of inlined function calls in code that is not in expression-split form.
|
|
37
|
+
- **Remediation:** Use the latest Solidity version.
|
|
38
|
+
- **References:**
|
|
39
|
+
- https://blog.soliditylang.org/2023/07/19/full-inliner-non-expression-split-argument-evaluation-order-bug/
|
|
40
|
+
|
|
41
|
+
- [ ] **[SOL-Basics-VI-SVI-6]** Are there any functions that conditionally terminate inside an inline assembly? (version 0.8.13~0.8.16)
|
|
42
|
+
- Calling functions that conditionally terminate the external EVM call using the assembly statements ``return(...)`` or ``stop()`` may result in incorrect removals of prior storage writes.
|
|
43
|
+
- **Remediation:** Use the latest Solidity version.
|
|
44
|
+
- **References:**
|
|
45
|
+
- https://blog.soliditylang.org/2022/09/08/storage-write-removal-before-conditional-termination/
|
|
46
|
+
|
|
47
|
+
- [ ] **[SOL-Basics-VI-SVI-7]** Are tuples containing a statically-sized calldata array at the end being ABI-encoded? (version 0.5.8~0.8.15)
|
|
48
|
+
- ABI-encoding a tuple with a statically-sized calldata array in the last component would corrupt 32 leading bytes of its first dynamically encoded component.
|
|
49
|
+
- **Remediation:** Use the latest Solidity version.
|
|
50
|
+
- **References:**
|
|
51
|
+
- https://blog.soliditylang.org/2022/08/08/calldata-tuple-reencoding-head-overflow-bug/
|
|
52
|
+
|
|
53
|
+
- [ ] **[SOL-Basics-VI-SVI-8]** Does the contract have functions that copy `bytes` arrays from memory or calldata directly to storage? (version 0.0.1~0.8.14)
|
|
54
|
+
- Copying ``bytes`` arrays from memory or calldata to storage may result in dirty storage values.
|
|
55
|
+
- **Remediation:** Use the latest Solidity version.
|
|
56
|
+
- **References:**
|
|
57
|
+
- https://blog.soliditylang.org/2022/06/15/dirty-bytes-array-to-storage-bug/
|
|
58
|
+
|
|
59
|
+
- [ ] **[SOL-Basics-VI-SVI-9]** Is there a function with multiple inline assembly blocks? (version 0.8.13~0.8.14)
|
|
60
|
+
- The Yul optimizer may incorrectly remove memory writes from inline assembly blocks, that do not access solidity variables.
|
|
61
|
+
- **Remediation:** Use the latest Solidity version.
|
|
62
|
+
- **References:**
|
|
63
|
+
- https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug/
|
|
64
|
+
|
|
65
|
+
- [ ] **[SOL-Basics-VI-SVI-10]** Is a nested array being ABI-encoded or passed directly to an external function? (version 0.5.8~0.8.13)
|
|
66
|
+
- ABI-reencoding of nested dynamic calldata arrays did not always perform proper size checks against the size of calldata and could read beyond `calldatasize()`.
|
|
67
|
+
- **Remediation:** Use the latest Solidity version.
|
|
68
|
+
- **References:**
|
|
69
|
+
- https://blog.soliditylang.org/2022/05/17/calldata-reencode-size-check-bug/
|
|
70
|
+
|
|
71
|
+
- [ ] **[SOL-Basics-VI-SVI-11]** Is `abi.encodeCall` used together with fixed-length bytes literals? (version 0.8.11~0.8.12)
|
|
72
|
+
- Literals used for a fixed length bytes parameter in ``abi.encodeCall`` were encoded incorrectly.
|
|
73
|
+
- **Remediation:** Use the latest Solidity version.
|
|
74
|
+
- **References:**
|
|
75
|
+
- https://blog.soliditylang.org/2022/03/16/encodecall-bug/
|
|
76
|
+
|
|
77
|
+
- [ ] **[SOL-Basics-VI-SVI-12]** Is there any user defined types based on types shorter than 32 bytes? (version =0.8.8)
|
|
78
|
+
- User defined value types with underlying type shorter than 32 bytes used incorrect storage layout and wasted storage
|
|
79
|
+
- **Remediation:** Use the latest Solidity version.
|
|
80
|
+
- **References:**
|
|
81
|
+
- https://blog.soliditylang.org/2021/09/29/user-defined-value-types-bug/
|
|
82
|
+
|
|
83
|
+
- [ ] **[SOL-Basics-VI-SVI-13]** Is there an immutable variable of signed integer type shorter than 256 bits? (version 0.6.5~0.8.8)
|
|
84
|
+
- Immutable variables of signed integer type shorter than 256 bits can lead to values with invalid higher order bits if inline assembly is used.
|
|
85
|
+
- **Remediation:** Use the latest Solidity version.
|
|
86
|
+
- **References:**
|
|
87
|
+
- https://blog.soliditylang.org/2021/09/29/signed-immutables-bug/
|
|
88
|
+
|
|
89
|
+
- [ ] **[SOL-Basics-VI-SVI-14]** Is there any use of `abi.encode` on memory with multi-dimensional array or structs? (version 0.4.16~0.8.3)
|
|
90
|
+
- If used on memory byte arrays, result of the function ``abi.decode`` can depend on the contents of memory outside of the actual byte array that is decoded.
|
|
91
|
+
- **Remediation:** Use the latest Solidity version.
|
|
92
|
+
- **References:**
|
|
93
|
+
- https://blog.soliditylang.org/2021/04/21/decoding-from-memory-bug/
|
|
94
|
+
|
|
95
|
+
- [ ] **[SOL-Basics-VI-SVI-15]** Is there an inline assembly block with `keccak256` inside? (version ~0.8.2)
|
|
96
|
+
- The bytecode optimizer incorrectly re-used previously evaluated Keccak-256 hashes. You are unlikely to be affected if you do not compute Keccak-256 hashes in inline assembly.
|
|
97
|
+
- **Remediation:** Use the latest Solidity version.
|
|
98
|
+
- **References:**
|
|
99
|
+
- https://blog.soliditylang.org/2021/03/23/keccak-optimizer-bug/
|
|
100
|
+
|
|
101
|
+
- [ ] **[SOL-Basics-VI-SVI-16]** Is there a copy of an empty `bytes` or `string` from `memory` or `calldata` to `storage`? (version ~0.7.3)
|
|
102
|
+
- Copying an empty byte array (or string) from memory or calldata to storage can result in data corruption if the target array's length is increased subsequently without storing new data.
|
|
103
|
+
- **Remediation:** Use the latest Solidity version.
|
|
104
|
+
- **References:**
|
|
105
|
+
- https://blog.soliditylang.org/2020/10/19/empty-byte-array-copy-bug/
|
|
106
|
+
|
|
107
|
+
- [ ] **[SOL-Basics-VI-SVI-17]** Is there a dynamically-sized storage-array with types of size at most 16 bytes? (version ~0.7.2)
|
|
108
|
+
- When assigning a dynamically-sized array with types of size at most 16 bytes in storage causing the assigned array to shrink, some parts of deleted slots were not zeroed out.
|
|
109
|
+
- **Remediation:** Use the latest Solidity version.
|
|
110
|
+
- **References:**
|
|
111
|
+
- https://blog.soliditylang.org/2020/10/07/solidity-dynamic-array-cleanup-bug/
|
|
112
|
+
|
|
113
|
+
- [ ] **[SOL-Basics-VI-SVI-18]** Does the library use contract types in events? (version 0.5.0~0.5.7)
|
|
114
|
+
- Contract types used in events in libraries cause an incorrect event signature hash
|
|
115
|
+
- **Remediation:** Use the latest Solidity version.
|
|
116
|
+
|
|
117
|
+
- [ ] **[SOL-Basics-VI-SVI-19]** Does the contract use internal library functions with calldata parameters via `using for`? (version =0.6.9)
|
|
118
|
+
- Function calls to internal library functions with calldata parameters called via ``using for`` can result in invalid data being read.
|
|
119
|
+
- **Remediation:** Use the latest Solidity version.
|
|
120
|
+
|
|
121
|
+
- [ ] **[SOL-Basics-VI-SVI-20]** Are string literals with double backslashes passed directly to external or encoding functions with ABIEncoderV2 enabled? (version 0.5.14~0.6.7)
|
|
122
|
+
- String literals containing double backslash characters passed directly to external or encoding function calls can lead to a different string being used when ABIEncoderV2 is enabled.
|
|
123
|
+
- **Remediation:** Use the latest Solidity version.
|
|
124
|
+
|
|
125
|
+
- [ ] **[SOL-Basics-VI-SVI-21]** Does the contract access slices of dynamic arrays, especially multi-dimensional ones? (version 0.6.0~0.6.7)
|
|
126
|
+
- Accessing array slices of arrays with dynamically encoded base types (e.g. multi-dimensional arrays) can result in invalid data being read.
|
|
127
|
+
- **Remediation:** Use the latest Solidity version.
|
|
128
|
+
|
|
129
|
+
- [ ] **[SOL-Basics-VI-SVI-22]** Is there a contract with creation code, no constructor, but a base with a constructor that accepts non-zero values? (version 0.4.5~0.6.7)
|
|
130
|
+
- The creation code of a contract that does not define a constructor but has a base that does define a constructor did not revert for calls with non-zero value.
|
|
131
|
+
- **Remediation:** Use the latest Solidity version.
|
|
132
|
+
|
|
133
|
+
- [ ] **[SOL-Basics-VI-SVI-23]** Does the contract create extremely large memory arrays? (version 0.2.0~0.6.4)
|
|
134
|
+
- The creation of very large memory arrays can result in overlapping memory regions and thus memory corruption.
|
|
135
|
+
- **Remediation:** Use the latest Solidity version.
|
|
136
|
+
- **References:**
|
|
137
|
+
- https://blog.soliditylang.org/2020/04/06/memory-creation-overflow-bug/
|
|
138
|
+
|
|
139
|
+
- [ ] **[SOL-Basics-VI-SVI-24]** Does the contract's inline assembly with Yul optimizer use assignments inside for loops combined with continue or break? (version =0.6.0)
|
|
140
|
+
- The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.
|
|
141
|
+
- **Remediation:** Use the latest Solidity version.
|
|
142
|
+
|
|
143
|
+
- [ ] **[SOL-Basics-VI-SVI-25]** Does the contract allow private methods to be overridden by inheriting contracts? (version 0.3.0~0.5.16)
|
|
144
|
+
- Private methods can be overridden by inheriting contracts.
|
|
145
|
+
- **Remediation:** Use the latest Solidity version.
|
|
146
|
+
|
|
147
|
+
- [ ] **[SOL-Basics-VI-SVI-26]** Is there any Yul's continue or break statement inside the loop?? (version 0.5.8~0.5.15)
|
|
148
|
+
- The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.
|
|
149
|
+
- **Remediation:** Use the latest Solidity version.
|
|
150
|
+
|
|
151
|
+
- [ ] **[SOL-Basics-VI-SVI-27]** Are both experimental ABIEncoderV2 and Yul optimizer activated? (version =0.5.14)
|
|
152
|
+
- If both the experimental ABIEncoderV2 and the experimental Yul optimizer are activated, one component of the Yul optimizer may reuse data in memory that has been changed in the meantime.
|
|
153
|
+
- **Remediation:** Use the latest Solidity version.
|
|
154
|
+
|
|
155
|
+
- [ ] **[SOL-Basics-VI-SVI-28]** Does the contract read from calldata structs with dynamic yet statically-sized members? (version 0.5.6~0.5.10)
|
|
156
|
+
- Reading from calldata structs that contain dynamically encoded, but statically-sized members can result in incorrect values.
|
|
157
|
+
- **Remediation:** Use the latest Solidity version.
|
|
158
|
+
|
|
159
|
+
- [ ] **[SOL-Basics-VI-SVI-29]** Does the contract assign arrays of signed integers to differently typed storage arrays? (version 0.4.7~0.5.9)
|
|
160
|
+
- Assigning an array of signed integers to a storage array of different type can lead to data corruption in that array.
|
|
161
|
+
- **Remediation:** Use the latest Solidity version.
|
|
162
|
+
- **References:**
|
|
163
|
+
- https://blog.soliditylang.org/2019/06/25/solidity-storage-array-bugs/
|
|
164
|
+
|
|
165
|
+
- [ ] **[SOL-Basics-VI-SVI-30]** Does the contract directly encode storage arrays with structs or static arrays in external calls or abi.encode*? (version 0.4.16~0.5.9)
|
|
166
|
+
- Storage arrays containing structs or other statically-sized arrays are not read properly when directly encoded in external function calls or in abi.encode*.
|
|
167
|
+
- **Remediation:** Use the latest Solidity version.
|
|
168
|
+
- **References:**
|
|
169
|
+
- https://blog.soliditylang.org/2019/06/25/solidity-storage-array-bugs/
|
|
170
|
+
|
|
171
|
+
- [ ] **[SOL-Basics-VI-SVI-31]** Does the contract's constructor accept structs or arrays with dynamic arrays? (version 0.4.16~0.5.8)
|
|
172
|
+
- A contract's constructor that takes structs or arrays that contain dynamically-sized arrays reverts or decodes to invalid data.
|
|
173
|
+
- **Remediation:** Use the latest Solidity version.
|
|
174
|
+
|
|
175
|
+
- [ ] **[SOL-Basics-VI-SVI-32]** Are uninitialized internal function pointers created in the constructor being called? (version 0.5.0~0.5.7)
|
|
176
|
+
- Calling uninitialized internal function pointers created in the constructor does not always revert and can cause unexpected behavior.
|
|
177
|
+
- **Remediation:** Use the latest Solidity version.
|
|
178
|
+
|
|
179
|
+
- [ ] **[SOL-Basics-VI-SVI-33]** Are uninitialized internal function pointers created in the constructor being called? (version 0.4.5~0.4.25)
|
|
180
|
+
- Calling uninitialized internal function pointers created in the constructor does not always revert and can cause unexpected behavior.
|
|
181
|
+
- **Remediation:** Use the latest Solidity version.
|
|
182
|
+
|
|
183
|
+
- [ ] **[SOL-Basics-VI-SVI-34]** Does the library use contract types in events? (version 0.3.0~0.4.25)
|
|
184
|
+
- Contract types used in events in libraries cause an incorrect event signature hash
|
|
185
|
+
- **Remediation:** Use the latest Solidity version.
|
|
186
|
+
|
|
187
|
+
- [ ] **[SOL-Basics-VI-SVI-35]** Does the contract encode storage structs or arrays with types under 32 bytes directly using experimental ABIEncoderV2? (version 0.4.19~0.4.25)
|
|
188
|
+
- Storage structs and arrays with types shorter than 32 bytes can cause data corruption if encoded directly from storage using the experimental ABIEncoderV2.
|
|
189
|
+
- **Remediation:** Use the latest Solidity version.
|
|
190
|
+
- **References:**
|
|
191
|
+
- https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/
|
|
192
|
+
|
|
193
|
+
- [ ] **[SOL-Basics-VI-SVI-36]** Does the contract's optimizer handle byte opcodes with a second argument of 31 or an equivalent constant expression? (version 0.5.5~0.5.6)
|
|
194
|
+
- The optimizer incorrectly handles byte opcodes whose second argument is 31 or a constant expression that evaluates to 31. This can result in unexpected values.
|
|
195
|
+
- **Remediation:** Use the latest Solidity version.
|
|
196
|
+
- **References:**
|
|
197
|
+
- https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/
|
|
198
|
+
|
|
199
|
+
- [ ] **[SOL-Basics-VI-SVI-37]** Are there double bitwise shifts with large constants that might sum up to overflow 256 bits? (version =0.5.5)
|
|
200
|
+
- Double bitwise shifts by large constants whose sum overflows 256 bits can result in unexpected values.
|
|
201
|
+
- **Remediation:** Use the latest Solidity version.
|
|
202
|
+
- **References:**
|
|
203
|
+
- https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/
|
|
204
|
+
|
|
205
|
+
- [ ] **[SOL-Basics-VI-SVI-38]** Is the ** operator used with an exponent type shorter than 256 bits? (version ~0.4.24)
|
|
206
|
+
- Using the ** operator with an exponent of type shorter than 256 bits can result in unexpected values.
|
|
207
|
+
- **Remediation:** Use the latest Solidity version.
|
|
208
|
+
- **References:**
|
|
209
|
+
- https://blog.soliditylang.org/2018/09/13/solidity-bugfix-release/
|
|
210
|
+
|
|
211
|
+
- [ ] **[SOL-Basics-VI-SVI-39]** Are structs used in the logged events? (version 0.4.17~0.4.24)
|
|
212
|
+
- Using structs in events logged wrong data.
|
|
213
|
+
- **Remediation:** Use the latest Solidity version.
|
|
214
|
+
- **References:**
|
|
215
|
+
- https://blog.soliditylang.org/2018/09/13/solidity-bugfix-release/
|
|
216
|
+
|
|
217
|
+
- [ ] **[SOL-Basics-VI-SVI-40]** Are functions returning multi-dimensional fixed-size arrays called? (version 0.1.4~0.4.21)
|
|
218
|
+
- Calling functions that return multi-dimensional fixed-size arrays can result in memory corruption.
|
|
219
|
+
- **Remediation:** Use the latest Solidity version.
|
|
220
|
+
- **References:**
|
|
221
|
+
- https://blog.soliditylang.org/2018/09/13/solidity-bugfix-release/
|
|
222
|
+
|
|
223
|
+
- [ ] **[SOL-Basics-VI-SVI-41]** Does the contract use both new-style and old-style constructors simultaneously? (version =0.4.22)
|
|
224
|
+
- If a contract has both a new-style constructor (using the constructor keyword) and an old-style constructor (a function with the same name as the contract) at the same time, one of them will be ignored.
|
|
225
|
+
- **Remediation:** Use the latest Solidity version.
|
|
226
|
+
|
|
227
|
+
- [ ] **[SOL-Basics-VI-SVI-42]** Is there a function name crafted to potentially override the fallback function execution? (version ~0.4.17)
|
|
228
|
+
- It is possible to craft the name of a function such that it is executed instead of the fallback function in very specific circumstances.
|
|
229
|
+
- **Remediation:** Use the latest Solidity version.
|
|
230
|
+
|
|
231
|
+
- [ ] **[SOL-Basics-VI-SVI-43]** Is the low-level .delegatecall() used without checking the actual execution outcome? (version 0.3.0~0.4.14)
|
|
232
|
+
- The low-level .delegatecall() does not return the execution outcome, but converts the value returned by the functioned called to a boolean instead.
|
|
233
|
+
- **Remediation:** Use the latest Solidity version.
|
|
234
|
+
|
|
235
|
+
- [ ] **[SOL-Basics-VI-SVI-44]** Is the ecrecover() function used without validating its input? (version ~0.4.13)
|
|
236
|
+
- The ecrecover() builtin can return garbage for malformed input.
|
|
237
|
+
- **Remediation:** Use the latest Solidity version.
|
|
238
|
+
|
|
239
|
+
- [ ] **[SOL-Basics-VI-SVI-45]** Is the `.selector` member accessed on complex expressions? (version 0.6.2~0.8.20)
|
|
240
|
+
- Accessing the ``.selector`` member on complex expressions leaves the expression unevaluated in the legacy code generation.
|
|
241
|
+
- **Remediation:** Use the latest Solidity version.
|
|
242
|
+
- **References:**
|
|
243
|
+
- https://blog.soliditylang.org/2023/07/19/missing-side-effects-on-selector-access-bug/
|
|
244
|
+
|
|
245
|
+
- [ ] **[SOL-Basics-VI-SVI-46]** Is there any inconsistency (`memory` vs `calldata`) in the param type during inheritance? (version 0.6.9~0.8.13)
|
|
246
|
+
- It was possible to change the data location of the parameters or return variables from ``calldata`` to ``memory`` and vice-versa while overriding internal and public functions. This caused invalid code to be generated when calling such a function internally through virtual function calls.
|
|
247
|
+
- **Remediation:** Use the latest Solidity version.
|
|
248
|
+
- **References:**
|
|
249
|
+
- https://blog.soliditylang.org/2022/05/17/data-location-inheritance-bug/
|
|
250
|
+
|
|
251
|
+
- [ ] **[SOL-Basics-VI-SVI-47]** Are there any functions with the same name and parameter type inside the same contract? (version =0.7.1)
|
|
252
|
+
- The compiler does not flag an error when two or more free functions with the same name and parameter types are defined in a source unit or when an imported free function alias shadows another free function with a different name but identical parameter types.
|
|
253
|
+
- **Remediation:** Use the latest Solidity version.
|
|
254
|
+
|
|
255
|
+
- [ ] **[SOL-Basics-VI-SVI-48]** Does the contract use tuple assignments with multi-stack-slot components, like nested tuples or dynamic calldata references? (version 0.1.6~0.6.5)
|
|
256
|
+
- Tuple assignments with components that occupy several stack slots, i.e. nested tuples, pointers to external functions or references to dynamically sized calldata arrays, can result in invalid values.
|
|
257
|
+
- **Remediation:** Use the latest Solidity version.
|
|
258
|
+
|
|
259
|
+
### Hash / Merkle Tree
|
|
260
|
+
|
|
261
|
+
- [ ] **[SOL-HMT-1]** Is the Merkle tree vulnerable to front-running attacks?
|
|
262
|
+
- When using a merkle tree, the new proof is calculated at a certain time and there exists a period of time between when the proof is generated and the proof is published.
|
|
263
|
+
- **Remediation:** Ensure that front-running the merkle proof setting does not affect the protocol.
|
|
264
|
+
|
|
265
|
+
- [ ] **[SOL-HMT-2]** Does the claim method validate `msg.sender`?
|
|
266
|
+
- Validation of `msg.sender` is critical in the use of Merkle tree.
|
|
267
|
+
- **Remediation:** Ensure that the `msg.sender` is actually the same address included in the leave.
|
|
268
|
+
|
|
269
|
+
- [ ] **[SOL-HMT-3]** What is the result when passing a zero hash to the Merkle tree functions?
|
|
270
|
+
- Passing the zero hash can lead to unintended behaviors or vulnerabilities if not properly handled.
|
|
271
|
+
- **Remediation:** Implement checks to handle zero hash values appropriately and prevent potential misuse.
|
|
272
|
+
|
|
273
|
+
- [ ] **[SOL-HMT-4]** What occurs if the same proof is duplicated within the Merkle tree?
|
|
274
|
+
- Duplicate proofs within a Merkle tree can lead to double-spending or other vulnerabilities.
|
|
275
|
+
- **Remediation:** Ensure the Merkle tree construction and verification process detects and prevents the use of duplicate proofs.
|
|
276
|
+
|
|
277
|
+
- [ ] **[SOL-HMT-5]** Are the leaves of the Merkle tree hashed with the claimable address included?
|
|
278
|
+
- Not including claimable addresses when hashing leaves can let an attacker to claim.
|
|
279
|
+
- **Remediation:** Ensure that the Merkle tree construction includes the hashing of claimable addresses within the leaves.
|
|
280
|
+
|
|
281
|
+
### Heuristics
|
|
282
|
+
|
|
283
|
+
- [ ] **[SOL-Heuristics-1]** Is there any logic implemented multiple times?
|
|
284
|
+
- Inconsistent implementations of the same logic can introduce errors or vulnerabilities.
|
|
285
|
+
- **Remediation:** Standardize the logic and make it as a separate function.
|
|
286
|
+
|
|
287
|
+
- [ ] **[SOL-Heuristics-2]** Does the contract use any nested structures?
|
|
288
|
+
- If a variable of nested structure is deleted, only the top-level fields are reset by default values (zero) and the nested level fields are not reset.
|
|
289
|
+
- **Remediation:** Always ensure that inner fields are deleted before the outer fields of the structure.
|
|
290
|
+
|
|
291
|
+
- [ ] **[SOL-Heuristics-3]** Is there any unexpected behavior when `src==dst` (or `caller==receiver`)?
|
|
292
|
+
- Overlooking the possibility of a sender and a recipient (source and destination) being the same in smart contracts can lead to unintended problems.
|
|
293
|
+
- **Remediation:** Ensure the protocol behaves as expected when `src==dst`.
|
|
294
|
+
|
|
295
|
+
- [ ] **[SOL-Heuristics-4]** Is the NonReentrant modifier placed before every other modifier?
|
|
296
|
+
- The order of modifiers can influence the behavior of a function. Generally, NonReentrant must come first than other modifiers.
|
|
297
|
+
- **Remediation:** Reorder modifiers so that NonReentrant is placed before other modifiers.
|
|
298
|
+
|
|
299
|
+
- [ ] **[SOL-Heuristics-6]** Did you check the relevant EIP recommendations and security concerns?
|
|
300
|
+
- Incomplete or incorrect implementation of EIP recommendations can lead to vulnerabilities.
|
|
301
|
+
- **Remediation:** Read the recommendations and security concerns and ensure all are implemented as per the official recommendations.
|
|
302
|
+
|
|
303
|
+
- [ ] **[SOL-Heuristics-7]** Are there any off-by-one errors?
|
|
304
|
+
- Off-by-one errors are not rare. Is `<=` correct in this context or should `<` be used? Should a variable be set to the length of a list or the length - 1? Should an iteration start at 1 or 0?
|
|
305
|
+
- **Remediation:** Review all usages of comparison operators for correctness.
|
|
306
|
+
|
|
307
|
+
- [ ] **[SOL-Heuristics-8]** Are logical operators used correctly?
|
|
308
|
+
- Logical operators like `==`, `!=`, `&&`, `||`, `!` can be overlooked especially when the test coverage is not good.
|
|
309
|
+
- **Remediation:** Review all usages of logical operators for correctness.
|
|
310
|
+
|
|
311
|
+
- [ ] **[SOL-Heuristics-9]** What happens if the protocol's contracts are inputted as if they are normal actors?
|
|
312
|
+
- Supplying unexpected addresses can lead to unintended behaviors, especially if the address points to another contract inside the same protocol.
|
|
313
|
+
- **Remediation:** Implement checks to validate receiver addresses and ensure the protocol behaves as expected.
|
|
314
|
+
|
|
315
|
+
- [ ] **[SOL-Heuristics-10]** Are there rounding errors that can be amplified?
|
|
316
|
+
- While minor rounding errors can be inevitable in certain operations, they can pose significant issues if they can be magnified. Amplification can occur when a function is invoked multiple times strategically or under specific conditions.
|
|
317
|
+
- **Remediation:** Conduct thorough tests to identify and understand potential rounding errors. Ensure that they cannot be amplified to a level that would be detrimental to the system or its users. In cases where significant rounding errors are detected, the implementation should be revised to minimize or eliminate them.
|
|
318
|
+
- **References:**
|
|
319
|
+
- https://github.com/OpenCoreCH/smart-contract-audits/blob/main/reports/c4/rigor.md#high-significant-rounding-errors-for-interest-calculation
|
|
320
|
+
|
|
321
|
+
- [ ] **[SOL-Heuristics-11]** Is there any uninitialized state?
|
|
322
|
+
- Checking a variable against its default value might be used to detect initialization. If such defaults can also be valid state, it could lead to vulnerabilities.
|
|
323
|
+
- **Remediation:** Avoid solely relying on default values to determine initialization status.
|
|
324
|
+
|
|
325
|
+
- [ ] **[SOL-Heuristics-12]** Can functions be invoked multiple times with identical parameters?
|
|
326
|
+
- Functions that should be unique per parameters set might be callable multiple times, leading to potential issues.
|
|
327
|
+
- **Remediation:** Ensure functions have measures to prevent repeated calls with identical or similar parameters, especially when these calls can produce adverse effects.
|
|
328
|
+
|
|
329
|
+
- [ ] **[SOL-Heuristics-13]** Is the global state updated correctly?
|
|
330
|
+
- While working with a `memory` copy for optimization, developers might overlook updating the global state.
|
|
331
|
+
- **Remediation:** Always ensure the global state mirrors changes made in `memory`. Consider tools or extensions that can highlight discrepancies.
|
|
332
|
+
|
|
333
|
+
- [ ] **[SOL-Heuristics-14]** Is ETH/WETH handling implemented correctly?
|
|
334
|
+
- Contracts might have special logic for ETH, like wrapping to WETH. Assuming exclusivity between handling ETH and WETH without checks can introduce errors.
|
|
335
|
+
- **Remediation:** Clearly differentiate the logic between ETH and WETH handling, ensuring no overlap or mutual exclusivity assumptions without validation.
|
|
336
|
+
|
|
337
|
+
- [ ] **[SOL-Heuristics-15]** Does the protocol put any sensitive data on the blockchain?
|
|
338
|
+
- Data on the blockchain, including that marked 'private' in smart contracts, is visible to anyone who knows how to query the blockchain's state or analyze its transaction history. Private variables are not exempt from public inspection.
|
|
339
|
+
- **Remediation:** Sensitive data should either be kept off-chain or encrypted before being stored on-chain. It's important to manage encryption keys securely and ensure that on-chain data does not expose private information even when encrypted, if the encryption method is weak or the keys are mishandled.
|
|
340
|
+
|
|
341
|
+
- [ ] **[SOL-Heuristics-16]** Are there any code asymmetries?
|
|
342
|
+
- In many projects, there should be some symmetries for different functions. For instance, a `withdraw` function should (usually) undo all the state changes of a `deposit` function and a `delete` function should undo all the state changes of the corresponding `add` function. Asymmetries in these function pairs (e.g., forgetting to unset a field or to subtract from a value) can often lead to undesired behavior. Sometimes one side of a 'pair' is missing, like missing removing from a whitelist while there is a function to add to a whitelist.
|
|
343
|
+
- **Remediation:** Review paired functions for symmetry and ensure they counteract each other's state changes appropriately.
|
|
344
|
+
- **References:**
|
|
345
|
+
- https://github.com/OpenCoreCH/smart-contract-auditing-heuristics#code-asymmetries
|
|
346
|
+
|
|
347
|
+
- [ ] **[SOL-Heuristics-17]** Does calling a function multiple times with smaller amounts yield the same contract state as calling it once with the aggregate amount?
|
|
348
|
+
- Associative properties of certain financial operations suggest that performing the operation multiple times with smaller amounts should yield an equivalent outcome as performing it once with the aggregate amount. Variations might be indicative of potential issues such as rounding errors, unintended fee accumulations, or other inconsistencies.
|
|
349
|
+
- **Remediation:** Implement tests to validate consistency. Where discrepancies exist, ensure they are intentional, minimal, and well-documented. If discrepancies are unintended, reevaluate the implementation to ensure precision and correctness.
|
|
350
|
+
|
|
351
|
+
### Multi-chain/Cross-chain
|
|
352
|
+
|
|
353
|
+
- [ ] **[SOL-McCc-1]** Are there assumption of consistency in the `block.number` or `block.timestamp` across chains?
|
|
354
|
+
- Block time can vary across different chains, leading to potential timing discrepancies.
|
|
355
|
+
- **Remediation:** Avoid comparing timestamp or block numbers for different chains.
|
|
356
|
+
- **References:**
|
|
357
|
+
- https://solodit.cyfrin.io/issues/m-06-l1xrenzobridge-and-l2xrenzobridge-uses-the-blocktimestamp-as-dependency-which-can-cause-issues-code4rena-renzo-renzo-git
|
|
358
|
+
|
|
359
|
+
- [ ] **[SOL-McCc-2]** Has the protocol been checked for the target chain differences?
|
|
360
|
+
- Understanding the differences between chains is vital for ensuring compatibility and preventing unexpected behaviors.
|
|
361
|
+
- **Remediation:** Regularly check for chain differences and update the protocol accordingly.
|
|
362
|
+
- **References:**
|
|
363
|
+
- https://www.evmdiff.com/diff?base=1&target=10
|
|
364
|
+
- https://github.com/0xJuancito/multichain-auditor#differences-from-ethereum
|
|
365
|
+
|
|
366
|
+
- [ ] **[SOL-McCc-3]** Are the EVM opcodes and operations used by the protocol compatible across all targeted chains?
|
|
367
|
+
- Incompatibility can arise when the protocol uses EVM operations not supported on certain chains.
|
|
368
|
+
- **Remediation:** Review and ensure compatibility for chains like Arbitrum and Optimism.
|
|
369
|
+
- **References:**
|
|
370
|
+
- https://docs.arbitrum.io/solidity-support
|
|
371
|
+
- https://community.optimism.io/docs/developers/build/differences/#transaction-costs
|
|
372
|
+
|
|
373
|
+
- [ ] **[SOL-McCc-4]** Does the expected behavior of `tx.origin` and `msg.sender` remain consistent across all deployment chains?
|
|
374
|
+
- Different chains might interpret these values differently, leading to unexpected behaviors.
|
|
375
|
+
- **Remediation:** Test and verify the behavior on all targeted chains.
|
|
376
|
+
- **References:**
|
|
377
|
+
- https://community.optimism.io/docs/developers/build/differences/#opcode-differences
|
|
378
|
+
|
|
379
|
+
- [ ] **[SOL-McCc-6]** Is there consistency in ERC20 decimals across chains?
|
|
380
|
+
- Decimals in ERC20 tokens can differ across chains.
|
|
381
|
+
- **Remediation:** Ensure consistent ERC20 decimals or implement chain-specific adjustments.
|
|
382
|
+
- **References:**
|
|
383
|
+
- https://github.com/0xJuancito/multichain-auditor#erc20-decimals
|
|
384
|
+
|
|
385
|
+
- [ ] **[SOL-McCc-7]** Have contract upgradability implications been evaluated on different chains?
|
|
386
|
+
- Contracts may have different upgradability properties depending on the chain, like USDT being upgradable on Polygon but not on Ethereum.
|
|
387
|
+
- **Remediation:** Verify and document upgradability characteristics for each chain.
|
|
388
|
+
|
|
389
|
+
- [ ] **[SOL-McCc-8]** Have cross-chain messaging implementations been thoroughly reviewed for permissions and functionality?
|
|
390
|
+
- Cross-chain messaging requires robust security checks to ensure the correct permissions and intended functionality.
|
|
391
|
+
- **Remediation:** Double check the access control over cross-chain messaging components.
|
|
392
|
+
|
|
393
|
+
- [ ] **[SOL-McCc-9]** Is there a whitelist of compatible chains?
|
|
394
|
+
- Allowing messages from an unsupported chain can lead to unpredictable results.
|
|
395
|
+
- **Remediation:** Implement a whitelist to prevent messages from unsupported chains.
|
|
396
|
+
|
|
397
|
+
- [ ] **[SOL-McCc-10]** Have contracts been checked for compatibility when deployed to the zkSync Era?
|
|
398
|
+
- zkSync Era might have specific requirements or differences when compared to standard Ethereum deployments.
|
|
399
|
+
- **Remediation:** Review and ensure compatibility before deploying contracts to zkSync Era.
|
|
400
|
+
- **References:**
|
|
401
|
+
- https://era.zksync.io/docs/reference/architecture/differences-with-ethereum.html
|
|
402
|
+
|
|
403
|
+
- [ ] **[SOL-McCc-11]** Is block production consistency ensured?
|
|
404
|
+
- Inconsistent block production can lead to unexpected application behaviors.
|
|
405
|
+
- **Remediation:** Develop with the assumption that block production may not always be consistent.
|
|
406
|
+
|
|
407
|
+
- [ ] **[SOL-McCc-12]** Is `PUSH0` opcode supported for Solidity version `>=0.8.20`?
|
|
408
|
+
- `PUSH0` might not be supported on all chains, leading to potential incompatibility issues.
|
|
409
|
+
- **Remediation:** Ensure if `PUSH0` is supported in the target chain.
|
|
410
|
+
- **References:**
|
|
411
|
+
- https://github.com/0xJuancito/multichain-auditor#support-for-the-push0-opcode
|
|
412
|
+
|
|
413
|
+
- [ ] **[SOL-McCc-13]** Are there any attributes attached to the bridged assets?
|
|
414
|
+
- When assets (e.g. tokens) are bridged across chains, the relevant attributes (e.g. approval) must be bridged or reset accordingly.
|
|
415
|
+
- **Remediation:** Ensure accounting all the relevant attributes when assets are bridged.
|
|
416
|
+
- **References:**
|
|
417
|
+
- https://solodit.cyfrin.io/issues/not-update-rewards-in-handleincomingupdate-function-of-sdlpoolprimary-leads-to-incorrect-reward-calculations-codehawks-stakelink-git
|
|
418
|
+
|
|
419
|
+
### Timelock
|
|
420
|
+
|
|
421
|
+
- [ ] **[SOL-Timelock-1]** Are timelocks implemented for important changes?
|
|
422
|
+
- Immediate changes in the protocol can affect the users.
|
|
423
|
+
- **Remediation:** Implement timelocks for important changes, allowing users adequate time to respond to proposed alterations.
|
|
424
|
+
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cyfrin-best-practices-upgrades
|
|
3
|
+
description: Cyfrin best-practice checklist focused on proxy, upgradeability, and versioning concerns
|
|
4
|
+
---
|
|
5
|
+
<!-- Source: Cyfrin/audit-checklist -->
|
|
6
|
+
<!-- Auto-generated from https://github.com/Cyfrin/audit-checklist -->
|
|
7
|
+
<!-- Total items: 112 -->
|
|
8
|
+
|
|
9
|
+
# Cyfrin Audit Checklist — Best Practices (Upgrades & Versioning)
|
|
10
|
+
|
|
11
|
+
Best practice checklist items from [Cyfrin's audit checklist](https://github.com/Cyfrin/audit-checklist).
|
|
12
|
+
|
|
13
|
+
Covers: proxy/upgradable patterns, Solidity version issues, OpenZeppelin version issues, EIP adoption, multi-chain/cross-chain considerations, timelocks, Merkle tree validation, block reorganization, and general heuristics for code quality.
|
|
14
|
+
|
|
15
|
+
## Checklist Items
|
|
16
|
+
|
|
17
|
+
### Basics > Block Reorganization
|
|
18
|
+
|
|
19
|
+
- [ ] **[SOL-Basics-BR-1]** Does the protocol implement a factory pattern using the CREATE opcode?
|
|
20
|
+
- Contracts created with the CREATE opcode will be eliminated if a block reorg happens.
|
|
21
|
+
- **Remediation:** Use CREATE2 instead of CREATE.
|
|
22
|
+
- **References:**
|
|
23
|
+
- https://solodit.xyz/issues/m-08-factorycreate-is-vulnerable-to-reorg-attacks-code4rena-abracadabra-money-abracadabra-money-git
|
|
24
|
+
- https://solodit.xyz/issues/m-02-reorg-attack-on-users-vault-deployment-and-deposit-may-lead-to-theft-of-funds-code4rena-amphora-protocol-amphora-protocol-git
|
|
25
|
+
- https://solodit.xyz/issues/m-4-loss-of-bond-amounts-on-re-org-attacks-sherlock-optimism-fault-proofs-git
|
|
26
|
+
- https://solodit.xyz/issues/m-01-questfactory-is-suspicious-of-the-reorg-attack-code4rena-rabbithole-rabbithole-quest-protocol-contest-git
|
|
27
|
+
- https://solodit.xyz/issues/m-14-re-org-attack-in-factory-code4rena-frankencoin-frankencoin-git
|
|
28
|
+
|
|
29
|
+
### Basics > Proxy/Upgradable
|
|
30
|
+
|
|
31
|
+
- [ ] **[SOL-Basics-PU-1]** Is there a constructor in the proxied contract?
|
|
32
|
+
- Proxied contract can't have a constructor and it's common to move constructor logic to an external initializer function, usually called initialize
|
|
33
|
+
- **Remediation:** Use initializer functions for initialization of proxied contracts.
|
|
34
|
+
|
|
35
|
+
- [ ] **[SOL-Basics-PU-2]** Is the `initializer` modifier applied to the `initialization()` function?
|
|
36
|
+
- Without the `initializer` modifier, there is a risk that the initialization function can be called multiple times.
|
|
37
|
+
- **Remediation:** Always use the `initializer` modifier for initialization functions in proxied contracts and ensure they're called once during deployment.
|
|
38
|
+
|
|
39
|
+
- [ ] **[SOL-Basics-PU-3]** Is the upgradable version used for initialization?
|
|
40
|
+
- Upgradable contracts must use the upgradable versions of parent initializer functions. (e.g. Pausable vs PausableUpgradable)
|
|
41
|
+
- **Remediation:** Use upgradable versions of parent initializer functions.
|
|
42
|
+
|
|
43
|
+
- [ ] **[SOL-Basics-PU-4]** Is the `authorizeUpgrade()` function properly secured in a UUPS setup?
|
|
44
|
+
- Inadequate security on the `authorizeUpgrade()` function can allow unauthorized upgrades.
|
|
45
|
+
- **Remediation:** Ensure proper access controls and checks are in place for the `authorizeUpgrade()` function.
|
|
46
|
+
|
|
47
|
+
- [ ] **[SOL-Basics-PU-5]** Is the contract initialized?
|
|
48
|
+
- An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy.
|
|
49
|
+
- **Remediation:** To prevent the implementation contract from being used, invoke the `_disableInitializers` function in the constructor to automatically lock it when it is deployed.
|
|
50
|
+
- **References:**
|
|
51
|
+
- https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable
|
|
52
|
+
|
|
53
|
+
- [ ] **[SOL-Basics-PU-6]** Are `selfdestruct` and `delegatecall` used within the implementation contracts?
|
|
54
|
+
- Using `selfdestruct` and `delegatecall` in implementation contracts can introduce vulnerabilities and unexpected behavior in a proxy setup.
|
|
55
|
+
- **Remediation:** Avoid using `selfdestruct` and `delegatecall` in implementation contracts to ensure contract stability and security.
|
|
56
|
+
|
|
57
|
+
- [ ] **[SOL-Basics-PU-7]** Are values in immutable variables preserved between upgrades?
|
|
58
|
+
- Immutable variables are stored in the bytecode, not in the proxy storage. So using immutable variable is not recommended in proxy setup. If used, make sure all immutables stay consistent across implementations during upgrades.
|
|
59
|
+
- **Remediation:** Avoid using immutable variables in upgradable contracts.
|
|
60
|
+
|
|
61
|
+
- [ ] **[SOL-Basics-PU-8]** Has the contract inherited the correct branch of OpenZeppelin library?
|
|
62
|
+
- Sometimes developers overlook and use an incorrect branch of OZ library, e.g. use Ownable instead of OwnableUpgradeable.
|
|
63
|
+
- **Remediation:** Make sure inherit the correct branch of OZ library according to the contract's upgradeability design.
|
|
64
|
+
- **References:**
|
|
65
|
+
- https://solodit.xyz/issues/h-01-usage-of-an-incorrect-version-of-ownbale-library-can-potentially-malfunction-all-onlyowner-functions-code4rena-covalent-covalent-contest-git
|
|
66
|
+
|
|
67
|
+
- [ ] **[SOL-Basics-PU-9]** Could an upgrade of the contract result in storage collision?
|
|
68
|
+
- Storage collisions can occur when storage layouts between contract versions conflict, leading to data corruption and unpredictable behavior.
|
|
69
|
+
- **Remediation:** Maintain a consistent storage layout between upgrades, and when using inheritance, set storage gaps to avoid potential collisions.
|
|
70
|
+
|
|
71
|
+
- [ ] **[SOL-Basics-PU-10]** Are the order and types of storage variables consistent between upgrades?
|
|
72
|
+
- Changing the order or type of storage variables between upgrades can lead to storage collisions.
|
|
73
|
+
- **Remediation:** Maintain a consistent order and type for storage variables across contract versions to avoid storage collisions.
|
|
74
|
+
|
|
75
|
+
### Basics > Version Issues > EIP Adoption Issues
|
|
76
|
+
|
|
77
|
+
- [ ] **[SOL-Basics-VI-EAI-1]** EIP-4758: Does the contract use `selfdestruct()`?
|
|
78
|
+
- `selfdestruct` will not be available after EIP-4758. This EIP will rename the SELFDESTRUCT opcode and replace its functionality.
|
|
79
|
+
- **Remediation:** Do not use `selfdestruct` to ensure the contract works in the future.
|
|
80
|
+
- **References:**
|
|
81
|
+
- https://eips.ethereum.org/EIPS/eip-4758
|
|
82
|
+
- https://solodit.xyz/issues/m-09-selfdestruct-will-not-be-available-after-eip-4758-code4rena-escher-escher-contest-git
|
|
83
|
+
- https://solodit.xyz/issues/m-03-system-will-not-work-anymore-after-eip-4758-code4rena-axelar-network-axelar-network-git
|
|
84
|
+
|
|
85
|
+
### Basics > Version Issues > OpenZeppelin Version Issues
|
|
86
|
+
|
|
87
|
+
- [ ] **[SOL-Basics-VI-OVI-1]** Does the contract use `ERC2771Context`? (version >=4.0.0 <4.9.3)
|
|
88
|
+
- `ERC2771Context._msgData()` reverts if `msg.data.length < 20`. The correct behavior is not specified in ERC-2771, but based on the specified behavior of `_msgSender` we assume the full `msg.data` should be returned in this case.
|
|
89
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
90
|
+
|
|
91
|
+
- [ ] **[SOL-Basics-VI-OVI-2]** Does the contract use OpenZeppelin's GovernorCompatibilityBravo? (version >=4.3.0 <4.8.3)
|
|
92
|
+
- GovernorCompatibilityBravo may trim proposal calldata. The proposal creation entrypoint (propose) in GovernorCompatibilityBravo allows the creation of proposals with a signatures array shorter than the calldatas array. This causes the additional elements of the latter to be ignored, and if the proposal succeeds the corresponding actions would eventually execute without any calldata. The ProposalCreated event correctly represents what will eventually execute, but the proposal parameters as queried through getActions appear to respect the original intended calldata.
|
|
93
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
94
|
+
|
|
95
|
+
- [ ] **[SOL-Basics-VI-OVI-3]** Does the contract use OpenZeppelin's ECDSA.recover or ECDSA.tryRecover? (version <4.7.3)
|
|
96
|
+
- ECDSA signature malleability. The functions ECDSA.recover and ECDSA.tryRecover are vulnerable to a kind of signature malleability due to accepting EIP-2098 compact signatures in addition to the traditional 65 byte signature format. This is only an issue for the functions that take a single bytes argument, and not the functions that take r, v, s or r, vs as separate arguments. The potentially affected contracts are those that implement signature reuse or replay protection by marking the signature itself as used rather than the signed message or a nonce included in it. A user may take a signature that has already been submitted, submit it again in a different form, and bypass this protection.
|
|
97
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
98
|
+
|
|
99
|
+
- [ ] **[SOL-Basics-VI-OVI-4]** Does the contract use OpenZeppelin's ERC777? (version <3.4.0-rc.0)
|
|
100
|
+
- Extending this contract with a custom _beforeTokenTransfer function could allow a reentrancy attack to happen. More specifically, when burning tokens, _beforeTokenTransfer is invoked before the send hook is externally called on the sender while token balances are adjusted afterwards. At the moment of the call to the sender, which can result in reentrancy, state managed by _beforeTokenTransfer may not correspond to the actual token balances or total supply.
|
|
101
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
102
|
+
|
|
103
|
+
- [ ] **[SOL-Basics-VI-OVI-5]** Does the contract use OpenZeppelin's `MerkleProof`? (version >=4.7.0 <4.9.2)
|
|
104
|
+
- When the `verifyMultiProof`, `verifyMultiProofCalldata`, `processMultiProof`, or `processMultiProofCalldata` functions are in use, it is possible to construct merkle trees that allow forging a valid multiproof for an arbitrary set of leaves.
|
|
105
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
106
|
+
|
|
107
|
+
- [ ] **[SOL-Basics-VI-OVI-6]** Does the contract use OpenZeppelin's Governor or GovernorCompatibilityBravo? (version >=4.3.0 <4.9.1)
|
|
108
|
+
- Governor proposal creation may be blocked by frontrunning. By frontrunning the creation of a proposal, an attacker can become the proposer and gain the ability to cancel it. The attacker can do this repeatedly to try to prevent a proposal from being proposed at all. This impacts the Governor contract in v4.9.0 only, and the GovernorCompatibilityBravo contract since v4.3.0.
|
|
109
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
110
|
+
|
|
111
|
+
- [ ] **[SOL-Basics-VI-OVI-7]** Does the contract use OpenZeppelin's TransparentUpgradeableProxy? (version >=3.2.0 <4.8.3)
|
|
112
|
+
- Transparency is broken in case of selector clash with non-decodable calldata. The TransparentUpgradeableProxy uses the ifAdmin modifier to achieve transparency. If a non-admin address calls the proxy the call should be frowarded transparently. This works well in most cases, but the forwarding of some functions can fail if there is a selector conflict and decoding issue.
|
|
113
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
114
|
+
|
|
115
|
+
- [ ] **[SOL-Basics-VI-OVI-8]** Does the contract use OpenZeppelin's ERC721Consecutive?(version >=4.8.0 <4.8.2)
|
|
116
|
+
- The ERC721Consecutive contract designed for minting NFTs in batches does not update balances when a batch has size 1 and consists of a single token. Subsequent transfers from the receiver of that token may overflow the balance as reported by balanceOf. The issue exclusively presents with batches of size 1.
|
|
117
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
118
|
+
|
|
119
|
+
- [ ] **[SOL-Basics-VI-OVI-9]** Does the contract use OpenZeppelin's ERC165Checker or ERC165CheckerUpgradeable? (version >=2.3.0 <4.7.2)
|
|
120
|
+
- Denial of Service (DoS) in the `supportsERC165InterfaceUnchecked()` function in `ERC165Checker.sol` and `ERC165CheckerUpgradeable.sol`, which can consume excessive resources when processing a large amount of data via an EIP-165 supportsInterface query.
|
|
121
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
122
|
+
|
|
123
|
+
- [ ] **[SOL-Basics-VI-OVI-10]** Does the contract use OpenZeppelin's LibArbitrumL2 or CrossChainEnabledArbitrumL2? (version >=4.6.0 <4.7.2)
|
|
124
|
+
- Incorrect resource transfer between spheres via contracts using the cross-chain utilities for Arbitrum L2: `CrossChainEnabledArbitrumL2` or `LibArbitrumL2`. Calls from EOAs would be classified as cross-chain calls. The vulnerability will classify direct interactions of externally owned accounts (EOAs) as cross-chain calls, even though they are not started on L1.
|
|
125
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
126
|
+
|
|
127
|
+
- [ ] **[SOL-Basics-VI-OVI-11]** Does the contract use OpenZeppelin's GovernorVotesQuorumFraction? (version >=4.3.0 <4.7.2)
|
|
128
|
+
- Checkpointing quorum was missing and past proposals that failed due to lack of quorum could pass later. It is necessary to avoid quorum changes making old, failed because of quorum, proposals suddenly successful.
|
|
129
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
130
|
+
|
|
131
|
+
- [ ] **[SOL-Basics-VI-OVI-12]** Does the contract use OpenZeppelin's SignatureChecker? (version >=4.1.0 <4.7.1)
|
|
132
|
+
- Since 0.8.0, abi.decode reverts if the bytes raw data overflow the target type. SignatureChecker.isValidSignatureNow is not expected to revert. However, an incorrect assumption about Solidity 0.8's abi.decode allows some cases to revert, given a target contract that doesn't implement EIP-1271 as expected. The contracts that may be affected are those that use SignatureChecker to check the validity of a signature and handle invalid signatures in a way other than reverting.
|
|
133
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
134
|
+
|
|
135
|
+
- [ ] **[SOL-Basics-VI-OVI-13]** Does the contract use OpenZeppelin's ERC165Checker? (version >=4.0.0 <4.7.1)
|
|
136
|
+
- Since 0.8.0, abi.decode reverts if the bytes raw data overflow the target type. ERC165Checker.supportsInterface is designed to always successfully return a boolean, and under no circumstance revert. However, an incorrect assumption about Solidity 0.8's abi.decode allows some cases to revert, given a target contract that doesn't implement EIP-165 as expected, specifically if it returns a value other than 0 or 1. The contracts that may be affected are those that use ERC165Checker to check for support for an interface and then handle the lack of support in a way other than reverting.
|
|
137
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
138
|
+
|
|
139
|
+
- [ ] **[SOL-Basics-VI-OVI-14]** Does the contract use OpenZeppelin's GovernorCompatibilityBravo? (version >=4.3.0 <4.4.2)
|
|
140
|
+
- GovernorCompatibilityBravo incorrect ABI encoding may lead to unexpected behavior
|
|
141
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
142
|
+
|
|
143
|
+
- [ ] **[SOL-Basics-VI-OVI-15]** Does the contract use OpenZeppelin's Initializable? (version >=3.2.0 <4.4.1)
|
|
144
|
+
- It is possible for `initializer()`-protected functions to be executed twice, if this happens in the same transaction. For this to happen, either one call has to be a subcall the other, or both call have to be subcalls of a common initializer()-protected function. This can particularly be dangerous is the initialization is not part of the proxy construction, and reentrancy is possible by executing an external call to an untrusted address.
|
|
145
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
146
|
+
|
|
147
|
+
- [ ] **[SOL-Basics-VI-OVI-16]** Does the contract use OpenZeppelin's ERC1155? (version >=4.2.0 <4.3.3)
|
|
148
|
+
- Possible inconsistency in the value returned by totalSupply DURING a mint. If you mint a token, the receiver is a smart contract, and the receiver implements onERC1155Receive, then this receiver is called with the balance already updated, but with the totalsupply not yet updated.
|
|
149
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
150
|
+
|
|
151
|
+
- [ ] **[SOL-Basics-VI-OVI-17]** Does the contract use OpenZeppelin's UUPSUpgradeable? (version >=4.1.0 <4.3.2)
|
|
152
|
+
- Upgradeable contracts using UUPSUpgradeable may be vulnerable to an attack affecting uninitialized implementation contracts.
|
|
153
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|
|
154
|
+
|
|
155
|
+
- [ ] **[SOL-Basics-VI-OVI-18]** Does the contract use OpenZeppelin's TimelockController? (version >=4.0.0-beta.0 <4.3.1\\n<3.4.2)
|
|
156
|
+
- A vulnerability in TimelockController allowed an actor with the executor role to take immediate control of the timelock, by resetting the delay to 0 and escalating privileges, thus gaining unrestricted access to assets held in the contract. Instances with the executor role set to 'open' allow anyone to use the executor role, thus leaving the timelock at risk of being taken over by an attacker.
|
|
157
|
+
- **Remediation:** Use the latest stable OpenZeppelin version
|