@btc-vision/btc-runtime 1.0.31 → 1.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.
@@ -1,341 +1,8 @@
1
- import { IOP_20 } from './interfaces/IOP_20';
2
- import { u256 } from 'as-bignum/assembly';
3
- import { Address } from '../types/Address';
4
- import { BytesWriter } from '../buffer/BytesWriter';
5
- import { Calldata } from '../universal/ABIRegistry';
6
- import { OP_NET } from './OP_NET';
7
- import { AddressMemoryMap } from '../memory/AddressMemoryMap';
8
- import { Revert } from '../types/Revert';
9
- import { SafeMath } from '../types/SafeMath';
10
- import { Blockchain } from '../env';
11
- import { MemorySlotData } from '../memory/MemorySlot';
12
- import { encodeSelector, Selector } from '../math/abi';
13
- import { MultiAddressMemoryMap } from '../memory/MultiAddressMemoryMap';
14
- import { StoredU256 } from '../storage/StoredU256';
15
- import { ApproveEvent, BurnEvent, MintEvent, TransferEvent } from '../events/predefined';
1
+ import { DeployableOP_20, OP20InitParameters } from './DeployableOP_20';
2
+ import { u256 } from 'as-bignum';
16
3
 
17
- export abstract class OP_20 extends OP_NET implements IOP_20 {
18
- protected readonly allowanceMap: MultiAddressMemoryMap<Address, Address, MemorySlotData<u256>>;
19
- protected readonly balanceOfMap: AddressMemoryMap<Address, MemorySlotData<u256>>;
20
-
21
- protected constructor(
22
- protected readonly maxSupply: u256,
23
- protected readonly decimals: u8,
24
- protected readonly name: string,
25
- protected readonly symbol: string,
26
- ) {
27
- super();
28
-
29
- this.allowanceMap = new MultiAddressMemoryMap<Address, Address, MemorySlotData<u256>>(
30
- Blockchain.nextPointer,
31
- u256.Zero,
32
- );
33
-
34
- this.balanceOfMap = new AddressMemoryMap<Address, MemorySlotData<u256>>(
35
- Blockchain.nextPointer,
36
- u256.Zero,
37
- );
38
-
39
- this._totalSupply = new StoredU256(Blockchain.nextPointer, u256.Zero, u256.Zero);
40
- }
41
-
42
- public _totalSupply: StoredU256;
43
-
44
- public get totalSupply(): u256 {
45
- return this._totalSupply.value;
46
- }
47
-
48
- /** METHODS */
49
- public allowance(callData: Calldata): BytesWriter {
50
- const response = new BytesWriter();
51
-
52
- const resp = this._allowance(callData.readAddress(), callData.readAddress());
53
- response.writeU256(resp);
54
-
55
- return response;
56
- }
57
-
58
- public approve(callData: Calldata): BytesWriter {
59
- const response = new BytesWriter();
60
-
61
- const spender: Address = callData.readAddress();
62
- const value = callData.readU256();
63
-
64
- const resp = this._approve(spender, value);
65
- response.writeBoolean(resp);
66
-
67
- this.createApproveEvent(Blockchain.callee(), spender, value);
68
-
69
- return response;
70
- }
71
-
72
- public balanceOf(callData: Calldata): BytesWriter {
73
- const response = new BytesWriter();
74
- const address: Address = callData.readAddress();
75
- const resp = this._balanceOf(address);
76
-
77
- response.writeU256(resp);
78
-
79
- return response;
80
- }
81
-
82
- public burn(callData: Calldata): BytesWriter {
83
- const response = new BytesWriter();
84
- const resp = this._burn(callData.readU256());
85
- response.writeBoolean(resp);
86
-
87
- return response;
88
- }
89
-
90
- public mint(callData: Calldata): BytesWriter {
91
- const response = new BytesWriter();
92
- const resp = this._mint(callData.readAddress(), callData.readU256());
93
-
94
- response.writeBoolean(resp);
95
-
96
- return response;
97
- }
98
-
99
- public transfer(callData: Calldata): BytesWriter {
100
- const response = new BytesWriter();
101
- const resp = this._transfer(callData.readAddress(), callData.readU256());
102
-
103
- response.writeBoolean(resp);
104
-
105
- return response;
106
- }
107
-
108
- public transferFrom(callData: Calldata): BytesWriter {
109
- const response = new BytesWriter();
110
- const resp = this._transferFrom(
111
- callData.readAddress(),
112
- callData.readAddress(),
113
- callData.readU256(),
114
- );
115
-
116
- response.writeBoolean(resp);
117
-
118
- return response;
119
- }
120
-
121
- public callMethod(method: Selector, calldata: Calldata): BytesWriter {
122
- switch (method) {
123
- case encodeSelector('allowance'):
124
- return this.allowance(calldata);
125
- case encodeSelector('approve'):
126
- return this.approve(calldata);
127
- case encodeSelector('balanceOf'):
128
- return this.balanceOf(calldata);
129
- case encodeSelector('burn'):
130
- return this.burn(calldata);
131
- case encodeSelector('mint'):
132
- return this.mint(calldata);
133
- case encodeSelector('transfer'):
134
- return this.transfer(calldata);
135
- case encodeSelector('transferFrom'):
136
- return this.transferFrom(calldata);
137
- default:
138
- return super.callMethod(method, calldata);
139
- }
140
- }
141
-
142
- public callView(method: Selector): BytesWriter {
143
- const response = new BytesWriter();
144
-
145
- switch (method) {
146
- case encodeSelector('decimals'):
147
- response.writeU8(this.decimals);
148
- break;
149
- case encodeSelector('name'):
150
- response.writeStringWithLength(this.name);
151
- break;
152
- case encodeSelector('symbol'):
153
- response.writeStringWithLength(this.symbol);
154
- break;
155
- case encodeSelector('totalSupply'):
156
- response.writeU256(this.totalSupply);
157
- break;
158
- case encodeSelector('maximumSupply'):
159
- response.writeU256(this.maxSupply);
160
- break;
161
- default:
162
- return super.callView(method);
163
- }
164
-
165
- return response;
166
- }
167
-
168
- /** REDEFINED METHODS */
169
- protected _allowance(owner: Address, spender: Address): u256 {
170
- const senderMap = this.allowanceMap.get(owner);
171
-
172
- return senderMap.get(spender);
173
- }
174
-
175
- protected _approve(spender: Address, value: u256): boolean {
176
- const callee = Blockchain.callee();
177
-
178
- const senderMap = this.allowanceMap.get(callee);
179
- senderMap.set(spender, value);
180
-
181
- return true;
182
- }
183
-
184
- protected _balanceOf(owner: Address): u256 {
185
- const hasAddress = this.balanceOfMap.has(owner);
186
- if (!hasAddress) return u256.Zero;
187
-
188
- return this.balanceOfMap.get(owner);
189
- }
190
-
191
- protected _burn(value: u256, onlyOwner: boolean = true): boolean {
192
- if (u256.eq(value, u256.Zero)) {
193
- throw new Revert(`No tokens`);
194
- }
195
-
196
- const callee = Blockchain.callee();
197
- const caller = Blockchain.caller();
198
-
199
- if (onlyOwner) this.onlyOwner(callee); // only indexers can burn tokens
200
-
201
- if (this._totalSupply.value < value) throw new Revert(`Insufficient total supply.`);
202
- if (!this.balanceOfMap.has(caller)) throw new Revert('Empty');
203
-
204
- const balance: u256 = this.balanceOfMap.get(caller);
205
- if (balance < value) throw new Revert(`Insufficient balance`);
206
-
207
- const newBalance: u256 = SafeMath.sub(balance, value);
208
- this.balanceOfMap.set(caller, newBalance);
209
-
210
- // @ts-ignore
211
- this._totalSupply -= value;
212
-
213
- this.createBurnEvent(value);
214
- return true;
215
- }
216
-
217
- protected _mint(to: Address, value: u256, onlyOwner: boolean = true): boolean {
218
- const callee = Blockchain.callee();
219
-
220
- if (onlyOwner) this.onlyOwner(callee);
221
-
222
- if (!this.balanceOfMap.has(to)) {
223
- this.balanceOfMap.set(to, value);
224
- } else {
225
- const toBalance: u256 = this.balanceOfMap.get(to);
226
- const newToBalance: u256 = SafeMath.add(toBalance, value);
227
-
228
- this.balanceOfMap.set(to, newToBalance);
229
- }
230
-
231
- // @ts-ignore
232
- this._totalSupply += value;
233
-
234
- if (this._totalSupply.value > this.maxSupply) throw new Revert('Max supply reached');
235
-
236
- this.createMintEvent(to, value);
237
- return true;
238
- }
239
-
240
- protected _transfer(to: string, value: u256): boolean {
241
- const caller = Blockchain.callee();
242
-
243
- if (!this.balanceOfMap.has(caller)) throw new Revert();
244
- if (this.isSelf(caller)) throw new Revert('Can not transfer from self account');
245
-
246
- if (caller === to) {
247
- throw new Revert(`Cannot transfer to self`);
248
- }
249
-
250
- if (u256.eq(value, u256.Zero)) {
251
- throw new Revert(`Cannot transfer 0 tokens`);
252
- }
253
-
254
- const balance: u256 = this.balanceOfMap.get(caller);
255
- if (balance < value) throw new Revert(`Insufficient balance`);
256
-
257
- const newBalance: u256 = SafeMath.sub(balance, value);
258
- this.balanceOfMap.set(caller, newBalance);
259
-
260
- const toBalance: u256 = this.balanceOfMap.get(to);
261
- const newToBalance: u256 = SafeMath.add(toBalance, value);
262
-
263
- this.balanceOfMap.set(to, newToBalance);
264
-
265
- this.createTransferEvent(caller, to, value);
266
-
267
- return true;
268
- }
269
-
270
- @unsafe
271
- protected _unsafeTransferFrom(from: Address, to: Address, value: u256): boolean {
272
- const balance: u256 = this.balanceOfMap.get(from);
273
- if (balance < value)
274
- throw new Revert(
275
- `TransferFrom insufficient balance of ${from} is ${balance} and value is ${value}`,
276
- );
277
-
278
- const newBalance: u256 = SafeMath.sub(balance, value);
279
-
280
- this.balanceOfMap.set(from, newBalance);
281
-
282
- if (!this.balanceOfMap.has(to)) {
283
- this.balanceOfMap.set(to, value);
284
- } else {
285
- const toBalance: u256 = this.balanceOfMap.get(to);
286
- const newToBalance: u256 = SafeMath.add(toBalance, value);
287
-
288
- this.balanceOfMap.set(to, newToBalance);
289
- }
290
-
291
- this.createTransferEvent(from, to, value);
292
-
293
- return true;
294
- }
295
-
296
- protected _transferFrom(from: Address, to: Address, value: u256): boolean {
297
- const spender = Blockchain.callee();
298
- if (Blockchain.caller() !== from) {
299
- throw new Revert('Not caller.');
300
- }
301
-
302
- if (this.isSelf(spender)) throw new Revert('Can not transfer from self account');
303
-
304
- const fromAllowanceMap = this.allowanceMap.get(from);
305
- const allowed: u256 = fromAllowanceMap.get(spender);
306
- if (allowed < value) throw new Revert(`Insufficient allowance ${allowed} < ${value}`);
307
-
308
- const newAllowance: u256 = SafeMath.sub(allowed, value);
309
- fromAllowanceMap.set(spender, newAllowance);
310
-
311
- this.allowanceMap.set(from, fromAllowanceMap);
312
-
313
- this._unsafeTransferFrom(from, to, value);
314
-
315
- return true;
316
- }
317
-
318
- protected createBurnEvent(value: u256): void {
319
- const burnEvent = new BurnEvent(value);
320
-
321
- this.emitEvent(burnEvent);
322
- }
323
-
324
- protected createApproveEvent(owner: Address, spender: Address, value: u256): void {
325
- const approveEvent = new ApproveEvent(owner, spender, value);
326
-
327
- this.emitEvent(approveEvent);
328
- }
329
-
330
- protected createMintEvent(owner: Address, value: u256): void {
331
- const mintEvent = new MintEvent(owner, value);
332
-
333
- this.emitEvent(mintEvent);
334
- }
335
-
336
- protected createTransferEvent(from: Address, to: Address, value: u256): void {
337
- const transferEvent = new TransferEvent(from, to, value);
338
-
339
- this.emitEvent(transferEvent);
4
+ export abstract class OP_20 extends DeployableOP_20 {
5
+ protected constructor(maxSupply: u256, decimals: u8, name: string, symbol: string) {
6
+ super(new OP20InitParameters(maxSupply, decimals, name, symbol));
340
7
  }
341
8
  }
@@ -6,9 +6,17 @@ import { BytesWriter } from '../buffer/BytesWriter';
6
6
  import { encodeSelector, Selector } from '../math/abi';
7
7
  import { Revert } from '../types/Revert';
8
8
  import { MAX_EVENT_DATA_SIZE, NetEvent } from '../events/NetEvent';
9
+ import { StoredBoolean } from '../storage/StoredBoolean';
9
10
 
10
11
  export class OP_NET implements IBTC {
11
- constructor() {}
12
+ private readonly instantiated: StoredBoolean = new StoredBoolean(Blockchain.nextPointer, false);
13
+
14
+ constructor() {
15
+ if (!this.instantiated.value) {
16
+ this.instantiated.value = true;
17
+ this.onContractInstantiate();
18
+ }
19
+ }
12
20
 
13
21
  public get address(): string {
14
22
  return Blockchain.contractAddress;
@@ -18,15 +26,16 @@ export class OP_NET implements IBTC {
18
26
  return Blockchain.owner;
19
27
  }
20
28
 
21
- public callMethod(method: Selector, calldata: Calldata): BytesWriter {
29
+ public callMethod(method: Selector, _calldata: Calldata): BytesWriter {
22
30
  switch (method) {
23
- case encodeSelector('isAddressOwner'):
24
- return this.isAddressOwner(calldata);
25
31
  default:
26
32
  throw new Revert('Method not found');
27
33
  }
28
34
  }
29
35
 
36
+ // Overwrite this method in your contract
37
+ public onContractInstantiate(): void {}
38
+
30
39
  public callView(method: Selector): BytesWriter {
31
40
  const response = new BytesWriter();
32
41
 
@@ -61,13 +70,4 @@ export class OP_NET implements IBTC {
61
70
  throw new Revert('Only owner can call this method');
62
71
  }
63
72
  }
64
-
65
- private isAddressOwner(calldata: Calldata): BytesWriter {
66
- const response = new BytesWriter();
67
- const owner = calldata.readAddress();
68
-
69
- response.writeBoolean(this.owner === owner);
70
-
71
- return response;
72
- }
73
73
  }