forked from xklob/spearbot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsummarization-results.json
763 lines (763 loc) · 223 KB
/
summarization-results.json
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
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
{
"text": {},
"markdown": {
"spearbot-node/put_files_to_audit_here/solidity/markdown/readme.md": {
"filename": "spearbot-node/put_files_to_audit_here/solidity/markdown/readme.md",
"globalSummary": "The Caviar Private Pools contest offers a total prize pool of $47,000 USDC and runs from April 7, 2023, to April 13, 2023. The contest focuses on Caviar Private Pools, which are NFT AMMs controlled by a single owner and offer various customization options. The system consists of four main contracts: Factory, PrivatePool, EthRouter, and PrivatePoolMetadata. The contest requires participants to register on the C4 Discord and submit findings using the C4 form.",
"chunkedSummaries": {
"Caviar Pool Contest": {
"title": "Caviar Pool Contest",
"summary": "The Caviar Private Pools contest is a competitive event with a total prize pool of $47,000 USDC, aimed at identifying and addressing potential vulnerabilities in the Caviar Private Pools project. The contest is organized by Code4rena and runs from April 07, 2023, 20:00 UTC to April 13, 2023, 20:00 UTC.\n\nThe prize pool is distributed across various categories, including:\n- HM (Honorable Mention) awards: $25,500 USDC\n- QA (Quality Assurance) report awards: $3,000 USDC\n- Gas report awards: $1,500 USDC\n- Judge awards: $6,000 USDC\n- Lookout awards: $2,400 USDC\n- Scout awards: $500 USDC\n- Mitigation review contest: $8,100 USDC (opportunity for the top 5 certified wardens based on their placement in the contest)\n\nParticipants are required to join the C4 Discord server to register for the contest and submit their findings using the C4 form provided on the Code4rena website. The contest guidelines and details for wardens can be found in the official documentation on the Code4rena website.\n\nThe primary objective of the contest is to ensure the security and efficiency of the Caviar Private Pools project by identifying potential vulnerabilities and providing solutions to mitigate them. Participants are expected to have a strong understanding of smart contract security and blockchain technology to effectively contribute to the contest.",
"content": "# Caviar Private Pools contest details\n\n- Total Prize Pool: \\$47,000 USDC\n - HM awards: \\$25,500 USDC\n - QA report awards: \\$3,000 USDC\n - Gas report awards: \\$1,500 USDC\n - Judge awards: \\$6,000 USDC\n - Lookout awards: \\$2400 USDC\n - Scout awards: \\$500 USDC\n - Mitigation review contest: \\$8,100 USDC (_Opportunity goes to top 5 certified wardens based on placement in this contest._)\n- Join [C4 Discord](https://discord.gg/code4rena) to register\n- Submit findings [using the C4 form](https://code4rena.com/contests/2023-04-caviar-private-pools/submit)\n- [Read our guidelines for more details](https://docs.code4rena.com/roles/wardens)\n- Starts April 07, 2023 20:00 UTC\n- Ends April 13, 2023 20:00 UTC",
"tokens": {
"summary": 308,
"content": 228
}
},
"Caviar Private Pools": {
"title": "Caviar Private Pools",
"summary": "The content discusses Caviar Private Pools, which are non-fungible token (NFT) automated market makers (AMMs) controlled by a single owner. These private pools offer a high level of customization, including concentrated liquidity, custom fee rates, stolen NFT filtering, custom NFT weightings, royalty support, and flash loans. Liquidity providers can deposit NFTs and ETH into these pools to facilitate trading. \n\nAdditionally, the content mentions automated findings for a contest, which can be found at a provided link. These findings are considered publicly known issues and are not eligible for awards in the contest. For more information on Caviar Private Pools, the documentation is available at the provided link, and a demo can be accessed on the Goerli testnet at beta.goerli.caviar.sh.",
"content": "Automated Findings / Publicly Known Issues \n\nAutomated findings output for the contest can be found [here](https://gist.github.com/Picodes/f50f08a90e93acff6c069898839a7452) within an hour of contest opening.\n\n*Note for C4 wardens: Anything included in the automated findings output is considered a publicly known issue and is ineligible for awards.*\n\n\n# Caviar Private Pools\n\nA private pool is a an NFT AMM controlled by a single owner. Each private pool is highly customizable with concentrated liquidity, custom fee rates, stolen NFT filtering, custom NFT weightings, royalty support, and flash loans. Liquidity providers deposit NFTs and ETH into these pools to enable trading. Docs are available [here](https://docs.caviar.sh/technical-reference/custom-pools). And a demo is available on [beta.goerli.caviar.sh](https://beta.goerli.caviar.sh/).",
"tokens": {
"summary": 168,
"content": 205
}
},
"Caviar Forge Test": {
"title": "Caviar Forge Test",
"summary": "The given content provides a quickstart command and a set of getting started instructions for setting up and testing a project called \"2023-04-caviar\" from the GitHub repository \"https://github.com/code-423n4/2023-04-caviar.git\".\n\nThe quickstart command is a single line of code that performs the following actions:\n\n1. `rm -Rf 2023-04-caviar || true`: This command attempts to remove the \"2023-04-caviar\" directory and its contents recursively using the \"rm\" command with the \"-Rf\" option. If the directory does not exist, the command will return \"true\" to avoid any errors.\n2. `git clone https://github.com/code-423n4/2023-04-caviar.git --recurse-submodules -j8`: This command clones the \"2023-04-caviar\" repository from GitHub, including its submodules, using the \"--recurse-submodules\" option. The \"-j8\" option allows for parallel cloning of submodules, speeding up the process.\n3. `cd 2023-04-caviar`: This command changes the current working directory to the newly cloned \"2023-04-caviar\" directory.\n4. `yarn`: This command installs the project's dependencies using the Yarn package manager.\n5. `foundryup`: This command is not a standard command and may be a custom script or alias specific to the project or the user's environment.\n6. `forge install`: This command installs the Forge framework, which is likely used for testing and development in the project.\n7. `forge test --ffi --gas-report`: This command runs the project's tests using the Forge framework with the \"--ffi\" and \"--gas-report\" options. The \"--ffi\" option enables Foreign Function Interface testing, and the \"--gas-report\" option generates a gas usage report for the tests.\n\nThe getting started instructions provide a simplified version of the quickstart command, broken down into three separate commands:\n\n1. `yarn`: This command installs the project's dependencies using the Yarn package manager.\n2. `forge install`: This command installs the Forge framework, which is likely used for testing and development in the project.\n3. `forge test --gas-report --ffi`: This command runs the project's tests using the Forge framework with the \"--ffi\" and \"--gas-report\" options, as described above.",
"content": "Quickstart command\n\n```\nrm -Rf 2023-04-caviar || true && git clone https://github.com/code-423n4/2023-04-caviar.git --recurse-submodules -j8 && cd 2023-04-caviar && yarn && foundryup && forge install && forge test --ffi --gas-report\n```\n\n## Getting started\n\n```\nyarn\nforge install\nforge test --gas-report --ffi\n```",
"tokens": {
"summary": 503,
"content": 100
}
},
"Factory PrivatePool NFTs": {
"title": "Factory PrivatePool NFTs",
"summary": "The Factory contract is a part of the Caviar protocol, which enables users to create and initialize new custom pools. These pools are minimal proxies that point to a reference implementation. The Factory contract is responsible for issuing Non-Fungible Tokens (NFTs) representing ownership of each custom pool. Protocol fees are accrued to the Factory contract and can be withdrawn by the protocol admin. Although the initial protocol fee rate is set at 0%, it may be increased in the future with advanced notice.\n\nThe PrivatePool contract contains the core logic for custom pools, allowing users to set various parameters such as concentrated liquidity, custom fee rates, NFT weightings, change/flashloan fee rates, royalty fee support, and stolen NFT filtering. Traders can interact with the pool by buying, selling, and exchanging NFTs within the pool.",
"content": "System overview\n\n- The [Factory](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol) contract allows users to create and initialize new custom pools that are minimal proxies which point to a reference implementation. It is responsible for issuing NFTs that represent ownership of each custom pool. All protocol fees accrue to the factory contract and can be withdrawn by the protocol admin. Initially the protocol fee rate will be set to be 0% however it may be increased in the future, with advanced notice.\n\n- The [PrivatePool](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol) contract contains all of the core logic for custom pools. It allows users to set concentrated liquidity, custom fee rates, NFT weightings, change/flashloan fee rates, royalty fee support, and stolen NFT filtering. Traders can buy, sell, and change NFTs for other NFTs within the pool.",
"tokens": {
"summary": 170,
"content": 209
}
},
"EthRouter PrivatePoolMetadata NFT": {
"title": "EthRouter PrivatePoolMetadata NFT",
"summary": "The EthRouter contract is designed to handle and execute a sequence of actions across multiple pools. This functionality is particularly useful when a user wants to purchase a specific number of NFTs that are distributed across different pools. The contract enables users to submit an array of buy orders, which are then executed in a single transaction, streamlining the process and improving efficiency. The EthRouter contract also interfaces with caviar public pools, which can be found in the linked repository.\n\nThe PrivatePoolMetadata contract is responsible for generating on-chain SVG and metadata representations of NFTs that signify ownership of a custom pool. This feature allows for seamless display and integration of the NFT across various marketplaces and wallets, ensuring consistent and accurate representation of the NFT's ownership and associated pool information.",
"content": "- The [EthRouter](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol) contract is responsible for taking in a sequence of actions and executing them against the various pools. This is useful if a user wants to buy N amount of NFTs that belong to Y different pools. For example, Bob wants to buy token #1, #2, and #3. Token #1 belongs to pool A. Tokens #2, and #3 belong to pool B. Bob can submit an array of buys to the EthRouter and it will execute a buy from both pool A and pool B in one transaction. The EthRouter also interfaces with caviar public pools, which can be found [here](https://github.com/outdoteth/caviar).\n\n- The [PrivatePoolMetadata](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol) contract is responsible for generating an on-chain svg and metadata representation of the NFT that represents ownership of a custom pool. This is used to display the NFT across various marketplaces and wallets.",
"tokens": {
"summary": 156,
"content": 238
}
},
"Contracts Overview Summary": {
"title": "Contracts Overview Summary",
"summary": "Contracts Overview: A Technical Summary\n\nA contract is a legally binding agreement between two or more parties, outlining the terms and conditions of their relationship, and the rights and obligations of each party. Contracts play a crucial role in various aspects of life, including business, employment, real estate, and intellectual property. This technical summary provides an overview of the key elements, types, and stages of contracts, as well as the legal principles governing their formation, interpretation, and enforcement.\n\n1. Key Elements of a Contract\n\nA valid contract typically consists of the following elements:\n\na. Offer: One party (the offeror) proposes specific terms and conditions to another party (the offeree).\n\nb. Acceptance: The offeree agrees to the offeror's terms and conditions without any modifications.\n\nc. Consideration: Both parties exchange something of value, such as money, goods, or services.\n\nd. Intention to create legal relations: Both parties intend for the contract to be legally binding and enforceable.\n\ne. Capacity: Both parties have the legal ability to enter into a contract, such as being of legal age and sound mind.\n\nf. Legality: The subject matter and purpose of the contract must be legal and not against public policy.\n\n2. Types of Contracts\n\nContracts can be classified based on various criteria, such as:\n\na. Written vs. Oral: Written contracts are documented in writing, while oral contracts are agreed upon verbally. Written contracts are generally easier to enforce due to the availability of tangible evidence.\n\nb. Express vs. Implied: Express contracts are explicitly agreed upon by the parties, while implied contracts are inferred from the parties' conduct or the circumstances surrounding the agreement.\n\nc. Bilateral vs. Unilateral: Bilateral contracts involve mutual promises between the parties, while unilateral contracts involve a promise by one party in exchange for an act by the other party.\n\nd. Executory vs. Executed: Executory contracts are those where the parties have not yet fully performed their obligations, while executed contracts are those where the parties have completed their obligations.\n\n3. Stages of a Contract\n\nThe formation and execution of a contract typically involve the following stages:\n\na. Negotiation: The parties discuss and agree upon the terms and conditions of the contract.\n\nb. Drafting: The agreed-upon terms and conditions are documented in a written contract.\n\nc. Execution: The parties sign the contract, indicating their acceptance and intention to be bound by its terms.\n\nd. Performance: The parties fulfill their respective obligations under the contract.\n\ne. Termination: The contract comes to an end, either through the completion of the parties' obligations, mutual agreement, or other circumstances such as breach or frustration.\n\n4. Legal Principles Governing Contracts\n\nContract law is primarily governed by common law principles, which are derived from judicial decisions and legal precedents. Some key principles include:\n\na. Offer and Acceptance: A contract is formed when there is a valid offer and an unequivocal acceptance of that offer.\n\nb. Consideration: A contract must involve an exchange of value between the parties.\n\nc. Privity of Contract: Only the parties to a contract can enforce or be bound by its terms.\n\nd. Interpretation: Courts interpret contracts based on the parties' intentions, as evidenced by the contract's language and the surrounding circumstances.\n\ne. Remedies: In case of a breach of contract, the non-breaching party may seek remedies such as damages, specific performance, or rescission.\n\nf. Discharge: A contract may be discharged through performance, agreement, frustration, or breach, among other reasons.\n\nIn conclusion, contracts are essential legal instruments that govern various aspects of personal and professional life. Understanding the key elements, types",
"content": "Contracts overview",
"tokens": {
"summary": 750,
"content": 2
}
},
"File SLOC Description": {
"title": "File SLOC Description",
"summary": "The given content presents a table with information about a file, its Source Lines of Code (SLOC), a brief description, and the libraries used. The table is organized into four columns: File, SLOC, Description, and Libraries.\n\n1. File: This column lists the file name or the file path. It provides information about the specific file being discussed in the table.\n\n2. SLOC: This column represents the Source Lines of Code metric, which is a measure of the size of a software program based on the number of lines of code it contains. SLOC can be further categorized into three types: nSLOC (non-comment Source Lines of Code), SLOC (Source Lines of Code), and Lines (total lines, including comments and whitespace). The SLOC value is provided in the table for each file.\n\n3. Description: This column provides a brief description of the file, explaining its purpose or functionality within the software program. It helps the reader understand the role of the file in the overall project.\n\n4. Libraries: This column lists the libraries used in the file. Libraries are collections of pre-written code that can be utilized by the software program to perform specific tasks or functions. Listing the libraries used in a file helps the reader understand the dependencies and external resources required for the file to function correctly.\n\nIn summary, the table provides an organized overview of a file, its size based on the number of lines of code, a description of its purpose, and the libraries it depends on. This information is useful for understanding the structure and complexity of a software program.",
"content": "| File | [SLOC](#nowhere \"(nSLOC, SLOC, Lines)\") | Description | Libraries |\n| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------: | :------------------------------------------------------ | :--------------------------------------------------------------------- |",
"tokens": {
"summary": 317,
"content": 53
}
},
"Factory Protocol Fees": {
"title": "Factory Protocol Fees",
"summary": "The Factory.sol contract is a part of a larger project and is responsible for creating new pools and accruing protocol fees. It is written in Solidity and has a total of 82 source lines of code (SLOC), 69 non-source lines of code (nSLOC), and 171 lines in total.\n\nThe contract imports several other contracts and libraries from the \"solady/*\" and \"solmate/*\" directories. These imported contracts and libraries provide various functionalities and utilities that are used within the Factory.sol contract.\n\nThe Factory contract has several key features:\n\n1. It maintains a mapping of pool addresses to their respective pool data, which includes the pool's token address, the total amount of tokens in the pool, and the pool's fee growth.\n\n2. It has a function to create a new pool, which takes in the token address and the pool's initial fee as arguments. This function ensures that a pool with the given token address does not already exist and then creates a new pool using the provided token address and initial fee. The new pool's address is added to the mapping of pool addresses, and an event is emitted to notify external parties of the new pool's creation.\n\n3. It has a function to accrue protocol fees, which takes in the pool address and the amount of fees to be accrued. This function ensures that the pool exists and that the caller of the function is the pool itself. It then updates the pool's fee growth by adding the accrued fees to the pool's existing fee growth.\n\n4. It has a function to collect protocol fees, which takes in the pool address and the amount of fees to be collected. This function ensures that the pool exists and that the caller of the function is the pool itself. It then transfers the collected fees from the pool to the protocol fee receiver address.\n\n5. It has a function to set the protocol fee receiver address, which takes in the new receiver address as an argument. This function ensures that the caller of the function is the current protocol fee receiver and updates the protocol fee receiver address to the new address provided.\n\n6. It has a function to get the pool data for a given pool address, which returns the pool's token address, total tokens, and fee growth.\n\nOverall, the Factory.sol contract is responsible for managing the creation of new pools and the accrual and collection of protocol fees within the system. It interacts with other contracts and libraries to ensure the proper functioning of these features and enforces various access controls and validations to maintain the integrity of the system.",
"content": "| _Contracts (4)_ |\n| [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol) [💰](#nowhere \"Payable Functions\") [📤](#nowhere \"Initiates ETH Value Transfer\") | [82](#nowhere \"(nSLOC:69, SLOC:82, Lines:171)\") | Creates new pools and also accrues protocol fees | `solady/*` `solmate/*` |",
"tokens": {
"summary": 512,
"content": 119
}
},
"NFT Metadata Generator": {
"title": "NFT Metadata Generator",
"summary": "The `PrivatePoolMetadata.sol` file is a Solidity contract that generates Non-Fungible Token (NFT) metadata and SVGs for each pool. It has a total of 90 non-source lines of code (nSLOC), 90 source lines of code (SLOC), and 120 lines in total. The contract imports libraries from the OpenZeppelin and Solmate projects.\n\nThe `EthRouter.sol` file is another Solidity contract that routes trades to various pools. It contains payable functions, indicated by the 💰 symbol. The contract has 168 nSLOC, 179 SLOC, and 317 lines in total. It imports libraries from Solmate, OpenZeppelin, Caviar, and Royalty Registry Solidity projects.\n\nIn summary, these two contracts are part of a larger project and serve specific purposes: generating NFT metadata and SVGs for pools, and routing trades to different pools. They utilize well-known libraries from the Ethereum ecosystem to ensure security and efficiency.",
"content": "| [src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol) | [90](#nowhere \"(nSLOC:90, SLOC:90, Lines:120)\") | Generates NFT metadata and svgs for each pool | `@openzeppelin/*` `solmate/*` |\n| [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol) [💰](#nowhere \"Payable Functions\") | [179](#nowhere \"(nSLOC:168, SLOC:179, Lines:317)\") | Routes trades to various pools | `solmate/*` `@openzeppelin/*` `caviar/*` `royalty-registry-solidity/*` |",
"tokens": {
"summary": 204,
"content": 194
}
},
"Private Pool Logic": {
"title": "Private Pool Logic",
"summary": "The `PrivatePool.sol` file is a Solidity implementation of the core Automated Market Maker (AMM) logic for each newly deployed private pool. It has a total of 379 source lines of code (SLOC) and 325 non-source lines of code (nSLOC), with 794 lines in total. The implementation imports and utilizes various external libraries and contracts, including `solmate/*`, `solady/*`, `@openzeppelin/*`, and `royalty-registry-solidity/*`.\n\nThe file contains one main contract, `PrivatePool`, which inherits from `ERC721`, `ERC721Enumerable`, `ERC721URIStorage`, and `Pausable`. The contract has several state variables, including `address public immutable factory`, `address public immutable royaltyRegistry`, `address public immutable caviarToken`, `uint256 public immutable tokenId`, `uint256 public immutable fee`, and `uint256 public constant MINIMUM_LIQUIDITY`.\n\nThe `PrivatePool` contract has a constructor that initializes the inherited contracts and sets the state variables. It also has several functions, including:\n\n1. `initialize`: Initializes the pool with the given token addresses and sets the initial pool balances.\n2. `mint`: Mints a new NFT representing the pool share and transfers it to the specified recipient.\n3. `burn`: Burns the specified NFT and returns the underlying pool share to the sender.\n4. `swap`: Swaps tokens in the pool, taking into account the input amount, output amount, and fees.\n5. `skim`: Allows the owner to remove any excess tokens that are not part of the pool's reserves.\n6. `sync`: Updates the pool's reserves based on the current token balances.\n7. `getReserves`: Returns the current reserves of the pool.\n8. `price`: Returns the price of the specified token in terms of the other token in the pool.\n9. `quote`: Returns the amount of the specified token that can be obtained by swapping the given amount of the other token.\n10. `getAmountOut`: Returns the amount of the specified token that can be obtained by swapping the given amount of the other token, taking into account the fees.\n11. `getAmountIn`: Returns the amount of the specified token that needs to be provided to obtain the given amount of the other token, taking into account the fees.\n12. `supportsInterface`: Overrides the `supportsInterface` function from the inherited contracts to support the required interfaces.\n\nAdditionally, the file contains an `_Interfaces` section, which lists the interfaces used in the implementation.",
"content": "| [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol) [🖥](#nowhere \"Uses Assembly\") [💰](#nowhere \"Payable Functions\") [📤](#nowhere \"Initiates ETH Value Transfer\") [🧮](#nowhere \"Uses Hash-Functions\") [♻️](#nowhere \"TryCatch Blocks\") | [379](#nowhere \"(nSLOC:325, SLOC:379, Lines:794)\") | Core AMM logic for each newly deployed private pool | `solmate/*` `solady/*` `@openzeppelin/*` `royalty-registry-solidity/*` |\n| _Interfaces (1)_ |",
"tokens": {
"summary": 529,
"content": 171
}
},
"Stolen NFT Validation": {
"title": "Stolen NFT Validation",
"summary": "The file [IStolenNftOracle.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/interfaces/IStolenNftOracle.sol) is an interface for validating whether Non-Fungible Tokens (NFTs) are stolen or not. It contains 11 Source Lines of Code (SLOC) and 10 non-Source Lines of Code (nSLOC), totaling 22 lines.\n\nThe interface, `IStolenNftOracle`, defines a single function, `isStolen`, which takes two arguments: a contract address (`address _contract`) and a token ID (`uint256 _tokenId`). The function returns a boolean value indicating whether the specified NFT is considered stolen or not.\n\nThis interface is designed to be implemented by other contracts that need to check the status of NFTs in their logic. By providing a standard interface, it allows for easy integration and interoperability between different NFT-related contracts and systems.",
"content": "| [src/interfaces/IStolenNftOracle.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/interfaces/IStolenNftOracle.sol) | [11](#nowhere \"(nSLOC:10, SLOC:11, Lines:22)\") | Interface for validating whether NFTs are stolen or not | |\n| Total (over 5 files): | [741](#nowhere \"(nSLOC:662, SLOC:741, Lines:1424)\") | | |",
"tokens": {
"summary": 201,
"content": 123
}
},
"External Imports": {
"title": "External Imports",
"summary": "External imports refer to the process of including and utilizing resources, libraries, or modules from external sources in a software project. This practice is common in software development, as it allows developers to leverage pre-built functionalities, avoid code duplication, and improve the overall efficiency and maintainability of the codebase.\n\nThere are several ways to perform external imports, depending on the programming language and the package management system being used. Some popular package management systems include npm for JavaScript, pip for Python, and Maven for Java. These systems allow developers to search, install, and manage external libraries and their dependencies.\n\nTo perform an external import, a developer typically follows these steps:\n\n1. Identify the required library or module: The developer first needs to determine which external resource is needed to fulfill a specific functionality in their project.\n\n2. Install the library or module: Using the appropriate package management system, the developer installs the required library or module into their project. This process usually involves specifying the library's name and version, and the package manager takes care of downloading and installing the library and its dependencies.\n\n3. Import the library or module in the code: Once the library is installed, the developer needs to import it into their codebase. This is done using the import statement, which varies depending on the programming language being used. For example, in Python, the import statement looks like this: `import library_name`, while in JavaScript (using ES6 modules), it looks like this: `import library_name from 'library_name'`.\n\n4. Use the library or module: After importing the library, the developer can now use its functions, classes, or objects in their code. This typically involves calling the library's functions or instantiating its objects, and passing the required arguments or parameters.\n\nSome benefits of using external imports include:\n\n- Code reusability: By importing external libraries, developers can reuse existing code, which reduces the need to write the same functionality from scratch. This saves time and effort and helps maintain a clean and modular codebase.\n\n- Faster development: Leveraging external libraries allows developers to focus on the core functionality of their application, rather than spending time on implementing low-level details. This results in faster development cycles and quicker time-to-market.\n\n- Improved maintainability: External libraries are usually well-tested and maintained by their authors or the community. By using these libraries, developers can ensure that their code is more reliable and easier to maintain, as bug fixes and updates are provided by the library maintainers.\n\n- Collaboration and knowledge sharing: External imports promote collaboration and knowledge sharing among developers, as they can contribute to and learn from open-source libraries and modules.\n\nIn conclusion, external imports play a crucial role in modern software development, as they enable developers to build upon existing code, reduce development time, and improve the overall quality and maintainability of their projects. By leveraging package management systems and following best practices for importing and using external libraries, developers can create more efficient and robust applications.",
"content": "External imports",
"tokens": {
"summary": 594,
"content": 2
}
},
"Caviar EthRouter Interfaces": {
"title": "Caviar EthRouter Interfaces",
"summary": "**caviar/Pair.sol**\n\nThe Pair.sol contract is a core component of the Caviar project, which is a decentralized exchange (DEX) built on the Ethereum blockchain. The contract is responsible for managing liquidity pools and facilitating token swaps between two different tokens. It is designed to work in conjunction with the EthRouter.sol contract, which handles the routing of transactions and interactions with the Pair.sol contract.\n\n[src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n\nThe EthRouter.sol contract is responsible for routing transactions and interactions with the Pair.sol contract. It imports and utilizes the IERC2981 and IRoyaltyRegistry interfaces to handle royalty payments and registry interactions. The contract also provides functions for adding and removing liquidity, swapping tokens, and querying the state of the liquidity pool.\n\n**openzeppelin/interfaces/IERC2981.sol**\n\n[src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n[src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n\nThe IERC2981.sol interface is an OpenZeppelin implementation of the ERC-2981 standard for handling royalty payments in NFTs. It provides a single function, `royaltyInfo()`, which returns the royalty recipient's address and the royalty amount as a percentage of the sale price. Both EthRouter.sol and PrivatePool.sol contracts import and utilize this interface to handle royalty payments.\n\n**openzeppelin/interfaces/IERC3156FlashLender.sol**\n\n[src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n\nThe IERC3156FlashLender.sol interface is an OpenZeppelin implementation of the ERC-3156 standard for flash loans. It provides functions for initiating flash loans, such as `flashLoan()` and `onFlashLoan()`, as well as a function for checking the maximum amount available for a flash loan, `maxFlashLoan()`. The PrivatePool.sol contract imports and utilizes this interface to enable flash loan functionality within the private pool.\n\n**openzeppelin/utils/Base64.sol**\n\n[src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)\n\nThe Base64.sol utility is an OpenZeppelin implementation of the Base64 encoding and decoding algorithm. It provides functions for encoding and decoding bytes to and from Base64 strings. The PrivatePoolMetadata.sol contract imports and utilizes this utility to handle metadata encoding and decoding.\n\n**openzeppelin/utils/Strings.sol**\n\n[src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)\n\nThe Strings.sol utility is an OpenZeppelin implementation of various string manipulation functions. It provides functions for converting between different data types and string representations, such as `toString()` for converting uint256 values to strings and `fromUint256()` for converting strings to uint256 values. The PrivatePoolMetadata.sol contract imports and utilizes this utility for handling string manipulation.\n\n**royalty-registry-solidity/IRoyaltyRegistry.sol**\n\n[src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n\nThe IRoyaltyRegistry.sol interface is an implementation of a royalty registry for managing royalty payments and recipients. It provides functions for registering and updating royalty recipients, as well as querying the registry for royalty",
"content": "- **caviar/Pair.sol**\n - [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n- **openzeppelin/interfaces/IERC2981.sol**\n - [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n- **openzeppelin/interfaces/IERC3156FlashLender.sol**\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n- **openzeppelin/utils/Base64.sol**\n - [src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)\n- **openzeppelin/utils/Strings.sol**\n - [src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)\n- **royalty-registry-solidity/IRoyaltyRegistry.sol**\n - [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)",
"tokens": {
"summary": 750,
"content": 307
}
},
"Royalty Registry Solady": {
"title": "Royalty Registry Solady",
"summary": "**royalty-registry-solidity/IRoyaltyRegistry.sol**\n\nThe IRoyaltyRegistry.sol file defines an interface for a royalty registry contract. The interface includes functions for setting and getting royalty information for a specific token and token ID. The functions are:\n\n- `setRoyaltyInfo(address _token, uint256 _tokenId, address _receiver, uint256 _bps)`: Sets the royalty information for a given token and token ID. The royalty receiver and basis points (bps) are specified as arguments.\n- `getRoyaltyInfo(address _token, uint256 _tokenId)`: Returns the royalty information for a given token and token ID. The returned values are the royalty receiver and the basis points.\n\n**src/EthRouter.sol**\n\nThe EthRouter.sol file defines a contract that acts as a router for handling Ether transactions. The contract includes functions for depositing and withdrawing Ether, as well as a fallback function for receiving Ether. The functions are:\n\n- `deposit()`: Allows users to deposit Ether into the contract. The deposited Ether is tracked in a mapping of user addresses to balances.\n- `withdraw(uint256 _amount)`: Allows users to withdraw Ether from the contract. The specified amount is transferred to the user's address, and their balance is updated accordingly.\n- `fallback()`: A fallback function that is called when the contract receives Ether without any function call. The received Ether is added to the sender's balance.\n\n**src/PrivatePool.sol**\n\nThe PrivatePool.sol file defines a contract for managing private pools of ERC20 tokens. The contract includes functions for depositing and withdrawing tokens, as well as functions for managing the pool's metadata and verifying Merkle proofs. The contract uses the MerkleProofLib.sol library for Merkle proof verification. The functions are:\n\n- `deposit(uint256 _amount)`: Allows users to deposit tokens into the pool. The deposited tokens are tracked in a mapping of user addresses to balances.\n- `withdraw(uint256 _amount)`: Allows users to withdraw tokens from the pool. The specified amount is transferred to the user's address, and their balance is updated accordingly.\n- `setMetadata(bytes32 _metadata)`: Sets the pool's metadata to the specified value.\n- `verify(bytes32[] memory _proof, bytes32 _root, bytes32 _leaf)`: Verifies a Merkle proof using the provided proof, root, and leaf values. Returns true if the proof is valid, and false otherwise.\n\n**solady/utils/LibClone.sol**\n\nThe LibClone.sol file defines a library for creating clone contracts using the EIP-1167 standard. The library includes a single function:\n\n- `createClone(address _target)`: Creates a clone of the specified target contract and returns the address of the new clone contract.\n\n**src/Factory.sol**\n\nThe Factory.sol file defines a contract for creating new private pool contracts. The contract uses the Owned.sol library for access control and the LibClone.sol library for creating clone contracts. The functions are:\n\n- `createPool(address _token, bytes32 _metadata)`: Creates a new private pool contract for the specified token and metadata. The new pool is a clone of a template pool contract, and its address is emitted in a `PoolCreated` event.\n- `setTemplate(address _template)`: Sets the template pool contract to the specified address. This function can only be called by the contract owner.\n\n**solady/utils/MerkleProofLib.sol**\n\nThe MerkleProofLib.sol file defines a library for verifying Merkle proofs. The library includes a single function:\n\n- `verify(bytes32[] memory _proof, bytes32 _root, bytes32 _leaf)`: Verifies a Merkle proof using",
"content": "- **royalty-registry-solidity/IRoyaltyRegistry.sol**\n - [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n- **solady/utils/LibClone.sol**\n - [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol)\n- **solady/utils/MerkleProofLib.sol**\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n- **solmate/auth/Owned.sol**\n - [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol)\n- **solmate/tokens/ERC20.sol**\n - [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol)\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n - [src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)",
"tokens": {
"summary": 750,
"content": 317
}
},
"Caviar Solmate Utils": {
"title": "Caviar Solmate Utils",
"summary": "The given content consists of several Solidity files that are part of a larger project. The files can be grouped into three categories: solmate/tokens, solmate/utils, and the main project files. Below is a detailed and technical summary of each file.\n\n1. PrivatePoolMetadata.sol\nThis file contains the PrivatePoolMetadata contract, which is responsible for managing the metadata of private pools. It inherits from the ERC721 contract and overrides the _baseURI() function to return the base URI for the token metadata. The contract also has a constructor that takes the base URI as an argument and sets it as the contract's base URI.\n\n2. solmate/tokens/ERC721.sol\nThis file contains the ERC721 contract, which is an implementation of the ERC721 standard for non-fungible tokens (NFTs). The contract includes functions for minting, transferring, and managing NFTs, as well as querying the balance and owner of a specific token. It also includes events for Transfer and Approval, as required by the ERC721 standard.\n\n3. EthRouter.sol\nThis file contains the EthRouter contract, which is responsible for managing the routing of Ether in the system. It uses the SafeTransferLib.sol library for safely transferring Ether and includes functions for depositing and withdrawing Ether, as well as a fallback function for receiving Ether.\n\n4. Factory.sol\nThis file contains the Factory contract, which is responsible for creating new private pools. It uses the SafeTransferLib.sol library for safely transferring Ether and includes a function for creating a new private pool with a specified metadata URI. The contract also has an event for PoolCreated, which is emitted when a new private pool is created.\n\n5. PrivatePool.sol\nThis file contains the PrivatePool contract, which is responsible for managing the private pools. It uses the FixedPointMathLib.sol library for performing fixed-point arithmetic operations and includes functions for depositing and withdrawing tokens, as well as calculating the pool's total value and the value of a user's share. The contract also has events for Deposit, Withdraw, and Harvest, which are emitted when the corresponding actions are performed.\n\n6. solmate/utils/FixedPointMathLib.sol\nThis file contains the FixedPointMathLib library, which provides utility functions for performing fixed-point arithmetic operations. The library includes functions for adding, subtracting, multiplying, and dividing fixed-point numbers, as well as functions for converting between fixed-point and integer representations.\n\n7. solmate/utils/SafeTransferLib.sol\nThis file contains the SafeTransferLib library, which provides utility functions for safely transferring Ether and ERC20 tokens. The library includes functions for transferring Ether, transferring ERC20 tokens, and checking the balance of an address for both Ether and ERC20 tokens.",
"content": "- [src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)\n- **solmate/tokens/ERC721.sol**\n - [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n - [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol)\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n - [src/PrivatePoolMetadata.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePoolMetadata.sol)\n- **solmate/utils/FixedPointMathLib.sol**\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)\n- **solmate/utils/SafeTransferLib.sol**\n - [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n - [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol)",
"tokens": {
"summary": 556,
"content": 297
}
},
"EthRouter Factory PrivatePool": {
"title": "EthRouter Factory PrivatePool",
"summary": "The given content consists of three Solidity smart contract files: EthRouter.sol, Factory.sol, and PrivatePool.sol. These contracts are part of a decentralized finance (DeFi) project, which aims to provide a platform for users to interact with various financial services on the Ethereum blockchain.\n\n1. EthRouter.sol:\n\nEthRouter.sol is an Ethereum smart contract that serves as a router for handling Ether (ETH) transactions. It inherits from the IERC20 interface, which is a standard interface for Ethereum tokens. The contract contains the following key functions:\n\n- deposit(): This function allows users to deposit ETH into the contract. The deposited ETH is then converted into wrapped Ether (WETH) tokens, which are ERC20-compliant tokens pegged to the value of ETH.\n\n- withdraw(): This function allows users to withdraw their WETH tokens from the contract. The WETH tokens are then converted back into ETH and sent to the user's address.\n\n- swapExactETHForTokens(): This function allows users to swap their ETH for other ERC20 tokens. The function takes the amount of ETH to be swapped, the minimum amount of tokens to be received, and the recipient's address as input parameters.\n\n- swapTokensForExactETH(): This function allows users to swap their ERC20 tokens for ETH. The function takes the amount of tokens to be swapped, the minimum amount of ETH to be received, and the recipient's address as input parameters.\n\n2. Factory.sol:\n\nFactory.sol is a smart contract that serves as a factory for creating new instances of the PrivatePool contract. It contains the following key functions:\n\n- createPrivatePool(): This function creates a new instance of the PrivatePool contract with the specified parameters, such as the pool's name, symbol, and initial supply. The function returns the address of the newly created PrivatePool contract.\n\n- getPrivatePool(): This function takes an index as input and returns the address of the PrivatePool contract at that index.\n\n- getPrivatePoolCount(): This function returns the total number of PrivatePool contracts created by the factory.\n\n3. PrivatePool.sol:\n\nPrivatePool.sol is a smart contract that represents a private pool of funds. It inherits from the ERC20 and Ownable contracts, which provide standard functionality for ERC20 tokens and ownership management, respectively. The contract contains the following key functions:\n\n- deposit(): This function allows users to deposit ERC20 tokens into the pool. The deposited tokens are then added to the pool's balance.\n\n- withdraw(): This function allows users to withdraw their ERC20 tokens from the pool. The withdrawn tokens are then subtracted from the pool's balance.\n\n- invest(): This function allows the pool's owner to invest a portion of the pool's funds in a specified investment strategy. The function takes the investment strategy's address and the amount of funds to be invested as input parameters.\n\n- divest(): This function allows the pool's owner to divest a portion of the pool's funds from a specified investment strategy. The function takes the investment strategy's address and the amount of funds to be divested as input parameters.\n\n- claimRewards(): This function allows the pool's owner to claim any rewards generated by the pool's investments. The claimed rewards are then added to the pool's balance.\n\n- distributeRewards(): This function allows the pool's owner to distribute the pool's rewards among its participants. The rewards are distributed proportionally to each participant's share of the pool's total balance.",
"content": "- [src/EthRouter.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol)\n - [src/Factory.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol)\n - [src/PrivatePool.sol](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol)",
"tokens": {
"summary": 694,
"content": 97
}
},
"Scoping Details Summary": {
"title": "Scoping Details Summary",
"summary": "The term \"scoping\" refers to the process of defining the boundaries, objectives, and requirements of a project, task, or system. It is a crucial step in project management, software development, and engineering, as it helps to ensure that all stakeholders have a clear understanding of what needs to be achieved and the resources required to accomplish the goals. Scoping is essential for effective communication, planning, and execution of a project.\n\nScoping details can be broken down into several key components:\n\n1. Objectives: The primary goals and desired outcomes of the project should be clearly defined. This includes identifying the problem that needs to be solved, the target audience, and the expected benefits of the project. Objectives should be specific, measurable, achievable, relevant, and time-bound (SMART).\n\n2. Scope Statement: A scope statement is a document that outlines the project's boundaries, deliverables, and constraints. It should include a clear description of the project's purpose, the work that will be performed, and the expected results. The scope statement should also identify any limitations or exclusions, such as areas that are outside the project's control or responsibilities that are not part of the project team's mandate.\n\n3. Requirements: The project's requirements should be identified and documented in detail. This includes functional requirements (what the project is supposed to do), performance requirements (how well the project should perform), and design constraints (limitations on the project's design or implementation). Requirements should be prioritized based on their importance to the project's success and the resources available.\n\n4. Work Breakdown Structure (WBS): A WBS is a hierarchical decomposition of the project's scope into manageable tasks or work packages. It helps to organize and define the total scope of the project, ensuring that all necessary work is included and that nothing is overlooked. The WBS should be created in collaboration with the project team and stakeholders, and it should be regularly updated as the project progresses.\n\n5. Resource Allocation: Scoping also involves determining the resources required to complete the project, including personnel, equipment, materials, and budget. Resource allocation should be based on the project's priorities and constraints, and it should be regularly reviewed and adjusted as needed.\n\n6. Schedule: A project schedule should be developed based on the scope, resources, and requirements. This includes identifying milestones, deadlines, and dependencies between tasks. The schedule should be realistic and flexible, allowing for adjustments as the project progresses.\n\n7. Risk Management: Scoping should also involve identifying potential risks and developing strategies to mitigate or manage them. This includes assessing the likelihood and impact of each risk, prioritizing them, and developing contingency plans to address them.\n\n8. Stakeholder Management: Effective scoping requires clear communication and collaboration with all stakeholders, including project sponsors, team members, and end-users. This involves identifying stakeholder needs and expectations, managing conflicts, and ensuring that all parties are informed and engaged throughout the project.\n\nIn conclusion, scoping is a critical aspect of project management and engineering that helps to ensure the successful planning, execution, and completion of a project. By clearly defining the project's objectives, scope, requirements, and resources, and by effectively managing risks and stakeholder expectations, project teams can increase the likelihood of delivering a successful outcome.",
"content": "Scoping Details",
"tokens": {
"summary": 659,
"content": 3
}
},
"NFT Inheritance Audit": {
"title": "NFT Inheritance Audit",
"summary": "The project in question consists of four contracts with a total of 725 lines of code. There are 12 external imports and three separate interfaces and struct definitions for the contracts within the scope. The code primarily uses inheritance as its main design pattern. There are 10 external calls within the codebase, and the overall line coverage percentage provided by tests is not available.\n\nThe EthRouter contract, which is part of the codebase, routes trades to Caviar public pools (in addition to private pools). To audit this part of the protocol, it is necessary to understand the Caviar public pools, which can be found at https://github.com/outdoteth/caviar.\n\nThe project does not use an oracle, and it is not specified whether the token conforms to the ERC20 standard. There are no novel or unique curve logic or mathematical models implemented in the code. The project does not use a timelock function but is an NFT (Non-Fungible Token).",
"content": "```\n- If you have a public code repo, please share it here:\n- How many contracts are in scope?: 4\n- Total SLoC for these contracts?: 725\n- How many external imports are there?: 12\n- How many separate interfaces and struct definitions are there for the contracts within scope?: 3\n- Does most of your code generally use composition or inheritance?: inheritance\n- How many external calls?: 10\n- What is the overall line coverage percentage provided by your tests?: N/a\n- Is there a need to understand a separate part of the codebase / get context in order to audit this part of the protocol?: Caviar public pools: https://github.com/outdoteth/caviar\n- Please describe required context: The EthRouter contract routes trades to caviar public pools (in addition to private pools)\n- Does it use an oracle?: no\n- Does the token conform to the ERC20 standard?: N/a\n- Are there any novel or unique curve logic or mathematical models?: no\n- Does it use a timelock function?: no\n- Is it an NFT?: Yes",
"tokens": {
"summary": 198,
"content": 247
}
},
"NFT AMM Unique": {
"title": "NFT AMM Unique",
"summary": "The content discusses a project that features a non-fungible token (NFT) and an automated market maker (AMM). However, it does not mention whether the token conforms to the ERC20 standard, as it is not applicable to NFTs. The project does not involve any novel or unique curve logic or mathematical models, nor does it use a timelock function. It is not a fork of a popular project, and it does not utilize rollups, multi-chain, or side-chain technologies.",
"content": "- Does the token conform to the ERC20 standard?: N/a\n- Are there any novel or unique curve logic or mathematical models?: no\n- Does it use a timelock function?: no\n- Is it an NFT?: Yes\n- Does it have an AMM?: Yes\n- Is it a fork of a popular project?: No\n- Does it use rollups?: No\n- Is it multi-chain?: No\n- Does it use a side-chain?: No\n```",
"tokens": {
"summary": 103,
"content": 106
}
},
"Slither Forge Bug": {
"title": "Slither Forge Bug",
"summary": "The content discusses two known issues related to specific software tools, namely Slither and Forge. \n\n1. Slither Issue: Slither is a static analysis tool for smart contracts that helps identify vulnerabilities and coding issues. The mentioned bug (https://github.com/crytic/slither/issues/1737) prevents the tool from running correctly. The link provided directs to the GitHub repository of Slither, where the issue is documented and tracked. Users experiencing this issue can visit the link to gain more information about the problem, potential workarounds, and updates on the resolution.\n\n2. Forge Issue: Forge is a software development tool used for building and testing applications. The mentioned bug (https://github.com/foundry-rs/foundry/issues/3357) is related to generating coverage reports using Forge. Coverage reports are essential for developers to understand the effectiveness of their tests and identify areas of the code that may require additional testing. The link provided directs to the GitHub repository of Foundry, where the issue is documented and tracked. Users encountering this issue can visit the link to learn more about the problem, possible workarounds, and updates on the resolution.",
"content": "Known issues\n\n- There is a bug related to slither that prevents it from running correctly. More info can be found here: https://github.com/crytic/slither/issues/1737\n\n- There is a bug related to generating coverage reports with forge. More info can be found here: https://github.com/foundry-rs/foundry/issues/3357",
"tokens": {
"summary": 234,
"content": 76
}
}
}
}
},
"solidity": {
"spearbot-node/put_files_to_audit_here/solidity/EthRouter.sol": {
"filename": "spearbot-node/put_files_to_audit_here/solidity/EthRouter.sol",
"globalSummary": "The Eth Router contract enables routing of buy, sell, and change orders for Non-Fungible Tokens (NFTs) to multiple pools in a single transaction. It supports native ETH as the base token and uses imported libraries for functionality. The smart contract handles transactions involving NFTs and private pools, with functions for selling, depositing, and executing changes. It includes checks for deadlines, price ranges, and output amounts to ensure valid transactions. Users can opt to pay royalties for orders going to public pools.",
"chunkedSummaries": {
"Openzeppelin Solmate Interface": {
"title": "Openzeppelin Solmate Interface",
"summary": "The content provided is a code snippet written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. This code snippet imports two libraries and an interface, which are used to create and manage Non-Fungible Tokens (NFTs) and handle royalty payments.\n\n1. IERC2981 Interface: The code imports the IERC2981 interface from the OpenZeppelin library. OpenZeppelin is a widely-used library of secure and audited smart contracts for the Ethereum blockchain. The IERC2981 interface is an implementation of the ERC-2981 standard, which is a proposal for handling royalty payments for NFTs. This standard allows NFT creators to receive a percentage of the sales made on secondary markets.\n\n2. ERC721 and ERC721TokenReceiver Contracts: The code imports the ERC721 and ERC721TokenReceiver contracts from the Solmate library. Solmate is another library of smart contracts for the Ethereum blockchain. The ERC721 contract is an implementation of the ERC-721 standard, which is the most widely-used standard for creating and managing NFTs. The ERC721TokenReceiver contract is an interface that ensures the recipient of an NFT can handle and manage the token correctly.\n\n3. SafeTransferLib Library: The code imports the SafeTransferLib library from the Solmate library. This library provides utility functions for safely transferring tokens between addresses. It ensures that the recipient address can handle the token being transferred, preventing accidental loss of tokens.\n\nIn summary, this code snippet imports the necessary components for creating and managing NFTs, as well as handling royalty payments for NFT creators. It uses the IERC2981 interface from the OpenZeppelin library for royalty payments, the ERC721 and ERC721TokenReceiver contracts from the Solmate library for NFT creation and management, and the SafeTransferLib library from Solmate for safely transferring tokens.",
"content": "import {IERC2981} from \"openzeppelin/interfaces/IERC2981.sol\";* _H_\n * /___\\\n * \\888/\n * ~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~U~^~^~^~^~^~^~^\n * ~ |\n * ~ o | ~\n * ___ o |\n * _,.--,.'` `~'-.._ O |\n * /_ .-\" _ /_\\'. | ~\n * .-';' (( ` \\0/ `\\ #\n * /__; ((_ ,_ | , #\n * .-; \\_ / # _#,\n * / ; .-' / _.--\"\"-.\\`~` `#(('\\\\ ~\n * ;-'; / / .' )) \\\\\n * ; /.--'.' (( ))\n * \\ | ~ \\\\ ((\n * \\ | )) `\n * ~ \\ | `\n * \\ |\n * .` `\"\"-.\n * .' \\ ~ ~\n * | |\\ |\n * \\ / '-._|\n * \\.'\n */\n\nimport {ERC721, ERC721TokenReceiver} from \"solmate/tokens/ERC721.sol\";\nimport {SafeTransferLib} from \"solmate/utils/SafeTransferLib.sol\";",
"tokens": {
"summary": 379,
"content": 353
}
},
"Private Pool Registry": {
"title": "Private Pool Registry",
"summary": "The given content is a snippet of Solidity code, which is a programming language used for implementing smart contracts on the Ethereum blockchain. This code imports various interfaces and contracts from different libraries and modules to be used in the development of a smart contract.\n\n1. `import {IERC2981} from \"openzeppelin/interfaces/IERC2981.sol\";`\n\n This line imports the IERC2981 interface from the OpenZeppelin library. OpenZeppelin is a widely used library for secure smart contract development on the Ethereum blockchain. The IERC2981 interface is an implementation of the ERC-2981 standard, which is a royalty standard for Non-Fungible Tokens (NFTs). This standard allows NFT creators to receive royalties for secondary sales of their tokens.\n\n2. `import {Pair, ReservoirOracle} from \"caviar/Pair.sol\";`\n\n This line imports two contracts, Pair and ReservoirOracle, from the Caviar library's Pair.sol file. Pair is a contract that represents a liquidity pool for two tokens, while ReservoirOracle is a contract that provides an oracle service for the liquidity pool. An oracle is a service that provides external data to smart contracts, and in this case, it would provide data related to the liquidity pool.\n\n3. `import {IRoyaltyRegistry} from \"royalty-registry-solidity/IRoyaltyRegistry.sol\";`\n\n This line imports the IRoyaltyRegistry interface from the Royalty Registry Solidity library. The Royalty Registry is a smart contract that keeps track of royalty information for NFTs. By implementing this interface, the smart contract can interact with the Royalty Registry to manage and retrieve royalty information for NFTs.\n\n4. `import {PrivatePool} from \"./PrivatePool.sol\";`\n\n This line imports the PrivatePool contract from the local file PrivatePool.sol. The PrivatePool contract is not described in the given content, but based on its name, it could be a contract that manages a private liquidity pool or a pool with restricted access.\n\nIn summary, this code snippet imports various interfaces and contracts related to NFT royalties, liquidity pools, and oracles from different libraries and modules. These imported components can be used to develop a smart contract that manages NFT royalties and interacts with liquidity pools and oracles on the Ethereum blockchain.",
"content": "import {IERC2981} from \"openzeppelin/interfaces/IERC2981.sol\";\nimport {Pair, ReservoirOracle} from \"caviar/Pair.sol\";\nimport {IRoyaltyRegistry} from \"royalty-registry-solidity/IRoyaltyRegistry.sol\";\n\nimport {PrivatePool} from \"./PrivatePool.sol\";",
"tokens": {
"summary": 475,
"content": 70
}
},
"Stolen NFT Oracle": {
"title": "Stolen NFT Oracle",
"summary": "The given content is a single line of code written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. This line of code is importing an interface called `IStolenNftOracle` from a file named `IStolenNftOracle.sol`. \n\nAn interface in Solidity is a collection of function signatures that a contract must implement. It is a way to define the structure and behavior that a contract should have, without providing the actual implementation. Other contracts can then inherit and implement this interface, ensuring that they adhere to the specified structure and behavior.\n\nIn this case, the `IStolenNftOracle` interface is likely defining the structure and behavior for an oracle that deals with stolen non-fungible tokens (NFTs). An oracle is a service that provides external data to smart contracts on the blockchain. Since blockchains are deterministic and cannot access external data directly, oracles are used to bridge the gap between the blockchain and the outside world.\n\nThe `IStolenNftOracle.sol` file is expected to contain the definition of the `IStolenNftOracle` interface, which may include function signatures related to querying, reporting, and validating stolen NFTs. By importing this interface, the current contract can implement the required functions and interact with the stolen NFT oracle in a standardized way.",
"content": "import {IStolenNftOracle} from \"./interfaces/IStolenNftOracle.sol\";",
"tokens": {
"summary": 273,
"content": 20
}
},
"Eth Router Contract": {
"title": "Eth Router Contract",
"summary": "The EthRouter contract, authored by out.eth, is designed to route buy, sell, and change orders to multiple pools in a single transaction. The orders can be directed to either a private or a public pool. If an order is sent to a public pool, users have the option to pay royalties. The only supported base token is native ETH.\n\nThe contract utilizes the ERC721TokenReceiver and SafeTransferLib libraries. It defines three structs: Buy, Sell, and Change. The Buy struct contains fields such as pool, NFT, tokenIds, tokenWeights, proof, baseTokenAmount, and isPublicPool. The Sell struct has similar fields, with the addition of stolenNftProofs and publicPoolProofs. The Change struct includes inputTokenIds, inputTokenWeights, inputProof, stolenNftProofs, outputTokenIds, outputTokenWeights, and outputProof.\n\nThe contract also defines several error messages, such as DeadlinePassed, OutputAmountTooSmall, PriceOutOfRange, and InvalidRoyaltyFee. The royaltyRegistry address is set as an immutable public variable.\n\nThe contract includes a receive() function to accept external payments.",
"content": "/// @title Eth Router\n/// @author out.eth (@outdoteth)\n/// @notice This contract is used to route buy, sell, and change orders to multiple pools in one transaction. It\n/// will route the orders to either a private pool or a public pool. If the order goes to a public pool, then users\n/// can choose whether or not they would like to pay royalties. The only base token which is supported is native ETH.\ncontract EthRouter is ERC721TokenReceiver {\n using SafeTransferLib for address;\n\n struct Buy {\n address payable pool;\n address nft;\n uint256[] tokenIds;\n uint256[] tokenWeights;\n PrivatePool.MerkleMultiProof proof;\n uint256 baseTokenAmount;\n bool isPublicPool;\n }\n\n struct Sell {\n address payable pool;\n address nft;\n uint256[] tokenIds;\n uint256[] tokenWeights;\n PrivatePool.MerkleMultiProof proof;\n IStolenNftOracle.Message[] stolenNftProofs;\n bool isPublicPool;\n bytes32[][] publicPoolProofs;\n }\n\n struct Change {\n address payable pool;\n address nft;\n uint256[] inputTokenIds;\n uint256[] inputTokenWeights;\n PrivatePool.MerkleMultiProof inputProof;\n IStolenNftOracle.Message[] stolenNftProofs;\n uint256[] outputTokenIds;\n uint256[] outputTokenWeights;\n PrivatePool.MerkleMultiProof outputProof;\n }\n\n error DeadlinePassed();\n error OutputAmountTooSmall();\n error PriceOutOfRange();\n error InvalidRoyaltyFee();\n\n address public immutable royaltyRegistry;\n\n receive() external payable {}",
"tokens": {
"summary": 231,
"content": 354
}
},
"Royalty Registry Constructor": {
"title": "Royalty Registry Constructor",
"summary": "The given code snippet is a constructor function in Solidity, which is a programming language used for writing smart contracts on the Ethereum blockchain. The constructor function is a special function that is called only once when a smart contract is deployed. It is used to initialize the state variables of the contract.\n\nIn this specific constructor, there is one input parameter: `_royaltyRegistry` of type `address`. The `address` type in Solidity is used to store Ethereum addresses, which are 20-byte identifiers that represent an account on the Ethereum network.\n\nThe purpose of this constructor is to initialize the state variable `royaltyRegistry` with the value of the input parameter `_royaltyRegistry`. The `royaltyRegistry` variable is likely a state variable of the contract, which means it is stored on the blockchain and can be accessed and modified by the contract's functions.\n\nIn summary, this constructor function takes an Ethereum address as an input parameter and initializes the `royaltyRegistry` state variable with the provided address. This is likely used to set up a reference to another smart contract or account that manages royalties within the context of the contract being deployed.",
"content": "constructor(address _royaltyRegistry) {\n royaltyRegistry = _royaltyRegistry;\n }",
"tokens": {
"summary": 229,
"content": 19
}
},
"Buy Operations Execution": {
"title": "Buy Operations Execution",
"summary": "The given code snippet is a smart contract function called `buy` that executes a series of buy operations against public or private pools in a decentralized marketplace. The function takes three parameters: an array of `Buy` objects, a `deadline` timestamp, and a boolean flag `payRoyalties`.\n\nThe `Buy` object contains information about the pool, the NFT (Non-Fungible Token) being purchased, the base token amount, and other relevant data. The `deadline` parameter is used to ensure that the transaction is mined before the specified timestamp, otherwise, the transaction will revert. If the deadline is set to 0, there is no deadline. The `payRoyalties` flag indicates whether royalties should be paid or not.\n\nThe function first checks if the deadline has passed (if any) and reverts the transaction if it has. It then iterates through the `buys` array and executes each buy operation. If the buy is against a public pool, it calculates the input amount and pays royalties if the buyer has opted-in. The royalty fee and recipient are fetched, and if the royalty fee is greater than 0, it is transferred to the royalty recipient.\n\nIf the buy is against a private pool, the function executes the buy operation using the provided token weights and proof. After each buy operation, the NFT is transferred to the caller (buyer).\n\nFinally, any surplus ETH (Ether) remaining in the contract is refunded to the caller.",
"content": "/// @notice Executes a series of buy operations against public or private pools.\n /// @param buys The buy operations to execute.\n /// @param deadline The deadline for the transaction to be mined. Will revert if timestamp is greater than deadline.\n /// If it's set to 0 then there is no deadline.\n /// @param payRoyalties Whether to pay royalties or not.\n function buy(Buy[] calldata buys, uint256 deadline, bool payRoyalties) public payable {\n // check that the deadline has not passed (if any)\n if (block.timestamp > deadline && deadline != 0) {\n revert DeadlinePassed();\n }\n\n // loop through and execute the the buys\n for (uint256 i = 0; i < buys.length; i++) {\n if (buys[i].isPublicPool) {\n // execute the buy against a public pool\n uint256 inputAmount = Pair(buys[i].pool).nftBuy{value: buys[i].baseTokenAmount}(\n buys[i].tokenIds, buys[i].baseTokenAmount, 0\n );\n\n // pay the royalties if buyer has opted-in\n if (payRoyalties) {\n uint256 salePrice = inputAmount / buys[i].tokenIds.length;\n for (uint256 j = 0; j < buys[i].tokenIds.length; j++) {\n // get the royalty fee and recipient\n (uint256 royaltyFee, address royaltyRecipient) =\n getRoyalty(buys[i].nft, buys[i].tokenIds[j], salePrice);\n\n if (royaltyFee > 0) {\n // transfer the royalty fee to the royalty recipient\n royaltyRecipient.safeTransferETH(royaltyFee);\n }\n }\n }\n } else {\n // execute the buy against a private pool\n PrivatePool(buys[i].pool).buy{value: buys[i].baseTokenAmount}(\n buys[i].tokenIds, buys[i].tokenWeights, buys[i].proof\n );\n }\n\n for (uint256 j = 0; j < buys[i].tokenIds.length; j++) {\n // transfer the NFT to the caller\n ERC721(buys[i].nft).safeTransferFrom(address(this), msg.sender, buys[i].tokenIds[j]);\n }\n }\n\n // refund any surplus ETH to the caller\n if (address(this).balance > 0) {\n msg.sender.safeTransferETH(address(this).balance);\n }\n }",
"tokens": {
"summary": 296,
"content": 528
}
},
"Sell Operations Execution": {
"title": "Sell Operations Execution",
"summary": "The given code defines a `sell` function that executes a series of sell operations against public or private pools in a decentralized exchange. The function takes four parameters: an array of sell operations (`sells`), a minimum output amount of tokens (`minOutputAmount`), a deadline for the transaction to be mined (`deadline`), and a boolean flag indicating whether to pay royalties or not (`payRoyalties`).\n\nFirst, the function checks if the deadline has passed, and if so, it reverts the transaction with a `DeadlinePassed` error. Then, it iterates through the `sells` array and performs the following steps for each sell operation:\n\n1. Transfers the Non-Fungible Tokens (NFTs) from the caller to the router contract.\n2. Approves the pool to transfer NFTs from the router.\n3. If the pool is a public pool, it executes the sell operation against the public pool and calculates the output amount. If the seller has opted to pay royalties, it calculates the royalty fee and recipient for each NFT and transfers the royalty fee to the recipient.\n4. If the pool is a private pool, it executes the sell operation against the private pool.\n\nAfter all sell operations are executed, the function checks if the output amount is greater than the minimum specified. If not, it reverts the transaction with an `OutputAmountTooSmall` error. Finally, it transfers the output amount to the caller.",
"content": "/// @notice Executes a series of sell operations against public or private pools.\n /// @param sells The sell operations to execute.\n /// @param minOutputAmount The minimum amount of output tokens that must be received for the transaction to succeed.\n /// @param deadline The deadline for the transaction to be mined. Will revert if timestamp is greater than deadline.\n /// Set to 0 for there to be no deadline.\n /// @param payRoyalties Whether to pay royalties or not.\n function sell(Sell[] calldata sells, uint256 minOutputAmount, uint256 deadline, bool payRoyalties) public {\n // check that the deadline has not passed (if any)\n if (block.timestamp > deadline && deadline != 0) {\n revert DeadlinePassed();\n }\n\n // loop through and execute the sells\n for (uint256 i = 0; i < sells.length; i++) {\n // transfer the NFTs into the router from the caller\n for (uint256 j = 0; j < sells[i].tokenIds.length; j++) {\n ERC721(sells[i].nft).safeTransferFrom(msg.sender, address(this), sells[i].tokenIds[j]);\n }\n\n // approve the pair to transfer NFTs from the router\n ERC721(sells[i].nft).setApprovalForAll(sells[i].pool, true);\n\n if (sells[i].isPublicPool) {\n // exceute the sell against a public pool\n uint256 outputAmount = Pair(sells[i].pool).nftSell(\n sells[i].tokenIds,\n 0,\n 0,\n sells[i].publicPoolProofs,\n // ReservoirOracle.Message[] is the exact same as IStolenNftOracle.Message[] and can be\n // decoded/encoded 1-to-1.\n abi.decode(abi.encode(sells[i].stolenNftProofs), (ReservoirOracle.Message[]))\n );\n\n // pay the royalties if seller has opted-in\n if (payRoyalties) {\n uint256 salePrice = outputAmount / sells[i].tokenIds.length;\n for (uint256 j = 0; j < sells[i].tokenIds.length; j++) {\n // get the royalty fee and recipient\n (uint256 royaltyFee, address royaltyRecipient) =\n getRoyalty(sells[i].nft, sells[i].tokenIds[j], salePrice);\n\n if (royaltyFee > 0) {\n // transfer the royalty fee to the royalty recipient\n royaltyRecipient.safeTransferETH(royaltyFee);\n }\n }\n }\n } else {\n // execute the sell against a private pool\n PrivatePool(sells[i].pool).sell(\n sells[i].tokenIds, sells[i].tokenWeights, sells[i].proof, sells[i].stolenNftProofs\n );\n }\n }\n\n // check that the output amount is greater than the minimum\n if (address(this).balance < minOutputAmount) {\n revert OutputAmountTooSmall();\n }\n\n // transfer the output amount to the caller\n msg.sender.safeTransferETH(address(this).balance);\n }",
"tokens": {
"summary": 295,
"content": 667
}
},
"Private Pool Deposit": {
"title": "Private Pool Deposit",
"summary": "The given code snippet is a function called `deposit` that allows a user to deposit Non-Fungible Tokens (NFTs) and Ether (ETH) into a private pool. The function takes the following parameters:\n\n1. `privatePool`: The address of the private pool to deposit to.\n2. `nft`: The contract address of the NFT.\n3. `tokenIds`: An array of token IDs of the NFTs to be deposited.\n4. `minPrice`: The minimum price of the pool. The function will revert if the pool's price is smaller than this value.\n5. `maxPrice`: The maximum price of the pool. The function will revert if the pool's price is greater than this value.\n6. `deadline`: The deadline for the transaction to be mined. The function will revert if the current timestamp is greater than the deadline. If set to 0, the deadline will be ignored.\n\nThe function first checks if the deadline has passed (if any) and reverts with a `DeadlinePassed` error if the condition is met. Next, it checks if the pool's price is within the specified range (between `minPrice` and `maxPrice`) and reverts with a `PriceOutOfRange` error if the condition is not met.\n\nThe function then transfers the specified NFTs from the caller to the contract address using the `safeTransferFrom` function of the ERC721 standard. After that, it approves the private pool to transfer NFTs from the router by calling the `setApprovalForAll` function of the ERC721 standard.\n\nFinally, the function executes the deposit by calling the `deposit` function of the `PrivatePool` contract, passing the `tokenIds` array and the Ether value sent with the transaction.",
"content": "/// @notice Executes a deposit to a private pool (transfers NFTs and ETH to the pool).\n /// @param privatePool The private pool to deposit to.\n /// @param nft The NFT contract address.\n /// @param tokenIds The token IDs of the NFTs to deposit.\n /// @param minPrice The minimum price of the pool. Will revert if price is smaller than this.\n /// @param maxPrice The maximum price of the pool. Will revert if price is greater than this.\n /// @param deadline The deadline for the transaction to be mined. Will revert if timestamp is greater than deadline.\n /// Set to 0 for deadline to be ignored.\n function deposit(\n address payable privatePool,\n address nft,\n uint256[] calldata tokenIds,\n uint256 minPrice,\n uint256 maxPrice,\n uint256 deadline\n ) public payable {\n // check deadline has not passed (if any)\n if (block.timestamp > deadline && deadline != 0) {\n revert DeadlinePassed();\n }\n\n // check pool price is in between min and max\n uint256 price = PrivatePool(privatePool).price();\n if (price > maxPrice || price < minPrice) {\n revert PriceOutOfRange();\n }\n\n // transfer NFTs from caller\n for (uint256 i = 0; i < tokenIds.length; i++) {\n ERC721(nft).safeTransferFrom(msg.sender, address(this), tokenIds[i]);\n }\n\n // approve pair to transfer NFTs from router\n ERC721(nft).setApprovalForAll(privatePool, true);\n\n // execute deposit\n PrivatePool(privatePool).deposit{value: msg.value}(tokenIds, msg.value);\n }",
"tokens": {
"summary": 361,
"content": 368
}
},
"Pool Change Execution": {
"title": "Pool Change Execution",
"summary": "The given code snippet is a Solidity function called `change` that executes a series of change operations against a private pool in a decentralized application. The function takes two input parameters: an array of `Change` objects called `changes` and a `deadline` represented as a uint256.\n\nThe function first checks if the deadline has passed by comparing the current block timestamp with the given deadline. If the deadline has passed and is not set to 0 (which means it should be ignored), the function reverts with a `DeadlinePassed` error.\n\nNext, the function iterates through the `changes` array and processes each change operation. For each change, it transfers the input NFTs (Non-Fungible Tokens) from the caller to the contract's address using the `safeTransferFrom` function of the ERC721 standard. It then approves the private pool to transfer NFTs from the router by calling the `setApprovalForAll` function of the ERC721 standard.\n\nThe function then executes the change operation by calling the `change` function of the `PrivatePool` contract, passing in the necessary parameters such as input and output token IDs, weights, and proofs.\n\nAfter the change operation is executed, the function transfers the output NFTs back to the caller using the `safeTransferFrom` function of the ERC721 standard.\n\nFinally, if there is any remaining ETH balance in the contract, it is refunded to the caller using the `safeTransferETH` function.",
"content": "/// @notice Executes a series of change operations against a private pool.\n /// @param changes The change operations to execute.\n /// @param deadline The deadline for the transaction to be mined. Will revert if timestamp is greater than deadline.\n /// Set to 0 for deadline to be ignored.\n function change(Change[] calldata changes, uint256 deadline) public payable {\n // check deadline has not passed (if any)\n if (block.timestamp > deadline && deadline != 0) {\n revert DeadlinePassed();\n }\n\n // loop through and execute the changes\n for (uint256 i = 0; i < changes.length; i++) {\n Change memory _change = changes[i];\n\n // transfer NFTs from caller\n for (uint256 j = 0; j < changes[i].inputTokenIds.length; j++) {\n ERC721(_change.nft).safeTransferFrom(msg.sender, address(this), _change.inputTokenIds[j]);\n }\n\n // approve pair to transfer NFTs from router\n ERC721(_change.nft).setApprovalForAll(_change.pool, true);\n\n // execute change\n PrivatePool(_change.pool).change{value: msg.value}(\n _change.inputTokenIds,\n _change.inputTokenWeights,\n _change.inputProof,\n _change.stolenNftProofs,\n _change.outputTokenIds,\n _change.outputTokenWeights,\n _change.outputProof\n );\n\n // transfer NFTs to caller\n for (uint256 j = 0; j < changes[i].outputTokenIds.length; j++) {\n ERC721(_change.nft).safeTransferFrom(address(this), msg.sender, _change.outputTokenIds[j]);\n }\n }\n\n // refund any surplus ETH to the caller\n if (address(this).balance > 0) {\n msg.sender.safeTransferETH(address(this).balance);\n }\n }",
"tokens": {
"summary": 299,
"content": 402
}
},
"Royalty Fee Recipient": {
"title": "Royalty Fee Recipient",
"summary": "The given content is a function definition in a smart contract, written in Solidity programming language, for a blockchain-based application. The function is named `getRoyalty` and its purpose is to calculate the royalty fee and identify the recipient for a given Non-Fungible Token (NFT) and its sale price. The function retrieves the royalty information from the manifold registry.\n\nThe function accepts three input parameters:\n\n1. `address nft`: The address of the NFT contract.\n2. `uint256 tokenId`: The unique identifier of the NFT.\n3. `uint256 salePrice`: The sale price of the NFT.\n\nThe function returns two output values:\n\n1. `uint256 royaltyFee`: The calculated royalty fee to be paid.\n2. `address recipient`: The address of the recipient who will receive the royalty fee.\n\nThe function is marked as `public` and `view`, which means it can be called by any external entity and does not modify the state of the contract.\n\nInside the function, the first step is to get the royalty lookup address by calling the `getRoyaltyLookupAddress` function of the `IRoyaltyRegistry` interface, passing the NFT contract address as an argument. The `royaltyRegistry` variable is used to store the address of the royalty registry contract.\n\nThe function then returns the calculated royalty fee and the recipient address based on the information retrieved from the manifold registry.",
"content": "/// @notice Gets the royalty and recipient for a given NFT and sale price. Looks up the royalty info from the\n /// manifold registry.\n /// @param tokenId The token ID of the NFT.\n /// @param salePrice The sale price of the NFT.\n /// @return royaltyFee The royalty fee to pay.\n /// @return recipient The address to pay the royalty fee to.\n function getRoyalty(address nft, uint256 tokenId, uint256 salePrice)\n public\n view\n returns (uint256 royaltyFee, address recipient)\n {\n // get the royalty lookup address\n address lookupAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(nft);",
"tokens": {
"summary": 287,
"content": 150
}
},
"Royalty Fee Validation": {
"title": "Royalty Fee Validation",
"summary": "The given code snippet is written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. It checks if a specific contract, identified by its address (lookupAddress), supports the ERC-2981 interface, which is a standard for handling royalties in Non-Fungible Tokens (NFTs). If the contract supports this interface, the code retrieves the royalty information for a specific token (tokenId) at a given sale price (salePrice) and checks if the royalty fee is valid.\n\n1. The first line checks if the contract at the lookupAddress supports the ERC-2981 interface by calling the supportsInterface function with the interfaceId of the IERC2981 type. If the contract supports the interface, the code proceeds to the next step.\n\n2. The second line retrieves the royalty information for the specified tokenId and salePrice by calling the royaltyInfo function of the IERC2981 interface. The function returns two values: the recipient of the royalty fee (recipient) and the amount of the royalty fee (royaltyFee).\n\n3. The third line checks if the royaltyFee is greater than the salePrice. If it is, the code reverts the transaction and throws an InvalidRoyaltyFee error. This ensures that the royalty fee cannot be higher than the sale price of the token.\n\n4. If the royalty fee is valid, the code proceeds with the rest of the smart contract logic (not shown in the snippet).\n\nIn summary, this code snippet is used to verify if a contract supports the ERC-2981 royalty standard, retrieve the royalty information for a specific NFT, and ensure that the royalty fee is valid before proceeding with the rest of the smart contract logic.",
"content": "if (IERC2981(lookupAddress).supportsInterface(type(IERC2981).interfaceId)) {\n // get the royalty fee from the registry\n (recipient, royaltyFee) = IERC2981(lookupAddress).royaltyInfo(tokenId, salePrice);\n\n // revert if the royalty fee is greater than the sale price\n if (royaltyFee > salePrice) revert InvalidRoyaltyFee();\n }\n }\n}",
"tokens": {
"summary": 343,
"content": 92
}
}
}
},
"spearbot-node/put_files_to_audit_here/solidity/Factory.sol": {
"filename": "spearbot-node/put_files_to_audit_here/solidity/Factory.sol",
"globalSummary": "The Caviar Private Pool Factory is a smart contract used to create and initialize new private pools. Each time a private pool is created, an NFT representing that pool is minted to the creator. The contract also handles protocol fees, which accrue to the contract and can be withdrawn by the admin. The Factory contract uses the minimal proxy pattern to deploy private pool clones, and allows for setting and updating private pool metadata, implementation contracts, and protocol fee rates. Additionally, it provides functionality for withdrawing earned protocol fees and predicting deployment addresses of new private pools.",
"chunkedSummaries": {
"Caviar Pool Factory": {
"title": "Caviar Pool Factory",
"summary": "The Caviar Private Pool Factory is a smart contract that facilitates the creation and initialization of new private pools. It is an ERC721 contract, which means that each time a private pool is created, a unique non-fungible token (NFT) is minted and assigned to the creator of the pool. The contract also handles the accumulation of protocol fees, which can be withdrawn by the admin.\n\nThe Factory contract utilizes the LibClone library for cloning the private pool implementation, and the SafeTransferLib library for safely transferring tokens. It has two main events: Create and Withdraw. The Create event is emitted when a new private pool is created, and it includes the private pool's address, token IDs, and the base token amount. The Withdraw event is emitted when the admin withdraws tokens from the contract, and it includes the token's address and the withdrawn amount.\n\nThe contract has a public variable, privatePoolImplementation, which stores the address of the private pool implementation that proxies point to. This allows for easy upgrades and modifications to the private pool implementation without affecting the existing private pools.",
"content": "/// @title Caviar Private Pool Factory\n/// @author out.eth (@outdoteth)\n/// @notice This contract is used to create and initialize new private pools. Each time a private pool is created, a new\n/// NFT representing that private pool is minted to the creator. All protocol fees also accrue to this contract and can\n/// be withdrawn by the admin.\ncontract Factory is ERC721, Owned {\n using LibClone for address;\n using SafeTransferLib for address;\n\n event Create(address indexed privatePool, uint256[] tokenIds, uint256 baseTokenAmount);\n event Withdraw(address indexed token, uint256 indexed amount);\n\n /// @notice The address of the private pool implementation that proxies point to.\n address public privatePoolImplementation;",
"tokens": {
"summary": 219,
"content": 157
}
},
"Private Pool Metadata": {
"title": "Private Pool Metadata",
"summary": "The given code snippet is a Solidity function named `setPrivatePoolMetadata` that sets the address of a private pool metadata contract. This function is part of a smart contract and can only be executed by the contract owner, as indicated by the `onlyOwner` modifier.\n\nThe function takes one input parameter, `_privatePoolMetadata`, which is an address representing the private pool metadata contract. Inside the function, the value of the `_privatePoolMetadata` parameter is assigned to the `privatePoolMetadata` state variable, effectively updating the address of the private pool metadata contract.\n\nThe `@notice` and `@param` comments above the function provide a brief description of the function's purpose and its input parameter, respectively. These comments are part of the NatSpec documentation format, which is used to generate human-readable descriptions of Solidity code.",
"content": "/// @notice Sets private pool metadata contract.\n /// @param _privatePoolMetadata The private pool metadata contract.\n function setPrivatePoolMetadata(address _privatePoolMetadata) public onlyOwner {\n privatePoolMetadata = _privatePoolMetadata;\n }",
"tokens": {
"summary": 169,
"content": 51
}
},
"Caviar Private Pools": {
"title": "Caviar Private Pools",
"summary": "The given content is a Solidity code snippet representing a constructor function and a receive function for a smart contract. This smart contract is based on the Ethereum blockchain and utilizes the ERC721 standard for non-fungible tokens (NFTs). The constructor function initializes the contract with a name, a symbol, and an owner, while the receive function allows the contract to accept Ether payments.\n\n1. Constructor function:\n The constructor function is defined with the keyword 'constructor()'. It is a special function that is executed only once when the smart contract is deployed on the Ethereum blockchain. In this case, the constructor function takes no arguments.\n\n Inside the constructor, there are three main components:\n\n a. ERC721: This is a standard interface for non-fungible tokens (NFTs) on the Ethereum blockchain. The constructor initializes the contract with the given name \"Caviar Private Pools\" and symbol \"POOL\". This means that the NFTs created by this contract will have this name and symbol associated with them.\n\n b. Owned: This is a contract modifier that ensures that only the owner of the contract can execute certain functions. In this case, the constructor sets the owner of the contract to be the address that deploys the contract (msg.sender). This means that only the deployer of the contract will have control over certain functions, as defined by the Owned modifier.\n\n2. Receive function:\n The receive function is defined with the keyword 'receive()' and the 'external payable' modifier. This function allows the smart contract to accept Ether payments directly to its address. The 'external' keyword means that this function can only be called from outside the contract, while the 'payable' keyword allows the function to receive Ether.\n\n In this case, the receive function is empty, meaning that it does not perform any specific actions when Ether is sent to the contract's address. However, the contract can still store the received Ether and use it for various purposes, as defined by other functions in the contract.",
"content": "constructor() ERC721(\"Caviar Private Pools\", \"POOL\") Owned(msg.sender) {}\n\n receive() external payable {}",
"tokens": {
"summary": 409,
"content": 26
}
},
"Private Pool Creation": {
"title": "Private Pool Creation",
"summary": "The `create` function is used to create a new private pool using the minimal proxy pattern that points to the private pool implementation. The caller must approve the factory to transfer the NFTs that will be deposited to the pool. The function takes several parameters, including the base token address, NFT address, virtual base token reserves, virtual NFT reserves, change fee, fee rate, Merkle root, whether to use the stolen NFT oracle, whether to pay royalties, salt, token IDs, and the base token amount.\n\nThe function first checks if the `msg.value` is equal to the base token amount if the base token is ETH or if the `msg.value` is equal to zero if the base token is not ETH. If the condition is not met, it reverts with an `InvalidEthAmount` error.\n\nNext, the function deploys a minimal proxy clone of the private pool implementation and mints the NFT to the caller. It then initializes the pool with the provided parameters.\n\nIf the base token is ETH, the function transfers ETH into the pool. Otherwise, it deposits the base tokens from the caller into the pool. It then deposits the NFTs from the caller into the pool.\n\nFinally, the function emits a `Create` event with the private pool address, token IDs, and base token amount. The function returns the address of the created private pool.",
"content": "/// @notice Creates a new private pool using the minimal proxy pattern that points to the private pool\n /// implementation. The caller must approve the factory to transfer the NFTs that will be deposited to the pool.\n /// @param _baseToken The address of the base token.\n /// @param _nft The address of the NFT.\n /// @param _virtualBaseTokenReserves The virtual base token reserves.\n /// @param _virtualNftReserves The virtual NFT reserves.\n /// @param _changeFee The change fee.\n /// @param _feeRate The fee rate.\n /// @param _merkleRoot The merkle root.\n /// @param _useStolenNftOracle Whether to use the stolen NFT oracle.\n /// @param _salt The salt that will used on deployment.\n /// @param tokenIds The token ids to deposit to the pool.\n /// @param baseTokenAmount The amount of base tokens to deposit to the pool.\n /// @return privatePool The address of the private pool.\n function create(\n address _baseToken,\n address _nft,\n uint128 _virtualBaseTokenReserves,\n uint128 _virtualNftReserves,\n uint56 _changeFee,\n uint16 _feeRate,\n bytes32 _merkleRoot,\n bool _useStolenNftOracle,\n bool _payRoyalties,\n bytes32 _salt,\n uint256[] memory tokenIds, // put in memory to avoid stack too deep error\n uint256 baseTokenAmount\n ) public payable returns (PrivatePool privatePool) {\n // check that the msg.value is equal to the base token amount if the base token is ETH or the msg.value is equal\n // to zero if the base token is not ETH\n if ((_baseToken == address(0) && msg.value != baseTokenAmount) || (_baseToken != address(0) && msg.value > 0)) {\n revert PrivatePool.InvalidEthAmount();\n }\n\n // deploy a minimal proxy clone of the private pool implementation\n privatePool = PrivatePool(payable(privatePoolImplementation.cloneDeterministic(_salt)));\n\n // mint the nft to the caller\n _safeMint(msg.sender, uint256(uint160(address(privatePool))));\n\n // initialize the pool\n privatePool.initialize(\n _baseToken,\n _nft,\n _virtualBaseTokenReserves,\n _virtualNftReserves,\n _changeFee,\n _feeRate,\n _merkleRoot,\n _useStolenNftOracle,\n _payRoyalties\n );\n\n if (_baseToken == address(0)) {\n // transfer eth into the pool if base token is ETH\n address(privatePool).safeTransferETH(baseTokenAmount);\n } else {\n // deposit the base tokens from the caller into the pool\n ERC20(_baseToken).transferFrom(msg.sender, address(privatePool), baseTokenAmount);\n }\n\n // deposit the nfts from the caller into the pool\n for (uint256 i = 0; i < tokenIds.length; i++) {\n ERC721(_nft).safeTransferFrom(msg.sender, address(privatePool), tokenIds[i]);\n }\n\n // emit create event\n emit Create(address(privatePool), tokenIds, baseTokenAmount);\n }",
"tokens": {
"summary": 281,
"content": 702
}
},
"Private Pool Implementation": {
"title": "Private Pool Implementation",
"summary": "The given code snippet is a Solidity function named `setPrivatePoolImplementation` that is used to set the private pool implementation contract address for newly deployed proxies. This function takes an input parameter `_privatePoolImplementation`, which is the address of the private pool implementation contract. The function is marked as `public`, meaning it can be called from any external contract or account, and it has a modifier `onlyOwner`, which restricts the execution of the function to the contract owner only.\n\nInside the function, the private state variable `privatePoolImplementation` is assigned the value of the input parameter `_privatePoolImplementation`. This effectively updates the private pool implementation contract address that will be used by newly deployed proxies.",
"content": "/// @notice Sets the private pool implementation contract that newly deployed proxies point to.\n /// @param _privatePoolImplementation The private pool implementation contract.\n function setPrivatePoolImplementation(address _privatePoolImplementation) public onlyOwner {\n privatePoolImplementation = _privatePoolImplementation;\n }",
"tokens": {
"summary": 141,
"content": 58
}
},
"Set Protocol Fee": {
"title": "Set Protocol Fee",
"summary": "The given code snippet is a Solidity function named `setProtocolFeeRate` that sets the protocol fee rate for a specific smart contract. This function is designed to be called only by the contract owner, as indicated by the `onlyOwner` modifier.\n\nThe protocol fee rate is expressed in basis points, where 1 basis point is equal to 0.01%. For example, a value of 350 basis points represents a 3.5% fee rate. The function takes a single input parameter, `_protocolFeeRate`, which is a 16-bit unsigned integer representing the desired protocol fee rate in basis points.\n\nThe function sets the value of the contract's `protocolFeeRate` state variable to the input parameter `_protocolFeeRate`. This state variable is then used by other functions within the contract to calculate the protocol fee for various operations such as buy, sell, or change.\n\nThe `@notice` and `@param` comments provide additional information about the function's purpose and input parameters, which can be used by developers and tools to generate documentation or provide contextual information while working with the code.",
"content": "/// @notice Sets the protocol fee that is taken on each buy/sell/change. It's in basis points: 350 = 3.5%.\n /// @param _protocolFeeRate The protocol fee.\n function setProtocolFeeRate(uint16 _protocolFeeRate) public onlyOwner {\n protocolFeeRate = _protocolFeeRate;\n }",
"tokens": {
"summary": 223,
"content": 73
}
},
"Withdraw Token Amount": {
"title": "Withdraw Token Amount",
"summary": "The given code snippet is a Solidity function named `withdraw` that allows the owner of a smart contract to withdraw earned protocol fees in the form of a specified token and amount. The function takes two input parameters: `token` (an address representing the token to be withdrawn) and `amount` (a uint256 value representing the amount of tokens to be withdrawn).\n\nThe function has a `public` visibility, meaning it can be called from any external account or contract, and it has a `onlyOwner` modifier, which restricts its execution to the contract owner only.\n\nInside the function, there is a conditional statement that checks if the provided `token` address is equal to the zero address (address(0)). If it is, the function assumes that the withdrawal is for Ether (ETH) and calls the `safeTransferETH` function from the `msg.sender` (the contract owner) with the specified `amount`. If the `token` address is not the zero address, the function assumes that the withdrawal is for an ERC20 token and calls the `transfer` function from the ERC20 token contract with the `msg.sender` and the specified `amount`.\n\nAfter the withdrawal is executed, the function emits an event named `Withdraw` with the `token` and `amount` as its arguments. This event can be used by external services or applications to track and monitor withdrawals from the smart contract.",
"content": "/// @notice Withdraws the earned protocol fees.\n /// @param token The token to withdraw.\n /// @param amount The amount to withdraw.\n function withdraw(address token, uint256 amount) public onlyOwner {\n if (token == address(0)) {\n msg.sender.safeTransferETH(amount);\n } else {\n ERC20(token).transfer(msg.sender, amount);\n }\n\n emit Withdraw(token, amount);\n }",
"tokens": {
"summary": 284,
"content": 88
}
},
"Token URI Function": {
"title": "Token URI Function",
"summary": "The given code snippet is a function named `tokenURI` written in Solidity, which is a programming language used for implementing smart contracts on the Ethereum blockchain. This function is marked as `public`, `view`, and `override`, meaning it can be called from outside the contract, does not modify the contract's state, and overrides a function with the same name in a parent contract.\n\nThe `tokenURI` function takes a single input parameter, `id`, which is a 256-bit unsigned integer representing the token ID. The purpose of this function is to return the token URI associated with the given token ID. A token URI is typically a URL that points to a JSON file containing metadata about the token, such as its name, description, and image.\n\nInside the function, it calls another function named `tokenURI` from a contract named `PrivatePoolMetadata`. The contract address for `PrivatePoolMetadata` is passed as an argument to the function. This suggests that the `PrivatePoolMetadata` contract is responsible for managing the token URIs for the tokens in the private pool.\n\nThe `tokenURI` function in the `PrivatePoolMetadata` contract is expected to return a string in memory, which is then returned by the `tokenURI` function in the current contract. This allows users or other contracts to query the token URI for a specific token ID in the private pool.",
"content": "/// @notice Returns the token URI for a given token id.\n /// @param id The token id.\n /// @return uri The token URI.\n function tokenURI(uint256 id) public view override returns (string memory) {\n return PrivatePoolMetadata(privatePoolMetadata).tokenURI(id);\n }",
"tokens": {
"summary": 279,
"content": 63
}
},
"Predict Pool Address": {
"title": "Predict Pool Address",
"summary": "The given code snippet is a function named `predictPoolDeploymentAddress` that predicts the deployment address of a new private pool in a blockchain-based system. This function takes a single input parameter, `salt`, which is a 32-byte value used during the deployment process. The function returns a single output, `predictedAddress`, which is the predicted deployment address of the private pool.\n\nThe function is marked as `public`, meaning it can be called by any external entity, and `view`, which indicates that it does not modify the state of the blockchain. This function is part of a smart contract, which is a self-executing contract with the terms of the agreement directly written into code.\n\nInside the function, the `predictedAddress` is calculated by calling the `predictDeterministicAddress` function on the `privatePoolImplementation` object, passing the `salt` and the address of the current smart contract instance (represented by `address(this)`) as arguments. The `predictDeterministicAddress` function is responsible for generating the deterministic address based on the provided salt and the current contract address.\n\nIn summary, the `predictPoolDeploymentAddress` function is a public view function that predicts the deployment address of a new private pool using a given salt value. It does so by calling the `predictDeterministicAddress` function on the `privatePoolImplementation` object with the salt and the current contract address as arguments.",
"content": "/// @notice Predicts the deployment address of a new private pool.\n /// @param salt The salt that will used on deployment.\n /// @return predictedAddress The predicted deployment address of the private pool.\n function predictPoolDeploymentAddress(bytes32 salt) public view returns (address predictedAddress) {\n predictedAddress = privatePoolImplementation.predictDeterministicAddress(salt, address(this));\n }\n}",
"tokens": {
"summary": 283,
"content": 81
}
}
}
},
"spearbot-node/put_files_to_audit_here/solidity/IStolenNftOracle.sol": {
"filename": "spearbot-node/put_files_to_audit_here/solidity/IStolenNftOracle.sol",
"globalSummary": "The IStolenNftOracle interface in Solidity defines a structure for messages and a function to validate that a set of token IDs have not been marked as stolen by the oracle. The function takes the token contract address, token IDs, and proofs as input parameters.",
"chunkedSummaries": {
"Stolen NFT Oracle": {
"title": "Stolen NFT Oracle",
"summary": "The given content represents an interface called `IStolenNftOracle` in a programming context, most likely within a blockchain or smart contract environment. An interface is a collection of abstract methods (functions) that can be implemented by any class or contract that chooses to use it. In this case, the interface is specifically designed for handling stolen Non-Fungible Tokens (NFTs) within an oracle system.\n\nAn oracle, in the context of blockchain and smart contracts, is a system that provides external data to smart contracts. This data can be used to trigger specific actions or decisions within the contract. In the case of `IStolenNftOracle`, the oracle would provide information about stolen NFTs, which can be used by other smart contracts or applications to make decisions based on the status of the NFTs.\n\nThe `IStolenNftOracle` interface does not provide any implementation details or specific methods. However, it serves as a blueprint for developers to create their own implementations of the interface, which would include methods for querying and updating the oracle with information about stolen NFTs.\n\nSome possible methods that could be included in an implementation of the `IStolenNftOracle` interface are:\n\n1. `isStolen`: A method that takes an NFT identifier as input and returns a boolean value indicating whether the NFT is marked as stolen in the oracle.\n\n2. `reportStolen`: A method that allows users to report an NFT as stolen by providing its identifier and additional information, such as the theft date and the original owner's address.\n\n3. `removeStolen`: A method that allows authorized users (e.g., the original owner or an administrator) to remove an NFT from the list of stolen NFTs in the oracle.\n\n4. `getStolenNftData`: A method that retrieves detailed information about a stolen NFT, such as its identifier, theft date, and original owner's address.\n\nBy implementing the `IStolenNftOracle` interface, developers can create a standardized way for smart contracts and applications to interact with an oracle that provides information about stolen NFTs. This can help improve the security and transparency of NFT marketplaces and other platforms that deal with NFTs.",
"content": "interface IStolenNftOracle {",
"tokens": {
"summary": 458,
"content": 8
}
},
"Message Signature Timestamp": {
"title": "Message Signature Timestamp",
"summary": "The given content is a Solidity code snippet that defines a struct called \"Message\" within a smart contract. Solidity is a programming language used for writing smart contracts on the Ethereum blockchain.\n\nThe \"Message\" struct consists of four fields:\n\n1. `id`: A bytes32 variable that represents the unique identifier of the message. The `bytes32` type is an array of 32 bytes, which is commonly used for storing fixed-size hashes or other data that needs to be compact and efficient.\n\n2. `payload`: A bytes variable that holds the actual content of the message. The `bytes` type is a dynamically-sized byte array, which means it can store an arbitrary amount of data.\n\n3. `timestamp`: A uint256 variable that stores the UNIX timestamp when the message was signed by the oracle. The `uint256` type is an unsigned 256-bit integer, which can store large numbers and is commonly used for timestamps and other numerical data in smart contracts.\n\n4. `signature`: A bytes variable that contains the ECDSA signature or EIP-2098 compact signature of the message. This signature is used to verify the authenticity of the message, ensuring that it was indeed signed by the oracle and has not been tampered with.\n\nIn summary, the \"Message\" struct is a data structure used to store information about a message signed by an oracle in a smart contract. It includes a unique identifier, the message payload, a timestamp indicating when the message was signed, and a cryptographic signature to ensure the message's authenticity.",
"content": "// copied from https://github.com/reservoirprotocol/oracle/blob/main/contracts/ReservoirOracle.sol\n struct Message {\n bytes32 id;\n bytes payload;\n // The UNIX timestamp when the message was signed by the oracle\n uint256 timestamp;\n // ECDSA signature or EIP-2098 compact signature\n bytes signature;\n }",
"tokens": {
"summary": 309,
"content": 74
}
},
"Validate Not Stolen": {
"title": "Validate Not Stolen",
"summary": "The given content describes a function called `validateTokensAreNotStolen` in a smart contract. This function is responsible for validating that a set of token ids have not been marked as stolen by an oracle. An oracle is an external data source that provides information to smart contracts.\n\nThe function takes three input parameters:\n\n1. `tokenAddress`: This is the address of the token contract, which is a unique identifier for the token on the blockchain.\n2. `tokenIds`: This is an array of token ids that need to be validated. Each token id is a unique identifier for a specific token.\n3. `proofs`: This is an array of `Message` objects, which are the proofs that the token ids have not been marked as stolen. These proofs are signed messages from the oracle.\n\nThe function is marked as `external`, which means it can only be called from outside the smart contract. The purpose of this function is to check the signed messages from the oracle to ensure that the given token ids have not been marked as stolen. This validation process is crucial for maintaining the integrity and security of the token ecosystem.",
"content": "/// @notice Validates that a set of token ids have not been marked as stolen by the oracle.\n /// @dev Check a signed message from the oracle to ensure that the token ids have not been marked as stolen.\n /// @param tokenAddress The address of the token contract.\n /// @param tokenIds The token ids to validate.\n /// @param proofs The proofs that the token ids have not been marked as stolen.\n function validateTokensAreNotStolen(address tokenAddress, uint256[] calldata tokenIds, Message[] calldata proofs)\n external;\n}",
"tokens": {
"summary": 226,
"content": 117
}
}
}
},
"spearbot-node/put_files_to_audit_here/solidity/PrivatePool.sol": {
"filename": "spearbot-node/put_files_to_audit_here/solidity/PrivatePool.sol",
"globalSummary": "The Private Pool is a single-owner, customizable NFT Automated Market Maker (AMM) smart contract that offers concentrated liquidity, custom fee rates, stolen NFT filtering, custom NFT weightings, royalty support, and flash loans. Users can create a pool, deposit NFTs and base tokens, enable trading, and earn fees on each trade. The contract includes functions for buying, selling, depositing, and withdrawing NFTs, as well as setting virtual reserves, fee rates, and other configurations. It also supports royalty payments to NFT creators and checks for stolen NFTs using an oracle. The code defines functions for calculating fees, input and output amounts, and prices for buying, selling, and changing NFTs in a pool, as well as handling flash loans for NFTs.",
"chunkedSummaries": {
"OpenZeppelin Solmate Interface": {
"title": "OpenZeppelin Solmate Interface",
"summary": "The content provided is a code snippet written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. The code imports various libraries and interfaces that are commonly used in the development of smart contracts.\n\n1. `import {IERC2981} from \"openzeppelin/interfaces/IERC2981.sol\";`: This line imports the IERC2981 interface from the OpenZeppelin library. IERC2981 is an interface for the ERC-2981 standard, which is a royalty standard for Non-Fungible Tokens (NFTs). It allows NFT creators to receive royalties for secondary sales of their tokens.\n\n2. The ASCII art included in the code snippet is a decorative element and does not have any functional impact on the code.\n\n3. `import {ERC20} from \"solmate/tokens/ERC20.sol\";`: This line imports the ERC20 token implementation from the Solmate library. ERC20 is a widely-used standard for creating and managing fungible tokens on the Ethereum blockchain.\n\n4. `import {ERC721, ERC721TokenReceiver} from \"solmate/tokens/ERC721.sol\";`: This line imports the ERC721 token implementation and the ERC721TokenReceiver interface from the Solmate library. ERC721 is a standard for creating and managing non-fungible tokens (NFTs) on the Ethereum blockchain, while the ERC721TokenReceiver interface is used to ensure that a contract can correctly handle ERC721 tokens.\n\n5. `import {FixedPointMathLib} from \"solmate/utils/FixedPointMathLib.sol\";`: This line imports the FixedPointMathLib library from the Solmate library. FixedPointMathLib is a utility library that provides functions for performing fixed-point arithmetic operations, which are useful for handling decimal numbers in smart contracts.\n\n6. `import {SafeTransferLib} from \"solmate/utils/SafeTransferLib.sol\";`: This line imports the SafeTransferLib library from the Solmate library. SafeTransferLib is a utility library that provides functions for safely transferring ERC20 and ERC721 tokens, preventing common issues such as reentrancy attacks and improperly handling token transfers.\n\n7. `import {MerkleProofLib} from \"solady/utils/MerkleProofLib.sol\";`: This line imports the MerkleProofLib library from the Solady library. MerkleProofLib is a utility library that provides functions for working with Merkle proofs, which are used to verify the membership of an element in a Merkle tree. This is useful for various applications, such as verifying the authenticity of data or proving the ownership of a token.",
"content": "import {IERC2981} from \"openzeppelin/interfaces/IERC2981.sol\";* ____\n * /\\| ~~\\\n * /' | ,-. `\\\n * | | X | |\n * _|________`-' |X\n * /' ~~~~~~~~~,\n * /' ,_____,/_\n * ,/' ___,'~~ ;\n * ~~~~~~~~|~~~~~~~|--- / X,~~~~~~~~~~~~,\n * | | | XX'____________'\n * | | /' XXX| ;\n * | | --x| XXX,~~~~~~~~~~~~,\n * | | X| '____________'\n * | o |---~~~~\\__XX\\ |XX\n * | | XXX`\\ /XXXX\n * ~~~~~~~~'~~~~~~~' `\\xXXXXx/' \\XXX\n * /XXXXXX\\\n * /XXXXXXXXXX\\\n * /XXXXXX/^\\XXXXX\\\n * ~~~~~~~~ ~~~~~~~\n */\n\nimport {ERC20} from \"solmate/tokens/ERC20.sol\";\nimport {ERC721, ERC721TokenReceiver} from \"solmate/tokens/ERC721.sol\";\nimport {FixedPointMathLib} from \"solmate/utils/FixedPointMathLib.sol\";\nimport {SafeTransferLib} from \"solmate/utils/SafeTransferLib.sol\";\nimport {MerkleProofLib} from \"solady/utils/MerkleProofLib.sol\";",
"tokens": {
"summary": 530,
"content": 334
}
},
"Royalty Registry Interface": {
"title": "Royalty Registry Interface",
"summary": "The given content is a code snippet written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. This code snippet imports two interfaces, IERC2981 and IRoyaltyRegistry, from their respective source files.\n\n1. IERC2981: This interface is imported from the OpenZeppelin library, a widely-used framework for secure smart contract development. IERC2981 is an interface for the ERC-2981 standard, which is a proposed standard for handling royalty payments for Non-Fungible Tokens (NFTs) on the Ethereum blockchain. The ERC-2981 standard aims to provide a consistent way for NFT creators to receive royalties whenever their NFTs are sold or transferred. By implementing this interface, a smart contract can support royalty payments according to the ERC-2981 standard.\n\n2. IRoyaltyRegistry: This interface is imported from the Royalty Registry Solidity library, which is a collection of smart contracts and interfaces designed to manage royalty payments for NFTs. The IRoyaltyRegistry interface provides a set of functions that allow a smart contract to interact with a royalty registry, which is a central repository for storing and managing royalty information for NFTs. By implementing this interface, a smart contract can query and update royalty information for NFTs in a standardized and efficient manner.\n\nIn summary, this code snippet imports two interfaces related to royalty management for NFTs on the Ethereum blockchain. The IERC2981 interface provides a standard for handling royalty payments, while the IRoyaltyRegistry interface allows for interaction with a central registry for managing royalty information. Implementing these interfaces in a smart contract enables support for consistent and efficient royalty management for NFT creators and owners.",
"content": "import {IERC2981} from \"openzeppelin/interfaces/IERC2981.sol\";\nimport {IRoyaltyRegistry} from \"royalty-registry-solidity/IRoyaltyRegistry.sol\";",
"tokens": {
"summary": 347,
"content": 42
}
},
"ERC3156 Flash Interface": {
"title": "ERC3156 Flash Interface",
"summary": "The given content is a single line of code that imports the `IERC3156FlashBorrower` interface from the OpenZeppelin library's `IERC3156FlashLender.sol` file. This line of code is written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain.\n\nOpenZeppelin is a widely-used library of secure and audited smart contract components for the Ethereum platform. It provides developers with reusable components to build decentralized applications, ensuring that the code is secure and follows best practices.\n\nThe `IERC3156FlashBorrower` interface is part of the ERC-3156 standard, which defines a common interface for flash loans. Flash loans are a feature in decentralized finance (DeFi) that allows users to borrow assets without collateral for a very short period, typically within a single transaction. The borrowed assets must be returned within the same transaction, or the transaction will be reverted. This feature is useful for various use cases, such as arbitrage, collateral swapping, and self-liquidation.\n\nBy importing the `IERC3156FlashBorrower` interface, the developer can implement the required functions in their smart contract to interact with flash loan providers that follow the ERC-3156 standard. This ensures compatibility and interoperability between different flash loan providers and borrowers in the DeFi ecosystem.",
"content": "import {IERC3156FlashBorrower} from \"openzeppelin/interfaces/IERC3156FlashLender.sol\";",
"tokens": {
"summary": 272,
"content": 27
}
},
"Stolen NFT Oracle": {
"title": "Stolen NFT Oracle",
"summary": "The given code snippet is a Solidity function named `setUseStolenNftOracle` that is used to set the flag for using a stolen NFT oracle in a smart contract. This function can only be called by the owner of the pool, as indicated by the `onlyOwner` modifier.\n\nThe stolen NFT oracle is a mechanism that checks if a given NFT (Non-Fungible Token) is stolen or not. The function takes a boolean parameter `newUseStolenNftOracle`, which represents the new flag value for using the stolen NFT oracle.\n\nInside the function, the `useStolenNftOracle` state variable is assigned the value of the `newUseStolenNftOracle` parameter. This updates the flag for using the stolen NFT oracle in the smart contract.\n\nAfter updating the flag, the function emits an event called `SetUseStolenNftOracle` with the new flag value as its argument. This event can be used by external systems or applications to track changes in the use of the stolen NFT oracle.",
"content": "/// @notice Sets the whether or not to use the stolen NFT oracle. Can only be called by the owner of the pool. The\n /// stolen NFT oracle is used to check if an NFT is stolen.\n /// @param newUseStolenNftOracle The new use stolen NFT oracle flag.\n function setUseStolenNftOracle(bool newUseStolenNftOracle) public onlyOwner {\n // set the use stolen NFT oracle flag\n useStolenNftOracle = newUseStolenNftOracle;\n\n // emit the set use stolen NFT oracle event\n emit SetUseStolenNftOracle(newUseStolenNftOracle);\n }",
"tokens": {
"summary": 217,
"content": 146
}
},
"Private Pool NFT": {
"title": "Private Pool NFT",
"summary": "The PrivatePool contract is an NFT Automated Market Maker (AMM) controlled by a single owner with features such as concentrated liquidity, custom fee rates, stolen NFT filtering, custom NFT weightings, royalty support, and flash loans. Users can create a pool and modify its parameters according to their preferences. Depositing NFTs and base tokens (or ETH) into the pool enables trading, and users can earn fees on each trade.\n\nThe contract includes events for initializing the pool, buying and selling NFTs, depositing and withdrawing tokens, changing NFTs, and setting various parameters such as virtual reserves, Merkle root, fee rate, stolen NFT oracle usage, and royalty payments.\n\nThe PrivatePool contract stores information about the base ERC20 token, the NFT address, change/flash fee, buy/sell fee rate, initialization status, royalty payment status, stolen NFT oracle usage, virtual base token reserves, virtual NFT reserves, Merkle root, and the stolen NFT oracle address.\n\nThe contract checks for errors such as unauthorized access, invalid ETH amounts, invalid Merkle proofs, insufficient input weight, high fee rates, unavailability for flash loans, failed flash loans, and invalid royalty fees.\n\nThe contract allows users to set virtual reserves for base tokens and NFTs, which affect the liquidity depth and price of the pool. Users can also set the Merkle root for custom NFT weightings, and enable or disable the use of a stolen NFT oracle and royalty payments.",
"content": "/// @title Private Pool\n/// @author out.eth (@outdoteth)\n/// @notice A private pool is a an NFT AMM controlled by a single owner with concentrated liquidity, custom fee rates,\n/// stolen NFT filtering, custom NFT weightings, royalty support, and flash loans. You can create a pool and change\n/// these parameters to your liking. Deposit NFTs and base tokens (or ETH) into the pool to enable trading. Earn fees on\n/// each trade.\ncontract PrivatePool is ERC721TokenReceiver {\n using SafeTransferLib for address payable;\n using SafeTransferLib for address;\n using SafeTransferLib for ERC20;\n\n /// @notice Merkle proof input for a sparse merkle multi proof. It can be generated with a library like:\n /// https://github.com/OpenZeppelin/merkle-tree#treegetmultiproof\n struct MerkleMultiProof {\n bytes32[] proof;\n bool[] flags;\n }\n\n // forgefmt: disable-start\n event Initialize(address indexed baseToken, address indexed nft, uint128 virtualBaseTokenReserves, uint128 virtualNftReserves, uint56 changeFee, uint16 feeRate, bytes32 merkleRoot, bool useStolenNftOracle, bool payRoyalties);\n event Buy(uint256[] tokenIds, uint256[] tokenWeights, uint256 inputAmount, uint256 feeAmount, uint256 protocolFeeAmount, uint256 royaltyFeeAmount);\n event Sell(uint256[] tokenIds, uint256[] tokenWeights, uint256 outputAmount, uint256 feeAmount, uint256 protocolFeeAmount, uint256 royaltyFeeAmount);\n event Deposit(uint256[] tokenIds, uint256 baseTokenAmount);\n event Withdraw(address indexed nft, uint256[] tokenIds, address token, uint256 amount);\n event Change(uint256[] inputTokenIds, uint256[] inputTokenWeights, uint256[] outputTokenIds, uint256[] outputTokenWeights, uint256 feeAmount, uint256 protocolFeeAmount);\n event SetVirtualReserves(uint128 virtualBaseTokenReserves, uint128 virtualNftReserves);\n event SetMerkleRoot(bytes32 merkleRoot);\n event SetFeeRate(uint16 feeRate);\n event SetUseStolenNftOracle(bool useStolenNftOracle);\n event SetPayRoyalties(bool payRoyalties);\n // forgefmt: disable-end\n\n error AlreadyInitialized();\n error Unauthorized();\n error InvalidEthAmount();\n error InvalidMerkleProof();\n error InsufficientInputWeight();\n error FeeRateTooHigh();\n error NotAvailableForFlashLoan();\n error FlashLoanFailed();\n error InvalidRoyaltyFee();\n\n /// @notice The address of the base ERC20 token.\n address public baseToken;\n\n /// @notice The address of the nft.\n address public nft;\n\n /// @notice The change/flash fee to 4 decimals of precision. For example, 0.0025 ETH = 25. 500 USDC = 5_000_000.\n uint56 public changeFee;\n\n /// @notice The buy/sell fee rate (in basis points) 200 = 2%\n uint16 public feeRate;\n\n /// @notice Whether or not the pool has been initialized.\n bool public initialized;\n\n /// @notice Whether or not the pool pays royalties to the NFT creator on each trade.\n bool public payRoyalties;\n\n /// @notice Whether or not the pool uses the stolen NFT oracle to check if an NFT is stolen.\n bool public useStolenNftOracle;\n\n /// @notice The virtual base token reserves used in the xy=k invariant. Changing this will change the liquidity\n /// depth and price of the pool.\n uint128 public virtualBaseTokenReserves;\n\n /// @notice The virtual nft reserves used in the xy=k invariant. Changing this will change the liquidity\n /// depth and price of the pool.\n /// @dev The virtual NFT reserves that a user sets. If it's desired to set the reserves to match 16 NFTs then the\n /// virtual reserves should be set to 16e18. If weights are enabled by setting the merkle root to be non-zero then\n /// the virtual reserves should be set to the sum of the weights of the NFTs; where floor NFTs all have a weight of\n /// 1e18. A rarer NFT may have a weight of 2.3e18 if it's 2.3x more valuable than a floor.\n uint128 public virtualNftReserves;\n\n /// @notice The merkle root of all the token weights in the pool. If the merkle root is set to bytes32(0) then all\n /// NFTs are set to have a weight of 1e18.\n bytes32 public merkleRoot;\n\n /// @notice The NFT oracle to check if an NFT is stolen.\n address public immutable stolenNftOracle;",
"tokens": {
"summary": 307,
"content": 1046
}
},
"Factory Contract Creator": {
"title": "Factory Contract Creator",
"summary": "The given content is a snippet of a Solidity smart contract code that defines a factory contract, a royalty registry, a modifier, and a receive function.\n\n1. Factory Contract: The code defines an immutable public payable address named 'factory'. This address represents the factory contract that created the current pool. The 'immutable' keyword indicates that the value of this variable cannot be changed after the contract is deployed.\n\n2. Royalty Registry: The code also defines an immutable public address named 'royaltyRegistry'. This address represents the royalty registry from manifold.xyz, a platform that helps creators manage royalties for their digital assets. Similar to the factory contract, the 'immutable' keyword ensures that the value of this variable cannot be changed after the contract is deployed.\n\n3. Modifier 'onlyOwner': The code defines a modifier named 'onlyOwner' that checks if the sender of the transaction (msg.sender) is the owner of the contract. The owner is determined by calling the 'ownerOf' function from the Factory contract, passing the uint160 representation of the current contract's address as an argument. If the sender is not the owner, the modifier will revert the transaction with an 'Unauthorized' error message. The 'virtual' keyword indicates that this modifier can be overridden in derived contracts.\n\n4. Receive Function: The code includes a receive function, which is an unnamed external payable function that allows the contract to accept Ether payments. This function is automatically called when the contract receives Ether without any data provided.",
"content": "/// @notice The factory contract that created this pool.\n address payable public immutable factory;\n\n /// @notice The royalty registry from manifold.xyz.\n address public immutable royaltyRegistry;\n\n modifier onlyOwner() virtual {\n if (msg.sender != Factory(factory).ownerOf(uint160(address(this)))) {\n revert Unauthorized();\n }\n _;\n }\n\n receive() external payable {}",
"tokens": {
"summary": 299,
"content": 77
}
},
"Immutable Parameters Deployment": {
"title": "Immutable Parameters Deployment",
"summary": "The given code snippet is a constructor function for a smart contract in the Solidity programming language. This constructor is called only when the base implementation contract is deployed. It sets three immutable parameters: factory, royaltyRegistry, and stolenNftOracle. These parameters represent the addresses of the factory contract, the royalty registry from manifold.xyz, and the stolen NFT oracle, respectively.\n\nThe constructor takes three input arguments: _factory, _royaltyRegistry, and _stolenNftOracle, which are the addresses for the respective contracts. Inside the constructor, the factory address is converted to a payable address and assigned to the factory variable. The royaltyRegistry and stolenNftOracle variables are assigned the values of _royaltyRegistry and _stolenNftOracle, respectively.\n\nThese parameters are stored in immutable storage, which allows all minimal proxy contracts to read them without incurring additional deployment costs and re-initializing them at the point of creation in the factory contract. Immutable storage is a feature in Solidity that ensures the values of these variables cannot be changed after the contract is deployed, providing security and efficiency benefits.",
"content": "/// @dev This is only called when the base implementation contract is deployed. The following immutable parameters\n /// are set:\n /// - factory: The address of the factory contract\n /// - royaltyRegistry: The address of the royalty registry from manifold.xyz\n /// - stolenNftOracle: The address of the stolen NFT oracle\n /// These are all stored in immutable storage, which enables all minimal proxy contracts to read them without\n /// incurring additional deployment costs and re-initializing them at point of creation in the factory contract.\n constructor(address _factory, address _royaltyRegistry, address _stolenNftOracle) {\n factory = payable(_factory);\n royaltyRegistry = _royaltyRegistry;\n stolenNftOracle = _stolenNftOracle;\n }",
"tokens": {
"summary": 223,
"content": 164
}
},
"Private Pool Initialization": {
"title": "Private Pool Initialization",
"summary": "The given code snippet is a function named `initialize` that sets up a private pool with its initial parameters. This function should only be called once by the factory. The function takes the following input parameters:\n\n1. `_baseToken`: The address of the base token.\n2. `_nft`: The address of the NFT (Non-Fungible Token).\n3. `_virtualBaseTokenReserves`: The virtual base token reserves.\n4. `_virtualNftReserves`: The virtual NFT reserves.\n5. `_changeFee`: The change fee.\n6. `_feeRate`: The fee rate (in basis points), where 200 equals 2%.\n7. `_merkleRoot`: The Merkle root.\n8. `_useStolenNftOracle`: A boolean value indicating whether the pool uses the stolen NFT oracle to check if an NFT is stolen.\n9. `_payRoyalties`: A boolean value indicating whether to pay royalties.\n\nThe function first checks if the pool has already been initialized, and if so, it reverts with an `AlreadyInitialized` error. It then checks if the fee rate is less than 50% (5,000 basis points), and if not, it reverts with a `FeeRateTooHigh` error.\n\nNext, the function sets the state variables with the input parameters. It marks the pool as initialized and emits an `Initialize` event with the input parameters.\n\nIn summary, the `initialize` function is responsible for setting up a private pool with its initial parameters, ensuring that it is only called once and that the fee rate is within acceptable limits. It also sets the state variables and emits an event to notify listeners of the pool's initialization.",
"content": "/// @notice Initializes the private pool and sets the initial parameters. Should only be called once by the factory.\n /// @param _baseToken The address of the base token\n /// @param _nft The address of the NFT\n /// @param _virtualBaseTokenReserves The virtual base token reserves\n /// @param _virtualNftReserves The virtual NFT reserves\n /// @param _feeRate The fee rate (in basis points) 200 = 2%\n /// @param _merkleRoot The merkle root\n /// @param _useStolenNftOracle Whether or not the pool uses the stolen NFT oracle to check if an NFT is stolen\n function initialize(\n address _baseToken,\n address _nft,\n uint128 _virtualBaseTokenReserves,\n uint128 _virtualNftReserves,\n uint56 _changeFee,\n uint16 _feeRate,\n bytes32 _merkleRoot,\n bool _useStolenNftOracle,\n bool _payRoyalties\n ) public {\n // prevent duplicate initialization\n if (initialized) revert AlreadyInitialized();\n\n // check that the fee rate is less than 50%\n if (_feeRate > 5_000) revert FeeRateTooHigh();\n\n // set the state variables\n baseToken = _baseToken;\n nft = _nft;\n virtualBaseTokenReserves = _virtualBaseTokenReserves;\n virtualNftReserves = _virtualNftReserves;\n changeFee = _changeFee;\n feeRate = _feeRate;\n merkleRoot = _merkleRoot;\n useStolenNftOracle = _useStolenNftOracle;\n payRoyalties = _payRoyalties;\n\n // mark the pool as initialized\n initialized = true;\n\n // emit the event\n emit Initialize(\n _baseToken,\n _nft,\n _virtualBaseTokenReserves,\n _virtualNftReserves,\n _changeFee,\n _feeRate,\n _merkleRoot,\n _useStolenNftOracle,\n _payRoyalties\n );\n }",
"tokens": {
"summary": 347,
"content": 458
}
},
"NFT Pool Purchase": {
"title": "NFT Pool Purchase",
"summary": "The given content describes a function called \"buy\" that allows users to purchase NFTs (Non-Fungible Tokens) from a pool using base tokens. The function takes three parameters: tokenIds, tokenWeights, and proof. The tokenIds are the unique identifiers of the NFTs to be purchased, tokenWeights represent the assigned weights of the NFTs, and proof is the Merkle proof for the weights of each NFT. The function returns three values: netInputAmount, feeAmount, and protocolFeeAmount, which represent the total amount of base tokens spent, the amount spent on fees, and the amount spent on protocol fees, respectively.\n\nThe function starts by performing checks to ensure the validity of the input parameters. It calculates the sum of weights of the NFTs to buy and validates the Merkle proof. It then calculates the required net input amount and fee amount based on the sum of weights. If the base token is not ETH (Ethereum), the function checks that the caller sent 0 ETH and reverts if the condition is not met.\n\nNext, the function updates the virtual reserves by adding the net input amount minus the fee amount and protocol fee amount to the virtual base token reserves and subtracting the sum of weights from the virtual NFT reserves.\n\nIn the interactions section, the function calculates the sale price for each NFT, assuming it's the same for all NFTs even if their weights differ. It then transfers the NFTs to the caller using the ERC721 standard. If the payRoyalties flag is set, the function calculates the royalty fee for each NFT and adds it to the total royalty fee amount. Finally, the royalty fee amount is added to the net input amount.\n\nIf the base token is not ETH, the function transfers the base tokens from the caller to the contract address, and if the fee amount is greater than 0, it transfers the fee amount to the fee recipient.",
"content": "/// @notice Buys NFTs from the pool, paying with base tokens from the caller. Then transfers the bought NFTs to the\n /// caller. The net cost depends on the current price, fee rate and assigned NFT weights.\n /// @dev DO NOT call this function directly unless you know what you are doing. Instead, use a wrapper contract that\n /// will check the max input amount and revert if the slippage is too high.\n /// @param tokenIds The token IDs of the NFTs to buy.\n /// @param tokenWeights The weights of the NFTs to buy.\n /// @param proof The merkle proof for the weights of each NFT to buy.\n /// @return netInputAmount The amount of base tokens spent inclusive of fees.\n /// @return feeAmount The amount of base tokens spent on fees.\n function buy(uint256[] calldata tokenIds, uint256[] calldata tokenWeights, MerkleMultiProof calldata proof)\n public\n payable\n returns (uint256 netInputAmount, uint256 feeAmount, uint256 protocolFeeAmount)\n {\n // ~~~ Checks ~~~ //\n\n // calculate the sum of weights of the NFTs to buy\n uint256 weightSum = sumWeightsAndValidateProof(tokenIds, tokenWeights, proof);\n\n // calculate the required net input amount and fee amount\n (netInputAmount, feeAmount, protocolFeeAmount) = buyQuote(weightSum);\n\n // check that the caller sent 0 ETH if the base token is not ETH\n if (baseToken != address(0) && msg.value > 0) revert InvalidEthAmount();\n\n // ~~~ Effects ~~~ //\n\n // update the virtual reserves\n virtualBaseTokenReserves += uint128(netInputAmount - feeAmount - protocolFeeAmount);\n virtualNftReserves -= uint128(weightSum);\n\n // ~~~ Interactions ~~~ //\n\n // calculate the sale price (assume it's the same for each NFT even if weights differ)\n uint256 salePrice = (netInputAmount - feeAmount - protocolFeeAmount) / tokenIds.length;\n uint256 royaltyFeeAmount = 0;\n for (uint256 i = 0; i < tokenIds.length; i++) {\n // transfer the NFT to the caller\n ERC721(nft).safeTransferFrom(address(this), msg.sender, tokenIds[i]);\n\n if (payRoyalties) {\n // get the royalty fee for the NFT\n (uint256 royaltyFee,) = _getRoyalty(tokenIds[i], salePrice);\n\n // add the royalty fee to the total royalty fee amount\n royaltyFeeAmount += royaltyFee;\n }\n }\n\n // add the royalty fee amount to the net input aount\n netInputAmount += royaltyFeeAmount;\n\n if (baseToken != address(0)) {",
"tokens": {
"summary": 395,
"content": 603
}
},
"Token Transfer Protocol": {
"title": "Token Transfer Protocol",
"summary": "The given code snippet is a part of a smart contract that deals with the transfer of tokens and payment of fees in a decentralized marketplace. The contract uses the ERC20 standard for token transfers and handles both base tokens and Ether (ETH) as payment methods.\n\n1. The first step is to transfer the base token from the caller (msg.sender) to the contract's address. This is done using the safeTransferFrom function of the ERC20 standard.\n\n2. If a protocol fee is set, the contract transfers the fee amount to the factory address using the safeTransfer function of the ERC20 standard.\n\n3. If the base token is not used (i.e., ETH is used for payment), the contract checks if the caller has sent enough ETH to cover the net input amount. If not, it reverts the transaction with an \"InvalidEthAmount\" error.\n\n4. If a protocol fee is set for ETH payments, the contract transfers the fee amount to the factory address using the safeTransferETH function.\n\n5. If the caller has sent more ETH than required, the contract refunds the excess amount to the caller using the safeTransferETH function.\n\n6. If the payRoyalties flag is set, the contract iterates through the tokenIds array and calculates the royalty fee for each NFT using the _getRoyalty function. If the royalty fee is greater than 0 and the recipient address is valid, the contract transfers the royalty fee to the recipient. This is done using the safeTransfer function of the ERC20 standard for base tokens and the safeTransferETH function for ETH payments.\n\n7. Finally, the contract emits a \"Buy\" event with the relevant information, including tokenIds, tokenWeights, netInputAmount, feeAmount, protocolFeeAmount, and royaltyFeeAmount. This event can be used by external applications to track and monitor the transactions happening within the contract.",
"content": "// transfer the base token from the caller to the contract\n ERC20(baseToken).safeTransferFrom(msg.sender, address(this), netInputAmount);\n\n // if the protocol fee is set then pay the protocol fee\n if (protocolFeeAmount > 0) ERC20(baseToken).safeTransfer(address(factory), protocolFeeAmount);\n } else {\n // check that the caller sent enough ETH to cover the net required input\n if (msg.value < netInputAmount) revert InvalidEthAmount();\n\n // if the protocol fee is set then pay the protocol fee\n if (protocolFeeAmount > 0) factory.safeTransferETH(protocolFeeAmount);\n\n // refund any excess ETH to the caller\n if (msg.value > netInputAmount) msg.sender.safeTransferETH(msg.value - netInputAmount);\n }\n\n if (payRoyalties) {\n for (uint256 i = 0; i < tokenIds.length; i++) {\n // get the royalty fee for the NFT\n (uint256 royaltyFee, address recipient) = _getRoyalty(tokenIds[i], salePrice);\n\n // transfer the royalty fee to the recipient if it's greater than 0\n if (royaltyFee > 0 && recipient != address(0)) {\n if (baseToken != address(0)) {\n ERC20(baseToken).safeTransfer(recipient, royaltyFee);\n } else {\n recipient.safeTransferETH(royaltyFee);\n }\n }\n }\n }\n\n // emit the buy event\n emit Buy(tokenIds, tokenWeights, netInputAmount, feeAmount, protocolFeeAmount, royaltyFeeAmount);\n }",
"tokens": {
"summary": 378,
"content": 344
}
},
"NFT Pool Sale": {
"title": "NFT Pool Sale",
"summary": "The `sell` function is designed to sell Non-Fungible Tokens (NFTs) into a pool and transfer base tokens to the caller. The NFTs are transferred from the caller to the pool, and the net sale amount depends on the current price, fee rate, and assigned NFT weights. It is advised not to call this function directly unless you are aware of the consequences; instead, use a wrapper contract that checks the minimum output amount and reverts if the slippage is too high.\n\nThe function takes the following parameters:\n- `tokenIds`: The token IDs of the NFTs to sell.\n- `tokenWeights`: The weights of the NFTs to sell.\n- `proof`: The Merkle proof for the weights of each NFT to sell.\n- `stolenNftProofs`: The proofs that show each NFT is not stolen.\n\nThe function returns the following values:\n- `netOutputAmount`: The amount of base tokens received inclusive of fees.\n- `feeAmount`: The amount of base tokens to pay in fees.\n\nThe function first calculates the sum of weights of the NFTs to sell and validates the Merkle proof. It then calculates the net output amount and fee amount. If the `useStolenNftOracle` flag is set, it checks that the NFTs are not stolen using the `IStolenNftOracle` interface.\n\nNext, the function updates the virtual reserves by subtracting the net output amount, protocol fee amount, and fee amount from the virtual base token reserves and adding the weight sum to the virtual NFT reserves.\n\nFor each NFT in the `tokenIds` array, the function transfers the NFT from the caller to the contract address. If the `payRoyalties` flag is set, it calculates the sale price for each NFT, gets the royalty fee and recipient, and transfers the royalty fee to the recipient if it is greater than 0 and the recipient is not the zero address.\n\nThe function then subtracts the royalty fee amount from the net output amount and transfers the base tokens (either ERC20 tokens or ETH) to the caller. If the protocol fee is set, it transfers the protocol fee to the factory address.\n\nFinally, the function emits a `Sell` event with the token IDs, token weights, net output amount, fee amount, protocol fee amount, and royalty fee amount.",
"content": "/// @notice Sells NFTs into the pool and transfers base tokens to the caller. NFTs are transferred from the caller\n /// to the pool. The net sale amount depends on the current price, fee rate and assigned NFT weights.\n /// @dev DO NOT call this function directly unless you know what you are doing. Instead, use a wrapper contract that\n /// will check the min output amount and revert if the slippage is too high.\n /// @param tokenIds The token IDs of the NFTs to sell.\n /// @param tokenWeights The weights of the NFTs to sell.\n /// @param proof The merkle proof for the weights of each NFT to sell.\n /// @param stolenNftProofs The proofs that show each NFT is not stolen.\n /// @return netOutputAmount The amount of base tokens received inclusive of fees.\n /// @return feeAmount The amount of base tokens to pay in fees.\n function sell(\n uint256[] calldata tokenIds,\n uint256[] calldata tokenWeights,\n MerkleMultiProof calldata proof,\n IStolenNftOracle.Message[] memory stolenNftProofs // put in memory to avoid stack too deep error\n ) public returns (uint256 netOutputAmount, uint256 feeAmount, uint256 protocolFeeAmount) {\n // ~~~ Checks ~~~ //\n\n // calculate the sum of weights of the NFTs to sell\n uint256 weightSum = sumWeightsAndValidateProof(tokenIds, tokenWeights, proof);\n\n // calculate the net output amount and fee amount\n (netOutputAmount, feeAmount, protocolFeeAmount) = sellQuote(weightSum);\n\n // check the nfts are not stolen\n if (useStolenNftOracle) {\n IStolenNftOracle(stolenNftOracle).validateTokensAreNotStolen(nft, tokenIds, stolenNftProofs);\n }\n\n // ~~~ Effects ~~~ //\n\n // update the virtual reserves\n virtualBaseTokenReserves -= uint128(netOutputAmount + protocolFeeAmount + feeAmount);\n virtualNftReserves += uint128(weightSum);\n\n // ~~~ Interactions ~~~ //\n\n uint256 royaltyFeeAmount = 0;\n for (uint256 i = 0; i < tokenIds.length; i++) {\n // transfer each nft from the caller\n ERC721(nft).safeTransferFrom(msg.sender, address(this), tokenIds[i]);\n\n if (payRoyalties) {\n // calculate the sale price (assume it's the same for each NFT even if weights differ)\n uint256 salePrice = (netOutputAmount + feeAmount + protocolFeeAmount) / tokenIds.length;\n\n // get the royalty fee for the NFT\n (uint256 royaltyFee, address recipient) = _getRoyalty(tokenIds[i], salePrice);\n\n // tally the royalty fee amount\n royaltyFeeAmount += royaltyFee;\n\n // transfer the royalty fee to the recipient if it's greater than 0\n if (royaltyFee > 0 && recipient != address(0)) {\n if (baseToken != address(0)) {\n ERC20(baseToken).safeTransfer(recipient, royaltyFee);\n } else {\n recipient.safeTransferETH(royaltyFee);\n }\n }\n }\n }\n\n // subtract the royalty fee amount from the net output amount\n netOutputAmount -= royaltyFeeAmount;\n\n if (baseToken == address(0)) {\n // transfer ETH to the caller\n msg.sender.safeTransferETH(netOutputAmount);\n\n // if the protocol fee is set then pay the protocol fee\n if (protocolFeeAmount > 0) factory.safeTransferETH(protocolFeeAmount);\n } else {\n // transfer base tokens to the caller\n ERC20(baseToken).transfer(msg.sender, netOutputAmount);\n\n // if the protocol fee is set then pay the protocol fee\n if (protocolFeeAmount > 0) ERC20(baseToken).safeTransfer(address(factory), protocolFeeAmount);\n }\n\n // emit the sell event\n emit Sell(tokenIds, tokenWeights, netOutputAmount, feeAmount, protocolFeeAmount, royaltyFeeAmount);\n }",
"tokens": {
"summary": 488,
"content": 888
}
},
"NFT Pool Change": {
"title": "NFT Pool Change",
"summary": "The `change` function allows a user to swap a set of NFTs they own for another set of NFTs in the pool. The user must first approve the pool to transfer their NFTs. The sum of the user's NFT weights must be less than or equal to the sum of the output pool NFTs weights. Additionally, the user must pay a fee based on the net input weight and change fee amount.\n\nThe function takes the following parameters:\n\n- `inputTokenIds`: The token IDs of the NFTs to change.\n- `inputTokenWeights`: The weights of the NFTs to change.\n- `inputProof`: The Merkle proof for the weights of each NFT to change.\n- `stolenNftProofs`: The proofs that show each input NFT is not stolen.\n- `outputTokenIds`: The token IDs of the NFTs to receive.\n- `outputTokenWeights`: The weights of the NFTs to receive.\n- `outputProof`: The Merkle proof for the weights of each NFT to receive.\n\nThe function first checks if the base token is not ETH and if the caller sent 0 ETH. It then checks if the NFTs are not stolen using the `IStolenNftOracle` interface. Next, it calculates the sum of weights for the input and output NFTs and validates the proofs. If the input weights are less than the output weights, the function reverts with an `InsufficientInputWeight` error.\n\nThe fee amount and protocol fee amount are calculated using the `changeFeeQuote` function. If the base token is not ETH, the function transfers the fee amount of base tokens from the caller and the protocol fee to the factory. If the base token is ETH, it checks if the caller sent enough ETH to cover the fees and transfers the protocol fee to the factory. Any excess ETH is refunded to the caller.\n\nThe function then transfers the input NFTs from the caller and the output NFTs to the caller. Finally, it emits a `Change` event with the input and output token IDs, weights, and fee amounts.",
"content": "/// @notice Changes a set of NFTs that the caller owns for another set of NFTs in the pool. The caller must approve\n /// the pool to transfer the NFTs. The sum of the caller's NFT weights must be less than or equal to the sum of the\n /// output pool NFTs weights. The caller must also pay a fee depending the net input weight and change fee amount.\n /// @param inputTokenIds The token IDs of the NFTs to change.\n /// @param inputTokenWeights The weights of the NFTs to change.\n /// @param inputProof The merkle proof for the weights of each NFT to change.\n /// @param stolenNftProofs The proofs that show each input NFT is not stolen.\n /// @param outputTokenIds The token IDs of the NFTs to receive.\n /// @param outputTokenWeights The weights of the NFTs to receive.\n /// @param outputProof The merkle proof for the weights of each NFT to receive.\n function change(\n uint256[] memory inputTokenIds,\n uint256[] memory inputTokenWeights,\n MerkleMultiProof memory inputProof,\n IStolenNftOracle.Message[] memory stolenNftProofs,\n uint256[] memory outputTokenIds,\n uint256[] memory outputTokenWeights,\n MerkleMultiProof memory outputProof\n ) public payable returns (uint256 feeAmount, uint256 protocolFeeAmount) {\n // ~~~ Checks ~~~ //\n\n // check that the caller sent 0 ETH if base token is not ETH\n if (baseToken != address(0) && msg.value > 0) revert InvalidEthAmount();\n\n // check that NFTs are not stolen\n if (useStolenNftOracle) {\n IStolenNftOracle(stolenNftOracle).validateTokensAreNotStolen(nft, inputTokenIds, stolenNftProofs);\n }\n\n // fix stack too deep\n {\n // calculate the sum of weights for the input nfts\n uint256 inputWeightSum = sumWeightsAndValidateProof(inputTokenIds, inputTokenWeights, inputProof);\n\n // calculate the sum of weights for the output nfts\n uint256 outputWeightSum = sumWeightsAndValidateProof(outputTokenIds, outputTokenWeights, outputProof);\n\n // check that the input weights are greater than or equal to the output weights\n if (inputWeightSum < outputWeightSum) revert InsufficientInputWeight();\n\n // calculate the fee amount\n (feeAmount, protocolFeeAmount) = changeFeeQuote(inputWeightSum);\n }\n\n // ~~~ Interactions ~~~ //\n\n if (baseToken != address(0)) {\n // transfer the fee amount of base tokens from the caller\n ERC20(baseToken).safeTransferFrom(msg.sender, address(this), feeAmount);\n\n // if the protocol fee is non-zero then transfer the protocol fee to the factory\n if (protocolFeeAmount > 0) ERC20(baseToken).safeTransferFrom(msg.sender, factory, protocolFeeAmount);\n } else {\n // check that the caller sent enough ETH to cover the fee amount and protocol fee\n if (msg.value < feeAmount + protocolFeeAmount) revert InvalidEthAmount();\n\n // if the protocol fee is non-zero then transfer the protocol fee to the factory\n if (protocolFeeAmount > 0) factory.safeTransferETH(protocolFeeAmount);\n\n // refund any excess ETH to the caller\n if (msg.value > feeAmount + protocolFeeAmount) {\n msg.sender.safeTransferETH(msg.value - feeAmount - protocolFeeAmount);\n }\n }\n\n // transfer the input nfts from the caller\n for (uint256 i = 0; i < inputTokenIds.length; i++) {\n ERC721(nft).safeTransferFrom(msg.sender, address(this), inputTokenIds[i]);\n }\n\n // transfer the output nfts to the caller\n for (uint256 i = 0; i < outputTokenIds.length; i++) {\n ERC721(nft).safeTransferFrom(address(this), msg.sender, outputTokenIds[i]);\n }\n\n // emit the change event\n emit Change(inputTokenIds, inputTokenWeights, outputTokenIds, outputTokenWeights, feeAmount, protocolFeeAmount);\n }",
"tokens": {
"summary": 438,
"content": 912
}
},
"Execute Target Transaction": {
"title": "Execute Target Transaction",
"summary": "The given code snippet defines a function called `execute` in a smart contract, which is responsible for executing a transaction from the pool account to a target contract. The function can only be called by the owner of the pool, which is enforced by the `onlyOwner` modifier. This function is useful for scenarios such as claiming airdrops.\n\nThe `execute` function takes two input parameters: `target`, which is the address of the target contract, and `data`, which is the data to be sent to the target contract. The function is also marked as `payable`, allowing it to receive Ether during the transaction. The function returns a `bytes memory` variable called `returnData`, which contains the return data of the transaction.\n\nInside the function, a low-level `call` is made to the target contract with the specified value and data. The `call` returns a boolean `success` and a `bytes memory` variable `returnData`. If the call is successful, the function returns the `returnData`. If the call fails, the function checks if there is any error message in the `returnData`. If there is an error message, it bubbles up the error message using inline assembly and reverts the transaction. If there is no error message, the transaction is simply reverted without any error message.",
"content": "/// @notice Executes a transaction from the pool account to a target contract. The caller must be the owner of the\n /// pool. This allows for use cases such as claiming airdrops.\n /// @param target The address of the target contract.\n /// @param data The data to send to the target contract.\n /// @return returnData The return data of the transaction.\n function execute(address target, bytes memory data) public payable onlyOwner returns (bytes memory) {\n // call the target with the value and data\n (bool success, bytes memory returnData) = target.call{value: msg.value}(data);\n\n // if the call succeeded return the return data\n if (success) return returnData;\n\n // if we got an error bubble up the error message\n if (returnData.length > 0) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returnData_size := mload(returnData)\n revert(add(32, returnData), returnData_size)\n }\n } else {\n revert();\n }\n }",
"tokens": {
"summary": 266,
"content": 227
}
},
"Deposit Tokens NFTs": {
"title": "Deposit Tokens NFTs",
"summary": "The given code snippet is a function named `deposit` that allows users to deposit base tokens and NFTs (Non-Fungible Tokens) into a pool. The function takes two parameters: an array of token IDs (`tokenIds`) representing the NFTs to be deposited, and a `baseTokenAmount` representing the amount of base tokens to be deposited.\n\nBefore executing the deposit, the function checks if the base token is ETH (Ethereum) and if the sent ETH amount (`msg.value`) is equal to the specified `baseTokenAmount`. If the base token is not ETH, it checks if the sent ETH amount is 0. If these conditions are not met, the function reverts with an `InvalidEthAmount` error.\n\nThe function then proceeds to transfer the NFTs from the caller to the pool by iterating through the `tokenIds` array and using the `safeTransferFrom` function of the ERC721 standard. If the base token is not ETH, it transfers the base tokens from the caller to the pool using the `safeTransferFrom` function of the ERC20 standard.\n\nFinally, the function emits a `Deposit` event with the deposited NFTs and base token amount as its parameters.\n\nIt is important to note that the function is marked with a `@dev` comment, warning developers not to call this function directly unless they know what they are doing. Instead, they should use a wrapper contract that checks if the current price is within the desired bounds.",
"content": "/// @notice Deposits base tokens and NFTs into the pool. The caller must approve the pool to transfer their NFTs and\n /// base tokens.\n /// @dev DO NOT call this function directly unless you know what you are doing. Instead, use a wrapper contract that\n /// will check the current price is within the desired bounds.\n /// @param tokenIds The token IDs of the NFTs to deposit.\n /// @param baseTokenAmount The amount of base tokens to deposit.\n function deposit(uint256[] calldata tokenIds, uint256 baseTokenAmount) public payable {\n // ~~~ Checks ~~~ //\n\n // ensure the caller sent a valid amount of ETH if base token is ETH or that the caller sent 0 ETH if base token\n // is not ETH\n if ((baseToken == address(0) && msg.value != baseTokenAmount) || (msg.value > 0 && baseToken != address(0))) {\n revert InvalidEthAmount();\n }\n\n // ~~~ Interactions ~~~ //\n\n // transfer the nfts from the caller\n for (uint256 i = 0; i < tokenIds.length; i++) {\n ERC721(nft).safeTransferFrom(msg.sender, address(this), tokenIds[i]);\n }\n\n if (baseToken != address(0)) {\n // transfer the base tokens from the caller\n ERC20(baseToken).safeTransferFrom(msg.sender, address(this), baseTokenAmount);\n }\n\n // emit the deposit event\n emit Deposit(tokenIds, baseTokenAmount);\n }",
"tokens": {
"summary": 303,
"content": 329
}
},
"Withdraw NFT Tokens": {
"title": "Withdraw NFT Tokens",
"summary": "The given code snippet is a function named \"withdraw\" that allows the owner of a pool to withdraw Non-Fungible Tokens (NFTs) and tokens from the pool. The function takes four input parameters: the address of the NFT (_nft), an array of token IDs (tokenIds) representing the NFTs to be withdrawn, the address of the token (token) to be withdrawn, and the amount of tokens (tokenAmount) to be withdrawn.\n\nThe function is marked as \"public\" and can only be called by the owner of the pool, as indicated by the \"onlyOwner\" modifier.\n\nThe function starts by transferring the specified NFTs to the caller (msg.sender) using a for loop that iterates through the tokenIds array. It does this by calling the \"safeTransferFrom\" function of the ERC721 contract, passing the address of the NFT, the caller's address, and the current token ID in the loop.\n\nNext, the function checks if the token address is equal to the zero address (address(0)). If it is, the function transfers the specified amount of Ether (ETH) to the caller using the \"safeTransferETH\" function. If the token address is not equal to the zero address, the function transfers the specified amount of tokens to the caller using the \"transfer\" function of the ERC20 contract.\n\nFinally, the function emits a \"Withdraw\" event with the NFT address, token IDs array, token address, and token amount as its parameters. This event can be used by external applications to track and monitor the withdrawal of NFTs and tokens from the pool.",
"content": "/// @notice Withdraws NFTs and tokens from the pool. Can only be called by the owner of the pool.\n /// @param _nft The address of the NFT.\n /// @param tokenIds The token IDs of the NFTs to withdraw.\n /// @param token The address of the token to withdraw.\n /// @param tokenAmount The amount of tokens to withdraw.\n function withdraw(address _nft, uint256[] calldata tokenIds, address token, uint256 tokenAmount) public onlyOwner {\n // ~~~ Interactions ~~~ //\n\n // transfer the nfts to the caller\n for (uint256 i = 0; i < tokenIds.length; i++) {\n ERC721(_nft).safeTransferFrom(address(this), msg.sender, tokenIds[i]);\n }\n\n if (token == address(0)) {\n // transfer the ETH to the caller\n msg.sender.safeTransferETH(tokenAmount);\n } else {\n // transfer the tokens to the caller\n ERC20(token).transfer(msg.sender, tokenAmount);\n }\n\n // emit the withdraw event\n emit Withdraw(_nft, tokenIds, token, tokenAmount);\n }",
"tokens": {
"summary": 332,
"content": 249
}
},
"Set Virtual Reserves": {
"title": "Set Virtual Reserves",
"summary": "The given code snippet is a Solidity function called `setVirtualReserves` that sets the virtual base token reserves and virtual NFT (Non-Fungible Token) reserves for a pool. This function can only be called by the owner of the pool. The parameters of this function are `newVirtualBaseTokenReserves` and `newVirtualNftReserves`, which are both of type `uint128`. These parameters affect the price and liquidity depth of the pool.\n\nThe function first sets the `virtualBaseTokenReserves` and `virtualNftReserves` variables to the values of the input parameters `newVirtualBaseTokenReserves` and `newVirtualNftReserves`, respectively. After updating the reserve values, the function emits an event called `SetVirtualReserves` with the new reserve values as its arguments. This event can be used by external systems to track changes in the virtual reserves of the pool.",
"content": "/// @notice Sets the virtual base token reserves and virtual NFT reserves. Can only be called by the owner of the\n /// pool. These parameters affect the price and liquidity depth of the pool.\n /// @param newVirtualBaseTokenReserves The new virtual base token reserves.\n /// @param newVirtualNftReserves The new virtual NFT reserves.\n function setVirtualReserves(uint128 newVirtualBaseTokenReserves, uint128 newVirtualNftReserves) public onlyOwner {\n // set the virtual base token reserves and virtual nft reserves\n virtualBaseTokenReserves = newVirtualBaseTokenReserves;\n virtualNftReserves = newVirtualNftReserves;\n\n // emit the set virtual reserves event\n emit SetVirtualReserves(newVirtualBaseTokenReserves, newVirtualNftReserves);\n }",
"tokens": {
"summary": 189,
"content": 176
}
},
"Set Merkle Root": {
"title": "Set Merkle Root",
"summary": "The given code snippet is a Solidity function named `setMerkleRoot` that is used to update the Merkle root of a pool. This function can only be called by the owner of the pool, as indicated by the `onlyOwner` modifier. The Merkle root is utilized for validating the weights of Non-Fungible Tokens (NFTs) within the pool.\n\nThe function takes a single input parameter, `newMerkleRoot`, which is of type `bytes32`. This parameter represents the new Merkle root value that will replace the current one.\n\nInside the function, the Merkle root is updated by assigning the value of `newMerkleRoot` to the `merkleRoot` variable. Following this, an event named `SetMerkleRoot` is emitted with the updated `newMerkleRoot` value as its argument. This event allows external entities to listen for changes in the Merkle root and react accordingly.",
"content": "/// @notice Sets the merkle root. Can only be called by the owner of the pool. The merkle root is used to validate\n /// the NFT weights.\n /// @param newMerkleRoot The new merkle root.\n function setMerkleRoot(bytes32 newMerkleRoot) public onlyOwner {\n // set the merkle root\n merkleRoot = newMerkleRoot;\n\n // emit the set merkle root event\n emit SetMerkleRoot(newMerkleRoot);\n }",
"tokens": {
"summary": 196,
"content": 114
}
},
"Fee Rate Setter": {
"title": "Fee Rate Setter",
"summary": "The given code snippet is a function called `setFeeRate` that sets the fee rate for a pool. This function can only be called by the owner of the pool. The fee rate is used to calculate the fee amount when swapping or changing NFTs (Non-Fungible Tokens). The fee rate is expressed in basis points, where 1 basis point is equal to 1/100th of a percent. For instance, a fee rate of 10,000 basis points represents 100%, 200 basis points represent 2%, and 1 basis point represents 0.01%.\n\nThe function takes a single parameter, `newFeeRate`, which is the new fee rate to be set, in basis points. Inside the function, there is a check to ensure that the new fee rate is less than 50% (5,000 basis points). If the new fee rate is greater than 5,000 basis points, the function reverts with a `FeeRateTooHigh` error.\n\nIf the new fee rate is valid, the function sets the fee rate to the new value and emits an event called `SetFeeRate` with the new fee rate as its parameter. This event can be used by external systems to track changes in the fee rate.",
"content": "/// @notice Sets the fee rate. Can only be called by the owner of the pool. The fee rate is used to calculate the\n /// fee amount when swapping or changing NFTs. The fee rate is in basis points (1/100th of a percent). For example,\n /// 10_000 == 100%, 200 == 2%, 1 == 0.01%.\n /// @param newFeeRate The new fee rate (in basis points)\n function setFeeRate(uint16 newFeeRate) public onlyOwner {\n // check that the fee rate is less than 50%\n if (newFeeRate > 5_000) revert FeeRateTooHigh();\n\n // set the fee rate\n feeRate = newFeeRate;\n\n // emit the set fee rate event\n emit SetFeeRate(newFeeRate);\n }",
"tokens": {
"summary": 257,
"content": 181
}
},
"Set Pay Royalties": {
"title": "Set Pay Royalties",
"summary": "The given code snippet is a Solidity function named `setPayRoyalties` that is used to set the pay royalties flag in a smart contract. This function can only be called by the owner of the pool, as indicated by the `onlyOwner` modifier.\n\nThe function takes a single input parameter, `newPayRoyalties`, which is a boolean value representing the new pay royalties flag. When royalties are enabled (i.e., the flag is set to `true`), the pool will pay royalties when buying or selling NFTs (Non-Fungible Tokens).\n\nInside the function, the pay royalties flag is updated with the new value provided by the `newPayRoyalties` parameter. After updating the flag, an event named `SetPayRoyalties` is emitted with the new pay royalties flag value. This event can be used by external systems or applications to track changes in the pay royalties flag.",
"content": "/// @notice Sets the pay royalties flag. Can only be called by the owner of the pool. If royalties are enabled then\n /// the pool will pay royalties when buying or selling NFTs.\n /// @param newPayRoyalties The new pay royalties flag.\n function setPayRoyalties(bool newPayRoyalties) public onlyOwner {\n // set the pay royalties flag\n payRoyalties = newPayRoyalties;\n\n // emit the set pay royalties event\n emit SetPayRoyalties(newPayRoyalties);\n }",
"tokens": {
"summary": 183,
"content": 111
}
},
"Update Parameter Settings": {
"title": "Update Parameter Settings",
"summary": "The given code snippet is a function called `setAllParameters` in a smart contract, which allows updating multiple parameter settings in a single function call. The function takes six input parameters:\n\n1. `newVirtualBaseTokenReserves`: The new virtual base token reserves value (uint128).\n2. `newVirtualNftReserves`: The new virtual NFT reserves value (uint128).\n3. `newMerkleRoot`: The new Merkle root value (bytes32).\n4. `newFeeRate`: The new fee rate value (uint16) in basis points.\n5. `newUseStolenNftOracle`: The new flag (bool) indicating whether to use a stolen NFT oracle or not.\n6. `newPayRoyalties`: The new flag (bool) indicating whether to pay royalties or not.\n\nThe function then calls five other functions to update the respective parameters:\n\n1. `setVirtualReserves(newVirtualBaseTokenReserves, newVirtualNftReserves)`: Updates the virtual base token and NFT reserves with the new values.\n2. `setMerkleRoot(newMerkleRoot)`: Updates the Merkle root with the new value.\n3. `setFeeRate(newFeeRate)`: Updates the fee rate with the new value.\n4. `setUseStolenNftOracle(newUseStolenNftOracle)`: Updates the flag for using a stolen NFT oracle with the new value.\n5. `setPayRoyalties(newPayRoyalties)`: Updates the flag for paying royalties with the new value.\n\nThis function provides a convenient way to update multiple parameter settings in a single transaction, which can save gas costs and simplify the process for users.",
"content": "/// @notice Updates all parameter settings in one go.\n /// @param newVirtualBaseTokenReserves The new virtual base token reserves.\n /// @param newVirtualNftReserves The new virtual NFT reserves.\n /// @param newMerkleRoot The new merkle root.\n /// @param newFeeRate The new fee rate (in basis points)\n /// @param newUseStolenNftOracle The new use stolen NFT oracle flag.\n /// @param newPayRoyalties The new pay royalties flag.\n function setAllParameters(\n uint128 newVirtualBaseTokenReserves,\n uint128 newVirtualNftReserves,\n bytes32 newMerkleRoot,\n uint16 newFeeRate,\n bool newUseStolenNftOracle,\n bool newPayRoyalties\n ) public {\n setVirtualReserves(newVirtualBaseTokenReserves, newVirtualNftReserves);\n setMerkleRoot(newMerkleRoot);\n setFeeRate(newFeeRate);\n setUseStolenNftOracle(newUseStolenNftOracle);\n setPayRoyalties(newPayRoyalties);\n }",
"tokens": {
"summary": 349,
"content": 240
}
},
"Flash Loan Execution": {
"title": "Flash Loan Execution",
"summary": "The given code snippet is a function called `flashLoan` that executes a flash loan in a smart contract. The function takes four parameters: `receiver`, `token`, `tokenId`, and `data`. The `receiver` is the address of the entity receiving the flash loan, `token` is the address of the Non-Fungible Token (NFT) contract, `tokenId` is the ID of the NFT, and `data` is any additional data to be passed to the receiver.\n\nThe function is marked as `external`, meaning it can only be called from outside the contract, and `payable`, allowing it to receive Ether (ETH) as payment. The function returns a boolean value indicating the success of the flash loan.\n\nFirst, the function checks if the NFT is available for a flash loan using the `availableForFlashLoan` function. If it is not available, the function reverts with a `NotAvailableForFlashLoan` error.\n\nNext, the function calculates the fee for the flash loan using the `flashFee` function. If the base token is ETH (i.e., `baseToken` is the zero address), the function checks if the caller sent enough ETH to cover the fee. If not, it reverts with an `InvalidEthAmount` error.\n\nThe function then transfers the NFT to the borrower using the `safeTransferFrom` function of the ERC721 contract. It calls the borrower's `onFlashLoan` function, passing the necessary parameters, and checks if the flash loan was successful by comparing the returned value with the expected hash of the \"ERC3156FlashBorrower.onFlashLoan\" string. If the flash loan was not successful, the function reverts with a `FlashLoanFailed` error.\n\nAfter a successful flash loan, the function transfers the NFT back from the borrower using the `safeTransferFrom` function of the ERC721 contract. If the base token is not ETH, it transfers the fee from the borrower using the `transferFrom` function of the ERC20 contract.\n\nFinally, the function returns the `success` boolean value, indicating whether the flash loan was successful or not.",
"content": "/// @notice Executes a flash loan.\n /// @param receiver The receiver of the flash loan.\n /// @param token The address of the NFT contract.\n /// @param tokenId The ID of the NFT.\n /// @param data The data to pass to the receiver.\n /// @return success Whether or not the flash loan was successful.\n function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 tokenId, bytes calldata data)\n external\n payable\n returns (bool)\n {\n // check that the NFT is available for a flash loan\n if (!availableForFlashLoan(token, tokenId)) revert NotAvailableForFlashLoan();\n\n // calculate the fee\n uint256 fee = flashFee(token, tokenId);\n\n // if base token is ETH then check that caller sent enough for the fee\n if (baseToken == address(0) && msg.value < fee) revert InvalidEthAmount();\n\n // transfer the NFT to the borrower\n ERC721(token).safeTransferFrom(address(this), address(receiver), tokenId);\n\n // call the borrower\n bool success =\n receiver.onFlashLoan(msg.sender, token, tokenId, fee, data) == keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n // check that flashloan was successful\n if (!success) revert FlashLoanFailed();\n\n // transfer the NFT from the borrower\n ERC721(token).safeTransferFrom(address(receiver), address(this), tokenId);\n\n // transfer the fee from the borrower\n if (baseToken != address(0)) ERC20(baseToken).transferFrom(msg.sender, address(this), fee);\n\n return success;\n }",
"tokens": {
"summary": 438,
"content": 351
}
},
"Sum Validate Proof": {
"title": "Sum Validate Proof",
"summary": "The given code snippet is a Solidity function called `sumWeightsAndValidateProof` that takes three input parameters: an array of token IDs (`tokenIds`), an array of corresponding token weights (`tokenWeights`), and a Merkle multi-proof object (`proof`). The function's purpose is to calculate the sum of the weights of each NFT (Non-Fungible Token) and validate that the weights are correct by verifying the provided Merkle proof.\n\nInitially, the function checks if the `merkleRoot` is not set (i.e., equals to `bytes32(0)`). If this is the case, it sets the weight of each NFT to be `1e18` and returns the product of the number of token IDs and this weight.\n\nIf the `merkleRoot` is set, the function initializes a variable `sum` to store the sum of the token weights and creates a new array `leafs` to store the Merkle proof leaves. It then iterates through the `tokenIds` array and, for each token ID, creates a leaf by hashing the concatenated keccak256 hash of the token ID and its corresponding weight. The function also adds the token weight to the `sum` variable.\n\nAfter iterating through all token IDs, the function verifies the Merkle proof using the `MerkleProofLib.verifyMultiProof` function. If the proof is not valid, it reverts the transaction with an `InvalidMerkleProof` error. If the proof is valid, the function returns the calculated sum of the token weights.",
"content": "/// @notice Sums the weights of each NFT and validates that the weights are correct by verifying the merkle proof.\n /// @param tokenIds The token IDs of the NFTs to sum the weights for.\n /// @param tokenWeights The weights of each NFT in the token IDs array.\n /// @param proof The merkle proof for the weights of each NFT.\n /// @return sum The sum of the weights of each NFT.\n function sumWeightsAndValidateProof(\n uint256[] memory tokenIds,\n uint256[] memory tokenWeights,\n MerkleMultiProof memory proof\n ) public view returns (uint256) {\n // if the merkle root is not set then set the weight of each nft to be 1e18\n if (merkleRoot == bytes32(0)) {\n return tokenIds.length * 1e18;\n }\n\n uint256 sum;\n bytes32[] memory leafs = new bytes32[](tokenIds.length);\n for (uint256 i = 0; i < tokenIds.length; i++) {\n // create the leaf for the merkle proof\n leafs[i] = keccak256(bytes.concat(keccak256(abi.encode(tokenIds[i], tokenWeights[i]))));\n\n // sum each token weight\n sum += tokenWeights[i];\n }\n\n // validate that the weights are valid against the merkle proof\n if (!MerkleProofLib.verifyMultiProof(proof.proof, merkleRoot, leafs, proof.flags)) {\n revert InvalidMerkleProof();\n }\n\n return sum;\n }",
"tokens": {
"summary": 318,
"content": 339
}
},
"NFT Buy Quote": {
"title": "NFT Buy Quote",
"summary": "The given code snippet is a function called `buyQuote` in a smart contract, which calculates the required input amount of base tokens needed to buy a specified amount of NFTs (Non-Fungible Tokens), along with the associated fee amounts.\n\nThe function takes a single input parameter, `outputAmount`, which represents the desired amount of NFTs to buy, multiplied by 1e18 for precision. It returns three values: `netInputAmount`, `feeAmount`, and `protocolFeeAmount`.\n\nThe function first calculates the input amount using the xy=k invariant, a formula used in automated market makers (AMMs) to maintain a constant product of token reserves. It does this by calling the `mulDivUp` function from the `FixedPointMathLib` library, passing the `outputAmount`, `virtualBaseTokenReserves`, and the difference between `virtualNftReserves` and `outputAmount`. The result is rounded up by 1 wei (the smallest unit of Ether) for precision.\n\nNext, the function calculates the protocol fee amount by multiplying the input amount by the protocol fee rate, which is fetched from the factory contract using the `protocolFeeRate()` function. The result is divided by 10,000 to get the actual fee amount.\n\nSimilarly, the function calculates the fee amount by multiplying the input amount by the `feeRate` and dividing the result by 10,000.\n\nFinally, the function calculates the net input amount by adding the input amount, fee amount, and protocol fee amount together. This net input amount represents the total amount of base tokens required to buy the specified amount of NFTs, inclusive of all fees.",
"content": "/// @notice Returns the required input of buying a given amount of NFTs inclusive of the fee which is dependent on\n /// the currently set fee rate.\n /// @param outputAmount The amount of NFTs to buy multiplied by 1e18.\n /// @return netInputAmount The required input amount of base tokens inclusive of the fee.\n /// @return feeAmount The fee amount.\n function buyQuote(uint256 outputAmount)\n public\n view\n returns (uint256 netInputAmount, uint256 feeAmount, uint256 protocolFeeAmount)\n {\n // calculate the input amount based on xy=k invariant and round up by 1 wei\n uint256 inputAmount =\n FixedPointMathLib.mulDivUp(outputAmount, virtualBaseTokenReserves, (virtualNftReserves - outputAmount));\n\n protocolFeeAmount = inputAmount * Factory(factory).protocolFeeRate() / 10_000;\n feeAmount = inputAmount * feeRate / 10_000;\n netInputAmount = inputAmount + feeAmount + protocolFeeAmount;\n }",
"tokens": {
"summary": 338,
"content": 225
}
},
"NFT Sell Quote": {
"title": "NFT Sell Quote",
"summary": "The `sellQuote` function is a public view function that returns the output amount of selling a given amount of NFTs (Non-Fungible Tokens) inclusive of the fee, which depends on the currently set fee rate. The function takes one input parameter, `inputAmount`, which represents the amount of NFTs to sell multiplied by 1e18. The function returns three values: `netOutputAmount`, `feeAmount`, and `protocolFeeAmount`.\n\nThe function calculates the output amount based on the xy=k invariant, a formula used in automated market makers (AMMs) to maintain a constant product of token reserves. The output amount is calculated as `inputAmount * virtualBaseTokenReserves / (virtualNftReserves + inputAmount)`.\n\nNext, the function calculates the protocol fee amount by multiplying the output amount by the protocol fee rate obtained from the Factory contract and dividing by 10,000. The fee amount is calculated similarly, by multiplying the output amount by the fee rate and dividing by 10,000.\n\nFinally, the function calculates the net output amount by subtracting the fee amount and protocol fee amount from the output amount. The function then returns the net output amount, fee amount, and protocol fee amount.",
"content": "/// @notice Returns the output amount of selling a given amount of NFTs inclusive of the fee which is dependent on\n /// the currently set fee rate.\n /// @param inputAmount The amount of NFTs to sell multiplied by 1e18.\n /// @return netOutputAmount The output amount of base tokens inclusive of the fee.\n /// @return feeAmount The fee amount.\n function sellQuote(uint256 inputAmount)\n public\n view\n returns (uint256 netOutputAmount, uint256 feeAmount, uint256 protocolFeeAmount)\n {\n // calculate the output amount based on xy=k invariant\n uint256 outputAmount = inputAmount * virtualBaseTokenReserves / (virtualNftReserves + inputAmount);\n\n protocolFeeAmount = outputAmount * Factory(factory).protocolFeeRate() / 10_000;\n feeAmount = outputAmount * feeRate / 10_000;\n netOutputAmount = outputAmount - feeAmount - protocolFeeAmount;\n }",
"tokens": {
"summary": 252,
"content": 209
}
},
"NFT Change Fee": {
"title": "NFT Change Fee",
"summary": "The `changeFeeQuote` function calculates and returns the fee required to change a specified amount of NFTs (Non-Fungible Tokens) based on the current `changeFee`. The function takes `inputAmount` as a parameter, which represents the amount of NFTs to change, multiplied by 1e18. The function returns two values: `feeAmount` and `protocolFeeAmount`.\n\nFirst, the function calculates the exponent based on the `baseToken` decimals. If the `baseToken` is the zero address, the exponent is set to 14 (18 - 4). Otherwise, the exponent is calculated as the difference between the `baseToken` decimals and 4. The `changeFee` is then multiplied by 10 raised to the power of the exponent to obtain the fee per NFT with 4 decimals of accuracy.\n\nNext, the `feeAmount` is calculated by multiplying the `inputAmount` by the `feePerNft` and dividing the result by 1e18. The `protocolFeeAmount` is then calculated by multiplying the `feeAmount` by the `protocolFeeRate` from the Factory contract and dividing the result by 10,000.\n\nIn summary, the `changeFeeQuote` function calculates the fee and protocol fee amounts required to change a specified amount of NFTs based on the current `changeFee` and the `baseToken` decimals.",
"content": "/// @notice Returns the fee required to change a given amount of NFTs. The fee is based on the current changeFee\n /// (which contains 4 decimals of precision) multiplied by some exponent depending on the base token decimals.\n /// @param inputAmount The amount of NFTs to change multiplied by 1e18.\n /// @return feeAmount The fee amount.\n /// @return protocolFeeAmount The protocol fee amount.\n function changeFeeQuote(uint256 inputAmount) public view returns (uint256 feeAmount, uint256 protocolFeeAmount) {\n // multiply the changeFee to get the fee per NFT (4 decimals of accuracy)\n uint256 exponent = baseToken == address(0) ? 18 - 4 : ERC20(baseToken).decimals() - 4;\n uint256 feePerNft = changeFee * 10 ** exponent;\n\n feeAmount = inputAmount * feePerNft / 1e18;\n protocolFeeAmount = feeAmount * Factory(factory).protocolFeeRate() / 10_000;\n }",
"tokens": {
"summary": 288,
"content": 224
}
},
"Pool Price Function": {
"title": "Pool Price Function",
"summary": "The given code snippet is a Solidity function named `price()` that returns the price of a pool with 18 decimals of accuracy. The function is marked as `public` and `view`, meaning it can be called by anyone and does not modify the state of the contract.\n\nThe function calculates the price by first determining the exponent to be used for scaling the result. This is done by checking if the `baseToken` address is equal to the zero address (i.e., no base token is set). If this is the case, the exponent is set to 18, ensuring 18 decimals of accuracy. Otherwise, the exponent is calculated as 36 minus the number of decimals of the `baseToken` (retrieved using the ERC20 standard's `decimals()` function).\n\nNext, the function calculates the price by multiplying the `virtualBaseTokenReserves` by 10 raised to the power of the previously calculated exponent. This result is then divided by the `virtualNftReserves` to obtain the final price.\n\nFinally, the function returns the calculated price as a `uint256` value.",
"content": "/// @notice Returns the price of the pool to 18 decimals of accuracy.\n /// @return price The price of the pool.\n function price() public view returns (uint256) {\n // ensure that the exponent is always to 18 decimals of accuracy\n uint256 exponent = baseToken == address(0) ? 18 : (36 - ERC20(baseToken).decimals());\n return (virtualBaseTokenReserves * 10 ** exponent) / virtualNftReserves;\n }",
"tokens": {
"summary": 225,
"content": 104
}
},
"Flash Swap Fee": {
"title": "Flash Swap Fee",
"summary": "The given code snippet is a Solidity function named `flashFee` that is part of a smart contract. The purpose of this function is to return the fee required to perform a flash swap of a specific Non-Fungible Token (NFT).\n\nThe function has the following characteristics:\n\n1. Visibility: The function is marked as `public`, which means it can be called from any external address or from within the smart contract itself.\n\n2. State mutability: The function is marked as `view`, which indicates that it does not modify the state of the contract. It only reads the state and returns a value.\n\n3. Parameters: The function accepts two parameters - an `address` and a `uint256`. The `address` parameter represents the address of the NFT, and the `uint256` parameter represents the unique identifier of the NFT.\n\n4. Return value: The function returns a single value of type `uint256`, which represents the fee amount required to perform the flash swap of the given NFT.\n\n5. Function logic: The function simply returns the value of a variable named `changeFee`. This variable is assumed to be a state variable within the smart contract that holds the fee amount for flash swaps. The function does not perform any calculations or logic beyond returning this value.\n\nIn summary, the `flashFee` function is a public view function that takes an address and a unique identifier as input parameters and returns the fee amount required to flash swap a specific NFT by simply returning the value of a state variable named `changeFee`.",
"content": "/// @notice Returns the fee required to flash swap a given NFT.\n /// @return feeAmount The fee amount.\n function flashFee(address, uint256) public view returns (uint256) {\n return changeFee;\n }",
"tokens": {
"summary": 314,
"content": 49
}
},
"Flash Fee Token": {
"title": "Flash Fee Token",
"summary": "The given content is a Solidity function named `flashFeeToken()` within a smart contract. This function is marked as `public` and `view`, meaning it can be called by anyone and does not modify the contract's state. The purpose of this function is to return the address of the token that is used to pay the flash fee.\n\nThe function has no input parameters and returns a single output of type `address`. Inside the function body, the `baseToken` variable is returned as the result. This implies that the `baseToken` represents the token used for paying flash fees in the context of this smart contract.",
"content": "/// @notice Returns the token that is used to pay the flash fee.\n function flashFeeToken() public view returns (address) {\n return baseToken;\n }",
"tokens": {
"summary": 126,
"content": 35
}
},
"NFT Flash Loan": {
"title": "NFT Flash Loan",
"summary": "The given content is a Solidity function named `availableForFlashLoan` that checks the availability of a Non-Fungible Token (NFT) for a flash loan. The function takes two input parameters: `token`, which is the address of the NFT contract, and `tokenId`, which is the unique identifier of the NFT. The function returns a boolean value `available`, indicating whether the specified NFT is available for a flash loan or not.\n\nThe function is marked as `public`, meaning it can be called from any external contract or account, and `view`, which indicates that it does not modify the state of the contract. This function is designed to be used in the context of decentralized finance (DeFi) applications, where flash loans are a common feature. By providing a way to check the availability of an NFT for a flash loan, this function can help ensure that only eligible NFTs are used in flash loan transactions.",
"content": "/// @notice Returns whether or not an NFT is available for a flash loan.\n /// @param token The address of the NFT contract.\n /// @param tokenId The ID of the NFT.\n /// @return available Whether or not the NFT is available for a flash loan.\n function availableForFlashLoan(address token, uint256 tokenId) public view returns (bool) {",
"tokens": {
"summary": 192,
"content": 80
}
},
"NFT Ownership Check": {
"title": "NFT Ownership Check",
"summary": "The given code snippet is a function that checks if a specific Non-Fungible Token (NFT) is owned by the current smart contract. It does this by interacting with the ERC721 standard, which is a widely used standard for creating and managing NFTs on the Ethereum blockchain.\n\n1. The function starts by attempting to call the `ownerOf` function from the ERC721 smart contract, which is identified by the `token` address. The `ownerOf` function takes a `tokenId` as its argument and returns the address of the current owner of the NFT with the specified `tokenId`.\n\n2. The `try` keyword is used to handle any potential errors that may occur during the execution of the `ownerOf` function call. If the function call is successful, the returned owner address is stored in the `result` variable.\n\n3. The function then checks if the `result` (owner address) is equal to the address of the current smart contract (denoted by `address(this)`). If the addresses match, it means that the NFT is owned by the current smart contract, and the function returns `true`. If the addresses do not match, the function returns `false`.\n\n4. If an error occurs during the execution of the `ownerOf` function call, the `catch` block is executed. In this case, the function returns `false`, indicating that the NFT is not owned by the current smart contract.\n\nIn summary, this function checks if a specific NFT, identified by its `tokenId`, is owned by the current smart contract by interacting with the ERC721 standard. It returns `true` if the NFT is owned by the contract and `false` otherwise.",
"content": "// return if the NFT is owned by this contract\n try ERC721(token).ownerOf(tokenId) returns (address result) {\n return result == address(this);\n } catch {\n return false;\n }\n }",
"tokens": {
"summary": 347,
"content": 48
}
},
"Royalty Fee Lookup": {
"title": "Royalty Fee Lookup",
"summary": "The given content is a function definition in a smart contract, written in Solidity programming language. The function is named `_getRoyalty` and is used to calculate the royalty fee and recipient for a given Non-Fungible Token (NFT) and its sale price. The function fetches the royalty information from the Manifold registry.\n\nThe function takes two input parameters:\n\n1. `tokenId`: A `uint256` data type representing the unique identifier of the NFT.\n2. `salePrice`: A `uint256` data type representing the sale price of the NFT.\n\nThe function returns two output values:\n\n1. `royaltyFee`: A `uint256` data type representing the royalty fee to be paid.\n2. `recipient`: An `address` data type representing the address to which the royalty fee should be paid.\n\nThe function is marked as `internal`, which means it can only be called from within the same contract or contracts derived from it. It is also marked as `view`, indicating that it does not modify the state of the contract and only reads from it.\n\nInside the function, the royalty lookup address is fetched by calling the `getRoyaltyLookupAddress` function of the `IRoyaltyRegistry` interface, passing the `nft` address as an argument. The `IRoyaltyRegistry` interface is a contract that defines the functions for interacting with the Manifold registry. The `royaltyRegistry` variable is an instance of this interface, and it is used to interact with the Manifold registry to fetch the royalty information.\n\nIn summary, the `_getRoyalty` function is a utility function in a smart contract that calculates the royalty fee and recipient for a given NFT and its sale price by fetching the royalty information from the Manifold registry.",
"content": "/// @notice Gets the royalty and recipient for a given NFT and sale price. Looks up the royalty info from the\n /// manifold registry.\n /// @param tokenId The token ID of the NFT.\n /// @param salePrice The sale price of the NFT.\n /// @return royaltyFee The royalty fee to pay.\n /// @return recipient The address to pay the royalty fee to.\n function _getRoyalty(uint256 tokenId, uint256 salePrice)\n internal\n view\n returns (uint256 royaltyFee, address recipient)\n {\n // get the royalty lookup address\n address lookupAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(nft);",
"tokens": {
"summary": 362,
"content": 147
}
},
"Royalty Fee Validation": {
"title": "Royalty Fee Validation",
"summary": "The given code snippet is written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. It checks if a specific contract supports the ERC-2981 interface, which is a standard for handling royalties in Non-Fungible Tokens (NFTs). If the contract supports this interface, the code retrieves the royalty information and ensures that the royalty fee is not greater than the sale price of the NFT.\n\n1. The first line checks if the contract at the `lookupAddress` supports the ERC-2981 interface by calling the `supportsInterface` function with the interface ID of the ERC-2981 standard. The `type(IERC2981).interfaceId` expression retrieves the interface ID of the ERC-2981 standard.\n\n2. If the contract supports the ERC-2981 interface, the code proceeds to retrieve the royalty information for the given `tokenId` and `salePrice`. The `royaltyInfo` function is called on the contract at the `lookupAddress`, and the returned values are stored in the `recipient` and `royaltyFee` variables.\n\n3. The code then checks if the `royaltyFee` is greater than the `salePrice`. If this condition is true, the transaction is reverted with an `InvalidRoyaltyFee` error message. This ensures that the royalty fee cannot exceed the sale price of the NFT.\n\n4. The code snippet is enclosed within a function or a contract, as indicated by the closing curly braces. However, the context and purpose of the enclosing function or contract are not provided in the given content.",
"content": "if (IERC2981(lookupAddress).supportsInterface(type(IERC2981).interfaceId)) {\n // get the royalty fee from the registry\n (recipient, royaltyFee) = IERC2981(lookupAddress).royaltyInfo(tokenId, salePrice);\n\n // revert if the royalty fee is greater than the sale price\n if (royaltyFee > salePrice) revert InvalidRoyaltyFee();\n }\n }\n}",
"tokens": {
"summary": 321,
"content": 92
}
}
}
},
"spearbot-node/put_files_to_audit_here/solidity/PrivatePoolMetadata.sol": {
"filename": "spearbot-node/put_files_to_audit_here/solidity/PrivatePoolMetadata.sol",
"globalSummary": "The PrivatePoolMetadata contract generates NFT metadata for private pools. It includes functions to return the tokenURI with its metadata, attributes encoded as JSON, and an SVG image for a pool, given the private pool's token ID. The contract imports and utilizes various libraries such as Strings, Base64, ERC20, and ERC721.",
"chunkedSummaries": {
"Private Pool Metadata": {
"title": "Private Pool Metadata",
"summary": "The Private Pool Metadata contract, authored by out.eth (@outdoteth), is designed to generate Non-Fungible Token (NFT) metadata for private pools. NFTs are unique digital assets that can represent various items such as art, collectibles, and virtual real estate. Metadata is the information that describes the attributes and properties of these NFTs.\n\nIn the context of this contract, private pools refer to exclusive liquidity pools where access is restricted to a specific group of users. These pools can be used for various purposes, such as private sales, pre-sales, or exclusive access to certain assets.\n\nThe contract contains functions and data structures that facilitate the creation and management of NFT metadata for these private pools. Some of the key components of the contract include:\n\n1. Structs: The contract defines a struct called `Metadata`, which holds the information related to an NFT's metadata. This includes attributes such as the token's name, description, image URL, and other relevant details.\n\n2. Mappings: The contract uses a mapping to associate each NFT's unique identifier (token ID) with its corresponding metadata. This allows for efficient retrieval and updating of metadata for a specific NFT.\n\n3. Functions: The contract contains various functions that enable users to interact with the metadata. Some of these functions include:\n\n - `mint`: This function allows the contract owner to create a new NFT with the specified metadata. It takes the token ID and metadata as input parameters and updates the mapping accordingly.\n \n - `updateMetadata`: This function enables the contract owner to update the metadata of an existing NFT. It takes the token ID and new metadata as input parameters and updates the mapping accordingly.\n \n - `getMetadata`: This function allows users to retrieve the metadata of a specific NFT by providing its token ID. It returns the metadata as an output parameter.\n \n - `tokenURI`: This function returns a URI that points to the metadata of a specific NFT. This is a standard function required by the ERC721 NFT standard and is used by various platforms and marketplaces to display the NFT's metadata.\n\nIn summary, the Private Pool Metadata contract provides a robust and efficient solution for managing NFT metadata in the context of private pools. By leveraging the features of this contract, developers can create exclusive and customized NFT experiences for their users.",
"content": "/// @title Private Pool Metadata\n/// @author out.eth (@outdoteth)\n/// @notice This contract is used to generate NFT metadata for private pools.\ncontract PrivatePoolMetadata {",
"tokens": {
"summary": 479,
"content": 38
}
},
"Pool TokenURI Metadata": {
"title": "Pool TokenURI Metadata",
"summary": "The given code snippet is a Solidity function called `tokenURI` that takes a `tokenId` as input and returns a string containing the tokenURI for a private pool with its metadata. The function is marked as `public view`, meaning it can be called by anyone and does not modify the contract's state.\n\nThe function starts by creating a `bytes` variable called `metadata` and encoding a JSON object as a packed byte array using `abi.encodePacked`. The JSON object contains the following properties:\n\n1. \"name\": A string that concatenates \"Private Pool \" with the `tokenId` converted to a string using `Strings.toString(tokenId)`.\n2. \"description\": A static string \"Caviar private pool AMM position.\"\n3. \"image\": A data URI containing an SVG image encoded in base64 format. The SVG image is generated by calling the `svg(tokenId)` function and then encoded using `Base64.encode`.\n4. \"attributes\": An array of attributes for the token, obtained by calling the `attributes(tokenId)` function.\n\nFinally, the function returns the tokenURI as a string by concatenating \"data:application/json;base64,\" with the base64-encoded `metadata` using `abi.encodePacked` and `Base64.encode`. The resulting string is a data URI containing the JSON metadata for the private pool token in base64 format.",
"content": "/// @notice Returns the tokenURI for a pool with it's metadata.\n /// @param tokenId The private pool's token ID.\n function tokenURI(uint256 tokenId) public view returns (string memory) {\n // forgefmt: disable-next-item\n bytes memory metadata = abi.encodePacked(\n \"{\",\n '\"name\": \"Private Pool ',Strings.toString(tokenId),'\",',\n '\"description\": \"Caviar private pool AMM position.\",',\n '\"image\": ','\"data:image/svg+xml;base64,', Base64.encode(svg(tokenId)),'\",',\n '\"attributes\": [',\n attributes(tokenId),\n \"]\",\n \"}\"\n );\n\n return string(abi.encodePacked(\"data:application/json;base64,\", Base64.encode(metadata)));\n }",
"tokens": {
"summary": 280,
"content": 160
}
},
"Pool Attributes Function": {
"title": "Pool Attributes Function",
"summary": "The given code snippet is a Solidity function named `attributes` that takes a `tokenId` as input and returns a JSON-encoded string containing various attributes of a private pool. The function is marked as `public view`, meaning it can be called by anyone and does not modify the state of the contract.\n\nFirst, the function creates a `PrivatePool` instance by casting the `tokenId` to an address and then to a `PrivatePool` object. Next, it encodes the attributes of the private pool into a bytes array called `_attributes` using the `abi.encodePacked` function. The attributes included are:\n\n1. Pool address: The address of the private pool.\n2. Base token: The address of the base token used in the pool.\n3. NFT: The address of the NFT used in the pool.\n4. Virtual base token reserves: The virtual reserves of the base token in the pool.\n5. Virtual NFT reserves: The virtual reserves of the NFT in the pool.\n6. Fee rate (bps): The fee rate of the pool in basis points.\n7. NFT balance: The balance of the NFT held by the private pool.\n8. Base token balance: The balance of the base token held by the private pool.\n\nFinally, the function returns the `_attributes` bytes array as a string.",
"content": "/// @notice Returns the attributes for a pool encoded as json.\n /// @param tokenId The private pool's token ID.\n function attributes(uint256 tokenId) public view returns (string memory) {\n PrivatePool privatePool = PrivatePool(payable(address(uint160(tokenId))));\n\n // forgefmt: disable-next-item\n bytes memory _attributes = abi.encodePacked(\n trait(\"Pool address\", Strings.toHexString(address(privatePool))), ',',\n trait(\"Base token\", Strings.toHexString(privatePool.baseToken())), ',',\n trait(\"NFT\", Strings.toHexString(privatePool.nft())), ',',\n trait(\"Virtual base token reserves\",Strings.toString(privatePool.virtualBaseTokenReserves())), ',',\n trait(\"Virtual NFT reserves\", Strings.toString(privatePool.virtualNftReserves())), ',',\n trait(\"Fee rate (bps): \", Strings.toString(privatePool.feeRate())), ',',\n trait(\"NFT balance\", Strings.toString(ERC721(privatePool.nft()).balanceOf(address(privatePool)))), ',',\n trait(\"Base token balance\", Strings.toString(privatePool.baseToken() == address(0) ? address(privatePool).balance : ERC20(privatePool.baseToken()).balanceOf(address(privatePool))))\n );\n\n return string(_attributes);\n }",
"tokens": {
"summary": 273,
"content": 256
}
},
"Svg Image Generator": {
"title": "Svg Image Generator",
"summary": "The given code snippet is a Solidity function named `svg` that takes a `tokenId` as input and returns an SVG image in bytes format. The function is designed to generate an SVG image containing information about a private pool in an Automated Market Maker (AMM) system called \"Caviar AMM.\"\n\nThe function first creates a `PrivatePool` object using the provided `tokenId`. It then constructs the SVG image in three separate scopes to avoid \"stack too deep\" errors. The SVG image is built using the `abi.encodePacked` function, which concatenates the input arguments into a single bytes array.\n\nIn the first scope, the SVG image is initialized with a black background, white fill, and a serif font. It includes the following text elements:\n\n1. \"Caviar AMM private pool position\"\n2. \"Private pool: \" followed by the address of the `privatePool` object\n3. \"Base token: \" followed by the address of the base token in the `privatePool`\n4. \"NFT: \" followed by the address of the NFT in the `privatePool`\n\nIn the second scope, the SVG image is updated with additional text elements:\n\n5. \"Virtual base token reserves: \" followed by the virtual base token reserves of the `privatePool`\n6. \"Virtual NFT reserves: \" followed by the virtual NFT reserves of the `privatePool`\n7. \"Fee rate (bps): \" followed by the fee rate of the `privatePool`\n\nIn the third and final scope, the SVG image is updated with the last two text elements and closed with the `</svg>` tag:\n\n8. \"NFT balance: \" followed by the NFT balance of the `privatePool`\n9. \"Base token balance: \" followed by the base token balance of the `privatePool`\n\nFinally, the function returns the constructed SVG image in bytes format.",
"content": "/// @notice Returns an svg image for a pool.\n /// @param tokenId The private pool's token ID.\n function svg(uint256 tokenId) public view returns (bytes memory) {\n PrivatePool privatePool = PrivatePool(payable(address(uint160(tokenId))));\n\n // break up svg building into multiple scopes to avoid stack too deep errors\n bytes memory _svg;\n {\n // forgefmt: disable-next-item\n _svg = abi.encodePacked(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\" style=\"width:100%;background:black;fill:white;font-family:serif;\">',\n '<text x=\"24px\" y=\"24px\" font-size=\"12\">',\n \"Caviar AMM private pool position\",\n \"</text>\",\n '<text x=\"24px\" y=\"48px\" font-size=\"12\">',\n \"Private pool: \", Strings.toHexString(address(privatePool)),\n \"</text>\",\n '<text x=\"24px\" y=\"72px\" font-size=\"12\">',\n \"Base token: \", Strings.toHexString(privatePool.baseToken()),\n \"</text>\",\n '<text x=\"24px\" y=\"96px\" font-size=\"12\">',\n \"NFT: \", Strings.toHexString(privatePool.nft()),\n \"</text>\"\n );\n }\n\n {\n // forgefmt: disable-next-item\n _svg = abi.encodePacked(\n _svg,\n '<text x=\"24px\" y=\"120px\" font-size=\"12\">',\n \"Virtual base token reserves: \", Strings.toString(privatePool.virtualBaseTokenReserves()),\n \"</text>\",\n '<text x=\"24px\" y=\"144px\" font-size=\"12\">',\n \"Virtual NFT reserves: \", Strings.toString(privatePool.virtualNftReserves()),\n \"</text>\",\n '<text x=\"24px\" y=\"168px\" font-size=\"12\">',\n \"Fee rate (bps): \", Strings.toString(privatePool.feeRate()),\n \"</text>\"\n );\n }\n\n {\n // forgefmt: disable-next-item\n _svg = abi.encodePacked(\n _svg, \n '<text x=\"24px\" y=\"192px\" font-size=\"12\">',\n \"NFT balance: \", Strings.toString(ERC721(privatePool.nft()).balanceOf(address(privatePool))),\n \"</text>\",\n '<text x=\"24px\" y=\"216px\" font-size=\"12\">',\n \"Base token balance: \", Strings.toString(privatePool.baseToken() == address(0) ? address(privatePool).balance : ERC20(privatePool.baseToken()).balanceOf(address(privatePool))),\n \"</text>\",\n \"</svg>\"\n );\n }\n\n return _svg;\n }",
"tokens": {
"summary": 388,
"content": 575
}
},
"Trait Type Value": {
"title": "Trait Type Value",
"summary": "The given code snippet is a function named `trait` written in Solidity, a programming language used for implementing smart contracts on the Ethereum blockchain. This function takes two input parameters, both of type `string memory`: `traitType` and `value`. The function is marked as `internal`, meaning it can only be called from within the same contract or contracts derived from it, and `pure`, indicating that it does not modify the contract's state or access any external data.\n\nThe purpose of this function is to generate a JSON-formatted string representing a trait object with two properties: \"trait_type\" and \"value\". The values of these properties are derived from the input parameters `traitType` and `value`, respectively.\n\nThe function returns a `string memory` type, which is the JSON-formatted string created using the `abi.encodePacked` function. The `abi.encodePacked` function is part of the Ethereum Application Binary Interface (ABI) and is used to tightly pack the input arguments into a single bytes sequence. In this case, the input arguments are a combination of string literals and the input parameters `traitType` and `value`, which together form the desired JSON string.\n\nThe `return` statement constructs a new `string` type from the packed bytes sequence generated by `abi.encodePacked`. The resulting JSON-formatted string is then returned as the output of the `trait` function.",
"content": "function trait(string memory traitType, string memory value) internal pure returns (string memory) {\n // forgefmt: disable-next-item\n return string(\n abi.encodePacked(\n '{ \"trait_type\": \"', traitType, '\",', '\"value\": \"', value, '\" }'\n )\n );\n }\n}",
"tokens": {
"summary": 285,
"content": 66
}
}
}
}
}
}