agentic-team-templates 0.3.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/README.md +280 -0
- package/bin/cli.js +5 -0
- package/package.json +47 -0
- package/src/index.js +521 -0
- package/templates/_shared/code-quality.md +162 -0
- package/templates/_shared/communication.md +114 -0
- package/templates/_shared/core-principles.md +62 -0
- package/templates/_shared/git-workflow.md +165 -0
- package/templates/_shared/security-fundamentals.md +173 -0
- package/templates/blockchain/.cursorrules/defi-patterns.md +520 -0
- package/templates/blockchain/.cursorrules/gas-optimization.md +339 -0
- package/templates/blockchain/.cursorrules/overview.md +130 -0
- package/templates/blockchain/.cursorrules/security.md +318 -0
- package/templates/blockchain/.cursorrules/smart-contracts.md +364 -0
- package/templates/blockchain/.cursorrules/testing.md +415 -0
- package/templates/blockchain/.cursorrules/web3-integration.md +538 -0
- package/templates/blockchain/CLAUDE.md +389 -0
- package/templates/cli-tools/.cursorrules/architecture.md +412 -0
- package/templates/cli-tools/.cursorrules/arguments.md +406 -0
- package/templates/cli-tools/.cursorrules/distribution.md +546 -0
- package/templates/cli-tools/.cursorrules/error-handling.md +455 -0
- package/templates/cli-tools/.cursorrules/overview.md +136 -0
- package/templates/cli-tools/.cursorrules/testing.md +537 -0
- package/templates/cli-tools/.cursorrules/user-experience.md +545 -0
- package/templates/cli-tools/CLAUDE.md +356 -0
- package/templates/data-engineering/.cursorrules/data-modeling.md +367 -0
- package/templates/data-engineering/.cursorrules/data-quality.md +455 -0
- package/templates/data-engineering/.cursorrules/overview.md +85 -0
- package/templates/data-engineering/.cursorrules/performance.md +339 -0
- package/templates/data-engineering/.cursorrules/pipeline-design.md +280 -0
- package/templates/data-engineering/.cursorrules/security.md +460 -0
- package/templates/data-engineering/.cursorrules/testing.md +452 -0
- package/templates/data-engineering/CLAUDE.md +974 -0
- package/templates/devops-sre/.cursorrules/capacity-planning.md +653 -0
- package/templates/devops-sre/.cursorrules/change-management.md +584 -0
- package/templates/devops-sre/.cursorrules/chaos-engineering.md +651 -0
- package/templates/devops-sre/.cursorrules/disaster-recovery.md +641 -0
- package/templates/devops-sre/.cursorrules/incident-management.md +565 -0
- package/templates/devops-sre/.cursorrules/observability.md +714 -0
- package/templates/devops-sre/.cursorrules/overview.md +230 -0
- package/templates/devops-sre/.cursorrules/postmortems.md +588 -0
- package/templates/devops-sre/.cursorrules/runbooks.md +760 -0
- package/templates/devops-sre/.cursorrules/slo-sli.md +617 -0
- package/templates/devops-sre/.cursorrules/toil-reduction.md +567 -0
- package/templates/devops-sre/CLAUDE.md +1007 -0
- package/templates/documentation/.cursorrules/adr.md +277 -0
- package/templates/documentation/.cursorrules/api-documentation.md +411 -0
- package/templates/documentation/.cursorrules/code-comments.md +253 -0
- package/templates/documentation/.cursorrules/maintenance.md +260 -0
- package/templates/documentation/.cursorrules/overview.md +82 -0
- package/templates/documentation/.cursorrules/readme-standards.md +306 -0
- package/templates/documentation/CLAUDE.md +120 -0
- package/templates/fullstack/.cursorrules/api-contracts.md +331 -0
- package/templates/fullstack/.cursorrules/architecture.md +298 -0
- package/templates/fullstack/.cursorrules/overview.md +109 -0
- package/templates/fullstack/.cursorrules/shared-types.md +348 -0
- package/templates/fullstack/.cursorrules/testing.md +386 -0
- package/templates/fullstack/CLAUDE.md +349 -0
- package/templates/ml-ai/.cursorrules/data-engineering.md +483 -0
- package/templates/ml-ai/.cursorrules/deployment.md +601 -0
- package/templates/ml-ai/.cursorrules/model-development.md +538 -0
- package/templates/ml-ai/.cursorrules/monitoring.md +658 -0
- package/templates/ml-ai/.cursorrules/overview.md +131 -0
- package/templates/ml-ai/.cursorrules/security.md +637 -0
- package/templates/ml-ai/.cursorrules/testing.md +678 -0
- package/templates/ml-ai/CLAUDE.md +1136 -0
- package/templates/mobile/.cursorrules/navigation.md +246 -0
- package/templates/mobile/.cursorrules/offline-first.md +302 -0
- package/templates/mobile/.cursorrules/overview.md +71 -0
- package/templates/mobile/.cursorrules/performance.md +345 -0
- package/templates/mobile/.cursorrules/testing.md +339 -0
- package/templates/mobile/CLAUDE.md +233 -0
- package/templates/platform-engineering/.cursorrules/ci-cd.md +778 -0
- package/templates/platform-engineering/.cursorrules/developer-experience.md +632 -0
- package/templates/platform-engineering/.cursorrules/infrastructure-as-code.md +600 -0
- package/templates/platform-engineering/.cursorrules/kubernetes.md +710 -0
- package/templates/platform-engineering/.cursorrules/observability.md +747 -0
- package/templates/platform-engineering/.cursorrules/overview.md +215 -0
- package/templates/platform-engineering/.cursorrules/security.md +855 -0
- package/templates/platform-engineering/.cursorrules/testing.md +878 -0
- package/templates/platform-engineering/CLAUDE.md +850 -0
- package/templates/utility-agent/.cursorrules/action-control.md +284 -0
- package/templates/utility-agent/.cursorrules/context-management.md +186 -0
- package/templates/utility-agent/.cursorrules/hallucination-prevention.md +253 -0
- package/templates/utility-agent/.cursorrules/overview.md +78 -0
- package/templates/utility-agent/.cursorrules/token-optimization.md +369 -0
- package/templates/utility-agent/CLAUDE.md +513 -0
- package/templates/web-backend/.cursorrules/api-design.md +255 -0
- package/templates/web-backend/.cursorrules/authentication.md +309 -0
- package/templates/web-backend/.cursorrules/database-patterns.md +298 -0
- package/templates/web-backend/.cursorrules/error-handling.md +366 -0
- package/templates/web-backend/.cursorrules/overview.md +69 -0
- package/templates/web-backend/.cursorrules/security.md +358 -0
- package/templates/web-backend/.cursorrules/testing.md +395 -0
- package/templates/web-backend/CLAUDE.md +366 -0
- package/templates/web-frontend/.cursorrules/accessibility.md +296 -0
- package/templates/web-frontend/.cursorrules/component-patterns.md +204 -0
- package/templates/web-frontend/.cursorrules/overview.md +72 -0
- package/templates/web-frontend/.cursorrules/performance.md +325 -0
- package/templates/web-frontend/.cursorrules/state-management.md +227 -0
- package/templates/web-frontend/.cursorrules/styling.md +271 -0
- package/templates/web-frontend/.cursorrules/testing.md +311 -0
- package/templates/web-frontend/CLAUDE.md +399 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Gas Optimization
|
|
2
|
+
|
|
3
|
+
Patterns and techniques for writing gas-efficient smart contracts without sacrificing security.
|
|
4
|
+
|
|
5
|
+
## Storage Optimization
|
|
6
|
+
|
|
7
|
+
### Understanding Storage Costs
|
|
8
|
+
|
|
9
|
+
| Operation | Gas Cost |
|
|
10
|
+
|-----------|----------|
|
|
11
|
+
| SSTORE (0 → non-zero) | 20,000 |
|
|
12
|
+
| SSTORE (non-zero → non-zero) | 5,000 |
|
|
13
|
+
| SSTORE (non-zero → 0) | Refund 4,800 |
|
|
14
|
+
| SLOAD | 2,100 (cold) / 100 (warm) |
|
|
15
|
+
| Memory | 3 per word + expansion cost |
|
|
16
|
+
| Calldata | 4 per zero byte, 16 per non-zero |
|
|
17
|
+
|
|
18
|
+
### Variable Packing
|
|
19
|
+
|
|
20
|
+
Pack variables into 32-byte slots:
|
|
21
|
+
|
|
22
|
+
```solidity
|
|
23
|
+
// Bad: Uses 3 storage slots (96 bytes)
|
|
24
|
+
contract Unoptimized {
|
|
25
|
+
uint256 public a; // Slot 0 (32 bytes)
|
|
26
|
+
uint128 public b; // Slot 1 (16 bytes, wastes 16)
|
|
27
|
+
uint128 public c; // Slot 2 (16 bytes, wastes 16)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Good: Uses 2 storage slots (64 bytes)
|
|
31
|
+
contract Optimized {
|
|
32
|
+
uint256 public a; // Slot 0 (32 bytes)
|
|
33
|
+
uint128 public b; // Slot 1 (16 bytes)
|
|
34
|
+
uint128 public c; // Slot 1 (16 bytes) - packed!
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Best: Pack related variables in structs
|
|
38
|
+
struct UserData {
|
|
39
|
+
uint128 balance; // 16 bytes
|
|
40
|
+
uint64 lastUpdate; // 8 bytes
|
|
41
|
+
uint32 nonce; // 4 bytes
|
|
42
|
+
bool isActive; // 1 byte
|
|
43
|
+
// Total: 29 bytes, fits in one slot
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Storage Variable Caching
|
|
48
|
+
|
|
49
|
+
Cache storage reads in memory:
|
|
50
|
+
|
|
51
|
+
```solidity
|
|
52
|
+
// Bad: Multiple storage reads (~4,200 gas per iteration)
|
|
53
|
+
function sumBad() external view returns (uint256 total) {
|
|
54
|
+
for (uint256 i = 0; i < s_values.length; i++) {
|
|
55
|
+
total += s_values[i];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Good: Cache length, single write (~2,100 initial + ~100 per iteration)
|
|
60
|
+
function sumGood() external view returns (uint256 total) {
|
|
61
|
+
uint256[] memory values = s_values; // Cache in memory
|
|
62
|
+
uint256 length = values.length;
|
|
63
|
+
|
|
64
|
+
for (uint256 i = 0; i < length; i++) {
|
|
65
|
+
total += values[i];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// For single values
|
|
70
|
+
function processBad() external {
|
|
71
|
+
for (uint256 i = 0; i < 10; i++) {
|
|
72
|
+
s_counter += 1; // 5,000 gas each write!
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function processGood() external {
|
|
77
|
+
uint256 counter = s_counter; // Read once
|
|
78
|
+
for (uint256 i = 0; i < 10; i++) {
|
|
79
|
+
counter += 1; // Memory is cheap
|
|
80
|
+
}
|
|
81
|
+
s_counter = counter; // Write once
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Memory vs Calldata
|
|
86
|
+
|
|
87
|
+
### Use Calldata for Read-Only Arrays
|
|
88
|
+
|
|
89
|
+
```solidity
|
|
90
|
+
// Bad: Copies data to memory (~3 gas per byte + overhead)
|
|
91
|
+
function processBad(uint256[] memory data) external {
|
|
92
|
+
// data is copied from calldata to memory
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Good: Read directly from calldata (no copy)
|
|
96
|
+
function processGood(uint256[] calldata data) external {
|
|
97
|
+
// data stays in calldata, read-only
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// When you need to modify, use memory
|
|
101
|
+
function processAndModify(uint256[] calldata data) external returns (uint256[] memory) {
|
|
102
|
+
uint256[] memory result = new uint256[](data.length);
|
|
103
|
+
for (uint256 i = 0; i < data.length; i++) {
|
|
104
|
+
result[i] = data[i] * 2;
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### String/Bytes Parameters
|
|
111
|
+
|
|
112
|
+
```solidity
|
|
113
|
+
// Bad
|
|
114
|
+
function setNameBad(string memory name) external {
|
|
115
|
+
s_name = name;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Good: Use calldata if not modifying
|
|
119
|
+
function setNameGood(string calldata name) external {
|
|
120
|
+
s_name = name;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Loop Optimizations
|
|
125
|
+
|
|
126
|
+
### Increment Patterns
|
|
127
|
+
|
|
128
|
+
```solidity
|
|
129
|
+
// Bad: Post-increment creates temporary variable
|
|
130
|
+
for (uint256 i = 0; i < length; i++) { }
|
|
131
|
+
|
|
132
|
+
// Good: Pre-increment (saves ~5 gas per iteration)
|
|
133
|
+
for (uint256 i = 0; i < length; ++i) { }
|
|
134
|
+
|
|
135
|
+
// Best: Unchecked increment when overflow is impossible
|
|
136
|
+
for (uint256 i = 0; i < length;) {
|
|
137
|
+
// loop body
|
|
138
|
+
unchecked { ++i; }
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Avoid Redundant Checks
|
|
143
|
+
|
|
144
|
+
```solidity
|
|
145
|
+
// Bad: Bounds check on every access
|
|
146
|
+
function sumArray(uint256[] calldata arr) external pure returns (uint256 sum) {
|
|
147
|
+
for (uint256 i = 0; i < arr.length; ++i) {
|
|
148
|
+
sum += arr[i]; // Bounds check each time
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Good: Assembly for direct access (use with caution!)
|
|
153
|
+
function sumArrayOptimized(uint256[] calldata arr) external pure returns (uint256 sum) {
|
|
154
|
+
assembly {
|
|
155
|
+
let length := arr.length
|
|
156
|
+
let offset := arr.offset
|
|
157
|
+
|
|
158
|
+
for { let i := 0 } lt(i, length) { i := add(i, 1) } {
|
|
159
|
+
sum := add(sum, calldataload(add(offset, mul(i, 32))))
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Function Optimizations
|
|
166
|
+
|
|
167
|
+
### Visibility Matters
|
|
168
|
+
|
|
169
|
+
```solidity
|
|
170
|
+
// External is cheaper than public for array parameters
|
|
171
|
+
function processBad(uint256[] memory data) public { } // Copies to memory
|
|
172
|
+
function processGood(uint256[] calldata data) external { } // No copy
|
|
173
|
+
|
|
174
|
+
// Use external when function is only called externally
|
|
175
|
+
function externalOnly() external { } // Cheaper
|
|
176
|
+
function publicFunc() public { } // Can be called internally too
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Short-Circuit Evaluation
|
|
180
|
+
|
|
181
|
+
```solidity
|
|
182
|
+
// Put cheaper/more likely to fail checks first
|
|
183
|
+
function validateBad(address user, uint256 amount) external view {
|
|
184
|
+
require(complexCheck(amount), "Complex failed"); // Expensive first
|
|
185
|
+
require(user != address(0), "Zero address"); // Cheap second
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function validateGood(address user, uint256 amount) external view {
|
|
189
|
+
require(user != address(0), "Zero address"); // Cheap first
|
|
190
|
+
require(complexCheck(amount), "Complex failed"); // Expensive second
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Custom Errors vs Require Strings
|
|
195
|
+
|
|
196
|
+
```solidity
|
|
197
|
+
// Bad: String storage is expensive
|
|
198
|
+
require(balance >= amount, "Insufficient balance");
|
|
199
|
+
|
|
200
|
+
// Good: Custom errors are cheaper and more informative
|
|
201
|
+
error InsufficientBalance(uint256 requested, uint256 available);
|
|
202
|
+
|
|
203
|
+
if (balance < amount) {
|
|
204
|
+
revert InsufficientBalance(amount, balance);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Bit Manipulation
|
|
209
|
+
|
|
210
|
+
### Packing Booleans
|
|
211
|
+
|
|
212
|
+
```solidity
|
|
213
|
+
// Bad: Each bool uses full storage slot
|
|
214
|
+
bool public flag1;
|
|
215
|
+
bool public flag2;
|
|
216
|
+
bool public flag3;
|
|
217
|
+
|
|
218
|
+
// Good: Pack into single uint256
|
|
219
|
+
uint256 private s_flags;
|
|
220
|
+
|
|
221
|
+
uint256 private constant FLAG1 = 1 << 0; // 0x01
|
|
222
|
+
uint256 private constant FLAG2 = 1 << 1; // 0x02
|
|
223
|
+
uint256 private constant FLAG3 = 1 << 2; // 0x04
|
|
224
|
+
|
|
225
|
+
function setFlag1(bool value) external {
|
|
226
|
+
if (value) {
|
|
227
|
+
s_flags |= FLAG1; // Set bit
|
|
228
|
+
} else {
|
|
229
|
+
s_flags &= ~FLAG1; // Clear bit
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function getFlag1() external view returns (bool) {
|
|
234
|
+
return s_flags & FLAG1 != 0;
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Efficient Division/Multiplication
|
|
239
|
+
|
|
240
|
+
```solidity
|
|
241
|
+
// Division by powers of 2
|
|
242
|
+
uint256 half = value / 2; // ~5 gas
|
|
243
|
+
uint256 halfOpt = value >> 1; // ~3 gas
|
|
244
|
+
|
|
245
|
+
// Multiplication by powers of 2
|
|
246
|
+
uint256 doubled = value * 2; // ~5 gas
|
|
247
|
+
uint256 doubledOpt = value << 1; // ~3 gas
|
|
248
|
+
|
|
249
|
+
// But only when overflow is handled!
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Constants and Immutables
|
|
253
|
+
|
|
254
|
+
```solidity
|
|
255
|
+
// Bad: Storage variable (2,100 gas to read)
|
|
256
|
+
address public owner;
|
|
257
|
+
|
|
258
|
+
// Good: Immutable (embedded in bytecode, ~3 gas)
|
|
259
|
+
address public immutable i_owner;
|
|
260
|
+
|
|
261
|
+
// Best: Constant (replaced at compile time, ~3 gas)
|
|
262
|
+
uint256 public constant MAX_SUPPLY = 1_000_000e18;
|
|
263
|
+
|
|
264
|
+
constructor(address _owner) {
|
|
265
|
+
i_owner = _owner; // Set once, never changes
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Batching Operations
|
|
270
|
+
|
|
271
|
+
```solidity
|
|
272
|
+
// Bad: Multiple transactions
|
|
273
|
+
function transferOne(address to, uint256 amount) external {
|
|
274
|
+
_transfer(msg.sender, to, amount);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Good: Batch in single transaction
|
|
278
|
+
function transferBatch(
|
|
279
|
+
address[] calldata recipients,
|
|
280
|
+
uint256[] calldata amounts
|
|
281
|
+
) external {
|
|
282
|
+
uint256 length = recipients.length;
|
|
283
|
+
require(length == amounts.length, "Length mismatch");
|
|
284
|
+
|
|
285
|
+
for (uint256 i = 0; i < length;) {
|
|
286
|
+
_transfer(msg.sender, recipients[i], amounts[i]);
|
|
287
|
+
unchecked { ++i; }
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Gas Benchmarking
|
|
293
|
+
|
|
294
|
+
### Foundry Gas Reports
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# Run tests with gas report
|
|
298
|
+
forge test --gas-report
|
|
299
|
+
|
|
300
|
+
# Compare before/after optimization
|
|
301
|
+
forge snapshot
|
|
302
|
+
# Make changes
|
|
303
|
+
forge snapshot --diff
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Manual Measurement
|
|
307
|
+
|
|
308
|
+
```solidity
|
|
309
|
+
function testGasUsage() public {
|
|
310
|
+
uint256 gasBefore = gasleft();
|
|
311
|
+
|
|
312
|
+
// Operation to measure
|
|
313
|
+
contract.someFunction();
|
|
314
|
+
|
|
315
|
+
uint256 gasUsed = gasBefore - gasleft();
|
|
316
|
+
console.log("Gas used:", gasUsed);
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## When NOT to Optimize
|
|
321
|
+
|
|
322
|
+
1. **Security**: Never sacrifice security for gas savings
|
|
323
|
+
2. **Readability**: Heavily optimized code is harder to audit
|
|
324
|
+
3. **Maintenance**: Complex optimizations create technical debt
|
|
325
|
+
4. **Premature**: Optimize after profiling, not before
|
|
326
|
+
|
|
327
|
+
```solidity
|
|
328
|
+
// Readable and secure > slightly cheaper
|
|
329
|
+
// This is fine even if not perfectly optimized
|
|
330
|
+
function transfer(address to, uint256 amount) external {
|
|
331
|
+
require(to != address(0), "Zero address");
|
|
332
|
+
require(s_balances[msg.sender] >= amount, "Insufficient balance");
|
|
333
|
+
|
|
334
|
+
s_balances[msg.sender] -= amount;
|
|
335
|
+
s_balances[to] += amount;
|
|
336
|
+
|
|
337
|
+
emit Transfer(msg.sender, to, amount);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Blockchain Development Overview
|
|
2
|
+
|
|
3
|
+
Staff-level guidelines for blockchain and Web3 development, covering smart contracts, DeFi protocols, and decentralized applications.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
This template applies to:
|
|
8
|
+
|
|
9
|
+
- Smart contract development (Solidity, Vyper)
|
|
10
|
+
- DeFi protocols (AMMs, lending, yield strategies)
|
|
11
|
+
- Token implementations (ERC-20, ERC-721, ERC-1155, ERC-4626)
|
|
12
|
+
- Web3 frontend applications
|
|
13
|
+
- Cross-chain and L2 integrations
|
|
14
|
+
|
|
15
|
+
## Core Principles
|
|
16
|
+
|
|
17
|
+
### 1. Security Is Non-Negotiable
|
|
18
|
+
|
|
19
|
+
Smart contracts are immutable and handle real value. Every line of code is a potential attack vector.
|
|
20
|
+
|
|
21
|
+
- Assume all external inputs are malicious
|
|
22
|
+
- Follow checks-effects-interactions pattern religiously
|
|
23
|
+
- Get audited before mainnet deployment
|
|
24
|
+
- Start with OpenZeppelin; don't reinvent cryptographic wheels
|
|
25
|
+
|
|
26
|
+
### 2. Gas Efficiency Matters
|
|
27
|
+
|
|
28
|
+
Users pay for every operation. Respect their money.
|
|
29
|
+
|
|
30
|
+
- Optimize storage access patterns
|
|
31
|
+
- Use calldata over memory for read-only parameters
|
|
32
|
+
- Pack variables into storage slots
|
|
33
|
+
- Cache storage reads in memory during loops
|
|
34
|
+
|
|
35
|
+
### 3. Composability Is King
|
|
36
|
+
|
|
37
|
+
DeFi's power comes from protocol interoperability.
|
|
38
|
+
|
|
39
|
+
- Follow established standards (ERC-20, ERC-721, etc.)
|
|
40
|
+
- Design for integration, not isolation
|
|
41
|
+
- Document external interfaces thoroughly
|
|
42
|
+
- Consider how others will build on top of your contracts
|
|
43
|
+
|
|
44
|
+
### 4. Defense in Depth
|
|
45
|
+
|
|
46
|
+
No single security measure is sufficient.
|
|
47
|
+
|
|
48
|
+
- Multiple layers of access control
|
|
49
|
+
- Rate limiting and circuit breakers
|
|
50
|
+
- Monitoring and incident response plans
|
|
51
|
+
- Gradual rollouts with timelocks
|
|
52
|
+
|
|
53
|
+
## Project Structure
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
contracts/
|
|
57
|
+
├── src/ # Contract source files
|
|
58
|
+
│ ├── core/ # Core protocol contracts
|
|
59
|
+
│ ├── periphery/ # Helper and router contracts
|
|
60
|
+
│ ├── interfaces/ # Interface definitions
|
|
61
|
+
│ ├── libraries/ # Shared libraries
|
|
62
|
+
│ └── tokens/ # Token implementations
|
|
63
|
+
├── test/ # Test files
|
|
64
|
+
│ ├── unit/ # Unit tests
|
|
65
|
+
│ ├── integration/ # Integration tests
|
|
66
|
+
│ ├── invariant/ # Invariant/fuzz tests
|
|
67
|
+
│ └── fork/ # Mainnet fork tests
|
|
68
|
+
├── script/ # Deployment scripts
|
|
69
|
+
├── lib/ # External dependencies (git submodules)
|
|
70
|
+
└── foundry.toml # Foundry configuration
|
|
71
|
+
|
|
72
|
+
frontend/
|
|
73
|
+
├── src/
|
|
74
|
+
│ ├── hooks/ # Web3 hooks (useContract, useBalance)
|
|
75
|
+
│ ├── providers/ # Wallet and chain providers
|
|
76
|
+
│ ├── contracts/ # ABIs and addresses
|
|
77
|
+
│ ├── utils/ # Web3 utilities
|
|
78
|
+
│ └── components/ # UI components
|
|
79
|
+
└── wagmi.config.ts # Wagmi configuration
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Technology Stack
|
|
83
|
+
|
|
84
|
+
### Smart Contracts
|
|
85
|
+
|
|
86
|
+
- **Language**: Solidity 0.8.x (latest stable)
|
|
87
|
+
- **Framework**: Foundry (preferred) or Hardhat
|
|
88
|
+
- **Libraries**: OpenZeppelin Contracts
|
|
89
|
+
- **Testing**: Forge (unit, fuzz, invariant)
|
|
90
|
+
- **Static Analysis**: Slither, Mythril
|
|
91
|
+
|
|
92
|
+
### Web3 Frontend
|
|
93
|
+
|
|
94
|
+
- **Library**: Viem + Wagmi (React) or Ethers.js
|
|
95
|
+
- **Wallet Connection**: ConnectKit, RainbowKit, or custom
|
|
96
|
+
- **State Management**: React Query (via Wagmi)
|
|
97
|
+
- **Transaction Handling**: Optimistic updates with confirmation
|
|
98
|
+
|
|
99
|
+
### Infrastructure
|
|
100
|
+
|
|
101
|
+
- **RPC**: Alchemy, Infura, or self-hosted
|
|
102
|
+
- **Indexing**: The Graph or custom indexer
|
|
103
|
+
- **Monitoring**: Tenderly, OpenZeppelin Defender
|
|
104
|
+
|
|
105
|
+
## Definition of Done (Smart Contracts)
|
|
106
|
+
|
|
107
|
+
A smart contract is production-ready when:
|
|
108
|
+
|
|
109
|
+
- [ ] All functions have NatSpec documentation
|
|
110
|
+
- [ ] Unit tests cover all branches (>95% coverage)
|
|
111
|
+
- [ ] Fuzz tests for all external functions
|
|
112
|
+
- [ ] Invariant tests for protocol properties
|
|
113
|
+
- [ ] Slither reports zero high/medium findings
|
|
114
|
+
- [ ] Gas benchmarks documented
|
|
115
|
+
- [ ] Mainnet fork tests pass
|
|
116
|
+
- [ ] External audit completed (for mainnet)
|
|
117
|
+
- [ ] Deployment scripts tested on testnet
|
|
118
|
+
- [ ] Upgrade/migration path documented
|
|
119
|
+
|
|
120
|
+
## Definition of Done (Web3 Frontend)
|
|
121
|
+
|
|
122
|
+
A Web3 frontend feature is complete when:
|
|
123
|
+
|
|
124
|
+
- [ ] Works with multiple wallet types
|
|
125
|
+
- [ ] Handles transaction states (pending, confirmed, failed)
|
|
126
|
+
- [ ] Shows meaningful error messages
|
|
127
|
+
- [ ] Respects user's network preferences
|
|
128
|
+
- [ ] Works on mobile wallets
|
|
129
|
+
- [ ] Transaction simulations before signing
|
|
130
|
+
- [ ] Gas estimation displayed to user
|