@btc-vision/btc-runtime 1.10.10 → 1.10.12

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.
Files changed (45) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +258 -137
  3. package/SECURITY.md +226 -0
  4. package/docs/README.md +614 -0
  5. package/docs/advanced/bitcoin-scripts.md +939 -0
  6. package/docs/advanced/cross-contract-calls.md +579 -0
  7. package/docs/advanced/plugins.md +1006 -0
  8. package/docs/advanced/quantum-resistance.md +660 -0
  9. package/docs/advanced/signature-verification.md +715 -0
  10. package/docs/api-reference/blockchain.md +729 -0
  11. package/docs/api-reference/events.md +642 -0
  12. package/docs/api-reference/op20.md +902 -0
  13. package/docs/api-reference/op721.md +819 -0
  14. package/docs/api-reference/safe-math.md +510 -0
  15. package/docs/api-reference/storage.md +731 -0
  16. package/docs/contracts/op-net-base.md +786 -0
  17. package/docs/contracts/op20-token.md +687 -0
  18. package/docs/contracts/op20s-signatures.md +614 -0
  19. package/docs/contracts/op721-nft.md +785 -0
  20. package/docs/contracts/reentrancy-guard.md +787 -0
  21. package/docs/core-concepts/blockchain-environment.md +724 -0
  22. package/docs/core-concepts/decorators.md +466 -0
  23. package/docs/core-concepts/events.md +652 -0
  24. package/docs/core-concepts/pointers.md +391 -0
  25. package/docs/core-concepts/security.md +370 -0
  26. package/docs/core-concepts/storage-system.md +938 -0
  27. package/docs/examples/basic-token.md +745 -0
  28. package/docs/examples/nft-with-reservations.md +1210 -0
  29. package/docs/examples/oracle-integration.md +1212 -0
  30. package/docs/examples/stablecoin.md +1180 -0
  31. package/docs/getting-started/first-contract.md +575 -0
  32. package/docs/getting-started/installation.md +384 -0
  33. package/docs/getting-started/project-structure.md +630 -0
  34. package/docs/storage/memory-maps.md +721 -0
  35. package/docs/storage/stored-arrays.md +714 -0
  36. package/docs/storage/stored-maps.md +686 -0
  37. package/docs/storage/stored-primitives.md +608 -0
  38. package/docs/types/address.md +773 -0
  39. package/docs/types/bytes-writer-reader.md +938 -0
  40. package/docs/types/calldata.md +744 -0
  41. package/docs/types/safe-math.md +403 -0
  42. package/package.json +51 -26
  43. package/runtime/memory/MapOfMap.ts +1 -0
  44. package/runtime/types/SafeMath.ts +121 -1
  45. package/LICENSE.md +0 -21
@@ -0,0 +1,370 @@
1
+ # Security
2
+
3
+ Security is paramount in smart contract development. This guide covers OPNet's security mechanisms and best practices for writing secure contracts.
4
+
5
+ ## Security Mechanisms
6
+
7
+ OPNet provides several built-in security features:
8
+
9
+ | Feature | Description |
10
+ |---------|-------------|
11
+ | **SafeMath** | Overflow/underflow protection |
12
+ | **ReentrancyGuard** | Reentrancy attack prevention |
13
+ | **Access Control** | Role-based authorization |
14
+ | **Input Validation** | Calldata parsing with bounds checks |
15
+ | **Storage Safety** | SHA256-hashed storage keys |
16
+
17
+ ## SafeMath
18
+
19
+ ### The Problem
20
+
21
+ Integer overflow/underflow can cause critical bugs:
22
+
23
+ ```typescript
24
+ // DANGEROUS: Native arithmetic can overflow silently
25
+ const a: u256 = u256.Max;
26
+ const b: u256 = u256.One;
27
+ const result = a + b; // Wraps to 0!
28
+ ```
29
+
30
+ ### The Solution
31
+
32
+ Always use SafeMath for arithmetic:
33
+
34
+ ```typescript
35
+ import { SafeMath } from '@btc-vision/btc-runtime/runtime';
36
+ import { u256 } from '@btc-vision/as-bignum/assembly';
37
+
38
+ const a = u256.fromU64(100);
39
+ const b = u256.fromU64(50);
40
+
41
+ // Safe operations
42
+ const sum = SafeMath.add(a, b); // Reverts on overflow
43
+ const diff = SafeMath.sub(a, b); // Reverts on underflow
44
+ const product = SafeMath.mul(a, b); // Reverts on overflow
45
+ const quotient = SafeMath.div(a, b); // Reverts on division by zero
46
+ const remainder = SafeMath.mod(a, b); // Reverts on division by zero
47
+ ```
48
+
49
+ ### Solidity Comparison
50
+
51
+ In Solidity 0.8+, arithmetic operations revert on overflow/underflow by default. OPNet achieves the same behavior through SafeMath:
52
+
53
+ ```solidity
54
+ // Solidity 0.8+ - automatic overflow protection
55
+ uint256 result = a + b; // Reverts on overflow
56
+ ```
57
+
58
+ ```typescript
59
+ // OPNet - explicit SafeMath usage
60
+ const result = SafeMath.add(a, b); // Reverts on overflow
61
+ ```
62
+
63
+ ### SafeMath Operations
64
+
65
+ | Operation | Method | Behavior |
66
+ |-----------|--------|----------|
67
+ | Addition | `SafeMath.add(a, b)` | Reverts on overflow |
68
+ | Subtraction | `SafeMath.sub(a, b)` | Reverts on underflow |
69
+ | Multiplication | `SafeMath.mul(a, b)` | Reverts on overflow |
70
+ | Division | `SafeMath.div(a, b)` | Reverts on zero divisor |
71
+ | Modulo | `SafeMath.mod(a, b)` | Reverts on zero divisor |
72
+ | Power | `SafeMath.pow(base, exp)` | Reverts on overflow |
73
+ | Square Root | `SafeMath.sqrt(a)` | Newton-Raphson method |
74
+
75
+ See [SafeMath API](../api-reference/safe-math.md) for complete reference.
76
+
77
+ ## Reentrancy Protection
78
+
79
+ Reentrancy attacks occur when a contract calls back into itself before completing, allowing attackers to drain funds by repeatedly calling withdraw before the balance is updated.
80
+
81
+ **Solution:** Extend `ReentrancyGuard` to automatically protect all methods:
82
+
83
+ ```typescript
84
+ import { ReentrancyGuard, ReentrancyLevel } from '@btc-vision/btc-runtime/runtime';
85
+
86
+ @final
87
+ export class MyContract extends ReentrancyGuard {
88
+ protected override readonly reentrancyLevel: ReentrancyLevel = ReentrancyLevel.STANDARD;
89
+
90
+ @method()
91
+ public withdraw(calldata: Calldata): BytesWriter {
92
+ // Protected automatically - re-entry attempts will revert
93
+ const amount = this.balances.get(Blockchain.tx.sender);
94
+ this.balances.set(Blockchain.tx.sender, u256.Zero);
95
+ // ... transfer funds ...
96
+ return new BytesWriter(0);
97
+ }
98
+ }
99
+ ```
100
+
101
+ | Mode | Description |
102
+ |------|-------------|
103
+ | `ReentrancyLevel.STANDARD` | Boolean lock (default) |
104
+ | `ReentrancyLevel.CALLBACK` | Depth counter for tracking |
105
+
106
+ Both modes block reentrancy. See [ReentrancyGuard](../contracts/reentrancy-guard.md) for detailed explanation, attack diagrams, and advanced usage.
107
+
108
+ ## Access Control
109
+
110
+ ### onlyDeployer Pattern
111
+
112
+ ```typescript
113
+ @final
114
+ export class MyContract extends OP_NET {
115
+ public constructor() {
116
+ super();
117
+ }
118
+
119
+ @method()
120
+ public adminFunction(calldata: Calldata): BytesWriter {
121
+ // Only deployer can call
122
+ this.onlyDeployer(Blockchain.tx.sender);
123
+
124
+ // Admin logic...
125
+ return new BytesWriter(0);
126
+ }
127
+ }
128
+ ```
129
+
130
+ ### Solidity Comparison
131
+
132
+ ```solidity
133
+ // Solidity
134
+ modifier onlyOwner() {
135
+ require(msg.sender == owner, "Not owner");
136
+ _;
137
+ }
138
+ ```
139
+
140
+ ```typescript
141
+ // OPNet
142
+ protected onlyOwner(): void {
143
+ if (!Blockchain.tx.sender.equals(this.owner.value)) {
144
+ throw new Revert('Not owner');
145
+ }
146
+ }
147
+ ```
148
+
149
+ ### Custom Roles
150
+
151
+ ```typescript
152
+ @final
153
+ export class MyContract extends OP_NET {
154
+ private readonly adminPointer: u16 = Blockchain.nextPointer;
155
+ private readonly admin: StoredAddress = new StoredAddress(this.adminPointer, Address.zero());
156
+
157
+ private readonly mintersPointer: u16 = Blockchain.nextPointer;
158
+ private readonly minters: AddressMemoryMap;
159
+
160
+ public constructor() {
161
+ super();
162
+ this.minters = new AddressMemoryMap(this.mintersPointer);
163
+ }
164
+
165
+ protected onlyAdmin(): void {
166
+ if (!Blockchain.tx.sender.equals(this.admin.value)) {
167
+ throw new Revert('Not admin');
168
+ }
169
+ }
170
+
171
+ protected onlyMinter(): void {
172
+ if (this.minters.get(Blockchain.tx.sender).isZero()) {
173
+ throw new Revert('Not minter');
174
+ }
175
+ }
176
+
177
+ @method()
178
+ public mint(calldata: Calldata): BytesWriter {
179
+ this.onlyMinter();
180
+ // ...
181
+ return new BytesWriter(0);
182
+ }
183
+
184
+ @method()
185
+ public setMinter(calldata: Calldata): BytesWriter {
186
+ this.onlyAdmin();
187
+ const minter = calldata.readAddress();
188
+ this.minters.set(minter, u256.One);
189
+ return new BytesWriter(0);
190
+ }
191
+ }
192
+ ```
193
+
194
+ ## Input Validation
195
+
196
+ ### Validate All Inputs
197
+
198
+ ```typescript
199
+ @method()
200
+ public transfer(calldata: Calldata): BytesWriter {
201
+ const to = calldata.readAddress();
202
+ const amount = calldata.readU256();
203
+
204
+ // Validate recipient
205
+ if (to.equals(Address.zero())) {
206
+ throw new Revert('Cannot transfer to zero address');
207
+ }
208
+
209
+ // Validate amount
210
+ if (amount.isZero()) {
211
+ throw new Revert('Amount must be greater than zero');
212
+ }
213
+
214
+ // Validate balance
215
+ const balance = this.balances.get(Blockchain.tx.sender);
216
+ if (balance < amount) {
217
+ throw new Revert('Insufficient balance');
218
+ }
219
+
220
+ // ... proceed with transfer
221
+ }
222
+ ```
223
+
224
+ ### Common Validations
225
+
226
+ ```typescript
227
+ // Zero address check
228
+ if (address.equals(Address.zero())) {
229
+ throw new Revert('Invalid address');
230
+ }
231
+
232
+ // Self-transfer check
233
+ if (from.equals(to)) {
234
+ throw new Revert('Cannot transfer to self');
235
+ }
236
+
237
+ // Amount checks
238
+ if (amount.isZero()) {
239
+ throw new Revert('Amount is zero');
240
+ }
241
+ if (amount > maxAmount) {
242
+ throw new Revert('Amount exceeds maximum');
243
+ }
244
+
245
+ // Array bounds
246
+ if (index >= array.length) {
247
+ throw new Revert('Index out of bounds');
248
+ }
249
+ ```
250
+
251
+ ## Common Vulnerabilities
252
+
253
+ ### 1. Integer Overflow/Underflow
254
+
255
+ ```typescript
256
+ // VULNERABLE
257
+ const newBalance = balance + amount; // Can overflow!
258
+
259
+ // SAFE
260
+ const newBalance = SafeMath.add(balance, amount);
261
+ ```
262
+
263
+ ### 2. Reentrancy
264
+
265
+ ```typescript
266
+ // VULNERABLE
267
+ @method()
268
+ public withdraw(): void {
269
+ const amount = balances.get(sender);
270
+ externalCall(sender, amount); // Can re-enter!
271
+ balances.set(sender, u256.Zero);
272
+ }
273
+
274
+ // SAFE (Checks-Effects-Interactions pattern)
275
+ @method()
276
+ public withdraw(): void {
277
+ const amount = balances.get(sender);
278
+ balances.set(sender, u256.Zero); // Update state first
279
+ externalCall(sender, amount); // Then make external call
280
+ }
281
+ ```
282
+
283
+ ### 3. Access Control Bypass
284
+
285
+ ```typescript
286
+ // VULNERABLE
287
+ @method()
288
+ public mint(calldata: Calldata): void {
289
+ // No access control!
290
+ this._mint(calldata.readAddress(), calldata.readU256());
291
+ }
292
+
293
+ // SAFE
294
+ @method()
295
+ public mint(calldata: Calldata): void {
296
+ this.onlyDeployer(Blockchain.tx.sender);
297
+ this._mint(calldata.readAddress(), calldata.readU256());
298
+ }
299
+ ```
300
+
301
+ ### 4. tx.origin Authentication
302
+
303
+ ```typescript
304
+ // VULNERABLE (phishing attack possible)
305
+ @method()
306
+ public withdraw(): void {
307
+ if (Blockchain.tx.origin.equals(owner)) { // WRONG!
308
+ // ...
309
+ }
310
+ }
311
+
312
+ // SAFE
313
+ @method()
314
+ public withdraw(): void {
315
+ if (Blockchain.tx.sender.equals(owner)) { // Correct
316
+ // ...
317
+ }
318
+ }
319
+ ```
320
+
321
+ ### 5. Floating Point
322
+
323
+ ```typescript
324
+ // VULNERABLE (non-deterministic)
325
+ const price: f64 = 1.5; // NEVER use floats!
326
+
327
+ // SAFE (fixed-point)
328
+ const PRECISION: u256 = u256.fromU64(1_000_000);
329
+ const price: u256 = SafeMath.mul(u256.fromU64(15), SafeMath.div(PRECISION, u256.fromU64(10)));
330
+ ```
331
+
332
+ ## Security Checklist
333
+
334
+ Before deploying, verify:
335
+
336
+ - [ ] All arithmetic uses SafeMath
337
+ - [ ] ReentrancyGuard on sensitive functions
338
+ - [ ] Access control on admin functions
339
+ - [ ] Input validation on all public methods
340
+ - [ ] No floating-point arithmetic
341
+ - [ ] No tx.origin for authentication
342
+ - [ ] Events emitted for state changes
343
+ - [ ] Tests cover edge cases
344
+ - [ ] No hardcoded secrets
345
+
346
+ ## Audit Information
347
+
348
+ btc-runtime has been audited by [Verichains](https://verichains.io). The audit covered:
349
+
350
+ - Contract standards (OP20, OP721)
351
+ - Storage system security
352
+ - Cryptographic implementations
353
+ - SafeMath operations
354
+ - ReentrancyGuard mechanisms
355
+
356
+ See [SECURITY.md](../../SECURITY.md) for full audit details.
357
+
358
+ ## Reporting Vulnerabilities
359
+
360
+ If you discover a security issue:
361
+
362
+ 1. **DO NOT** open a public GitHub issue
363
+ 2. Report via [GitHub Security Advisories](https://github.com/btc-vision/btc-runtime/security/advisories)
364
+ 3. Allow time for fix before disclosure
365
+
366
+ ---
367
+
368
+ **Navigation:**
369
+ - Previous: [Events](./events.md)
370
+ - Next: [OP_NET Base Contract](../contracts/op-net-base.md)