Contract Address Details

Contract
0x57a74ca474123c4c128538e5ebfd7aa0140cb6e5
Balance
9.0 @G ($1.19)
Tokens
0 Tokens
$0.0 USD
Transactions
Balance changes
9
Gas Used
0
Last Balance Update
Contract Source Code Verified
Contract NamePhoneReputation
Compiler Versionv0.8.17+commit.8df45f5f
Optimization EnabledNo
Other SettingsDefault evmVersion
Contract Source Code (Solidity)
1
// Sources flattened with hardhat v2.23.0 https://hardhat.org
2
 
3
// SPDX-License-Identifier: GPL-3.0 AND MIT AND Unlicense
4
 
5
// File @prb/math/contracts/[email protected]
6
 
7
// Original license: SPDX_License_Identifier: Unlicense
8
pragma solidity >=0.8.4;
9
 
10
/// @notice Emitted when the result overflows uint256.
11
error PRBMath__MulDivFixedPointOverflow(uint256 prod1);
12
 
13
/// @notice Emitted when the result overflows uint256.
14
error PRBMath__MulDivOverflow(uint256 prod1, uint256 denominator);
15
 
16
/// @notice Emitted when one of the inputs is type(int256).min.
17
error PRBMath__MulDivSignedInputTooSmall();
18
 
19
/// @notice Emitted when the intermediary absolute result overflows int256.
20
error PRBMath__MulDivSignedOverflow(uint256 rAbs);
21
 
22
/// @notice Emitted when the input is MIN_SD59x18.
23
error PRBMathSD59x18__AbsInputTooSmall();
24
 
25
/// @notice Emitted when ceiling a number overflows SD59x18.
26
error PRBMathSD59x18__CeilOverflow(int256 x);
27
 
28
/// @notice Emitted when one of the inputs is MIN_SD59x18.
29
error PRBMathSD59x18__DivInputTooSmall();
30
 
31
/// @notice Emitted when one of the intermediary unsigned results overflows SD59x18.
32
error PRBMathSD59x18__DivOverflow(uint256 rAbs);
33
 
34
/// @notice Emitted when the input is greater than 133.084258667509499441.
35
error PRBMathSD59x18__ExpInputTooBig(int256 x);
36
 
37
/// @notice Emitted when the input is greater than 192.
38
error PRBMathSD59x18__Exp2InputTooBig(int256 x);
39
 
40
/// @notice Emitted when flooring a number underflows SD59x18.
41
error PRBMathSD59x18__FloorUnderflow(int256 x);
42
 
43
/// @notice Emitted when converting a basic integer to the fixed-point format overflows SD59x18.
44
error PRBMathSD59x18__FromIntOverflow(int256 x);
45
 
46
/// @notice Emitted when converting a basic integer to the fixed-point format underflows SD59x18.
47
error PRBMathSD59x18__FromIntUnderflow(int256 x);
48
 
49
/// @notice Emitted when the product of the inputs is negative.
50
error PRBMathSD59x18__GmNegativeProduct(int256 x, int256 y);
51
 
52
/// @notice Emitted when multiplying the inputs overflows SD59x18.
53
error PRBMathSD59x18__GmOverflow(int256 x, int256 y);
54
 
55
/// @notice Emitted when the input is less than or equal to zero.
56
error PRBMathSD59x18__LogInputTooSmall(int256 x);
57
 
58
/// @notice Emitted when one of the inputs is MIN_SD59x18.
59
error PRBMathSD59x18__MulInputTooSmall();
60
 
61
/// @notice Emitted when the intermediary absolute result overflows SD59x18.
62
error PRBMathSD59x18__MulOverflow(uint256 rAbs);
63
 
64
/// @notice Emitted when the intermediary absolute result overflows SD59x18.
65
error PRBMathSD59x18__PowuOverflow(uint256 rAbs);
66
 
67
/// @notice Emitted when the input is negative.
68
error PRBMathSD59x18__SqrtNegativeInput(int256 x);
69
 
70
/// @notice Emitted when the calculating the square root overflows SD59x18.
71
error PRBMathSD59x18__SqrtOverflow(int256 x);
72
 
73
/// @notice Emitted when addition overflows UD60x18.
74
error PRBMathUD60x18__AddOverflow(uint256 x, uint256 y);
75
 
76
/// @notice Emitted when ceiling a number overflows UD60x18.
77
error PRBMathUD60x18__CeilOverflow(uint256 x);
78
 
79
/// @notice Emitted when the input is greater than 133.084258667509499441.
80
error PRBMathUD60x18__ExpInputTooBig(uint256 x);
81
 
82
/// @notice Emitted when the input is greater than 192.
83
error PRBMathUD60x18__Exp2InputTooBig(uint256 x);
84
 
85
/// @notice Emitted when converting a basic integer to the fixed-point format format overflows UD60x18.
86
error PRBMathUD60x18__FromUintOverflow(uint256 x);
87
 
88
/// @notice Emitted when multiplying the inputs overflows UD60x18.
89
error PRBMathUD60x18__GmOverflow(uint256 x, uint256 y);
90
 
91
/// @notice Emitted when the input is less than 1.
92
error PRBMathUD60x18__LogInputTooSmall(uint256 x);
93
 
94
/// @notice Emitted when the calculating the square root overflows UD60x18.
95
error PRBMathUD60x18__SqrtOverflow(uint256 x);
96
 
97
/// @notice Emitted when subtraction underflows UD60x18.
98
error PRBMathUD60x18__SubUnderflow(uint256 x, uint256 y);
99
 
100
/// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library
101
/// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point
102
/// representation. When it does not, it is explicitly mentioned in the NatSpec documentation.
103
library PRBMath {
104
/// STRUCTS ///
105
 
106
struct SD59x18 {
107
int256 value;
108
}
109
 
110
struct UD60x18 {
111
uint256 value;
112
}
113
 
114
/// STORAGE ///
115
 
116
/// @dev How many trailing decimals can be represented.
117
uint256 internal constant SCALE = 1e18;
118
 
119
/// @dev Largest power of two divisor of SCALE.
120
uint256 internal constant SCALE_LPOTD = 262144;
121
 
122
/// @dev SCALE inverted mod 2^256.
123
uint256 internal constant SCALE_INVERSE =
124
78156646155174841979727994598816262306175212592076161876661_508869554232690281;
125
 
126
/// FUNCTIONS ///
127
 
128
/// @notice Calculates the binary exponent of x using the binary fraction method.
129
/// @dev Has to use 192.64-bit fixed-point numbers.
130
/// See https://ethereum.stackexchange.com/a/96594/24693.
131
/// @param x The exponent as an unsigned 192.64-bit fixed-point number.
132
/// @return result The result as an unsigned 60.18-decimal fixed-point number.
133
function exp2(uint256 x) internal pure returns (uint256 result) {
134
unchecked {
135
// Start from 0.5 in the 192.64-bit fixed-point format.
136
result = 0x800000000000000000000000000000000000000000000000;
137
 
138
// Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows
139
// because the initial result is 2^191 and all magic factors are less than 2^65.
140
if (x & 0x8000000000000000 > 0) {
141
result = (result * 0x16A09E667F3BCC909) >> 64;
142
}
143
if (x & 0x4000000000000000 > 0) {
144
result = (result * 0x1306FE0A31B7152DF) >> 64;
145
}
146
if (x & 0x2000000000000000 > 0) {
147
result = (result * 0x1172B83C7D517ADCE) >> 64;
148
}
149
if (x & 0x1000000000000000 > 0) {
150
result = (result * 0x10B5586CF9890F62A) >> 64;
151
}
152
if (x & 0x800000000000000 > 0) {
153
result = (result * 0x1059B0D31585743AE) >> 64;
154
}
155
if (x & 0x400000000000000 > 0) {
156
result = (result * 0x102C9A3E778060EE7) >> 64;
157
}
158
if (x & 0x200000000000000 > 0) {
159
result = (result * 0x10163DA9FB33356D8) >> 64;
160
}
161
if (x & 0x100000000000000 > 0) {
162
result = (result * 0x100B1AFA5ABCBED61) >> 64;
163
}
164
if (x & 0x80000000000000 > 0) {
165
result = (result * 0x10058C86DA1C09EA2) >> 64;
166
}
167
if (x & 0x40000000000000 > 0) {
168
result = (result * 0x1002C605E2E8CEC50) >> 64;
169
}
170
if (x & 0x20000000000000 > 0) {
171
result = (result * 0x100162F3904051FA1) >> 64;
172
}
173
if (x & 0x10000000000000 > 0) {
174
result = (result * 0x1000B175EFFDC76BA) >> 64;
175
}
176
if (x & 0x8000000000000 > 0) {
177
result = (result * 0x100058BA01FB9F96D) >> 64;
178
}
179
if (x & 0x4000000000000 > 0) {
180
result = (result * 0x10002C5CC37DA9492) >> 64;
181
}
182
if (x & 0x2000000000000 > 0) {
183
result = (result * 0x1000162E525EE0547) >> 64;
184
}
185
if (x & 0x1000000000000 > 0) {
186
result = (result * 0x10000B17255775C04) >> 64;
187
}
188
if (x & 0x800000000000 > 0) {
189
result = (result * 0x1000058B91B5BC9AE) >> 64;
190
}
191
if (x & 0x400000000000 > 0) {
192
result = (result * 0x100002C5C89D5EC6D) >> 64;
193
}
194
if (x & 0x200000000000 > 0) {
195
result = (result * 0x10000162E43F4F831) >> 64;
196
}
197
if (x & 0x100000000000 > 0) {
198
result = (result * 0x100000B1721BCFC9A) >> 64;
199
}
200
if (x & 0x80000000000 > 0) {
201
result = (result * 0x10000058B90CF1E6E) >> 64;
202
}
203
if (x & 0x40000000000 > 0) {
204
result = (result * 0x1000002C5C863B73F) >> 64;
205
}
206
if (x & 0x20000000000 > 0) {
207
result = (result * 0x100000162E430E5A2) >> 64;
208
}
209
if (x & 0x10000000000 > 0) {
210
result = (result * 0x1000000B172183551) >> 64;
211
}
212
if (x & 0x8000000000 > 0) {
213
result = (result * 0x100000058B90C0B49) >> 64;
214
}
215
if (x & 0x4000000000 > 0) {
216
result = (result * 0x10000002C5C8601CC) >> 64;
217
}
218
if (x & 0x2000000000 > 0) {
219
result = (result * 0x1000000162E42FFF0) >> 64;
220
}
221
if (x & 0x1000000000 > 0) {
222
result = (result * 0x10000000B17217FBB) >> 64;
223
}
224
if (x & 0x800000000 > 0) {
225
result = (result * 0x1000000058B90BFCE) >> 64;
226
}
227
if (x & 0x400000000 > 0) {
228
result = (result * 0x100000002C5C85FE3) >> 64;
229
}
230
if (x & 0x200000000 > 0) {
231
result = (result * 0x10000000162E42FF1) >> 64;
232
}
233
if (x & 0x100000000 > 0) {
234
result = (result * 0x100000000B17217F8) >> 64;
235
}
236
if (x & 0x80000000 > 0) {
237
result = (result * 0x10000000058B90BFC) >> 64;
238
}
239
if (x & 0x40000000 > 0) {
240
result = (result * 0x1000000002C5C85FE) >> 64;
241
}
242
if (x & 0x20000000 > 0) {
243
result = (result * 0x100000000162E42FF) >> 64;
244
}
245
if (x & 0x10000000 > 0) {
246
result = (result * 0x1000000000B17217F) >> 64;
247
}
248
if (x & 0x8000000 > 0) {
249
result = (result * 0x100000000058B90C0) >> 64;
250
}
251
if (x & 0x4000000 > 0) {
252
result = (result * 0x10000000002C5C860) >> 64;
253
}
254
if (x & 0x2000000 > 0) {
255
result = (result * 0x1000000000162E430) >> 64;
256
}
257
if (x & 0x1000000 > 0) {
258
result = (result * 0x10000000000B17218) >> 64;
259
}
260
if (x & 0x800000 > 0) {
261
result = (result * 0x1000000000058B90C) >> 64;
262
}
263
if (x & 0x400000 > 0) {
264
result = (result * 0x100000000002C5C86) >> 64;
265
}
266
if (x & 0x200000 > 0) {
267
result = (result * 0x10000000000162E43) >> 64;
268
}
269
if (x & 0x100000 > 0) {
270
result = (result * 0x100000000000B1721) >> 64;
271
}
272
if (x & 0x80000 > 0) {
273
result = (result * 0x10000000000058B91) >> 64;
274
}
275
if (x & 0x40000 > 0) {
276
result = (result * 0x1000000000002C5C8) >> 64;
277
}
278
if (x & 0x20000 > 0) {
279
result = (result * 0x100000000000162E4) >> 64;
280
}
281
if (x & 0x10000 > 0) {
282
result = (result * 0x1000000000000B172) >> 64;
283
}
284
if (x & 0x8000 > 0) {
285
result = (result * 0x100000000000058B9) >> 64;
286
}
287
if (x & 0x4000 > 0) {
288
result = (result * 0x10000000000002C5D) >> 64;
289
}
290
if (x & 0x2000 > 0) {
291
result = (result * 0x1000000000000162E) >> 64;
292
}
293
if (x & 0x1000 > 0) {
294
result = (result * 0x10000000000000B17) >> 64;
295
}
296
if (x & 0x800 > 0) {
297
result = (result * 0x1000000000000058C) >> 64;
298
}
299
if (x & 0x400 > 0) {
300
result = (result * 0x100000000000002C6) >> 64;
301
}
302
if (x & 0x200 > 0) {
303
result = (result * 0x10000000000000163) >> 64;
304
}
305
if (x & 0x100 > 0) {
306
result = (result * 0x100000000000000B1) >> 64;
307
}
308
if (x & 0x80 > 0) {
309
result = (result * 0x10000000000000059) >> 64;
310
}
311
if (x & 0x40 > 0) {
312
result = (result * 0x1000000000000002C) >> 64;
313
}
314
if (x & 0x20 > 0) {
315
result = (result * 0x10000000000000016) >> 64;
316
}
317
if (x & 0x10 > 0) {
318
result = (result * 0x1000000000000000B) >> 64;
319
}
320
if (x & 0x8 > 0) {
321
result = (result * 0x10000000000000006) >> 64;
322
}
323
if (x & 0x4 > 0) {
324
result = (result * 0x10000000000000003) >> 64;
325
}
326
if (x & 0x2 > 0) {
327
result = (result * 0x10000000000000001) >> 64;
328
}
329
if (x & 0x1 > 0) {
330
result = (result * 0x10000000000000001) >> 64;
331
}
332
 
333
// We're doing two things at the same time:
334
//
335
// 1. Multiply the result by 2^n + 1, where "2^n" is the integer part and the one is added to account for
336
// the fact that we initially set the result to 0.5. This is accomplished by subtracting from 191
337
// rather than 192.
338
// 2. Convert the result to the unsigned 60.18-decimal fixed-point format.
339
//
340
// This works because 2^(191-ip) = 2^ip / 2^191, where "ip" is the integer part "2^n".
341
result *= SCALE;
342
result >>= (191 - (x >> 64));
343
}
344
}
345
 
346
/// @notice Finds the zero-based index of the first one in the binary representation of x.
347
/// @dev See the note on msb in the "Find First Set" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set
348
/// @param x The uint256 number for which to find the index of the most significant bit.
349
/// @return msb The index of the most significant bit as an uint256.
350
function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) {
351
if (x >= 2**128) {
352
x >>= 128;
353
msb += 128;
354
}
355
if (x >= 2**64) {
356
x >>= 64;
357
msb += 64;
358
}
359
if (x >= 2**32) {
360
x >>= 32;
361
msb += 32;
362
}
363
if (x >= 2**16) {
364
x >>= 16;
365
msb += 16;
366
}
367
if (x >= 2**8) {
368
x >>= 8;
369
msb += 8;
370
}
371
if (x >= 2**4) {
372
x >>= 4;
373
msb += 4;
374
}
375
if (x >= 2**2) {
376
x >>= 2;
377
msb += 2;
378
}
379
if (x >= 2**1) {
380
// No need to shift x any more.
381
msb += 1;
382
}
383
}
384
 
385
/// @notice Calculates floor(x*y÷denominator) with full precision.
386
///
387
/// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.
388
///
389
/// Requirements:
390
/// - The denominator cannot be zero.
391
/// - The result must fit within uint256.
392
///
393
/// Caveats:
394
/// - This function does not work with fixed-point numbers.
395
///
396
/// @param x The multiplicand as an uint256.
397
/// @param y The multiplier as an uint256.
398
/// @param denominator The divisor as an uint256.
399
/// @return result The result as an uint256.
400
function mulDiv(
401
uint256 x,
402
uint256 y,
403
uint256 denominator
404
) internal pure returns (uint256 result) {
405
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
406
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
407
// variables such that product = prod1 * 2^256 + prod0.
408
uint256 prod0; // Least significant 256 bits of the product
409
uint256 prod1; // Most significant 256 bits of the product
410
assembly {
411
let mm := mulmod(x, y, not(0))
412
prod0 := mul(x, y)
413
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
414
}
415
 
416
// Handle non-overflow cases, 256 by 256 division.
417
if (prod1 == 0) {
418
unchecked {
419
result = prod0 / denominator;
420
}
421
return result;
422
}
423
 
424
// Make sure the result is less than 2^256. Also prevents denominator == 0.
425
if (prod1 >= denominator) {
426
revert PRBMath__MulDivOverflow(prod1, denominator);
427
}
428
 
429
///////////////////////////////////////////////
430
// 512 by 256 division.
431
///////////////////////////////////////////////
432
 
433
// Make division exact by subtracting the remainder from [prod1 prod0].
434
uint256 remainder;
435
assembly {
436
// Compute remainder using mulmod.
437
remainder := mulmod(x, y, denominator)
438
 
439
// Subtract 256 bit number from 512 bit number.
440
prod1 := sub(prod1, gt(remainder, prod0))
441
prod0 := sub(prod0, remainder)
442
}
443
 
444
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
445
// See https://cs.stackexchange.com/q/138556/92363.
446
unchecked {
447
// Does not overflow because the denominator cannot be zero at this stage in the function.
448
uint256 lpotdod = denominator & (~denominator + 1);
449
assembly {
450
// Divide denominator by lpotdod.
451
denominator := div(denominator, lpotdod)
452
 
453
// Divide [prod1 prod0] by lpotdod.
454
prod0 := div(prod0, lpotdod)
455
 
456
// Flip lpotdod such that it is 2^256 / lpotdod. If lpotdod is zero, then it becomes one.
457
lpotdod := add(div(sub(0, lpotdod), lpotdod), 1)
458
}
459
 
460
// Shift in bits from prod1 into prod0.
461
prod0 |= prod1 * lpotdod;
462
 
463
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
464
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
465
// four bits. That is, denominator * inv = 1 mod 2^4.
466
uint256 inverse = (3 * denominator) ^ 2;
467
 
468
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
469
// in modular arithmetic, doubling the correct bits in each step.
470
inverse *= 2 - denominator * inverse; // inverse mod 2^8
471
inverse *= 2 - denominator * inverse; // inverse mod 2^16
472
inverse *= 2 - denominator * inverse; // inverse mod 2^32
473
inverse *= 2 - denominator * inverse; // inverse mod 2^64
474
inverse *= 2 - denominator * inverse; // inverse mod 2^128
475
inverse *= 2 - denominator * inverse; // inverse mod 2^256
476
 
477
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
478
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
479
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
480
// is no longer required.
481
result = prod0 * inverse;
482
return result;
483
}
484
}
485
 
486
/// @notice Calculates floor(x*y÷1e18) with full precision.
487
///
488
/// @dev Variant of "mulDiv" with constant folding, i.e. in which the denominator is always 1e18. Before returning the
489
/// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of
490
/// being rounded to 1e-18. See "Listing 6" and text above it at https://accu.org/index.php/journals/1717.
491
///
492
/// Requirements:
493
/// - The result must fit within uint256.
494
///
495
/// Caveats:
496
/// - The body is purposely left uncommented; see the NatSpec comments in "PRBMath.mulDiv" to understand how this works.
497
/// - It is assumed that the result can never be type(uint256).max when x and y solve the following two equations:
498
/// 1. x * y = type(uint256).max * SCALE
499
/// 2. (x * y) % SCALE >= SCALE / 2
500
///
501
/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.
502
/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.
503
/// @return result The result as an unsigned 60.18-decimal fixed-point number.
504
function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) {
505
uint256 prod0;
506
uint256 prod1;
507
assembly {
508
let mm := mulmod(x, y, not(0))
509
prod0 := mul(x, y)
510
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
511
}
512
 
513
if (prod1 >= SCALE) {
514
revert PRBMath__MulDivFixedPointOverflow(prod1);
515
}
516
 
517
uint256 remainder;
518
uint256 roundUpUnit;
519
assembly {
520
remainder := mulmod(x, y, SCALE)
521
roundUpUnit := gt(remainder, 499999999999999999)
522
}
523
 
524
if (prod1 == 0) {
525
unchecked {
526
result = (prod0 / SCALE) + roundUpUnit;
527
return result;
528
}
529
}
530
 
531
assembly {
532
result := add(
533
mul(
534
or(
535
div(sub(prod0, remainder), SCALE_LPOTD),
536
mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1))
537
),
538
SCALE_INVERSE
539
),
540
roundUpUnit
541
)
542
}
543
}
544
 
545
/// @notice Calculates floor(x*y÷denominator) with full precision.
546
///
547
/// @dev An extension of "mulDiv" for signed numbers. Works by computing the signs and the absolute values separately.
548
///
549
/// Requirements:
550
/// - None of the inputs can be type(int256).min.
551
/// - The result must fit within int256.
552
///
553
/// @param x The multiplicand as an int256.
554
/// @param y The multiplier as an int256.
555
/// @param denominator The divisor as an int256.
556
/// @return result The result as an int256.
557
function mulDivSigned(
558
int256 x,
559
int256 y,
560
int256 denominator
561
) internal pure returns (int256 result) {
562
if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {
563
revert PRBMath__MulDivSignedInputTooSmall();
564
}
565
 
566
// Get hold of the absolute values of x, y and the denominator.
567
uint256 ax;
568
uint256 ay;
569
uint256 ad;
570
unchecked {
571
ax = x < 0 ? uint256(-x) : uint256(x);
572
ay = y < 0 ? uint256(-y) : uint256(y);
573
ad = denominator < 0 ? uint256(-denominator) : uint256(denominator);
574
}
575
 
576
// Compute the absolute value of (x*y)÷denominator. The result must fit within int256.
577
uint256 rAbs = mulDiv(ax, ay, ad);
578
if (rAbs > uint256(type(int256).max)) {
579
revert PRBMath__MulDivSignedOverflow(rAbs);
580
}
581
 
582
// Get the signs of x, y and the denominator.
583
uint256 sx;
584
uint256 sy;
585
uint256 sd;
586
assembly {
587
sx := sgt(x, sub(0, 1))
588
sy := sgt(y, sub(0, 1))
589
sd := sgt(denominator, sub(0, 1))
590
}
591
 
592
// XOR over sx, sy and sd. This is checking whether there are one or three negative signs in the inputs.
593
// If yes, the result should be negative.
594
result = sx ^ sy ^ sd == 0 ? -int256(rAbs) : int256(rAbs);
595
}
596
 
597
/// @notice Calculates the square root of x, rounding down.
598
/// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
599
///
600
/// Caveats:
601
/// - This function does not work with fixed-point numbers.
602
///
603
/// @param x The uint256 number for which to calculate the square root.
604
/// @return result The result as an uint256.
605
function sqrt(uint256 x) internal pure returns (uint256 result) {
606
if (x == 0) {
607
return 0;
608
}
609
 
610
// Set the initial guess to the least power of two that is greater than or equal to sqrt(x).
611
uint256 xAux = uint256(x);
612
result = 1;
613
if (xAux >= 0x100000000000000000000000000000000) {
614
xAux >>= 128;
615
result <<= 64;
616
}
617
if (xAux >= 0x10000000000000000) {
618
xAux >>= 64;
619
result <<= 32;
620
}
621
if (xAux >= 0x100000000) {
622
xAux >>= 32;
623
result <<= 16;
624
}
625
if (xAux >= 0x10000) {
626
xAux >>= 16;
627
result <<= 8;
628
}
629
if (xAux >= 0x100) {
630
xAux >>= 8;
631
result <<= 4;
632
}
633
if (xAux >= 0x10) {
634
xAux >>= 4;
635
result <<= 2;
636
}
637
if (xAux >= 0x8) {
638
result <<= 1;
639
}
640
 
641
// The operations can never overflow because the result is max 2^127 when it enters this block.
642
unchecked {
643
result = (result + x / result) >> 1;
644
result = (result + x / result) >> 1;
645
result = (result + x / result) >> 1;
646
result = (result + x / result) >> 1;
647
result = (result + x / result) >> 1;
648
result = (result + x / result) >> 1;
649
result = (result + x / result) >> 1; // Seven iterations should be enough
650
uint256 roundedDownResult = x / result;
651
return result >= roundedDownResult ? roundedDownResult : result;
652
}
653
}
654
}
655
 
656
 
657
// File @prb/math/contracts/[email protected]
658
 
659
// Original license: SPDX_License_Identifier: Unlicense
660
pragma solidity >=0.8.4;
661
 
662
/// @title PRBMathSD59x18
663
/// @author Paul Razvan Berg
664
/// @notice Smart contract library for advanced fixed-point math that works with int256 numbers considered to have 18
665
/// trailing decimals. We call this number representation signed 59.18-decimal fixed-point, since the numbers can have
666
/// a sign and there can be up to 59 digits in the integer part and up to 18 decimals in the fractional part. The numbers
667
/// are bound by the minimum and the maximum values permitted by the Solidity type int256.
668
library PRBMathSD59x18 {
669
/// @dev log2(e) as a signed 59.18-decimal fixed-point number.
670
int256 internal constant LOG2_E = 1_442695040888963407;
671
 
672
/// @dev Half the SCALE number.
673
int256 internal constant HALF_SCALE = 5e17;
674
 
675
/// @dev The maximum value a signed 59.18-decimal fixed-point number can have.
676
int256 internal constant MAX_SD59x18 =
677
57896044618658097711785492504343953926634992332820282019728_792003956564819967;
678
 
679
/// @dev The maximum whole value a signed 59.18-decimal fixed-point number can have.
680
int256 internal constant MAX_WHOLE_SD59x18 =
681
57896044618658097711785492504343953926634992332820282019728_000000000000000000;
682
 
683
/// @dev The minimum value a signed 59.18-decimal fixed-point number can have.
684
int256 internal constant MIN_SD59x18 =
685
-57896044618658097711785492504343953926634992332820282019728_792003956564819968;
686
 
687
/// @dev The minimum whole value a signed 59.18-decimal fixed-point number can have.
688
int256 internal constant MIN_WHOLE_SD59x18 =
689
-57896044618658097711785492504343953926634992332820282019728_000000000000000000;
690
 
691
/// @dev How many trailing decimals can be represented.
692
int256 internal constant SCALE = 1e18;
693
 
694
/// INTERNAL FUNCTIONS ///
695
 
696
/// @notice Calculate the absolute value of x.
697
///
698
/// @dev Requirements:
699
/// - x must be greater than MIN_SD59x18.
700
///
701
/// @param x The number to calculate the absolute value for.
702
/// @param result The absolute value of x.
703
function abs(int256 x) internal pure returns (int256 result) {
704
unchecked {
705
if (x == MIN_SD59x18) {
706
revert PRBMathSD59x18__AbsInputTooSmall();
707
}
708
result = x < 0 ? -x : x;
709
}
710
}
711
 
712
/// @notice Calculates the arithmetic average of x and y, rounding down.
713
/// @param x The first operand as a signed 59.18-decimal fixed-point number.
714
/// @param y The second operand as a signed 59.18-decimal fixed-point number.
715
/// @return result The arithmetic average as a signed 59.18-decimal fixed-point number.
716
function avg(int256 x, int256 y) internal pure returns (int256 result) {
717
// The operations can never overflow.
718
unchecked {
719
int256 sum = (x >> 1) + (y >> 1);
720
if (sum < 0) {
721
// If at least one of x and y is odd, we add 1 to the result. This is because shifting negative numbers to the
722
// right rounds down to infinity.
723
assembly {
724
result := add(sum, and(or(x, y), 1))
725
}
726
} else {
727
// If both x and y are odd, we add 1 to the result. This is because if both numbers are odd, the 0.5
728
// remainder gets truncated twice.
729
result = sum + (x & y & 1);
730
}
731
}
732
}
733
 
734
/// @notice Yields the least greatest signed 59.18 decimal fixed-point number greater than or equal to x.
735
///
736
/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.
737
/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
738
///
739
/// Requirements:
740
/// - x must be less than or equal to MAX_WHOLE_SD59x18.
741
///
742
/// @param x The signed 59.18-decimal fixed-point number to ceil.
743
/// @param result The least integer greater than or equal to x, as a signed 58.18-decimal fixed-point number.
744
function ceil(int256 x) internal pure returns (int256 result) {
745
if (x > MAX_WHOLE_SD59x18) {
746
revert PRBMathSD59x18__CeilOverflow(x);
747
}
748
unchecked {
749
int256 remainder = x % SCALE;
750
if (remainder == 0) {
751
result = x;
752
} else {
753
// Solidity uses C fmod style, which returns a modulus with the same sign as x.
754
result = x - remainder;
755
if (x > 0) {
756
result += SCALE;
757
}
758
}
759
}
760
}
761
 
762
/// @notice Divides two signed 59.18-decimal fixed-point numbers, returning a new signed 59.18-decimal fixed-point number.
763
///
764
/// @dev Variant of "mulDiv" that works with signed numbers. Works by computing the signs and the absolute values separately.
765
///
766
/// Requirements:
767
/// - All from "PRBMath.mulDiv".
768
/// - None of the inputs can be MIN_SD59x18.
769
/// - The denominator cannot be zero.
770
/// - The result must fit within int256.
771
///
772
/// Caveats:
773
/// - All from "PRBMath.mulDiv".
774
///
775
/// @param x The numerator as a signed 59.18-decimal fixed-point number.
776
/// @param y The denominator as a signed 59.18-decimal fixed-point number.
777
/// @param result The quotient as a signed 59.18-decimal fixed-point number.
778
function div(int256 x, int256 y) internal pure returns (int256 result) {
779
if (x == MIN_SD59x18 || y == MIN_SD59x18) {
780
revert PRBMathSD59x18__DivInputTooSmall();
781
}
782
 
783
// Get hold of the absolute values of x and y.
784
uint256 ax;
785
uint256 ay;
786
unchecked {
787
ax = x < 0 ? uint256(-x) : uint256(x);
788
ay = y < 0 ? uint256(-y) : uint256(y);
789
}
790
 
791
// Compute the absolute value of (x*SCALE)÷y. The result must fit within int256.
792
uint256 rAbs = PRBMath.mulDiv(ax, uint256(SCALE), ay);
793
if (rAbs > uint256(MAX_SD59x18)) {
794
revert PRBMathSD59x18__DivOverflow(rAbs);
795
}
796
 
797
// Get the signs of x and y.
798
uint256 sx;
799
uint256 sy;
800
assembly {
801
sx := sgt(x, sub(0, 1))
802
sy := sgt(y, sub(0, 1))
803
}
804
 
805
// XOR over sx and sy. This is basically checking whether the inputs have the same sign. If yes, the result
806
// should be positive. Otherwise, it should be negative.
807
result = sx ^ sy == 1 ? -int256(rAbs) : int256(rAbs);
808
}
809
 
810
/// @notice Returns Euler's number as a signed 59.18-decimal fixed-point number.
811
/// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).
812
function e() internal pure returns (int256 result) {
813
result = 2_718281828459045235;
814
}
815
 
816
/// @notice Calculates the natural exponent of x.
817
///
818
/// @dev Based on the insight that e^x = 2^(x * log2(e)).
819
///
820
/// Requirements:
821
/// - All from "log2".
822
/// - x must be less than 133.084258667509499441.
823
///
824
/// Caveats:
825
/// - All from "exp2".
826
/// - For any x less than -41.446531673892822322, the result is zero.
827
///
828
/// @param x The exponent as a signed 59.18-decimal fixed-point number.
829
/// @return result The result as a signed 59.18-decimal fixed-point number.
830
function exp(int256 x) internal pure returns (int256 result) {
831
// Without this check, the value passed to "exp2" would be less than -59.794705707972522261.
832
if (x < -41_446531673892822322) {
833
return 0;
834
}
835
 
836
// Without this check, the value passed to "exp2" would be greater than 192.
837
if (x >= 133_084258667509499441) {
838
revert PRBMathSD59x18__ExpInputTooBig(x);
839
}
840
 
841
// Do the fixed-point multiplication inline to save gas.
842
unchecked {
843
int256 doubleScaleProduct = x * LOG2_E;
844
result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);
845
}
846
}
847
 
848
/// @notice Calculates the binary exponent of x using the binary fraction method.
849
///
850
/// @dev See https://ethereum.stackexchange.com/q/79903/24693.
851
///
852
/// Requirements:
853
/// - x must be 192 or less.
854
/// - The result must fit within MAX_SD59x18.
855
///
856
/// Caveats:
857
/// - For any x less than -59.794705707972522261, the result is zero.
858
///
859
/// @param x The exponent as a signed 59.18-decimal fixed-point number.
860
/// @return result The result as a signed 59.18-decimal fixed-point number.
861
function exp2(int256 x) internal pure returns (int256 result) {
862
// This works because 2^(-x) = 1/2^x.
863
if (x < 0) {
864
// 2^59.794705707972522262 is the maximum number whose inverse does not truncate down to zero.
865
if (x < -59_794705707972522261) {
866
return 0;
867
}
868
 
869
// Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.
870
unchecked {
871
result = 1e36 / exp2(-x);
872
}
873
} else {
874
// 2^192 doesn't fit within the 192.64-bit format used internally in this function.
875
if (x >= 192e18) {
876
revert PRBMathSD59x18__Exp2InputTooBig(x);
877
}
878
 
879
unchecked {
880
// Convert x to the 192.64-bit fixed-point format.
881
uint256 x192x64 = (uint256(x) << 64) / uint256(SCALE);
882
 
883
// Safe to convert the result to int256 directly because the maximum input allowed is 192.
884
result = int256(PRBMath.exp2(x192x64));
885
}
886
}
887
}
888
 
889
/// @notice Yields the greatest signed 59.18 decimal fixed-point number less than or equal to x.
890
///
891
/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.
892
/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
893
///
894
/// Requirements:
895
/// - x must be greater than or equal to MIN_WHOLE_SD59x18.
896
///
897
/// @param x The signed 59.18-decimal fixed-point number to floor.
898
/// @param result The greatest integer less than or equal to x, as a signed 58.18-decimal fixed-point number.
899
function floor(int256 x) internal pure returns (int256 result) {
900
if (x < MIN_WHOLE_SD59x18) {
901
revert PRBMathSD59x18__FloorUnderflow(x);
902
}
903
unchecked {
904
int256 remainder = x % SCALE;
905
if (remainder == 0) {
906
result = x;
907
} else {
908
// Solidity uses C fmod style, which returns a modulus with the same sign as x.
909
result = x - remainder;
910
if (x < 0) {
911
result -= SCALE;
912
}
913
}
914
}
915
}
916
 
917
/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right
918
/// of the radix point for negative numbers.
919
/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part
920
/// @param x The signed 59.18-decimal fixed-point number to get the fractional part of.
921
/// @param result The fractional part of x as a signed 59.18-decimal fixed-point number.
922
function frac(int256 x) internal pure returns (int256 result) {
923
unchecked {
924
result = x % SCALE;
925
}
926
}
927
 
928
/// @notice Converts a number from basic integer form to signed 59.18-decimal fixed-point representation.
929
///
930
/// @dev Requirements:
931
/// - x must be greater than or equal to MIN_SD59x18 divided by SCALE.
932
/// - x must be less than or equal to MAX_SD59x18 divided by SCALE.
933
///
934
/// @param x The basic integer to convert.
935
/// @param result The same number in signed 59.18-decimal fixed-point representation.
936
function fromInt(int256 x) internal pure returns (int256 result) {
937
unchecked {
938
if (x < MIN_SD59x18 / SCALE) {
939
revert PRBMathSD59x18__FromIntUnderflow(x);
940
}
941
if (x > MAX_SD59x18 / SCALE) {
942
revert PRBMathSD59x18__FromIntOverflow(x);
943
}
944
result = x * SCALE;
945
}
946
}
947
 
948
/// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.
949
///
950
/// @dev Requirements:
951
/// - x * y must fit within MAX_SD59x18, lest it overflows.
952
/// - x * y cannot be negative.
953
///
954
/// @param x The first operand as a signed 59.18-decimal fixed-point number.
955
/// @param y The second operand as a signed 59.18-decimal fixed-point number.
956
/// @return result The result as a signed 59.18-decimal fixed-point number.
957
function gm(int256 x, int256 y) internal pure returns (int256 result) {
958
if (x == 0) {
959
return 0;
960
}
961
 
962
unchecked {
963
// Checking for overflow this way is faster than letting Solidity do it.
964
int256 xy = x * y;
965
if (xy / x != y) {
966
revert PRBMathSD59x18__GmOverflow(x, y);
967
}
968
 
969
// The product cannot be negative.
970
if (xy < 0) {
971
revert PRBMathSD59x18__GmNegativeProduct(x, y);
972
}
973
 
974
// We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE
975
// during multiplication. See the comments within the "sqrt" function.
976
result = int256(PRBMath.sqrt(uint256(xy)));
977
}
978
}
979
 
980
/// @notice Calculates 1 / x, rounding toward zero.
981
///
982
/// @dev Requirements:
983
/// - x cannot be zero.
984
///
985
/// @param x The signed 59.18-decimal fixed-point number for which to calculate the inverse.
986
/// @return result The inverse as a signed 59.18-decimal fixed-point number.
987
function inv(int256 x) internal pure returns (int256 result) {
988
unchecked {
989
// 1e36 is SCALE * SCALE.
990
result = 1e36 / x;
991
}
992
}
993
 
994
/// @notice Calculates the natural logarithm of x.
995
///
996
/// @dev Based on the insight that ln(x) = log2(x) / log2(e).
997
///
998
/// Requirements:
999
/// - All from "log2".
1000
///
1001
/// Caveats:
1002
/// - All from "log2".
1003
/// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.
1004
///
1005
/// @param x The signed 59.18-decimal fixed-point number for which to calculate the natural logarithm.
1006
/// @return result The natural logarithm as a signed 59.18-decimal fixed-point number.
1007
function ln(int256 x) internal pure returns (int256 result) {
1008
// Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)
1009
// can return is 195205294292027477728.
1010
unchecked {
1011
result = (log2(x) * SCALE) / LOG2_E;
1012
}
1013
}
1014
 
1015
/// @notice Calculates the common logarithm of x.
1016
///
1017
/// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common
1018
/// logarithm based on the insight that log10(x) = log2(x) / log2(10).
1019
///
1020
/// Requirements:
1021
/// - All from "log2".
1022
///
1023
/// Caveats:
1024
/// - All from "log2".
1025
///
1026
/// @param x The signed 59.18-decimal fixed-point number for which to calculate the common logarithm.
1027
/// @return result The common logarithm as a signed 59.18-decimal fixed-point number.
1028
function log10(int256 x) internal pure returns (int256 result) {
1029
if (x <= 0) {
1030
revert PRBMathSD59x18__LogInputTooSmall(x);
1031
}
1032
 
1033
// Note that the "mul" in this block is the assembly mul operation, not the "mul" function defined in this contract.
1034
// prettier-ignore
1035
assembly {
1036
switch x
1037
case 1 { result := mul(SCALE, sub(0, 18)) }
1038
case 10 { result := mul(SCALE, sub(1, 18)) }
1039
case 100 { result := mul(SCALE, sub(2, 18)) }
1040
case 1000 { result := mul(SCALE, sub(3, 18)) }
1041
case 10000 { result := mul(SCALE, sub(4, 18)) }
1042
case 100000 { result := mul(SCALE, sub(5, 18)) }
1043
case 1000000 { result := mul(SCALE, sub(6, 18)) }
1044
case 10000000 { result := mul(SCALE, sub(7, 18)) }
1045
case 100000000 { result := mul(SCALE, sub(8, 18)) }
1046
case 1000000000 { result := mul(SCALE, sub(9, 18)) }
1047
case 10000000000 { result := mul(SCALE, sub(10, 18)) }
1048
case 100000000000 { result := mul(SCALE, sub(11, 18)) }
1049
case 1000000000000 { result := mul(SCALE, sub(12, 18)) }
1050
case 10000000000000 { result := mul(SCALE, sub(13, 18)) }
1051
case 100000000000000 { result := mul(SCALE, sub(14, 18)) }
1052
case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }
1053
case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }
1054
case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }
1055
case 1000000000000000000 { result := 0 }
1056
case 10000000000000000000 { result := SCALE }
1057
case 100000000000000000000 { result := mul(SCALE, 2) }
1058
case 1000000000000000000000 { result := mul(SCALE, 3) }
1059
case 10000000000000000000000 { result := mul(SCALE, 4) }
1060
case 100000000000000000000000 { result := mul(SCALE, 5) }
1061
case 1000000000000000000000000 { result := mul(SCALE, 6) }
1062
case 10000000000000000000000000 { result := mul(SCALE, 7) }
1063
case 100000000000000000000000000 { result := mul(SCALE, 8) }
1064
case 1000000000000000000000000000 { result := mul(SCALE, 9) }
1065
case 10000000000000000000000000000 { result := mul(SCALE, 10) }
1066
case 100000000000000000000000000000 { result := mul(SCALE, 11) }
1067
case 1000000000000000000000000000000 { result := mul(SCALE, 12) }
1068
case 10000000000000000000000000000000 { result := mul(SCALE, 13) }
1069
case 100000000000000000000000000000000 { result := mul(SCALE, 14) }
1070
case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }
1071
case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }
1072
case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }
1073
case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }
1074
case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }
1075
case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }
1076
case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }
1077
case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }
1078
case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }
1079
case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }
1080
case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }
1081
case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }
1082
case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }
1083
case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }
1084
case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }
1085
case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }
1086
case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }
1087
case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }
1088
case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }
1089
case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }
1090
case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }
1091
case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }
1092
case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }
1093
case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }
1094
case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }
1095
case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }
1096
case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }
1097
case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }
1098
case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }
1099
case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }
1100
case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }
1101
case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }
1102
case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }
1103
case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }
1104
case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }
1105
case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }
1106
case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }
1107
case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }
1108
case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }
1109
case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }
1110
case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }
1111
case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }
1112
case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }
1113
case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }
1114
default {
1115
result := MAX_SD59x18
1116
}
1117
}
1118
 
1119
if (result == MAX_SD59x18) {
1120
// Do the fixed-point division inline to save gas. The denominator is log2(10).
1121
unchecked {
1122
result = (log2(x) * SCALE) / 3_321928094887362347;
1123
}
1124
}
1125
}
1126
 
1127
/// @notice Calculates the binary logarithm of x.
1128
///
1129
/// @dev Based on the iterative approximation algorithm.
1130
/// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation
1131
///
1132
/// Requirements:
1133
/// - x must be greater than zero.
1134
///
1135
/// Caveats:
1136
/// - The results are not perfectly accurate to the last decimal, due to the lossy precision of the iterative approximation.
1137
///
1138
/// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm.
1139
/// @return result The binary logarithm as a signed 59.18-decimal fixed-point number.
1140
function log2(int256 x) internal pure returns (int256 result) {
1141
if (x <= 0) {
1142
revert PRBMathSD59x18__LogInputTooSmall(x);
1143
}
1144
unchecked {
1145
// This works because log2(x) = -log2(1/x).
1146
int256 sign;
1147
if (x >= SCALE) {
1148
sign = 1;
1149
} else {
1150
sign = -1;
1151
// Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.
1152
assembly {
1153
x := div(1000000000000000000000000000000000000, x)
1154
}
1155
}
1156
 
1157
// Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).
1158
uint256 n = PRBMath.mostSignificantBit(uint256(x / SCALE));
1159
 
1160
// The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow
1161
// because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1.
1162
result = int256(n) * SCALE;
1163
 
1164
// This is y = x * 2^(-n).
1165
int256 y = x >> n;
1166
 
1167
// If y = 1, the fractional part is zero.
1168
if (y == SCALE) {
1169
return result * sign;
1170
}
1171
 
1172
// Calculate the fractional part via the iterative approximation.
1173
// The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster.
1174
for (int256 delta = int256(HALF_SCALE); delta > 0; delta >>= 1) {
1175
y = (y * y) / SCALE;
1176
 
1177
// Is y^2 > 2 and so in the range [2,4)?
1178
if (y >= 2 * SCALE) {
1179
// Add the 2^(-m) factor to the logarithm.
1180
result += delta;
1181
 
1182
// Corresponds to z/2 on Wikipedia.
1183
y >>= 1;
1184
}
1185
}
1186
result *= sign;
1187
}
1188
}
1189
 
1190
/// @notice Multiplies two signed 59.18-decimal fixed-point numbers together, returning a new signed 59.18-decimal
1191
/// fixed-point number.
1192
///
1193
/// @dev Variant of "mulDiv" that works with signed numbers and employs constant folding, i.e. the denominator is
1194
/// always 1e18.
1195
///
1196
/// Requirements:
1197
/// - All from "PRBMath.mulDivFixedPoint".
1198
/// - None of the inputs can be MIN_SD59x18
1199
/// - The result must fit within MAX_SD59x18.
1200
///
1201
/// Caveats:
1202
/// - The body is purposely left uncommented; see the NatSpec comments in "PRBMath.mulDiv" to understand how this works.
1203
///
1204
/// @param x The multiplicand as a signed 59.18-decimal fixed-point number.
1205
/// @param y The multiplier as a signed 59.18-decimal fixed-point number.
1206
/// @return result The product as a signed 59.18-decimal fixed-point number.
1207
function mul(int256 x, int256 y) internal pure returns (int256 result) {
1208
if (x == MIN_SD59x18 || y == MIN_SD59x18) {
1209
revert PRBMathSD59x18__MulInputTooSmall();
1210
}
1211
 
1212
unchecked {
1213
uint256 ax;
1214
uint256 ay;
1215
ax = x < 0 ? uint256(-x) : uint256(x);
1216
ay = y < 0 ? uint256(-y) : uint256(y);
1217
 
1218
uint256 rAbs = PRBMath.mulDivFixedPoint(ax, ay);
1219
if (rAbs > uint256(MAX_SD59x18)) {
1220
revert PRBMathSD59x18__MulOverflow(rAbs);
1221
}
1222
 
1223
uint256 sx;
1224
uint256 sy;
1225
assembly {
1226
sx := sgt(x, sub(0, 1))
1227
sy := sgt(y, sub(0, 1))
1228
}
1229
result = sx ^ sy == 1 ? -int256(rAbs) : int256(rAbs);
1230
}
1231
}
1232
 
1233
/// @notice Returns PI as a signed 59.18-decimal fixed-point number.
1234
function pi() internal pure returns (int256 result) {
1235
result = 3_141592653589793238;
1236
}
1237
 
1238
/// @notice Raises x to the power of y.
1239
///
1240
/// @dev Based on the insight that x^y = 2^(log2(x) * y).
1241
///
1242
/// Requirements:
1243
/// - All from "exp2", "log2" and "mul".
1244
/// - z cannot be zero.
1245
///
1246
/// Caveats:
1247
/// - All from "exp2", "log2" and "mul".
1248
/// - Assumes 0^0 is 1.
1249
///
1250
/// @param x Number to raise to given power y, as a signed 59.18-decimal fixed-point number.
1251
/// @param y Exponent to raise x to, as a signed 59.18-decimal fixed-point number.
1252
/// @return result x raised to power y, as a signed 59.18-decimal fixed-point number.
1253
function pow(int256 x, int256 y) internal pure returns (int256 result) {
1254
if (x == 0) {
1255
result = y == 0 ? SCALE : int256(0);
1256
} else {
1257
result = exp2(mul(log2(x), y));
1258
}
1259
}
1260
 
1261
/// @notice Raises x (signed 59.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the
1262
/// famous algorithm "exponentiation by squaring".
1263
///
1264
/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring
1265
///
1266
/// Requirements:
1267
/// - All from "abs" and "PRBMath.mulDivFixedPoint".
1268
/// - The result must fit within MAX_SD59x18.
1269
///
1270
/// Caveats:
1271
/// - All from "PRBMath.mulDivFixedPoint".
1272
/// - Assumes 0^0 is 1.
1273
///
1274
/// @param x The base as a signed 59.18-decimal fixed-point number.
1275
/// @param y The exponent as an uint256.
1276
/// @return result The result as a signed 59.18-decimal fixed-point number.
1277
function powu(int256 x, uint256 y) internal pure returns (int256 result) {
1278
uint256 xAbs = uint256(abs(x));
1279
 
1280
// Calculate the first iteration of the loop in advance.
1281
uint256 rAbs = y & 1 > 0 ? xAbs : uint256(SCALE);
1282
 
1283
// Equivalent to "for(y /= 2; y > 0; y /= 2)" but faster.
1284
uint256 yAux = y;
1285
for (yAux >>= 1; yAux > 0; yAux >>= 1) {
1286
xAbs = PRBMath.mulDivFixedPoint(xAbs, xAbs);
1287
 
1288
// Equivalent to "y % 2 == 1" but faster.
1289
if (yAux & 1 > 0) {
1290
rAbs = PRBMath.mulDivFixedPoint(rAbs, xAbs);
1291
}
1292
}
1293
 
1294
// The result must fit within the 59.18-decimal fixed-point representation.
1295
if (rAbs > uint256(MAX_SD59x18)) {
1296
revert PRBMathSD59x18__PowuOverflow(rAbs);
1297
}
1298
 
1299
// Is the base negative and the exponent an odd number?
1300
bool isNegative = x < 0 && y & 1 == 1;
1301
result = isNegative ? -int256(rAbs) : int256(rAbs);
1302
}
1303
 
1304
/// @notice Returns 1 as a signed 59.18-decimal fixed-point number.
1305
function scale() internal pure returns (int256 result) {
1306
result = SCALE;
1307
}
1308
 
1309
/// @notice Calculates the square root of x, rounding down.
1310
/// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
1311
///
1312
/// Requirements:
1313
/// - x cannot be negative.
1314
/// - x must be less than MAX_SD59x18 / SCALE.
1315
///
1316
/// @param x The signed 59.18-decimal fixed-point number for which to calculate the square root.
1317
/// @return result The result as a signed 59.18-decimal fixed-point .
1318
function sqrt(int256 x) internal pure returns (int256 result) {
1319
unchecked {
1320
if (x < 0) {
1321
revert PRBMathSD59x18__SqrtNegativeInput(x);
1322
}
1323
if (x > MAX_SD59x18 / SCALE) {
1324
revert PRBMathSD59x18__SqrtOverflow(x);
1325
}
1326
// Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two signed
1327
// 59.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).
1328
result = int256(PRBMath.sqrt(uint256(x * SCALE)));
1329
}
1330
}
1331
 
1332
/// @notice Converts a signed 59.18-decimal fixed-point number to basic integer form, rounding down in the process.
1333
/// @param x The signed 59.18-decimal fixed-point number to convert.
1334
/// @return result The same number in basic integer form.
1335
function toInt(int256 x) internal pure returns (int256 result) {
1336
unchecked {
1337
result = x / SCALE;
1338
}
1339
}
1340
}
1341
 
1342
 
1343
// File contracts/Context.sol
1344
 
1345
// Original license: SPDX_License_Identifier: MIT
1346
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
1347
 
1348
pragma solidity ^0.8.0;
1349
 
1350
/**
1351
* @dev Provides information about the current execution context, including the
1352
* sender of the transaction and its data. While these are generally available
1353
* via msg.sender and msg.data, they should not be accessed in such a direct
1354
* manner, since when dealing with meta-transactions the account sending and
1355
* paying for execution may not be the actual sender (as far as an application
1356
* is concerned).
1357
*
1358
* This contract is only required for intermediate, library-like contracts.
1359
*/
1360
abstract contract Context {
1361
function _msgSender() internal view virtual returns (address) {
1362
return msg.sender;
1363
}
1364
 
1365
function _msgData() internal view virtual returns (bytes calldata) {
1366
return msg.data;
1367
}
1368
 
1369
function _contextSuffixLength() internal view virtual returns (uint256) {
1370
return 0;
1371
}
1372
}
1373
 
1374
 
1375
// File contracts/Ownable.sol
1376
 
1377
// Original license: SPDX_License_Identifier: MIT
1378
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
1379
 
1380
pragma solidity ^0.8.0;
1381
 
1382
/**
1383
* @dev Contract module which provides a basic access control mechanism, where
1384
* there is an account (an owner) that can be granted exclusive access to
1385
* specific functions.
1386
*
1387
* By default, the owner account will be the one that deploys the contract. This
1388
* can later be changed with {transferOwnership}.
1389
*
1390
* This module is used through inheritance. It will make available the modifier
1391
* `onlyOwner`, which can be applied to your functions to restrict their use to
1392
* the owner.
1393
*/
1394
abstract contract Ownable is Context {
1395
address private _owner;
1396
 
1397
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
1398
 
1399
/**
1400
* @dev Initializes the contract setting the deployer as the initial owner.
1401
*/
1402
constructor() {
1403
_transferOwnership(_msgSender());
1404
}
1405
 
1406
/**
1407
* @dev Throws if called by any account other than the owner.
1408
*/
1409
modifier onlyOwner() {
1410
_checkOwner();
1411
_;
1412
}
1413
 
1414
/**
1415
* @dev Returns the address of the current owner.
1416
*/
1417
function owner() public view virtual returns (address) {
1418
return _owner;
1419
}
1420
 
1421
/**
1422
* @dev Throws if the sender is not the owner.
1423
*/
1424
function _checkOwner() internal view virtual {
1425
require(owner() == _msgSender(), "Ownable: caller is not the owner");
1426
}
1427
 
1428
/**
1429
* @dev Leaves the contract without owner. It will not be possible to call
1430
* `onlyOwner` functions. Can only be called by the current owner.
1431
*
1432
* NOTE: Renouncing ownership will leave the contract without an owner,
1433
* thereby disabling any functionality that is only available to the owner.
1434
*/
1435
function renounceOwnership() public virtual onlyOwner {
1436
_transferOwnership(address(0));
1437
}
1438
 
1439
/**
1440
* @dev Transfers ownership of the contract to a new account (`newOwner`).
1441
* Can only be called by the current owner.
1442
*/
1443
function transferOwnership(address newOwner) public virtual onlyOwner {
1444
require(newOwner != address(0), "Ownable: new owner is the zero address");
1445
_transferOwnership(newOwner);
1446
}
1447
 
1448
/**
1449
* @dev Transfers ownership of the contract to a new account (`newOwner`).
1450
* Internal function without access restriction.
1451
*/
1452
function _transferOwnership(address newOwner) internal virtual {
1453
address oldOwner = _owner;
1454
_owner = newOwner;
1455
emit OwnershipTransferred(oldOwner, newOwner);
1456
}
1457
}
1458
 
1459
 
1460
// File contracts/PhoneReputation.sol
1461
 
1462
// Original license: SPDX_License_Identifier: GPL-3.0
1463
pragma solidity 0.8.17;
1464
 
1465
 
1466
contract PhoneReputation is Ownable {
1467
using PRBMathSD59x18 for int;
1468
uint public scaling = 5e18;
1469
uint public k = 14;
1470
uint public c = 1e17; // 0.1 * 1e18
1471
uint public startBalance = 100;
1472
uint public verificationFee;
1473
 
1474
struct Vote {
1475
uint phone;
1476
int vote;
1477
uint userHistoryWeight;
1478
uint timestamp;
1479
}
1480
 
1481
struct Voter {
1482
uint posVotes;
1483
uint negVotes;
1484
uint balance;
1485
Vote[] votingHistory;
1486
}
1487
 
1488
enum RegisterStatus {
1489
None,
1490
PaidFee,
1491
Registered
1492
}
1493
 
1494
mapping(address => Voter) public voters;
1495
mapping(uint => mapping(address => Vote)) public voteFromUser;
1496
mapping(uint => address[]) public votersPerPhone;
1497
 
1498
mapping(uint => int[]) private reputationHistory;
1499
mapping(uint => uint[]) private tsReputationHistory;
1500
 
1501
mapping(address => RegisterStatus) public registerStatus;
1502
mapping(bytes32 => address) private registeredPhone;
1503
 
1504
event TopUpRequested(address indexed user, uint timestamp, uint value);
1505
event VoteSubmitted(
1506
address indexed voter,
1507
uint indexed phone,
1508
int vote,
1509
uint weight
1510
);
1511
event Registered(address indexed user, bytes32 indexed phoneHash);
1512
 
1513
constructor(uint _verificationFee) Ownable() {
1514
verificationFee = _verificationFee;
1515
}
1516
 
1517
function abs(int x) internal pure returns (uint) {
1518
return uint(x < 0 ? -x : x);
1519
}
1520
 
1521
function ratioToWeight(uint ratio) internal view returns (uint) {
1522
int exponent = int(k) * (int(c) - int(ratio));
1523
int e = exp(exponent);
1524
uint denom = uint(1e18 + e);
1525
return (1e18 * scaling) / denom;
1526
}
1527
 
1528
function exp(int x) internal pure returns (int) {
1529
return PRBMathSD59x18.exp(x);
1530
}
1531
 
1532
function requestTopUp() external payable {
1533
require(msg.value >= verificationFee, "Insufficient fee");
1534
require(
1535
registerStatus[msg.sender] == RegisterStatus.None,
1536
"Already requested"
1537
);
1538
 
1539
registerStatus[msg.sender] = RegisterStatus.PaidFee;
1540
emit TopUpRequested(msg.sender, block.timestamp, msg.value);
1541
}
1542
 
1543
function completeRegistration(
1544
address user,
1545
bytes32 phoneHash
1546
) external onlyOwner {
1547
require(registerStatus[user] == RegisterStatus.PaidFee, "Not eligible");
1548
require(
1549
registeredPhone[phoneHash] == address(0),
1550
"Phone already registered"
1551
);
1552
 
1553
registeredPhone[phoneHash] = user;
1554
registerStatus[user] = RegisterStatus.Registered;
1555
 
1556
voters[user].balance = startBalance;
1557
emit Registered(user, phoneHash);
1558
}
1559
 
1560
function voteForPhone(uint phone, int vote) external {
1561
require(
1562
registerStatus[msg.sender] == RegisterStatus.Registered,
1563
"Not registered"
1564
);
1565
require(vote != 0, "Zero vote");
1566
uint cost = abs(vote);
1567
 
1568
Voter storage v = voters[msg.sender];
1569
require(v.balance >= cost, "Not enough balance");
1570
 
1571
v.balance -= cost;
1572
if (vote > 0) {
1573
v.posVotes += 1;
1574
} else {
1575
v.negVotes += 1;
1576
}
1577
 
1578
uint historyWeight = getUserHistoryWeight(msg.sender);
1579
Vote memory newVote = Vote(phone, vote, historyWeight, block.timestamp);
1580
 
1581
if (voteFromUser[phone][msg.sender].timestamp == 0) {
1582
votersPerPhone[phone].push(msg.sender);
1583
} else {
1584
address[] storage votersList = votersPerPhone[phone];
1585
for (uint i = 0; i < votersList.length; i++) {
1586
if (votersList[i] == msg.sender) {
1587
votersList[i] = votersList[votersList.length - 1];
1588
votersList.pop();
1589
break;
1590
}
1591
}
1592
votersList.push(msg.sender);
1593
}
1594
 
1595
voteFromUser[phone][msg.sender] = newVote;
1596
 
1597
for (uint i = 0; i < v.votingHistory.length; i++) {
1598
if (v.votingHistory[i].phone == phone) {
1599
v.votingHistory[i] = v.votingHistory[
1600
v.votingHistory.length - 1
1601
];
1602
v.votingHistory.pop();
1603
break;
1604
}
1605
}
1606
v.votingHistory.push(newVote);
1607
 
1608
reputationHistory[phone].push(getReputation(phone));
1609
tsReputationHistory[phone].push(newVote.timestamp);
1610
 
1611
emit VoteSubmitted(msg.sender, phone, vote, historyWeight);
1612
}
1613
 
1614
function getUserHistoryWeight(address user) public view returns (uint) {
1615
Voter storage v = voters[user];
1616
if (v.posVotes == 0 && v.negVotes == 0) return 3e18;
1617
 
1618
uint minVotes = v.posVotes < v.negVotes ? v.posVotes : v.negVotes;
1619
uint maxVotes = v.posVotes > v.negVotes ? v.posVotes : v.negVotes;
1620
 
1621
uint ratio = (1e18 * minVotes) / maxVotes;
1622
return ratioToWeight(ratio);
1623
}
1624
 
1625
function getReputation(uint phone) public view returns (int) {
1626
address[] memory addresses = votersPerPhone[phone];
1627
uint len = addresses.length;
1628
if (len == 0) return 0;
1629
 
1630
int total = 0;
1631
 
1632
for (uint i = 0; i < len; i++) {
1633
Vote memory v = voteFromUser[phone][addresses[i]];
1634
uint idxRatio = (1e18 * (i + 1)) / len;
1635
uint timeWeight = ratioToWeight(idxRatio);
1636
uint sumWeight = v.userHistoryWeight + timeWeight;
1637
 
1638
int weightedVote = (v.vote * int(sumWeight)) / int(1e18);
1639
total += weightedVote;
1640
}
1641
 
1642
return total / int(len);
1643
}
1644
 
1645
function getReputationTimeline(
1646
uint phone
1647
)
1648
external
1649
view
1650
returns (int[] memory reputations, uint[] memory timestamps)
1651
{
1652
reputations = reputationHistory[phone];
1653
timestamps = tsReputationHistory[phone];
1654
}
1655
 
1656
function getVotesForPhone(
1657
uint phone
1658
) external view returns (Vote[] memory) {
1659
address[] memory addresses = votersPerPhone[phone];
1660
Vote[] memory result = new Vote[](addresses.length);
1661
for (uint i = 0; i < addresses.length; i++) {
1662
result[i] = voteFromUser[phone][addresses[i]];
1663
}
1664
return result;
1665
}
1666
 
1667
function getMyVotingHistory() external view returns (Vote[] memory) {
1668
return voters[msg.sender].votingHistory;
1669
}
1670
 
1671
function getRegisteredPhone(
1672
bytes32 phoneHash
1673
) external view returns (address) {
1674
return registeredPhone[phoneHash];
1675
}
1676
 
1677
function getRegisterStatus(
1678
address user
1679
) external view returns (RegisterStatus) {
1680
return registerStatus[user];
1681
}
1682
 
1683
function setVerificationFee(uint newFee) external onlyOwner {
1684
verificationFee = newFee;
1685
}
1686
 
1687
function setStartBalance(uint newBalance) external onlyOwner {
1688
startBalance = newBalance;
1689
}
1690
 
1691
function withdrawFees(address payable to) external onlyOwner {
1692
to.transfer(address(this).balance);
1693
}
1694
}
1695
 
Contract ABI
[
{
"type": "constructor",
"inputs": [
{
"name": "_verificationFee",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "PRBMathSD59x18__Exp2InputTooBig",
"type": "error",
"inputs": [
{
"name": "x",
"type": "int256",
"internalType": "int256"
}
]
},
{
"name": "PRBMathSD59x18__ExpInputTooBig",
"type": "error",
"inputs": [
{
"name": "x",
"type": "int256",
"internalType": "int256"
}
]
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Registered",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "phoneHash",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "TopUpRequested",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "timestamp",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "VoteSubmitted",
"type": "event",
"inputs": [
{
"name": "voter",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "phone",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "vote",
"type": "int256",
"indexed": false,
"internalType": "int256"
},
{
"name": "weight",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "c",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "completeRegistration",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
},
{
"name": "phoneHash",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "getMyVotingHistory",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "tuple[]",
"components": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "vote",
"type": "int256",
"internalType": "int256"
},
{
"name": "userHistoryWeight",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "timestamp",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct PhoneReputation.Vote[]"
}
],
"stateMutability": "view"
},
{
"name": "getRegisterStatus",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "enum PhoneReputation.RegisterStatus"
}
],
"stateMutability": "view"
},
{
"name": "getRegisteredPhone",
"type": "function",
"inputs": [
{
"name": "phoneHash",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "getReputation",
"type": "function",
"inputs": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "int256",
"internalType": "int256"
}
],
"stateMutability": "view"
},
{
"name": "getReputationTimeline",
"type": "function",
"inputs": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "reputations",
"type": "int256[]",
"internalType": "int256[]"
},
{
"name": "timestamps",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "view"
},
{
"name": "getUserHistoryWeight",
"type": "function",
"inputs": [
{
"name": "user",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getVotesForPhone",
"type": "function",
"inputs": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "tuple[]",
"components": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "vote",
"type": "int256",
"internalType": "int256"
},
{
"name": "userHistoryWeight",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "timestamp",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct PhoneReputation.Vote[]"
}
],
"stateMutability": "view"
},
{
"name": "k",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "registerStatus",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "enum PhoneReputation.RegisterStatus"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "requestTopUp",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "scaling",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "setStartBalance",
"type": "function",
"inputs": [
{
"name": "newBalance",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setVerificationFee",
"type": "function",
"inputs": [
{
"name": "newFee",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "startBalance",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "verificationFee",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "voteForPhone",
"type": "function",
"inputs": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "vote",
"type": "int256",
"internalType": "int256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "voteFromUser",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "phone",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "vote",
"type": "int256",
"internalType": "int256"
},
{
"name": "userHistoryWeight",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "timestamp",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "voters",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "posVotes",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "negVotes",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "balance",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "votersPerPhone",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "withdrawFees",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address payable"
}
],
"outputs": [],
"stateMutability": "nonpayable"
}
]
Contract Creation Code
0x6080604052674563918244f40000600155600e60025567016345785d8a000060035560646004553480156200003357600080fd5b506040516200398438038062003984833981810160405281019062000059919062000193565b620000796200006d6200008760201b60201c565b6200008f60201b60201c565b8060058190555050620001c5565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b6000819050919050565b6200016d8162000158565b81146200017957600080fd5b50565b6000815190506200018d8162000162565b92915050565b600060208284031215620001ac57620001ab62000153565b5b6000620001bc848285016200017c565b91505092915050565b6137af80620001d56000396000f3fe6080604052600436106101565760003560e01c80638da5cb5b116100c1578063b4aee76c1161007a578063b4aee76c146104ed578063b4f40c611461052a578063c3da42b814610555578063c8fc36cb14610580578063cbfa3c9c146105a9578063f2fde38b146105d4578063fc7ebe4a146105fd57610156565b80638da5cb5b146103c75780638dcf6846146103f257806396cd6a3a1461042f578063a3ec138d1461045a578063a8c278a214610499578063aae9d5f2146104c457610156565b80635364e45d116101135780635364e45d146102a45780635ef31e5b146102cd578063715018a61461030a57806387bcac0214610321578063880e97ee1461034a57806389370d8b1461038a57610156565b806307d1e1f91461015b578063164e68de1461019957806317a1e3ee146101c25780632bb9ffef146101ff578063426e236d1461022a5780634fa47a5b14610267575b600080fd5b34801561016757600080fd5b50610182600480360381019061017d9190612844565b610607565b6040516101909291906129f7565b60405180910390f35b3480156101a557600080fd5b506101c060048036038101906101bb9190612a8c565b6106d7565b005b3480156101ce57600080fd5b506101e960048036038101906101e49190612af7565b610729565b6040516101f69190612b9b565b60405180910390f35b34801561020b57600080fd5b50610214610749565b6040516102219190612bc5565b60405180910390f35b34801561023657600080fd5b50610251600480360381019061024c9190612af7565b61074f565b60405161025e9190612b9b565b60405180910390f35b34801561027357600080fd5b5061028e60048036038101906102899190612c16565b6107a5565b60405161029b9190612c52565b60405180910390f35b3480156102b057600080fd5b506102cb60048036038101906102c69190612844565b6107e2565b005b3480156102d957600080fd5b506102f460048036038101906102ef9190612af7565b6107f4565b6040516103019190612bc5565b60405180910390f35b34801561031657600080fd5b5061031f6108e4565b005b34801561032d57600080fd5b5061034860048036038101906103439190612c6d565b6108f8565b005b34801561035657600080fd5b50610371600480360381019061036c9190612cad565b610ba0565b6040516103819493929190612cfc565b60405180910390f35b34801561039657600080fd5b506103b160048036038101906103ac9190612844565b610bdd565b6040516103be9190612d41565b60405180910390f35b3480156103d357600080fd5b506103dc610df5565b6040516103e99190612c52565b60405180910390f35b3480156103fe57600080fd5b5061041960048036038101906104149190612844565b610e1e565b6040516104269190612e60565b60405180910390f35b34801561043b57600080fd5b50610444610ffa565b6040516104519190612e60565b60405180910390f35b34801561046657600080fd5b50610481600480360381019061047c9190612af7565b6110c1565b60405161049093929190612e82565b60405180910390f35b3480156104a557600080fd5b506104ae6110eb565b6040516104bb9190612bc5565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e69190612844565b6110f1565b005b3480156104f957600080fd5b50610514600480360381019061050f9190612eb9565b611103565b6040516105219190612c52565b60405180910390f35b34801561053657600080fd5b5061053f611151565b60405161054c9190612bc5565b60405180910390f35b34801561056157600080fd5b5061056a611157565b6040516105779190612bc5565b60405180910390f35b34801561058c57600080fd5b506105a760048036038101906105a29190612f25565b61115d565b005b3480156105b557600080fd5b506105be61192c565b6040516105cb9190612bc5565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f69190612af7565b611932565b005b6106056119b5565b005b6060806009600084815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561066757602002820191906000526020600020905b815481526020019060010190808311610653575b50505050509150600a60008481526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156106cb57602002820191906000526020600020905b8154815260200190600101908083116106b7575b50505050509050915091565b6106df611b67565b8073ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610725573d6000803e3d6000fd5b5050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60045481565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600c600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6107ea611b67565b8060048190555050565b600080600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154148015610850575060008160010154145b15610866576729a2241af62c00009150506108df565b60008160010154826000015410610881578160010154610887565b81600001545b9050600082600101548360000154116108a45782600101546108aa565b82600001545b905060008183670de0b6b3a76400006108c39190612f94565b6108cd9190613005565b90506108d881611be5565b9450505050505b919050565b6108ec611b67565b6108f66000611c55565b565b610900611b67565b6001600281111561091457610913612b24565b5b600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16600281111561097357610972612b24565b5b146109b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109aa90613093565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600c600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4c906130ff565b60405180910390fd5b81600c600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506002600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690836002811115610b0a57610b09612b24565b5b0217905550600454600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550808273ffffffffffffffffffffffffffffffffffffffff167fb8142d42f05d95abf0a6570799774d59276e49ea32a04d9a4ec316ea4a6886bc60405160405180910390a35050565b6007602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154908060030154905084565b60008060086000848152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610c7357602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c29575b5050505050905060008151905060008103610c9357600092505050610df0565b6000805b82811015610ddd576000600760008881526020019081526020016000206000868481518110610cc957610cc861311f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600084600184610d50919061314e565b670de0b6b3a7640000610d639190612f94565b610d6d9190613005565b90506000610d7a82611be5565b90506000818460400151610d8e919061314e565b90506000670de0b6b3a7640000828660200151610dab9190613182565b610db591906131fa565b90508087610dc39190613264565b965050505050508080610dd5906132a8565b915050610c97565b508181610dea91906131fa565b93505050505b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600060086000848152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610eb557602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610e6b575b505050505090506000815167ffffffffffffffff811115610ed957610ed86132f0565b5b604051908082528060200260200182016040528015610f1257816020015b610eff6127e1565b815260200190600190039081610ef75790505b50905060005b8251811015610fef57600760008681526020019081526020016000206000848381518110610f4957610f4861311f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050828281518110610fd157610fd061311f565b5b60200260200101819052508080610fe7906132a8565b915050610f18565b508092505050919050565b6060600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301805480602002602001604051908101604052809291908181526020016000905b828210156110b857838290600052602060002090600402016040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250508152602001906001019061105e565b50505050905090565b60066020528060005260406000206000915090508060000154908060010154908060020154905083565b60055481565b6110f9611b67565b8060058190555050565b6008602052816000526040600020818154811061111f57600080fd5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b60035481565b6002808111156111705761116f612b24565b5b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660028111156111cf576111ce612b24565b5b1461120f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112069061336b565b60405180910390fd5b60008103611252576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611249906133d7565b60405180910390fd5b600061125d82611d19565b90506000600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905081816002015410156112e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e090613443565b60405180910390fd5b818160020160008282546112fd9190613463565b92505081905550600083131561132e576001816000016000828254611322919061314e565b9250508190555061134b565b6001816001016000828254611343919061314e565b925050819055505b6000611356336107f4565b90506000604051806080016040528087815260200186815260200183815260200142815250905060006007600088815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154036114515760086000878152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611653565b600060086000888152602001908152602001600020905060005b81805490508110156115ee573373ffffffffffffffffffffffffffffffffffffffff168282815481106114a1576114a061311f565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036115db5781600183805490506114f99190613463565b8154811061150a5761150961311f565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168282815481106115485761154761311f565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818054806115a1576115a0613497565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590556115ee565b80806115e6906132a8565b91505061146b565b5080339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b806007600088815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015590505060005b83600301805490508110156117fa57868460030182815481106116f8576116f761311f565b5b906000526020600020906004020160000154036117e75783600301600185600301805490506117279190613463565b815481106117385761173761311f565b5b906000526020600020906004020184600301828154811061175c5761175b61311f565b5b906000526020600020906004020160008201548160000155600182015481600101556002820154816002015560038201548160030155905050836003018054806117a9576117a8613497565b5b6001900381819060005260206000209060040201600080820160009055600182016000905560028201600090556003820160009055505090556117fa565b80806117f2906132a8565b9150506116d2565b50826003018190806001815401808255809150506001900390600052602060002090600402016000909190919091506000820151816000015560208201518160010155604082015181600201556060820151816003015550506009600087815260200190815260200160002061186f87610bdd565b9080600181540180825580915050600190039060005260206000200160009091909190915055600a600087815260200190815260200160002081606001519080600181540180825580915050600190039060005260206000200160009091909190915055853373ffffffffffffffffffffffffffffffffffffffff167f05a3f150a5227b4510ce75ff89b8a3d02b2150735f0d585dc565176310efec09878560405161191c9291906134c6565b60405180910390a3505050505050565b60015481565b61193a611b67565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a090613561565b60405180910390fd5b6119b281611c55565b50565b6005543410156119fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f1906135cd565b60405180910390fd5b60006002811115611a0e57611a0d612b24565b5b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166002811115611a6d57611a6c612b24565b5b14611aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa490613639565b60405180910390fd5b6001600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690836002811115611b1057611b0f612b24565b5b02179055503373ffffffffffffffffffffffffffffffffffffffff167f3d69eb4237df8f8b3da669f2b2c52c6a39f43412b8adebd9d152c9869cf2c86d4234604051611b5d929190613659565b60405180910390a2565b611b6f611d3a565b73ffffffffffffffffffffffffffffffffffffffff16611b8d610df5565b73ffffffffffffffffffffffffffffffffffffffff1614611be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bda906136ce565b60405180910390fd5b565b60008082600354611bf691906136ee565b600254611c039190613182565b90506000611c1082611d42565b9050600081670de0b6b3a7640000611c289190613264565b905080600154670de0b6b3a7640000611c419190612f94565b611c4b9190613005565b9350505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808212611d285781611d33565b81611d3290613731565b5b9050919050565b600033905090565b6000611d4d82611d54565b9050919050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462ce821215611d875760009050611e12565b680736ea4425c11ac6318212611dd457816040517f99bb7541000000000000000000000000000000000000000000000000000000008152600401611dcb9190612d41565b60405180910390fd5b60006714057b7ef767814f83029050611e0e670de0b6b3a76400006706f05b59d3b20000830181611e0857611e07612fd6565b5b05611e17565b9150505b919050565b600080821215611e84577ffffffffffffffffffffffffffffffffffffffffffffffffcc22e87f6eb468eeb821215611e525760009050611f00565b611e5e82600003611e17565b6ec097ce7bc90715b34b9f100000000081611e7c57611e7b612fd6565b5b059050611eff565b680a688906bd8b0000008212611ed157816040517fe69458f9000000000000000000000000000000000000000000000000000000008152600401611ec89190612d41565b60405180910390fd5b6000670de0b6b3a7640000604084901b81611eef57611eee612fd6565b5b049050611efb81611f05565b9150505b5b919050565b6000778000000000000000000000000000000000000000000000009050600067800000000000000083161115611f4857604068016a09e667f3bcc9098202901c90505b600067400000000000000083161115611f6e5760406801306fe0a31b7152df8202901c90505b600067200000000000000083161115611f945760406801172b83c7d517adce8202901c90505b600067100000000000000083161115611fba57604068010b5586cf9890f62a8202901c90505b600067080000000000000083161115611fe05760406801059b0d31585743ae8202901c90505b600067040000000000000083161115612006576040680102c9a3e778060ee78202901c90505b60006702000000000000008316111561202c57604068010163da9fb33356d88202901c90505b600067010000000000000083161115612052576040680100b1afa5abcbed618202901c90505b600066800000000000008316111561207757604068010058c86da1c09ea28202901c90505b600066400000000000008316111561209c5760406801002c605e2e8cec508202901c90505b60006620000000000000831611156120c1576040680100162f3904051fa18202901c90505b60006610000000000000831611156120e65760406801000b175effdc76ba8202901c90505b600066080000000000008316111561210b576040680100058ba01fb9f96d8202901c90505b600066040000000000008316111561213057604068010002c5cc37da94928202901c90505b60006602000000000000831611156121555760406801000162e525ee05478202901c90505b600066010000000000008316111561217a57604068010000b17255775c048202901c90505b6000658000000000008316111561219e5760406801000058b91b5bc9ae8202901c90505b600065400000000000831611156121c2576040680100002c5c89d5ec6d8202901c90505b600065200000000000831611156121e657604068010000162e43f4f8318202901c90505b6000651000000000008316111561220a576040680100000b1721bcfc9a8202901c90505b6000650800000000008316111561222e57604068010000058b90cf1e6e8202901c90505b600065040000000000831611156122525760406801000002c5c863b73f8202901c90505b60006502000000000083161115612276576040680100000162e430e5a28202901c90505b6000650100000000008316111561229a5760406801000000b1721835518202901c90505b6000648000000000831611156122bd576040680100000058b90c0b498202901c90505b6000644000000000831611156122e057604068010000002c5c8601cc8202901c90505b6000642000000000831611156123035760406801000000162e42fff08202901c90505b60006410000000008316111561232657604068010000000b17217fbb8202901c90505b6000640800000000831611156123495760406801000000058b90bfce8202901c90505b60006404000000008316111561236c576040680100000002c5c85fe38202901c90505b60006402000000008316111561238f57604068010000000162e42ff18202901c90505b6000640100000000831611156123b2576040680100000000b17217f88202901c90505b60006380000000831611156123d457604068010000000058b90bfc8202901c90505b60006340000000831611156123f65760406801000000002c5c85fe8202901c90505b6000632000000083161115612418576040680100000000162e42ff8202901c90505b600063100000008316111561243a5760406801000000000b17217f8202901c90505b600063080000008316111561245c576040680100000000058b90c08202901c90505b600063040000008316111561247e57604068010000000002c5c8608202901c90505b60006302000000831611156124a05760406801000000000162e4308202901c90505b60006301000000831611156124c257604068010000000000b172188202901c90505b600062800000831611156124e35760406801000000000058b90c8202901c90505b60006240000083161115612504576040680100000000002c5c868202901c90505b6000622000008316111561252557604068010000000000162e438202901c90505b60006210000083161115612546576040680100000000000b17218202901c90505b6000620800008316111561256757604068010000000000058b918202901c90505b600062040000831611156125885760406801000000000002c5c88202901c90505b600062020000831611156125a9576040680100000000000162e48202901c90505b600062010000831611156125ca5760406801000000000000b1728202901c90505b6000618000831611156125ea576040680100000000000058b98202901c90505b60006140008316111561260a57604068010000000000002c5d8202901c90505b60006120008316111561262a5760406801000000000000162e8202901c90505b60006110008316111561264a57604068010000000000000b178202901c90505b60006108008316111561266a5760406801000000000000058c8202901c90505b60006104008316111561268a576040680100000000000002c68202901c90505b6000610200831611156126aa576040680100000000000001638202901c90505b6000610100831611156126ca576040680100000000000000b18202901c90505b60006080831611156126e9576040680100000000000000598202901c90505b60006040831611156127085760406801000000000000002c8202901c90505b6000602083161115612727576040680100000000000000168202901c90505b60006010831611156127465760406801000000000000000b8202901c90505b6000600883161115612765576040680100000000000000068202901c90505b6000600483161115612784576040680100000000000000038202901c90505b60006002831611156127a3576040680100000000000000018202901c90505b60006001831611156127c2576040680100000000000000018202901c90505b670de0b6b3a764000081029050604082901c60bf0381901c9050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600080fd5b6000819050919050565b6128218161280e565b811461282c57600080fd5b50565b60008135905061283e81612818565b92915050565b60006020828403121561285a57612859612809565b5b60006128688482850161282f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6128b08161289d565b82525050565b60006128c283836128a7565b60208301905092915050565b6000602082019050919050565b60006128e682612871565b6128f0818561287c565b93506128fb8361288d565b8060005b8381101561292c57815161291388826128b6565b975061291e836128ce565b9250506001810190506128ff565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61296e8161280e565b82525050565b60006129808383612965565b60208301905092915050565b6000602082019050919050565b60006129a482612939565b6129ae8185612944565b93506129b983612955565b8060005b838110156129ea5781516129d18882612974565b97506129dc8361298c565b9250506001810190506129bd565b5085935050505092915050565b60006040820190508181036000830152612a1181856128db565b90508181036020830152612a258184612999565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a5982612a2e565b9050919050565b612a6981612a4e565b8114612a7457600080fd5b50565b600081359050612a8681612a60565b92915050565b600060208284031215612aa257612aa1612809565b5b6000612ab084828501612a77565b91505092915050565b6000612ac482612a2e565b9050919050565b612ad481612ab9565b8114612adf57600080fd5b50565b600081359050612af181612acb565b92915050565b600060208284031215612b0d57612b0c612809565b5b6000612b1b84828501612ae2565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612b6457612b63612b24565b5b50565b6000819050612b7582612b53565b919050565b6000612b8582612b67565b9050919050565b612b9581612b7a565b82525050565b6000602082019050612bb06000830184612b8c565b92915050565b612bbf8161280e565b82525050565b6000602082019050612bda6000830184612bb6565b92915050565b6000819050919050565b612bf381612be0565b8114612bfe57600080fd5b50565b600081359050612c1081612bea565b92915050565b600060208284031215612c2c57612c2b612809565b5b6000612c3a84828501612c01565b91505092915050565b612c4c81612ab9565b82525050565b6000602082019050612c676000830184612c43565b92915050565b60008060408385031215612c8457612c83612809565b5b6000612c9285828601612ae2565b9250506020612ca385828601612c01565b9150509250929050565b60008060408385031215612cc457612cc3612809565b5b6000612cd28582860161282f565b9250506020612ce385828601612ae2565b9150509250929050565b612cf68161289d565b82525050565b6000608082019050612d116000830187612bb6565b612d1e6020830186612ced565b612d2b6040830185612bb6565b612d386060830184612bb6565b95945050505050565b6000602082019050612d566000830184612ced565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b608082016000820151612d9e6000850182612965565b506020820151612db160208501826128a7565b506040820151612dc46040850182612965565b506060820151612dd76060850182612965565b50505050565b6000612de98383612d88565b60808301905092915050565b6000602082019050919050565b6000612e0d82612d5c565b612e178185612d67565b9350612e2283612d78565b8060005b83811015612e53578151612e3a8882612ddd565b9750612e4583612df5565b925050600181019050612e26565b5085935050505092915050565b60006020820190508181036000830152612e7a8184612e02565b905092915050565b6000606082019050612e976000830186612bb6565b612ea46020830185612bb6565b612eb16040830184612bb6565b949350505050565b60008060408385031215612ed057612ecf612809565b5b6000612ede8582860161282f565b9250506020612eef8582860161282f565b9150509250929050565b612f028161289d565b8114612f0d57600080fd5b50565b600081359050612f1f81612ef9565b92915050565b60008060408385031215612f3c57612f3b612809565b5b6000612f4a8582860161282f565b9250506020612f5b85828601612f10565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612f9f8261280e565b9150612faa8361280e565b9250828202612fb88161280e565b91508282048414831517612fcf57612fce612f65565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006130108261280e565b915061301b8361280e565b92508261302b5761302a612fd6565b5b828204905092915050565b600082825260208201905092915050565b7f4e6f7420656c696769626c650000000000000000000000000000000000000000600082015250565b600061307d600c83613036565b915061308882613047565b602082019050919050565b600060208201905081810360008301526130ac81613070565b9050919050565b7f50686f6e6520616c726561647920726567697374657265640000000000000000600082015250565b60006130e9601883613036565b91506130f4826130b3565b602082019050919050565b60006020820190508181036000830152613118816130dc565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006131598261280e565b91506131648361280e565b925082820190508082111561317c5761317b612f65565b5b92915050565b600061318d8261289d565b91506131988361289d565b92508282026131a68161289d565b91507f800000000000000000000000000000000000000000000000000000000000000084146000841216156131de576131dd612f65565b5b82820584148315176131f3576131f2612f65565b5b5092915050565b60006132058261289d565b91506132108361289d565b9250826132205761321f612fd6565b5b600160000383147f80000000000000000000000000000000000000000000000000000000000000008314161561325957613258612f65565b5b828205905092915050565b600061326f8261289d565b915061327a8361289d565b9250828201905082811215600083121683821260008412151617156132a2576132a1612f65565b5b92915050565b60006132b38261280e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036132e5576132e4612f65565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e6f742072656769737465726564000000000000000000000000000000000000600082015250565b6000613355600e83613036565b91506133608261331f565b602082019050919050565b6000602082019050818103600083015261338481613348565b9050919050565b7f5a65726f20766f74650000000000000000000000000000000000000000000000600082015250565b60006133c1600983613036565b91506133cc8261338b565b602082019050919050565b600060208201905081810360008301526133f0816133b4565b9050919050565b7f4e6f7420656e6f7567682062616c616e63650000000000000000000000000000600082015250565b600061342d601283613036565b9150613438826133f7565b602082019050919050565b6000602082019050818103600083015261345c81613420565b9050919050565b600061346e8261280e565b91506134798361280e565b925082820390508181111561349157613490612f65565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506134db6000830185612ced565b6134e86020830184612bb6565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061354b602683613036565b9150613556826134ef565b604082019050919050565b6000602082019050818103600083015261357a8161353e565b9050919050565b7f496e73756666696369656e742066656500000000000000000000000000000000600082015250565b60006135b7601083613036565b91506135c282613581565b602082019050919050565b600060208201905081810360008301526135e6816135aa565b9050919050565b7f416c726561647920726571756573746564000000000000000000000000000000600082015250565b6000613623601183613036565b915061362e826135ed565b602082019050919050565b6000602082019050818103600083015261365281613616565b9050919050565b600060408201905061366e6000830185612bb6565b61367b6020830184612bb6565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006136b8602083613036565b91506136c382613682565b602082019050919050565b600060208201905081810360008301526136e7816136ab565b9050919050565b60006136f98261289d565b91506137048361289d565b925082820390508181126000841216828213600085121516171561372b5761372a612f65565b5b92915050565b600061373c8261289d565b91507f8000000000000000000000000000000000000000000000000000000000000000820361376e5761376d612f65565b5b81600003905091905056fea2646970667358221220863190178cd4c7e0c4de49081f0e807e940482a29cd9bf64c7dc37a54e194f9864736f6c634300081100330000000000000000000000000000000000000000000000000de0b6b3a7640000
©2022-now by Graphite