@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
|
@@ -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
|
/**
|