-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflattened_source.txt
More file actions
566 lines (475 loc) · 19.4 KB
/
flattened_source.txt
File metadata and controls
566 lines (475 loc) · 19.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File contracts/interfaces/ITypeface.sol
/**
@title ITypeface
@author peri
@notice Interface for Typeface contract
*/
pragma solidity ^0.8.8;
struct Font {
uint256 weight;
string style;
}
interface ITypeface {
/// @notice Emitted when the source is set for a font.
/// @param font The font the source has been set for.
event SetSource(Font font);
/// @notice Emitted when the source hash is set for a font.
/// @param font The font the source hash has been set for.
/// @param sourceHash The source hash that was set.
event SetSourceHash(Font font, bytes32 sourceHash);
/// @notice Emitted when the donation address is set.
/// @param donationAddress New donation address.
event SetDonationAddress(address donationAddress);
/// @notice Returns the typeface name.
function name() external view returns (string memory);
/// @notice Check if typeface includes a glyph for a specific character code point.
/// @dev 3 bytes supports all possible unicodes.
/// @param codePoint Character code point.
/// @return true True if supported.
function supportsCodePoint(bytes3 codePoint) external view returns (bool);
/// @notice Return source data of Font.
/// @param font Font to return source data for.
/// @return source Source data of font.
function sourceOf(Font memory font) external view returns (bytes memory);
/// @notice Checks if source data has been stored for font.
/// @param font Font to check if source data exists for.
/// @return true True if source exists.
function hasSource(Font memory font) external view returns (bool);
/// @notice Stores source data for a font.
/// @param font Font to store source data for.
/// @param source Source data of font.
function setSource(Font memory font, bytes memory source) external;
/// @notice Sets a new donation address.
/// @param donationAddress New donation address.
function setDonationAddress(address donationAddress) external;
/// @notice Returns donation address
/// @return donationAddress Donation address.
function donationAddress() external view returns (address);
}
// File contracts/Typeface.sol
pragma solidity ^0.8.8;
/**
@title Typeface
@author peri
@notice The Typeface contract allows storing and retrieving a "source", such as a base64-encoded file, for all fonts in a typeface.
Sources may be large and require a high gas fee to store. To reduce gas costs while deploying a contract containing source data, or to avoid surpassing gas limits of the deploy transaction block, only a hash of each source is stored when the contract is deployed. This allows sources to be stored in later transactions, ensuring the hash of the source matches the hash already stored for that font.
Once the Typeface contract has been deployed, source hashes can't be added or modified.
Fonts are identified by the Font struct, which includes "style" and "weight" properties.
*/
abstract contract Typeface is ITypeface, ERC165 {
modifier onlyDonationAddress() {
if (msg.sender != _donationAddress) {
revert("Typeface: Not donation address");
}
_;
}
/// @notice Mapping of style => weight => font source data as bytes.
mapping(string => mapping(uint256 => bytes)) private _source;
/// @notice Mapping of style => weight => keccack256 hash of font source data as bytes.
mapping(string => mapping(uint256 => bytes32)) private _sourceHash;
/// @notice Mapping of style => weight => true if font source has been stored.
/// @dev This serves as a gas-efficient way to check if a font source has been stored without getting the entire source data.
mapping(string => mapping(uint256 => bool)) private _hasSource;
/// @notice Address to receive donations.
address _donationAddress;
/// @notice Typeface name
string private _name;
/// @notice Return typeface name.
/// @return name Name of typeface
function name() public view virtual override returns (string memory) {
return _name;
}
/// @notice Return source bytes for font.
/// @param font Font to check source of.
/// @return source Font source data as bytes.
function sourceOf(
Font memory font
) public view virtual returns (bytes memory) {
return _source[font.style][font.weight];
}
/// @notice Return true if font source exists.
/// @param font Font to check if source exists for.
/// @return true True if font source exists.
function hasSource(Font memory font) public view virtual returns (bool) {
return _hasSource[font.style][font.weight];
}
/// @notice Return hash of source bytes for font.
/// @param font Font to return source hash of.
/// @return sourceHash Hash of source for font.
function sourceHash(
Font memory font
) public view virtual returns (bytes32) {
return _sourceHash[font.style][font.weight];
}
/// @notice Returns the address to receive donations.
/// @return donationAddress The address to receive donations.
function donationAddress() external view returns (address) {
return _donationAddress;
}
/// @notice Allows the donation address to set a new donation address.
/// @param __donationAddress New donation address.
function setDonationAddress(
address __donationAddress
) external onlyDonationAddress {
_setDonationAddress(__donationAddress);
}
function _setDonationAddress(address __donationAddress) internal {
_donationAddress = payable(__donationAddress);
emit SetDonationAddress(__donationAddress);
}
/// @notice Sets source for Font.
/// @dev The keccack256 hash of the source must equal the sourceHash of the font.
/// @param font Font to set source for.
/// @param source Font source as bytes.
function setSource(Font calldata font, bytes calldata source) public {
require(!hasSource(font), "Typeface: Source already exists");
require(
keccak256(source) == sourceHash(font),
"Typeface: Invalid font"
);
_beforeSetSource(font, source);
_source[font.style][font.weight] = source;
_hasSource[font.style][font.weight] = true;
emit SetSource(font);
_afterSetSource(font, source);
}
/// @notice Sets hash of source data for each font in a list.
/// @dev Length of fonts and hashes arrays must be equal. Each hash from hashes array will be set for the font with matching index in the fonts array.
/// @param fonts Array of fonts to set hashes for.
/// @param hashes Array of hashes to set for fonts.
function _setSourceHashes(
Font[] memory fonts,
bytes32[] memory hashes
) internal {
require(
fonts.length == hashes.length,
"Typeface: Unequal number of fonts and hashes"
);
for (uint256 i; i < fonts.length; i++) {
_sourceHash[fonts[i].style][fonts[i].weight] = hashes[i];
emit SetSourceHash(fonts[i], hashes[i]);
}
}
constructor(string memory __name, address __donationAddress) {
_name = __name;
_setDonationAddress(__donationAddress);
}
/// @dev See {IERC165-supportsInterface}.
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC165) returns (bool) {
return
interfaceId == type(ITypeface).interfaceId ||
super.supportsInterface(interfaceId);
}
/// @notice Function called before setSource() is called.
function _beforeSetSource(
Font calldata font,
bytes calldata src
) internal virtual {}
/// @notice Function called after setSource() is called.
function _afterSetSource(
Font calldata font,
bytes calldata src
) internal virtual {}
}
// File contracts/interfaces/ITypefaceExpandable.sol
/**
@title ITypefaceExpandable
@author peri
@notice Interface for TypefaceExpandable contract
*/
pragma solidity ^0.8.8;
interface ITypefaceExpandable is ITypeface {
event SetOperator(address operator);
function operator() external view returns (address);
function setSourceHashes(Font[] memory fonts, bytes32[] memory hashes)
external;
function setOperator(address operator) external;
}
/**
@title TypefaceExpandable
@author peri
@notice TypefaceExpandable is an extension of the Typeface contract that allows an operator to add or modify font hashes after the contract has been deployed, as long as a source for the font hasn't been stored yet.
*/
abstract contract TypefaceExpandable is Typeface, ITypefaceExpandable {
/// @notice Require that the sender is the operator address.
modifier onlyOperator() {
if (msg.sender != _operator) revert("TypefaceExpandable: Not operator");
_;
}
/// @notice Require that all fonts have not been stored.
modifier onlyUnstoredFonts(Font[] calldata fonts) {
for (uint256 i; i < fonts.length; i++) {
Font memory font = fonts[i];
if (hasSource(font)) {
revert("TypefaceExpandable: Source already exists");
}
}
_;
}
/// Address with permission to add or modify font hashes, as long as no source has been stored for that font.
address internal _operator;
/// @notice Allows operator to set new font hashes.
/// @dev Equal number of fonts and hashes must be provided.
/// @param fonts Array of fonts to set hashes for.
/// @param hashes Array of hashes to set for fonts.
function setSourceHashes(Font[] calldata fonts, bytes32[] calldata hashes)
external
onlyOperator
onlyUnstoredFonts(fonts)
{
_setSourceHashes(fonts, hashes);
}
/// @notice Returns operator of contract. Operator has permission to add or modify font hashes, as long as no source has been stored for that font.
/// @return operator Operator address.
function operator() external view returns (address) {
return _operator;
}
/// @notice Allows operator to set new operator.
/// @param __operator New operator address.
function setOperator(address __operator) external onlyOperator {
_setOperator(__operator);
}
constructor(
string memory __name,
address donationAddress,
address __operator
) Typeface(__name, donationAddress) {
_setOperator(__operator);
}
/// @dev See {IERC165-supportsInterface}.
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(Typeface)
returns (bool)
{
return
interfaceId == type(ITypefaceExpandable).interfaceId ||
super.supportsInterface(interfaceId);
}
function _setOperator(address __operator) internal {
_operator = __operator;
emit SetOperator(__operator);
}
}
// File contracts/CapsulesTypeface.sol
// SPDX-License-Identifier: GPL-3.0
/**
@title Capsules Typeface
@author peri
@notice Capsules typeface stored on-chain using the TypefaceExpandable contract, allowing additional fonts to be added later.
*/
pragma solidity ^0.8.8;
contract CapsulesTypeface is TypefaceExpandable {
constructor(
address donationAddress,
address operator
) TypefaceExpandable("Capsules", donationAddress, operator) {}
/// @notice Returns true if a unicode codepoint is supported by the Capsules typeface.
/// @param cp Codepoint to check.
/// @return ture True if supported.
function supportsCodePoint(bytes3 cp) external pure returns (bool) {
// Optimize gas by first checking outer bounds of byte ranges
if (cp < 0x000020 || cp > 0x00ffe6) return false;
return ((cp >= 0x000020 && cp <= 0x00007e) ||
(cp >= 0x0000a0 && cp <= 0x0000a8) ||
(cp >= 0x0000ab && cp <= 0x0000ac) ||
(cp >= 0x0000af && cp <= 0x0000b1) ||
cp == 0x0000b4 ||
(cp >= 0x0000b6 && cp <= 0x0000b7) ||
(cp >= 0x0000ba && cp <= 0x0000bb) ||
(cp >= 0x0000bf && cp <= 0x0000c4) ||
(cp >= 0x0000c6 && cp <= 0x0000cf) ||
(cp >= 0x0000d1 && cp <= 0x0000d7) ||
(cp >= 0x0000d9 && cp <= 0x0000dc) ||
(cp >= 0x0000e0 && cp <= 0x0000e4) ||
(cp >= 0x0000e6 && cp <= 0x0000ef) ||
(cp >= 0x0000f1 && cp <= 0x0000fc) ||
(cp >= 0x0000ff && cp <= 0x000101) ||
(cp >= 0x000112 && cp <= 0x000113) ||
(cp >= 0x000128 && cp <= 0x00012b) ||
cp == 0x000131 ||
(cp >= 0x00014c && cp <= 0x00014d) ||
(cp >= 0x000168 && cp <= 0x00016b) ||
cp == 0x000178 ||
cp == 0x000192 ||
cp == 0x000262 ||
cp == 0x00026a ||
cp == 0x000274 ||
cp == 0x000280 ||
cp == 0x00028f ||
cp == 0x000299 ||
cp == 0x00029c ||
cp == 0x00029f ||
(cp >= 0x0002c2 && cp <= 0x0002c3) ||
cp == 0x0002c6 ||
cp == 0x0002dc ||
cp == 0x000394 ||
cp == 0x00039e ||
cp == 0x0003c0 ||
cp == 0x000e3f ||
(cp >= 0x001d00 && cp <= 0x001d01) ||
cp == 0x001d05 ||
cp == 0x001d07 ||
(cp >= 0x001d0a && cp <= 0x001d0b) ||
cp == 0x001d0d ||
cp == 0x001d18 ||
cp == 0x001d1b ||
(cp >= 0x002013 && cp <= 0x002015) ||
(cp >= 0x002017 && cp <= 0x00201a) ||
(cp >= 0x00201c && cp <= 0x00201e) ||
(cp >= 0x002020 && cp <= 0x002022) ||
cp == 0x002026 ||
cp == 0x002030 ||
(cp >= 0x002032 && cp <= 0x002033) ||
(cp >= 0x002039 && cp <= 0x00203a) ||
cp == 0x00203c ||
cp == 0x00203e ||
cp == 0x002044 ||
cp == 0x00204e ||
(cp >= 0x002058 && cp <= 0x00205b) ||
(cp >= 0x00205d && cp <= 0x00205e) ||
(cp >= 0x0020a3 && cp <= 0x0020a4) ||
(cp >= 0x0020a6 && cp <= 0x0020a9) ||
(cp >= 0x0020ac && cp <= 0x0020ad) ||
(cp >= 0x0020b2 && cp <= 0x0020b6) ||
cp == 0x0020b8 ||
cp == 0x0020ba ||
(cp >= 0x0020bc && cp <= 0x0020bd) ||
cp == 0x0020bf ||
cp == 0x00211e ||
cp == 0x002126 ||
(cp >= 0x002190 && cp <= 0x002199) ||
(cp >= 0x0021ba && cp <= 0x0021bb) ||
cp == 0x002206 ||
cp == 0x00220f ||
(cp >= 0x002211 && cp <= 0x002214) ||
cp == 0x00221a ||
cp == 0x00221e ||
cp == 0x00222b ||
cp == 0x002238 ||
cp == 0x002243 ||
cp == 0x002248 ||
(cp >= 0x002254 && cp <= 0x002255) ||
cp == 0x002260 ||
(cp >= 0x002264 && cp <= 0x002267) ||
(cp >= 0x00229e && cp <= 0x0022a1) ||
cp == 0x0022c8 ||
(cp >= 0x002302 && cp <= 0x002304) ||
cp == 0x002310 ||
cp == 0x00231b ||
cp == 0x0023cf ||
(cp >= 0x0023e9 && cp <= 0x0023ea) ||
(cp >= 0x0023ed && cp <= 0x0023ef) ||
(cp >= 0x0023f8 && cp <= 0x0023fa) ||
(cp >= 0x002506 && cp <= 0x002507) ||
cp == 0x00250c ||
(cp >= 0x00250f && cp <= 0x002510) ||
(cp >= 0x002513 && cp <= 0x002514) ||
(cp >= 0x002517 && cp <= 0x002518) ||
(cp >= 0x00251b && cp <= 0x00251c) ||
(cp >= 0x002523 && cp <= 0x002524) ||
(cp >= 0x00252b && cp <= 0x00252c) ||
(cp >= 0x002533 && cp <= 0x002534) ||
(cp >= 0x00253b && cp <= 0x00253c) ||
(cp >= 0x00254b && cp <= 0x00254f) ||
(cp >= 0x00256d && cp <= 0x00257b) ||
(cp >= 0x002580 && cp <= 0x002590) ||
(cp >= 0x002594 && cp <= 0x002595) ||
(cp >= 0x002599 && cp <= 0x0025a1) ||
(cp >= 0x0025b0 && cp <= 0x0025b2) ||
cp == 0x0025b6 ||
cp == 0x0025bc ||
cp == 0x0025c0 ||
cp == 0x0025ca ||
(cp >= 0x0025cf && cp <= 0x0025d3) ||
(cp >= 0x0025d6 && cp <= 0x0025d7) ||
(cp >= 0x0025e0 && cp <= 0x0025e5) ||
(cp >= 0x0025e7 && cp <= 0x0025eb) ||
(cp >= 0x0025f0 && cp <= 0x0025f3) ||
(cp >= 0x0025f8 && cp <= 0x0025fa) ||
(cp >= 0x0025ff && cp <= 0x002600) ||
cp == 0x002610 ||
cp == 0x002612 ||
(cp >= 0x002630 && cp <= 0x002637) ||
(cp >= 0x002639 && cp <= 0x00263a) ||
cp == 0x00263c ||
cp == 0x002665 ||
(cp >= 0x002680 && cp <= 0x002685) ||
(cp >= 0x00268a && cp <= 0x002691) ||
cp == 0x0026a1 ||
cp == 0x002713 ||
cp == 0x002795 ||
cp == 0x002797 ||
(cp >= 0x0029d1 && cp <= 0x0029d5) ||
cp == 0x0029fa ||
cp == 0x002a25 ||
(cp >= 0x002a2a && cp <= 0x002a2c) ||
(cp >= 0x002a71 && cp <= 0x002a72) ||
cp == 0x002a75 ||
(cp >= 0x002a99 && cp <= 0x002a9a) ||
(cp >= 0x002b05 && cp <= 0x002b0d) ||
(cp >= 0x002b16 && cp <= 0x002b19) ||
(cp >= 0x002b90 && cp <= 0x002b91) ||
cp == 0x002b95 ||
cp == 0x00a730 ||
cp == 0x00a7af ||
(cp >= 0x00e000 && cp <= 0x00e02c) ||
(cp >= 0x00e02e && cp <= 0x00e032) ||
cp == 0x00e069 ||
(cp >= 0x00e420 && cp <= 0x00e421) ||
cp == 0x00fe69 ||
cp == 0x00ff04 ||
(cp >= 0x00ffe0 && cp <= 0x00ffe1) ||
(cp >= 0x00ffe5 && cp <= 0x00ffe6));
}
}