@btc-vision/btc-runtime 1.10.4 → 1.10.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btc-vision/btc-runtime",
3
- "version": "1.10.4",
3
+ "version": "1.10.6",
4
4
  "description": "Bitcoin Smart Contract Runtime",
5
5
  "main": "btc/index.ts",
6
6
  "scripts": {
@@ -0,0 +1,222 @@
1
+ import { u256 } from '@btc-vision/as-bignum/assembly';
2
+ import { BytesWriter } from '../buffer/BytesWriter';
3
+ import { Blockchain } from '../env';
4
+ import { Calldata } from '../types';
5
+ import { Address } from '../types/Address';
6
+ import { Revert } from '../types/Revert';
7
+ import { StoredU256 } from '../storage/StoredU256';
8
+ import { StoredAddress } from '../storage/StoredAddress';
9
+ import { EMPTY_POINTER } from '../math/bytes';
10
+ import { OP20 } from './OP20';
11
+ import { IOP20S } from './interfaces/IOP20S';
12
+ import { OP20InitParameters } from './interfaces/OP20InitParameters';
13
+ import { ADDRESS_BYTE_LENGTH, U256_BYTE_LENGTH, U64_BYTE_LENGTH } from '../utils';
14
+ import { Selector } from '../math/abi';
15
+
16
+ const pegRatePointer: u16 = Blockchain.nextPointer;
17
+ const pegAuthorityPointer: u16 = Blockchain.nextPointer;
18
+ const pegUpdatedAtPointer: u16 = Blockchain.nextPointer;
19
+ const maxStalenessPointer: u16 = Blockchain.nextPointer;
20
+ const pendingAuthorityPointer: u16 = Blockchain.nextPointer;
21
+
22
+ // "pegRate()"
23
+ export const PEG_RATE_SELECTOR: u32 = 0x4d1f6caf;
24
+
25
+ // "pegAuthority()"
26
+ export const PEG_AUTHORITY_SELECTOR: u32 = 0xd767a583;
27
+
28
+ // "pegUpdatedAt()"
29
+ export const PEG_UPDATED_AT_SELECTOR: u32 = 0x1e99d1a1;
30
+
31
+ // "maxStaleness()"
32
+ export const MAX_STALENESS_SELECTOR: u32 = 0x0b17a602;
33
+
34
+ // "isStale()"
35
+ export const IS_STALE_SELECTOR: u32 = 0x147c08ef;
36
+
37
+ export interface OP20SInitParameters extends OP20InitParameters {
38
+ pegAuthority: Address;
39
+ initialPegRate: u256;
40
+ maxStaleness: u64;
41
+ }
42
+
43
+ export abstract class OP20S extends OP20 implements IOP20S {
44
+ protected readonly _pegRate: StoredU256;
45
+ protected readonly _pegAuthority: StoredAddress;
46
+ protected readonly _pegUpdatedAt: StoredU256;
47
+ protected readonly _maxStaleness: StoredU256;
48
+ protected readonly _pendingAuthority: StoredAddress;
49
+
50
+ public constructor() {
51
+ super();
52
+ this._pegRate = new StoredU256(pegRatePointer, EMPTY_POINTER);
53
+ this._pegAuthority = new StoredAddress(pegAuthorityPointer);
54
+ this._pegUpdatedAt = new StoredU256(pegUpdatedAtPointer, EMPTY_POINTER);
55
+ this._maxStaleness = new StoredU256(maxStalenessPointer, EMPTY_POINTER);
56
+ this._pendingAuthority = new StoredAddress(pendingAuthorityPointer);
57
+ }
58
+
59
+ public override instantiate(
60
+ params: OP20SInitParameters,
61
+ skipDeployerVerification: boolean = false,
62
+ ): void {
63
+ super.instantiate(params, skipDeployerVerification);
64
+
65
+ if (params.pegAuthority === Address.zero()) {
66
+ throw new Revert('Invalid peg authority');
67
+ }
68
+ if (params.initialPegRate.isZero()) {
69
+ throw new Revert('Invalid initial peg rate');
70
+ }
71
+ if (params.maxStaleness === 0) {
72
+ throw new Revert('Invalid max staleness');
73
+ }
74
+
75
+ this._pegAuthority.value = params.pegAuthority;
76
+ this._pegRate.value = params.initialPegRate;
77
+ this._pegUpdatedAt.value = u256.fromU64(Blockchain.block.number);
78
+ this._maxStaleness.value = u256.fromU64(params.maxStaleness);
79
+ }
80
+
81
+ @method()
82
+ @returns({ name: 'rate', type: ABIDataTypes.UINT256 })
83
+ public pegRate(_: Calldata): BytesWriter {
84
+ const w = new BytesWriter(U256_BYTE_LENGTH);
85
+ w.writeU256(this._pegRate.value);
86
+ return w;
87
+ }
88
+
89
+ @method()
90
+ @returns({ name: 'authority', type: ABIDataTypes.ADDRESS })
91
+ public pegAuthority(_: Calldata): BytesWriter {
92
+ const w = new BytesWriter(ADDRESS_BYTE_LENGTH);
93
+ w.writeAddress(this._pegAuthority.value);
94
+ return w;
95
+ }
96
+
97
+ @method()
98
+ @returns({ name: 'updatedAt', type: ABIDataTypes.UINT64 })
99
+ public pegUpdatedAt(_: Calldata): BytesWriter {
100
+ const w = new BytesWriter(U64_BYTE_LENGTH);
101
+ w.writeU64(this._pegUpdatedAt.value.toU64());
102
+ return w;
103
+ }
104
+
105
+ @method()
106
+ @returns({ name: 'staleness', type: ABIDataTypes.UINT64 })
107
+ public maxStaleness(_: Calldata): BytesWriter {
108
+ const w = new BytesWriter(U64_BYTE_LENGTH);
109
+ w.writeU64(this._maxStaleness.value.toU64());
110
+ return w;
111
+ }
112
+
113
+ @method()
114
+ @returns({ name: 'stale', type: ABIDataTypes.BOOL })
115
+ public isStale(_: Calldata): BytesWriter {
116
+ const w = new BytesWriter(1);
117
+ w.writeBoolean(this._isStale());
118
+ return w;
119
+ }
120
+
121
+ @method({ name: 'newRate', type: ABIDataTypes.UINT256 })
122
+ public updatePegRate(calldata: Calldata): BytesWriter {
123
+ this.onlyPegAuthority();
124
+
125
+ const newRate = calldata.readU256();
126
+ if (newRate.isZero()) {
127
+ throw new Revert('Invalid peg rate');
128
+ }
129
+
130
+ this._pegRate.value = newRate;
131
+ this._pegUpdatedAt.value = u256.fromU64(Blockchain.block.number);
132
+
133
+ return new BytesWriter(0);
134
+ }
135
+
136
+ @method({ name: 'newStaleness', type: ABIDataTypes.UINT64 })
137
+ public updateMaxStaleness(calldata: Calldata): BytesWriter {
138
+ this.onlyPegAuthority();
139
+
140
+ const newStaleness = calldata.readU64();
141
+ if (newStaleness === 0) {
142
+ throw new Revert('Invalid max staleness');
143
+ }
144
+
145
+ this._maxStaleness.value = u256.fromU64(newStaleness);
146
+
147
+ return new BytesWriter(0);
148
+ }
149
+
150
+ @method({ name: 'newAuthority', type: ABIDataTypes.ADDRESS })
151
+ public transferPegAuthority(calldata: Calldata): BytesWriter {
152
+ this.onlyPegAuthority();
153
+
154
+ const newAuthority = calldata.readAddress();
155
+ if (newAuthority === Address.zero()) {
156
+ throw new Revert('Invalid new authority');
157
+ }
158
+
159
+ this._pendingAuthority.value = newAuthority;
160
+
161
+ return new BytesWriter(0);
162
+ }
163
+
164
+ @method()
165
+ public acceptPegAuthority(_: Calldata): BytesWriter {
166
+ const pending = this._pendingAuthority.value;
167
+ if (pending === Address.zero()) {
168
+ throw new Revert('No pending authority');
169
+ }
170
+ if (!Blockchain.tx.sender.equals(pending)) {
171
+ throw new Revert('Not pending authority');
172
+ }
173
+
174
+ this._pegAuthority.value = pending;
175
+ this._pendingAuthority.value = Address.zero();
176
+
177
+ return new BytesWriter(0);
178
+ }
179
+
180
+ @method()
181
+ public renouncePegAuthority(_: Calldata): BytesWriter {
182
+ this.onlyPegAuthority();
183
+
184
+ this._pegAuthority.value = Address.zero();
185
+ this._pendingAuthority.value = Address.zero();
186
+
187
+ return new BytesWriter(0);
188
+ }
189
+
190
+ protected _isStale(): boolean {
191
+ const currentBlock = Blockchain.block.number;
192
+ const updatedAt = this._pegUpdatedAt.value.toU64();
193
+ const maxStale = this._maxStaleness.value.toU64();
194
+
195
+ return currentBlock > updatedAt + maxStale;
196
+ }
197
+
198
+ protected _requireFreshPeg(): void {
199
+ if (this._isStale()) {
200
+ throw new Revert('Peg rate stale');
201
+ }
202
+ }
203
+
204
+ protected onlyPegAuthority(): void {
205
+ if (!Blockchain.tx.sender.equals(this._pegAuthority.value)) {
206
+ throw new Revert('Not peg authority');
207
+ }
208
+ }
209
+
210
+ protected override isSelectorExcluded(selector: Selector): boolean {
211
+ if (
212
+ selector === PEG_RATE_SELECTOR ||
213
+ selector === PEG_AUTHORITY_SELECTOR ||
214
+ selector === PEG_UPDATED_AT_SELECTOR ||
215
+ selector === MAX_STALENESS_SELECTOR ||
216
+ selector === IS_STALE_SELECTOR
217
+ ) {
218
+ return true;
219
+ }
220
+ return super.isSelectorExcluded(selector);
221
+ }
222
+ }
@@ -0,0 +1,8 @@
1
+ import { Calldata } from '../../types';
2
+ import { BytesWriter } from '../../buffer/BytesWriter';
3
+
4
+ export interface IOP20S {
5
+ pegRate(calldata: Calldata): BytesWriter;
6
+ pegAuthority(calldata: Calldata): BytesWriter;
7
+ pegUpdatedAt(calldata: Calldata): BytesWriter;
8
+ }
package/runtime/index.ts CHANGED
@@ -3,7 +3,9 @@ export * from './env';
3
3
 
4
4
  /** Contracts */
5
5
  export * from './contracts/interfaces/IOP20';
6
+ export * from './contracts/interfaces/IOP20S';
6
7
  export * from './contracts/OP20';
8
+ export * from './contracts/OP20S';
7
9
  export * from './contracts/OP_NET';
8
10
  export * from './contracts/interfaces/OP20InitParameters';
9
11
 
@@ -410,14 +410,14 @@ export const ZERO_BITCOIN_ADDRESS: ExtendedAddress = new ExtendedAddress(
410
410
  * Hash: 284ae4acdb32a99ba3ebfa66a91ddb41a7b7a1d2fef415399922cd8a04485c02
411
411
  */
412
412
  export const DEAD_ADDRESS: ExtendedAddress = new ExtendedAddress(
413
- [
414
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
415
- 0,
416
- ],
417
413
  [
418
414
  40, 74, 228, 172, 219, 50, 169, 155, 163, 235, 250, 102, 169, 29, 219, 65, 167, 183, 161,
419
415
  210, 254, 244, 21, 57, 153, 34, 205, 138, 4, 72, 92, 2,
420
416
  ],
417
+ [
418
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
419
+ 0,
420
+ ],
421
421
  );
422
422
 
423
423
  /**