# EDGAR Filing Document

**Accession Number:** 0002024815
**File Stem:** 0002024815-26-000002
**Filing Date:** 2026-3
**Character Count:** 3263139
**Document Hash:** eba7b82d73798448c0e448990be58679
**Contains OCR:** False
**Source Format:** 

## Filing Content

## Filing Summary
**0002024815-26-000002.hdr.sgml**: 20260331

**ACCESSION NUMBER**: 0002024815-26-000002

**CONFORMED SUBMISSION TYPE**: DRS/A

**PUBLIC DOCUMENT COUNT**: 117

**FILED AS OF DATE**: 20260331

**DATE AS OF CHANGE**: 20260331

**FILER**: 

**COMPANY DATA:**
- **COMPANY CONFORMED NAME:** Comboox DAO LLC
- **CENTRAL INDEX KEY:** 0002024815
- **STANDARD INDUSTRIAL CLASSIFICATION:** FINANCE SERVICES [6199]
- **ORGANIZATION NAME:** 09 Crypto Assets
- **EIN:** 000000000
- **STATE OF INCORPORATION:** WY
- **FISCAL YEAR END:** 1231

**FILING VALUES:**
- **FORM TYPE:** DRS/A
- **SEC ACT:** 1933 Act
- **SEC FILE NUMBER:** 377-07391
- **FILM NUMBER:** 26817173

**BUSINESS ADDRESS:**
- **STREET 1:** 30 N GOULD ST STE R
- **CITY:** SHERIDAN
- **STATE:** WY
- **ZIP:** 82801
- **BUSINESS PHONE:** 307-200-2803

**MAIL ADDRESS:**
- **STREET 1:** 30 N GOULD ST STE R
- **CITY:** SHERIDAN
- **STATE:** WY
- **ZIP:** 82801

&nbsp;&nbsp;&nbsp;&nbsp; **As filed with the U.S. Securities and Exchange Commission on October ______, 2026.** 

&nbsp;&nbsp;&nbsp;&nbsp; **Registration No. ______________** 

UNITED STATES <br> SECURITIES AND EXCHANGE COMMISSION <br> Washington, D.C. 20549

## FORM S-1
REGISTRATION STATEMENT<br> UNDER THE SECURITIES ACT OF 1933

# COMBOOX DAO LLC
&nbsp;&nbsp;&nbsp;&nbsp; (Name of small business issuer in its charter)

---

| | | |
|:---|:---|:---|
| **Wyoming** | **6794** | **38-432-2575** |
| (State or other jurisdiction of incorporation or organization) | (Primary Standard Industrial Classification Code Number) | (I.R.S. Employer Identification Number) |
|  | <br> **30 N Gold St Ste R** <br> **Sheridan, Wyoming 82801** <br> **(307) 200-2803** <br>(Address, including zip code, and telephone number, including area code, of registrant's principal executive offices) <br>**Registered Agents Inc** <br> **30 N Gold St Ste R** <br> **Sheridan, Wyoming 82801** <br> **(307) 200-2803** <br>(Name, address, including zip code, and telephone number, including area code, of agent for service)  |  |

---

&nbsp;&nbsp;&nbsp;&nbsp; Approximate date of commencement of proposed sale to the public: **As soon as practicable after this Registration Statement is declared effective**.

&nbsp;&nbsp;&nbsp;&nbsp; If any of the securities being registered on this Form are to be offered on a delayed or continuous basis pursuant to Rule 415 under the Securities Act of 1933 check the following box: 🗹

&nbsp;&nbsp;&nbsp;&nbsp; If this Form is filed to register additional securities for an offering pursuant to Rule 462(b) under the Securities Act, please check the following box and list the Securities Act registration statement number of the earlier effective registration statement for the same offering. □

&nbsp;&nbsp;&nbsp;&nbsp; If this Form is a post-effective amendment filed pursuant to Rule 462(c) under the Securities Act, check the following box and list the Securities Act registration statement number of the earlier effective registration statement for the same offering. □

&nbsp;&nbsp;&nbsp;&nbsp; If this Form is a post-effective amendment filed pursuant to Rule 462(d) under the Securities Act, check the following box and list the Securities Act registration statement number of the earlier effective registration statement for the same offering. □

&nbsp;&nbsp;&nbsp;&nbsp; Indicate by check mark whether the registrant is a large accelerated filer, an accelerated filer, a non-accelerated filer, smaller reporting company, or an emerging growth company. See the definitions of "large accelerated filer," "accelerated filer," "smaller reporting company," and "emerging growth company" in Rule 12b-2 of the Exchange Act.

Large accelerated filer □ <br> Non-accelerated filer 🗹 <br> Accelerated filer □ <br> Smaller reporting company 🗹 <br> Emerging growth company 🗹 <br>

&nbsp;&nbsp;&nbsp;&nbsp; If an emerging growth company, indicate by check mark if the registrant has elected not to use the extended transition period for complying with any new or revised financial accounting standards provided pursuant to Section 7(a)(2)(B) of the Securities Act. □

**&nbsp;&nbsp;&nbsp;&nbsp; The registrant hereby amends this registration statement on such date or dates as may be necessary to delay its effective date until the registrant shall file a further amendment which specifically states that this registration statement shall thereafter become effective in accordance with Section 8(a) of the Securities Act of 1933 or until the registration statement shall become effective on such date as the Securities and Exchange Commission, acting pursuant to said Section 8(a), may determine.** 

i

**&nbsp;&nbsp;&nbsp;&nbsp; THE INFORMATION IN THIS PROSPECTUS IS NOT COMPLETE AND MAY BE CHANGED. WE MAY NOT SELL THESE SECURITIES UNTIL THE REGISTRATION STATEMENT FILED WITH THE SECURITIES AND EXCHANGE COMMISSION IS EFFECTIVE. THIS PROSPECTUS IS NOT AN OFFER TO SELL THESE SECURITIES AND IT IS NOT SOLICITING AN OFFER TO BUY THESE SECURITIES IN ANY STATE WHERE THE OFFER OR SALE IS NOT PERMITTED.**![](comboox_s1img1.jpg)

## PRELIMINARY PROSPECTUS
&nbsp;&nbsp;&nbsp;&nbsp; Subject to Completion

&nbsp;&nbsp;&nbsp;&nbsp; [ ], 2026

## COMBOOX DAO LLC
(A Wyoming Limited Liability Company)

(Registration Number on ComBoox Platform: "61AE0A9E6F")

#### Offering $3,760,000 Class B Shares
ComBoox DAO LLC ("**we**","**our**" or the "**Company**") is a Wyoming limited liability company electing to be a decentralized autonomous organization ("**DAO**") pursuant to the Wyoming Limited Liability Company Act (the "**Act**") and the Wyoming Decentralized Autonomous Organization Supplement (the "**Supplement**"), formed on November 8, 2023.

&nbsp;&nbsp;&nbsp;&nbsp; This prospectus relates to the offer and sale of our Class B members' ownership interests and rights ("**Class B Shares**") of the Company. We are offering for sale 37,600,000,000 Class B Shares (the "**Offered Shares**") at an offering price of $0.0001 per share.

&nbsp;&nbsp;&nbsp;&nbsp; We have already offered and sold 2,500,000,000 Class A Shares and 500,000,000 Class B Shares, with par value of each Share as 0.0001 USD. Each Class A Share entitles the holder to forty votes per share, while each Class B Share entitles the holder to one vote per share. However, both Class A and Class B Shares carry equal economic rights, including the same per-share entitlement to profit distributions and liquidation proceeds. See "Dilution" for additional information regarding the Class A Shares.

As of the date of this Registration Statement, the Founding Member, Mr. Li Li, owns and holds 100% of the Company's issued Class A Shares and 100% of the Company's issued Class B Shares. Following the offering, assuming full subscription of the Class B Shares as planned, the Founding Member's ownership will be as follows: 100% of Class A Shares, 1.31% of Class B Shares, representing in total approximately 72.77% of the Company's voting power.

Pursuant to the currently effective Operating Agreement, the approval of an Ordinary Resolution requires at least 75% of the voting power, and the approval of a Special Resolution requires at least 80% of the voting power. Accordingly, without the support of the Founding Member, no Ordinary Resolution or Special Resolution can be passed.

ii

The Company will be arranged, as much as possible, as a passive income entity and an on-chain DAO. It will hold the intellectual property right ("**IPR**") of smart contracts, and will automatically collect royalties incurred thereof as its revenue. All assets of the Company will be held or materially controlled by smart contracts on the public block chain. All payments and legal acts of the Company can only be conducted upon prior approvals of members by public voting. No employees will be hired, and no managers or members will be paid for remuneration either. All the legal acts of members and the Company, i.e. the actions that create, modify or terminate legal rights or obligations thereof, will be automatically recorded and processed by predefined smart contracts, and can only be triggered by the specific right-holders directly with no intermediaries or agents involved.

To facilitate a clearer understanding of how the Company automatically controls and records legal actions through the smart contract system, we have included the ComBoox White Paper (the "**White Paper**", See Exhibit 32.1) and the complete set of smart contract source code (See Exhibit 32.2) as special exhibits to this statement.

Section 7 of the White Paper provides a systematic description of 12 operational scenarios encountered in user registration, corporate governance, equity registration and transactions, and explains sequentially the specific application programming interfaces ("**APIs**") that shall be invoked, based on predefined procedures and requirements, to achieve different business objectives in each such scenario.

Section 6 of the White Paper analyzes, in detail, the conditions, procedural logic, input parameters, and legal consequences associated with these APIs, and is supplemented by intuitive logical flowcharts designed to facilitate understanding.

Section 3 of the White Paper addresses the smart contract system at a more abstract and architectural level, describing the structure, functionality, and intelligence of the various categories of smart contracts deployed within the system. In particular, this section provides a detailed explanation of the rules and terms of the Shareholders' Agreement (the constitutional document implemented in code) with respect to their specific attributes, meanings, configuration methods, and the related editorial APIs.

The smart contract source code provides the primary basis for understanding and verifying the implementation of the mechanisms described in the White Paper. It enables readers to examine how such mechanisms are implemented programmatically and, through public blockchain explorers (such as arbiscan.io), to verify the consistency between the disclosed source code and the bytecode deployed on-chain. The settings, configurations, and on-chain legal and financial records of the Company, as recorded in the relevant smart contracts, may be accessed and retrieved through ComBoox's official website (https://comboox.vercel.app/app) by clicking the ComBoox logo displayed on the front page of the website. The records may also be independently verified via arbiscan.io by searching for the relevant smart contract addresses and associated APIs.

iii

These materials are essential to an informed understanding of the Company's operational framework for users onboarding, corporate governance, equity registration, and equity transactions, including the triggering conditions and operational methods applicable to various legal actions. Accordingly, we respectfully recommend that you review and fully consider the relevant portions of the White Paper at an early stage.

Prior to this offering, there has been no public market for our shares, and, probably there will be no such legal markets within a predictable future either. Subject to the satisfaction of certain contingent conditions: (1) the registration statement, of which this prospectus forms a part, is qualified by the United States Securities and Exchange Commission (the "**SEC**"); (2) the Company is either registered with the SEC as a transfer agent for its own shares or has entered into a collaboration with a registered transfer agent; and (3) the Company's smart contracts for share trading by listing are integrated with a registered Alternative Trading System ("**ATS**"), an initial public offering ("**IPO**") will be conducted.

Investors may use USDC to directly acquire Offered Shares at the offering price under the automatically control and execution of our smart contracts. Upon closing, new shares will be automatically issued to investors and the consideration paid in USDC will be received and held by the Company directly. During the entire process of the IPO, no underwriters, brokers, dealers or other intermediaries will be involved.

We are offering our Class B Shares on a best efforts basis directly to the public without the involvement of underwriters, placement agents, or broker-dealers. No party has committed to purchase or sell any quantity of securities, and there can be no assurance that all or any portion of the offered securities will be sold. This offering will terminate on the earlier of (i) the date on which the maximum offering amount is sold or (ii) the date that is 360 days following the commencement of this offering, unless earlier terminated by us in our sole discretion. There is no minimum aggregate offering amount and no minimum purchase requirement applicable to investors. Subscriptions will be accepted on a rolling basis, and subscribed funds will be delivered directly to us upon acceptance.

We have not established an escrow, trust, or similar account for investor funds. Accordingly, investors will not have the protection of a contingency or escrow arrangement, and subscribed funds will be immediately available for our use regardless of the amount raised. As a result, investors bear the risk that we may raise only limited proceeds and may be unable to execute our broader business development plans.

iv

**&nbsp;&nbsp;&nbsp;&nbsp; We are an "emerging growth company", as that term is used in the Jumpstart Our Business Startups Act of 2012, and, as such, we are subject to reduced public company reporting requirements. We have not generated any incomes or profits.** 

**&nbsp;&nbsp;&nbsp;&nbsp; These securities are highly speculative and involve a high degree of risk. You should purchase these securities only if you can afford a complete loss of your investment. See "Risk Factors" beginning on page 6 to read about factors you should consider before buying our Shares.** 

---

| | | |
|:---|:---|:---|
|  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Per Share**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Value**  |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Initial Public Offering Price  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3760000.00  |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Underwriting Discounts and Commissions:  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.00  |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Proceeds to the Company, before expenses:  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3760000.00  |

---

***&nbsp;&nbsp;&nbsp;&nbsp; NEITHER THE SECURITIES AND EXCHANGE COMMISSION NOR ANY STATE SECURITIES COMMISSION HAS APPROVED OR DISAPPROVED OF THESE SECURITIES OR PASSED UPON THE ADEQUACY OR ACCURACY OF THIS PROSPECTUS. ANY REPRESENTATION TO THE CONTRARY IS A CRIMINAL OFFENSE.***

&nbsp;&nbsp;&nbsp;&nbsp; The date of this Prospectus is [ ], 2026.

v

 **TABLE OF CONTENTS**

---

| | |
|:---|:---|
|  | **Page** |
| [1 GLOSSARY OF TERMS](#GLOSSARY OF TERMS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2  |
| [2 TRADEMARKS AND COPYRIGHTS](#TRADEMARKS AND COPYRIGHTS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8  |
| [3 CAUTIONARY STATEMENT REGARDING FORWARD-LOOKING STATEMENTS](#CAUTIONARY STATEMENT)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8  |
| [4 PROSPECTUS SUMMARY](#PROSPECTUS SUMMARY)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10  |
| [5 RISK FACTORS](#RISK FACTORS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 23  |
| [6 USE OF PROCEEDS](#USE OF PROCEEDS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 33  |
| [7 DETERMINATION OF OFFERING PRICE](#DETERMINATION OF OFFERING PRICE)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 35  |
| [8 PLAN OF DISTRIBUTION AND TERMS OF THE OFFERING](#PLAN OF DISTRIBUTION AND TERMS OF THE OFFERING)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 35  |
| [9 DILUTION](#DILUTION)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 47  |
| [10 THE COMPANY'S BUSINESS](#THE COMPANY'S BUSINESS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 50  |
| [11 PLAN OF DISTRIBUTION AND SELLING SECURITYHOLDERS](#PLAN OF DISTRIBUTION AND SELLING SECURITYHOLDERS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 78  |
| [12 MANAGEMENT'S DISCUSSION AND ANALYSIS OF FINANCIAL CONDITION AND RESULTS OF OPERATIONS](#MANAGEMENT'S DISCUSSION AND ANALYSIS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 78  |
| [13 DIRECTORS, EXECUTIVE OFFICERS AND SIGNIFICANT EMPLOYEES](#DIRECTORS, EXECUTIVE OFFICERS AND SIGNIFICANT EMPLOYEES)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 81  |
| [14 COMPENSATION OF MANAGERS](#COMPENSATION OF MANAGERS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 82  |
| [15 CERTAIN RELATIONSHIPS AND RELATED TRANSACTIONS](#CERTAIN RELATIONSHIPS AND RELATED TRANSACTIONS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 82  |
| [16 SECURITY OWNERSHIP OF CERTAIN BENEFICIAL OWNERS AND MANAGEMENT](#SECURITY OWNERSHIP OF CERTAIN BENEFICIAL OWNERS AND MANAGEMENT)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 82  |
| [17 DESCRIPTION OF SECURITIES](#DESCRIPTION OF SECURITIES)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 84  |
| [18 SHARES ELIGIBLE FOR FUTURE SALE](#SHARES ELIGIBLE FOR FUTURE SALE)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 88  |
| [19 WHERE YOU CAN FIND MORE INFORMATION](#WHERE YOU CAN FIND MORE INFORMATION)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90  |
| [INDEX TO FINANCIAL STATEMENTS](#INDEX TO FINANCIAL STATEMENTS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-1  |
| [PART II - INFORMATION NOT REQUIRED IN PROSPECTUS](#INFORMATION NOT REQUIRED IN PROSPECTUS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; II-1  |

---

vi

**Please read this prospectus carefully. It describes our business, our financial condition and our results of operations. We have prepared this prospectus so that you will have the information necessary to make an informed investment decision.** 

 **We have not authorized anyone to provide you with any information other than that contained in this prospectus. We do not take responsibility for, and can provide no assurance as to the reliability of, any other information that others may give you. We are offering to sell, and seeking offers to buy, Offered Shares only in jurisdictions where offers and sales are permitted. The information in this prospectus is complete and accurate only as of date on the cover hereof regardless of the time of delivery of this prospectus or any sale of Offered Shares. Our business, financial condition, results of operations and prospects may have changed since that date. We are not making an offer of these securities in any jurisdiction where the offer thereof is not permitted.** 

 **For investors outside the United States: We have not taken any action that would permit this Offering or possession or distribution of this prospectus in any jurisdiction where action for that purpose is required, other than the United States. You are required to inform yourselves about and to observe any restrictions relating to the Offering and the distribution of this prospectus.** 

---

| |
|:---|
| 1 |
| *[**Table of Contents**](#Toc)* |

---

#### 1 GLOSSARY OF TERMS
We provide this glossary to help those reading this prospectus understand the industry and other technical terms that are used in this prospectus. For many of these terms, there is no generally accepted definition. In this glossary, we present our definition of such terms as used in this prospectus.

(1) "**Act**" means The Wyoming Limited Liability Company Act, as amended from time to time.

(2) "**Arbitrum One**" means the Ethereum layer-2 public blockchain network operating under the name "Arbitrum One", which is connected to the main net of Ethereum and uses a technology called "Optimistic Rollups" to improve the scalability and efficiency of Ethereum.

(3) "**AML**" means Anti-Money Laundering.

(4) "**ATS**" means Alternative Trading System.

(5) "**Backup Key**" means the other account address added by a user into its ComBoox user account, which may also be recognized by Registration Center to retrieve the User Number for identification purpose.

(6) "**Buy Orders**" means the limit buy orders and market buy orders created and placed on the List of Orders by the Verified Investors, together with sufficient USDC paid as consideration or margin, to purchase the offered Shares in Initial Offers or Sell Orders at a specific bid price or market price (Price of Paid) with a specific amount (Paid Value), in accordance with the relevant Listing Rule.

(7) "**Cashier**" means the Smart Contract adopted by the Company to hold USDC on its behalf and to automatically record, maintain and publicly document payment and receipt transactions in USDC.

(8) "**CBP**" or "**ComBoox Points**" means the ERC-20 token booked in Registration Center, the primary function of which is to act as the ComBoox Community's utility token to automatically calculate, collect and transfer royalties from user of Templates to the relevant intellectual properties' holder.

(9) "**Closed Deals**" means the deals established and settled automatically via List of Orders upon placement of a Buy Order by matching and closing the Buy Order with the available Initial Offers and Sell Orders with equal or lower offer price. They will be automatically recorded as events in List of Orders.

(10) "**ComBoox**" or "**ComBoox Platform**" means the company book-entry platform consisting of a core smart contract called "Registration Center" and a set of Template Contracts deployed on Arbitrum One, which is designed for share registration and corporate statutory books-keeping, and aims to assist users to quickly establish a legal, secure, transparent and reliable smart contract system to enable the company's stakeholders to perform legal acts related to share transactions or corporate governance in a self-service mode.

---

| |
|:---|
| 2 |
| *[**Table of Contents**](#Toc)* |

---

(11) "**ComBoox Community**" means the open, unincorporated, loose organization of CBP holders, whose primary function is to decide, through discussion forums and public voting, which new template smart contracts is suitable to be included into the ComBoox Platform, so as to improve or expand the functionality thereof.

(12) "**Company**" means ComBoox DAO LLC.

(13) "**Contractual Transfer**" means the transfer mode of Shares which shall be carried out in accordance with an Investment Agreement that the seller and the buyer entered into previously, in which the basic transaction elements shall be set out clearly such as Paid Price, Paid Value, Class of Share, payment method, and closing deadline etc.

(14) "**CTF**" means Counter-Terrorist Financing.

(15) "**DAO**" means on-chain decentralized autonomous organization.

(16) "**Days**" means natural days, each consisting of 24 hours.

(17) "**Dollar**", "**USD**" or "**$**" means the legal currency of the United States.

(18) "**DVP**" means Delivery-versus payment.

(19) "**ETH**" means the native utility token of the Arbitrum One network, issued 1:1 against Ether locked on the Ethereum mainnet bridge, used for paying transaction fees and transferable among accounts on Arbitrum One.

(20) "**ExRate**"means the fixed exchange rate, predefined and adjusted by the Company.

(21) "**Founding Member**" means the member who set up the Company and invested Royalty Interests as his initial capital contribution in exchange for his Shares.

(22) "**Fuel Tank**" means a smart contract deployed on Arbitrum One that serves as an exchange pool, enabling users to buy CBP at a fixed rate in USD set by the company, while also allowing the company to manage supply of CBP and collect revenue in USDC.

(23) "**General Meeting**" means the ONLY decision -making authority of the Company which consists of all member. All legal acts conducted on behalf of the Company shall be subject to a prior approval by the General Meeting, either through an Ordinary Resolution or a Special Resolution, and any off-chain legal documents shall only become legally effective and binding on the Company upon such approval.

(24) "**General Meeting Minutes**" means the Smart Contract adopted by the Company to automatically book and maintain the public record of the proposals and voting results at General Meetings. Each proposal, proxy, vote and resolution shall only be effective and legally binding on the Company and the member upon its registration in General Meeting Minutes.

---

| |
|:---|
| 3 |
| *[**Table of Contents**](#Toc)* |

---

(25)"**General Keeper**" means the core Smart Contract that represents the legal entity of the Company to hold crypto assets, to receive revenue incurred from Royalty Interests, to elect or impeach any managers, to make payments, and to conduct any legal acts on behalf of the Company on Arbitrum One. Therefore, contract address of General Keeper shall be specified as and can be retrieved from, directly or indirectly, the "public available identifier" in the Articles in accordance with Section 17-31-106(b) of the Supplement.

(26) "**Initial Offers**" means the limit sell orders created and placed on the List of Orders by the authorized issuer on behalf of the Company to issue new Shares of the relevant Class at a specific offer price (Price of Paid) with a specific amount (Par Value and Paid Value) and the available hours thereof, in accordance with the relevant Listing Rule, which shall also set forth other necessary elements of a capital increase deal, such as Voting Weight and Distribution Weight.

(27) "**Initial Public Offering**" or "**IPO**" refers to a company's first public sale of equity securities on a registered stock exchange.

(28) "**IPR**" means intellectual property rights.

(29) "**Hague Service Convention**" means the Convention on the Service Abroad of Judicial and Extrajudicial Documents in Civil or Commercial Matters, concluded at The Hague on 15 November 1965.

(30) "**KYC**" means Know Your Customer.

(31) "**List of Orders**" means the Smart Contract adopted by the Company to book and maintain the public records of Listing Trade in USDC, which will automatically record the Initial Offers, Sell Orders, Buy Orders, as well as the Closed Deals concerned.

(32) "**Listing Rule**" means the rule governing the Listing Transfer of specific Class of Shares with respect to the title of issuer, Class of Shares, maximum Par Value, title of verifier, maximum quantity of Investors, ceiling price, floor price, lockup days, off listing price, Voting Weight, Distribution Weight and other attributes concerned, which shall be incorporated by a Shareholders Agreement and approved by Special Resolution.

---

| |
|:---|
| 4 |
| *[**Table of Contents**](#Toc)* |

---

(33) "**Listing Transfer**" means that the transfer of Shares that is arranged by listing, i.e. the seller may place Sell Orders on the List of Orders with its acceptable offer price and sell amount, thereafter, the buyer may accordingly place Buy Orders on the List of Orders with its acceptable bid price and buy amount, and the system will automatically match and settle the Sell Orders against each Buy Order on the basis of their price and amount.

(34) "**Managers**" means the administrative officer elected by Ordinary Resolution, who have NO decision-making powers but may execute any administrative, commercial or technical matters authorized by this Agreement or approved by Ordinary Resolution.

(35) "**Members**" means the equity owners of the Company, who may enjoy and exercise the distribution rights to the profits and residual assets in proportion to the aggregate Distribution Points of each member and may enjoy and exercise the voting rights in proportion to the aggregate Voting Points of each member. For the purposes of the Operating Agreement and in most contexts relating to the Company, the term "member" may usually be used interchangeably with the term "shareholder".

(36) "**Offered Shares**" means the 37,600,000,000 Class B shares being offered by the company at an offering price of $0.0001 per share, representing the specific class of securities available for subscription by investors in this issuance.

(37) "**Operating Agreement**" means the decentralized autonomous organization operating agreement of the Company, which may be approved, adopted, and/or amended pursuant to the Agreement, as well as the Company's Articles of Organization.

(38) "**Ordinary Resolution**" means a resolution passed at a General Meeting by a special majority of the members voting in person or by proxy on the relevant motion, where the total number of Voting Points represented by the votes in favor of the motion exceeds three times the number of votes cast against it.

(39) "**OTC**" means Over-the-Counter.

(40) "**Prime Key**" means the external account address or smart contract address used to register a user's account with ComBoox that can be recognised by Registration Center to retrieve the relevant User Number for identity verification purposes.

(41) "**Registration Center**" means the core smart contract of ComBoox deployed on Arbitrum One at the address as publicly disclosed on ComBoox's website and its white paper, which has the following primary functions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a) User Registration: to register users of ComBoox against their Prime Key;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b) CBP book keeping: to record balance amount of CBP for each account holder;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c) Document Registration: to register Template Contracts and their clone copies according to the contract address; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d) Royalty Collecting: to automatically transfer certain amount of CBP from the user to the author as royalty when the user calls certain write function of the smart contract created based on the specific Template Contract developed by the author.

---

| |
|:---|
| 5 |
| *[**Table of Contents**](#Toc)* |

---

(42) "**Register of Investors**" means the Smart Contract adopted by the Company to book and maintain the public records of Verified Investors. Any application, approval, or revocation of any Verified Investors shall only be effective and legally binding on the Company and members upon its entry into Register of Investors.

(43) "**Register of Members**" means the Smart Contract adopted by the Company to book and maintain the public records of members and their shareholding situation. Any admission, alteration or revocation of any member can only be effective and legally binding to the Company and members upon its book-entry on Register of Members.

(44) "**Register of Shares**" means the Smart Contract adopted by the Company to book and maintain the public record of Shares, i.e. the Certificate of Contribution concerned. Any creation, alteration or revocation of any Share can only be effective and legally binding to the Company and members upon its book-entry on Register of Shares.

(45) "**Royalty Interests**" means a type of passive (non-operational) interest contributed by the Founding Member that provides the right to revenues generated from the use of ComBoox's Templates, consisting of: (1) royalties collected automatically, as the intellectual property right holder, from the user who invokes the corresponding write function of the smart contracts cloned based on the Templates; and (2) commissions collected automatically, as the owner of ComBoox Platform, by splitting the fore mentioned royalty revenues.

(46) "**SEC**" means the United States Securities and Exchange Commission.

(47) "**Sell Orders**" means the limit sell orders and market sell orders created and placed on the List of Orders by the shareholders to transfer their Shares at a specific offer price or market price (Price of Paid) with a specific amount (Par Value and Paid Value) and available hours thereof, in accordance with the relevant Listing Rule.

(48) "**Shares**" means a member's ownership interests and rights in the Company, which will be booked automatically on Register of Shares in form of a digital object named "Certificate of Contribution".

(49) "**Shareholder**" has the same meaning with "member", which means the equity owners of the Company, who may enjoy and exercise the distribution rights to the profits and residual assets in proportion to the aggregate Distribution Points of each member and may enjoy and exercise the voting rights in proportion to the aggregate Voting Points of each member.

(50) "**Shareholders Agreement**" means the Smart Contract adopted by the Company to record and maintain the public records of the Operating Agreement, its amendments and any restated new edition thereof. In case there is any discrepancies between the Operating Agreement and the effective Shareholders Agreement, the Shareholders Agreement shall prevail.

---

| |
|:---|
| 6 |
| *[**Table of Contents**](#Toc)* |

---

(51) "**Smart Contracts**" means the smart contracts adopted by the Company, pursuant to Section 17-31-106 of the Supplement, to govern the operations of the Company which shall be the fundamental basis for verifying the legal documents of the Company. In the event of any conflict between the Articles and the Smart Contracts, the Smart Contracts shall prevail. In the event of any conflict between the Articles and the Operating Agreement, the Articles shall prevail. In the event of any conflict between the Operating Agreement and the Smart Contracts, the Smart Contracts shall prevail. Any time the Smart Contracts are changed, the members shall cause the Articles and the Operating Agreement to be amended accordingly. The information of Smart Contracts can be queried through the specific Smart Contract representing the legal entity of the Company named "General Keeper".

(52) "**Special Resolution**" means a resolution passed at a General Meeting by a special majority of the members voting in person or by proxy on the relevant motion, where the total number of Voting Points represented by the votes in favor of the motion exceeds four times the number of votes cast against it.

(53) "**Supplement**" means The Wyoming Decentralized Autonomous Organization Supplement, as amended and in effect from time to time.

(54) "**Template Smart Contracts**" or "**Templates**" means the smart contracts adopted by the ComBoox Community and registered in Registration Center as templates to create clone copies for its users to deploy and use on ComBoox.

(55) "**Transfer Agent**" or "**TA**" means the service provider responsible for managing and maintaining records of securities ownership on behalf of a company.

(56) "**USDC**" or "**USD Coin**" means a United States dollar-pegged stable coin issued and managed by Circle Internet Financial, LLC, recorded on Arbitrum One at the address "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", and designed to maintain a stable value of $1.00 per USDC.

(57) "**Users**" means the external account holder or the smart contract that has registered as a user with ComBoox by calling the specific function of Registration Center, each of whom is assigned a User Number that represents their unique identity against their Prime Key or Backup Key.

(58) "**User Number**" means a user's identity number in ComBoox, which is automatically assigned by Registration Center during the registration process. Both the Prime Key and the Backup Key can be recognized by Registration Center to automatically return the corresponding User Number, which can be further used for identity verification, access control or confirmation of legal rights.

---

| |
|:---|
| 7 |
| *[**Table of Contents**](#Toc)* |

---

(59) "**Verified Investor**" means the user that already has his or her identity and other relevant materials verified: (1) by the relevant service provider engaged by the Company; or (2) by the manager in person. Only Verified Investor can participate in Listing Transfer, or acquire Shares of the Company to become a member, and the manager may revoke the qualification of Verified Investor, according to the suggestion of the relevant service provider, or pursuant to any applicable laws or regulations.

(60) "**White Paper**" means the informational document, filed as Exhibit 32.1, that describes, at a high level, the design, architecture, and intended operation of the ComBoox blockchain-based company book-entry platform, including typical scenarios of corporate governance and equity transaction, role-based decision-making mechanisms, on-chain and off-chain interaction models, and illustrative logic flowcharts for external APIs through which legal actions may be invoked and recorded.

#### &nbsp;&nbsp;&nbsp;&nbsp; 2 TRADEMARKS AND COPYRIGHTS
Founding Member owns or plans to apply for rights to trademarks or trade names that we use or intend to use in connection with the operation of our business, including our names, logos and website names. In addition, Founding Member owns or has the rights to patent applications, copyrights, trade secrets and other proprietary rights that protect the intellectual property used in our business, including the ComBoox Platform. In addition to the exclusive intellectual properties of ComBoox invested by Founding Member as his initial capital contribution, we also have the rights to use trademarks and trade names under royalty free, non-exclusive licenses granted by Founding Member. Our use or display of such trademarks, service marks, trade names or products in this prospectus is not intended to, and should not be read to, imply a relationship with or endorsement or sponsorship of us. Solely for convenience, some of the copyrights, trade names and trademarks referred to in this prospectus are listed without their copyright and trade mark symbols, but we will assert, to the fullest extent under applicable law, our rights to our copyrights, trade names and trademarks. All other trademarks are the property of their respective owners.

#### 3 CAUTIONARY STATEMENT REGARDING FORWARD-LOOKING STATEMENTS
This prospectus contains certain forward-looking statements that are subject to various risks and uncertainties. Forward-looking statements convey our current expectations or forecasts of future events and are not guarantees of future performance. They are based on numerous assumptions that we believe are reasonable, but they are open to a wide range of uncertainties and business risks. Our ability to predict results or the actual effect of future plans or strategies is inherently uncertain.

---

| |
|:---|
| 8 |
| *[**Table of Contents**](#Toc)* |

---

Any statements contained in the prospectus that are not statements of historical fact may be forward-looking statements, which are generally identifiable by use of terminology such as "may," "will," "should," "potential," "plan," "intend," "expect," "outlook," "seek," "anticipate," "estimate," "approximately," "believe," "could," "project," "predict," or other similar words or expressions.

Although we believe that the expectations reflected in our forward-looking statements are based on reasonable assumptions, actual outcomes could differ materially from those set forth or anticipated in our forward-looking statements. Factors that could cause our forward-looking statements to differ from actual outcomes include, but are not limited to, those described under the heading "Risk Factors". Readers are cautioned not to place undue reliance on any of these forward-looking statements, which reflect our views as of the date of this prospectus.

Furthermore, except as required by law, we are under no duty to, and do not intend to, update any of our forward-looking statements after the date of this prospectus, whether as a result of new information, future events or otherwise.

---

| |
|:---|
| 9 |
| *[**Table of Contents**](#Toc)* |

---

#### 4 PROSPECTUS SUMMARY
*This summary highlights certain information appearing elsewhere in this prospectus. Because this is only a summary, it does not contain all of the information you should consider before investing in our securities and it is qualified in its entirety by, and should be read in conjunction with, the more detailed information included elsewhere in this prospectus. Before you make an investment decision, you should read this entire prospectus carefully, including the risks of investing in our securities discussed under the section of this prospectus entitled "**Risk Factors**" and similar headings. You should also carefully read our financial statements, and the exhibits to the registration statement of which this prospectus is a part.*

**The Company's Business**

The Company is a Wyoming limited liability company electing to be a DAO pursuant to the Act and the Supplement, formed on November 8, 2023. We are engaged in the business of acquiring, holding, and commercializing the IPR related to the ComBoox Platform-a block chain-based infrastructure for automating corporate record keeping and governance through smart contracts.

**ComBoox Platform**

Human civilization has entered the 21st century. Most wealth exists in the form of book-entry interests. To regulate these wealth and their trading activities, various laws, charters and contracts are established, and different centralized intermediaries are involved. However, in case these laws, charters or contracts are violated, people can only rely on judicial remedies, which are proven to be costly and time-consuming.

The emergence of block chain technology offers a new solution. That is, to define the rules and terms in smart contracts, and use the distributed systems to automatically keep the book-entry records. By implementing the basic concepts of "Code Is Law" and "Decentralization", the terms and conditions defined by legal documents can be implemented by rigid code, and the human management of centralized intermediaries can be replaced by consensus protocols and smart contracts with automated operation.

This establishes an automated mode of asset bookkeeping and transaction management in which owners can directly manage and dispose their assets without relying on any intermediaries or counter parties.

Among the book-entry interests, except for deposit currency, company equity is probably the most important and critical category. The company is the carrier of various assets and also the investment target of capital. Its external legal acts are the main components of modern commercial activities, while its internal governance involves the rights and interests of many investors. Therefore, company equity is the critical joint linking the capital and assets, commercial activities and corporate governance.

---

| |
|:---|
| 10 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) right holders may directly exercise their rights;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) obligors have no chance to default or violate; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) real time full disclosure of each legal acts.

ComBoox adopts a civil law-style abstract concept of "legal acts" that aligns with the formal, rule-based, and state-oriented logic of smart contract systems. Under this framework, a legal act shall satisfy the following conditions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) it is based on an expression of intent, which may be manifested either expressly through natural language or implicitly through acts of performance, such as delivery or payment;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) it is undertaken with the purpose of creating, modifying, or terminating legal relationships; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) it results in definite, identifiable, and recognizable legal consequences.

**CBP and its Function**

ComBoox Points (the "**CBP**") is an ERC-20 non-redeemable token registered in Registration Center, which is used as a utility token of ComBoox to measure and collect royalties for using the Templates. Each time when a user calls specific function of the proxy contracts or clone copies of Templates, an amount of CBP will be automatically transferred from the user to the account of the Template owner. The royalty rate is predefined by the original author in the respective Template, and the beneficiary rights can be transferred on-chain to any other party.

ComBoox is an open platform. Any developer may deploy smart contracts and apply to incorporate them by the platform. As long as the application is approved by the General Meeting, the relevant smart contracts may be adopted by ComBoox as a Template. The developer can then collect royalties in CBP.

Users may acquire CBP through the following methods: (1) automatic rewards granted upon registration on ComBoox; (2) purchase using USDC from a smart contract named Fuel Tank; or (3) receipt from third parties via ERC-20 token transfers.

---

| |
|:---|
| 11 |
| *[**Table of Contents**](#Toc)* |

---

CBP is minted by the Company through the Registration Center and deposited into the Fuel Tank smart contract for user acquisition. The Company can decide the total supply of CBP and can throw significant influence on the market price thereof.

CBP is freely transferable between wallets and is not subject to any contractual or technical transfer restrictions. Users may sell or gift CBP at their discretion. CBP is divisible to 18 decimal places (i.e., the smallest unit is 10<sup>-18</sup> CBP), consistent with the ERC-20 standard, allowing for fractional use.

CBP confers no voting rights, ownership interest, equity participation, or residual claims against the Company. Holders are not entitled to any proceeds in the event of liquidation, merger, or sale of the Company. Because the operation and royalty rates of each Template are permanently encoded upon deployment to the blockchain, and remain functional in a decentralized and immutable manner, the rights of CBP holders are unaffected by changes in Company control or corporate structure.

The Company, as the owner of the Registration Center, holds the exclusive right to mint CBP and is entitled to receive a share of commission income derived from third-party royalty payments. While, the Company does not commit to redeem CBP for fiat currency, digital assets, or services. All Templates are provided on an "As Is" basis and do not include any commitment by the Company for upgrades, maintenance, or support.

**Principal Products and Services**

The Company is a Wyoming limited liability company electing to be a DAO. It engaged in the business of acquiring, holding and commercializing the IPR to collect royalties of Templates and commission of ComBoox Platform within the territory of Arbitrum One.

The Founding Member, currently as the sole developer of ComBoox, has invested the following rights and interests into the Company as capital contribution:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the beneficiary right to collect royalties of the Templates within the territory of Arbitrum One;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the beneficial right to collect up to 20% commission from royalties paid to third-party developers whose Templates are adopted by the ComBoox Platform; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the exclusive right to mint CBP.

Therefore, the Company has the right to collect the following passive income in CBP as revenue: (1) royalties for the use of Templates; and (2) commission splitting from the payment of royalties.

The Company's business model is designed to generate passive, on-chain income through rights associated with the ComBoox Platform. The Company has no employees, does not actively provide operational services; rather, it passively earns income through smart contract-defined mechanisms embedded in the platform, and will use its best efforts to avoid incurring any liabilities.

---

| |
|:---|
| 12 |
| *[**Table of Contents**](#Toc)* |

---

**No Bank Accounts and Payment Mechanism**

To mitigate the risk of insider misuse of the Company's assets and ensure transparent, member-approved governance, the Company has adopted a strict on-chain asset policy. All Company assets must be held and managed through smart contracts, and all payments must be made exclusively in ETH via the General Keeper or in USDC held by the Cashier, subject to prior approval by members through an Ordinary Resolution. The Company does not maintain any off-chain bank accounts and will not make fiat currency payments, even for government fees, registered agent services, or professional service providers.

The Company believes that with the growing acceptance and regulatory recognition of stablecoins such as USDC, an increasing number of service providers will accept on-chain assets as payment. However, in situations where fiat payments remain necessary, the Company utilizes a prepay-and-reimburse mechanism. Under this process, a member or the manager may advance the fiat payment following General Meeting approval, and then seek reimbursement in USDC through a member vote and smart contract execution.

**Transparency, Automation, and On-Chain Corporate Governance**

In accordance with Section 17-31-109 of the Supplement, which vests DAO management in its members or in a combination of members and smart contracts, the Company has structured its governance model to ensure full compliance with the statutory framework. Under the Company's Operating Agreement (the "**OA**"), the General Meeting, composed of all members, serves as the sole decision-making authority (OA §9.1.1). Managers do not possess independent authority and are limited to executing administrative, commercial, or technical functions as expressly authorized by the OA or approved by the General Meeting (OA §10.4.1). Managerial appointments and removals require approval by public vote (OA §10.4.3), and all legal acts and off-chain legal documents binding the Company require prior member approval through on-chain voting (OA §9.1.1). Company assets are strictly limited to on-chain digital assets held or controlled through smart contracts designated as the General Keeper or Cashier (OA §6.5).

To support the practical implementation of these governance principles, the Company has adopted several commercial and technical measures. These include a passive revenue model based on the automatic collection of intellectual property royalties, the absence of traditional bank accounts with all transactions executed in ETH or USDC, and the exclusive use of smart contracts for member voting, resolution validation, manager elections, asset transfers, and legal act execution. All actions require the retrieval of a "passed" resolution from the General Meeting Minutes smart contract to be validly executed.

For transparency and accountability, the Company publicly discloses all smart contract source code and testing scripts on GitHub and has verified its deployed bytecode on Arbiscan.io to ensure alignment with the published code. All material actions-including governance decisions, asset movements, and managerial changes-are conducted on-chain and subject to approval by DAO members through blockchain-based voting.

---

| |
|:---|
| 13 |
| *[**Table of Contents**](#Toc)* |

---

The Company's governance framework includes clear rules on proposal submission and voting thresholds. Members holding over 10% of Voting Points may submit proposals to the General Meeting. A quorum is established when over 25% of Voting Points are cast. Resolutions are categorized as Ordinary or Special, with Ordinary Resolutions requiring 75% approval of the votes cast, and Special Resolutions-applicable to critical matters such as amending governance rules or replacing key smart contracts-requiring at least four times as many votes in favor as against. Managers act solely to carry out the will of the members as expressed through approved Resolutions and have no discretionary authority.

To mitigate moral hazard arising from off-chain human intervention, the Company has deliberately simplified its business model, asset composition, decision-making scope, and governance procedures. For example, open-ended preparatory processes for the formulation of expressions of intent are conducted off-chain, whereas the actions that confer legal effect on such expressions-specifically, the submission of proposals and the conduct of voting-are strictly confined to on-chain processes that are automatically governed and enforced by smart contracts.

Similarly, any advance of fiat currency by stakeholders necessarily occurs off-chain. However, the approval of such advance arrangements, the related proposal and voting actions, and the disbursement of Company assets, including payments in USDC, are all required to be executed exclusively through on-chain smart contracts. Through this structure, the Company seeks to ensure that all actions capable of producing legal or economic effects with respect to the Company are subject to smart contracts' automated, rule-based execution and control.

Therefore, not all activities involving legal responsibility or expressions of intent are subject to on-chain automation. At the same time, the system is designed to reduce reliance on off-chain human intervention by streamlining governance and business processes, while still allowing different forms of intent to be expressed and executed through a clear, rule-based and automated structure.

Please refer to the relevant sections of the White Paper for a comprehensive understanding of the Company's rules and mechanisms relating to governance and voting activities, including rule configuration, voting procedures, operational methods, and logical workflows.

**Development Stage and Technical Deployment**

The ComBoox Platform is fully operational and open-source. All smart contracts, testing scripts, and users interfaces have been published on GitHub. The Company's own equity records, governance framework, and financial systems are implemented exclusively through these smart contracts, demonstrating live usage.

No additional technical milestones are required for commercialization. However, the Company expects to develop community contributions, and potentially acquire new Templates subject to members approval and funding.

---

| |
|:---|
| 14 |
| *[**Table of Contents**](#Toc)* |

---

**Competitive Position and Differentiation**

To our knowledge, ComBoox is the first public platform offering fully on-chain smart contracts for equity and corporate governance management. While various software as a service tools and blockchain registries exist, no direct competitor currently offers the same degree of automation, decentralization, and legal integration through autonomous smart contracts. We expect to compete on the basis of technological innovation, transparency, automation, and cost-efficiency rather than through traditional customer relationships or service models.

**Intellectual Property and Royalties**

The Company holds exclusive royalty and commission interests in a defined set of Templates as well as minting and pricing rights to CBP within Arbitrum One blockchain network. These interests and rights were developed and contributed by the Founding Member. However, he retains the right to deploy ComBoox on other blockchains. The Company does not currently own any patents or registered trademarks but may acquire additional IPR from external developers if approved by members vote. The source code for all Templates is publicly available, but the royalty logic embedded in smart contracts ensures enforceable monetization.

The Company protects the above intellectual properties principally through copyright law. Copyright protection for computer programs is recognized in jurisdictions that are parties to the Berne Convention and the Agreement on Trade-Related Aspects of Intellectual Property Rights, covering the vast majority of the world's principal economies. In addition, the deployment of the Company's smart contracts on public blockchains immutably records the source code, compiled bytecode, and time of publication, which may support evidentiary proof of authorship and creation date, subject to jurisdictional variations in legal treatment.

In addition, the Founding Member has filed patent applications for certain innovative algorithms and technical solutions through the Patent Cooperation Treaty process, with national phase entries in the United States and China. All such applications are under examination, and no patent rights have been granted. Notwithstanding the foregoing, the Company's use of the relevant technology and its business model are not dependent on the outcome of the patent application process, as the Company holds an exclusive license to use and commercially exploit the ComBoox system within the Arbitrum One blockchain network, which is sufficient to support its current and reasonably contemplated operations.

**Regulatory Environment and Legal Compliance**

The ComBoox Platform is a set of smart contract tools. It can be used by listed companies or private entities, subject to the discretion and compliance responsibilities of each user. The Company does not provide legal advice, governance services, or regulatory compliance on behalf of any platform user.

---

| |
|:---|
| 15 |
| *[**Table of Contents**](#Toc)* |

---

As the IPR holder and a passive royalty recipient, the Company is not responsible for how users adopt or apply the Templates. Our own regulatory obligations are limited to securities compliance as a public issuer and our pending registration as a transfer agent for our own shares. We maintain automated on-chain recordkeeping and voting to ensure transparency and support for federal disclosure requirements.

**Feasibility of Bring Legal Action Against Foreign Managers** The Company has adopted a unique smart contract-based governance and legal architecture designed to minimize risks typically associated with managerial misconduct, insider control, misrepresentation, and insider trading. All Company assets are fully controlled by smart contracts on public blockchain, and managers lack discretionary authority, access to assets, or the ability to bind the Company to off-chain contracts without member approval. All decisions and legal acts are executed and disclosed on-chain in real time, eliminating opportunities for information asymmetry or misuse. Managers are unpaid and function solely in a technical or administrative capacity, further reducing the risk of liability or misconduct.

In response to concerns about the feasibility of bringing legal actions against managers residing in foreign jurisdictions such as China, the Company notes that while service of process is permissible under the Hague Service Convention, enforcement of U.S. court judgments in China remains uncertain. Chinese courts apply a reciprocity standard and assess judgments for alignment with public policy, often rejecting those involving regulatory penalties or extraterritorial application of public laws. Furthermore, original actions based on U.S. securities laws are generally not permitted in Chinese courts due to sovereignty concerns and the classification of such laws as non-civil regulatory statutes. As such, civil liability against foreign managers under U.S. securities laws may be practically limited, though the Company's governance structure is designed to mitigate these risks at the outset.

The foregoing discussion concerning the enforceability in the PRC of U.S. judgments based on U.S. securities laws relates to issues of PRC civil procedure and judgment enforcement, and does not constitute an interpretation of U.S. law. The disclosure is based on publicly available and generally applicable PRC laws, regulations, and is not tailored to, nor dependent on, any specific facts or circumstances of the Company. This is fundamentally different from rendering a legal opinion based on the Company's particular factual situation.

The Founding Member, who also serves as a Manager, is a PRC-licensed attorney with professional experience in corporate and commercial law. In light of the general and non-fact-specific nature of the discussion described above, the inclusion of risk disclosures that may be adverse to the Company's capital-raising prospects does not give rise to a direct conflict of interest.

Similar disclosures regarding the uncertainty of enforcing U.S. securities law judgments in the PRC have been made by PRC-based issuers listed in the United States, and are commonly included as risk disclosures in U.S. securities filings. The Company acknowledges that such disclosure may negatively affect the attractiveness of its equity offering.

---

| |
|:---|
| 16 |
| *[**Table of Contents**](#Toc)* |

---

For these reasons, the Company provides the above disclosure without reliance on any formal legal opinion from PRC or U.S. counsel, and solely on the basis of the Founding Member's general understanding of PRC civil procedure law and related publicly available legal materials.

**Summary Risk Factors**

Our business and Class B Shares are subject to many risks, as more fully described in the "Risk factors" section immediately following this "Prospectus Summary" section. These risks include, among others:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Evolving regulatory environment may bring negative impact on ComBoox and the Company's revenue.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) As a newly established entity, the Company may face revenue uncertainty due to lack of track record, and no current customers, impacting investment value and profitability potential.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Market acceptance and CBP-based royalty model may impact revenue stability.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Because we lack the name recognition, customer base and resources of other companies in the internet software market, we may be unable to compete successfully which would reduce our revenue and the value of your investment.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) DAO Management Structures may impose investment risks.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Different legal requirements on statutory books may bring risks of uncertainty for the Company's revenue.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Different regulatory rules for public block chain and crypto assets may bring uncertainty risks for the Company's revenue.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) There are no established trading markets for the Company's Share, which will bring risks of uncertainty in the Company's value.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) Volatility in crypto-asset prices may bring uncertain impacts on the value of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) Security vulnerabilities in Template Smart Contracts may pose an uncertainty risk to the Company's revenues.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) The open-source nature of smart contracts makes Template Contracts susceptible to illegal copying or imitation, which in turn will negatively impact the Company's revenue.

---

| |
|:---|
| 17 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) Cyberattacks and security vulnerabilities could lead to reduced revenue, increased costs, liability claims, or harm to our reputation or competitive position.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (13) ComBoox may be deployed on other blockchains, which in turn will negatively impact the Company's revenue.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (14) Legal changes, our evolving business model, piracy, and other factors may decrease the value of our intellectual property.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (15) Third parties may claim we infringe their intellectual property rights.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (16) The Company does not set specific decision-making mechanisms for related transactions, which may bring the related transaction risks to the investors.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (17) Our Founding Member will maintain substantial voting control following the offering, which may limit your ability to influence corporate decisions.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (18) Although our governance structure minimizes managerial discretion, investors may face significant challenges in pursuing legal actions against our foreign-based managers.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (19) If no member or manager is willing to advance fiat currency payments, the Company may face operational delays or service disruptions.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (20) We are conducting this offering on a best efforts basis without a minimum offering amount, which may limit our ability to execute our business plan and increase risks to investors.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (21) Our reliance on the Arbitrum One layer-2 network and the Ethereum blockchain exposes us to risks of outages, protocol changes, security vulnerabilities, and other disruptions that could materially and adversely affect our operations and financial condition.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (22) Our exclusive forum provision requiring most disputes to be litigated in Wyoming courts may increase costs, limit preferred venues, discourage claims, and faces uncertainty regarding enforceability, though it does not apply to claims under the Securities Act or Exchange Act.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (23) Our strategy to avoid incurring liabilities by relying on prepaid arrangements and a passive business model may fail, resulting in unexpected obligations that could adversely affect our business and securities.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (24) The Company relies on the Founding Member to advance fiat currency payments for prepaid third-party service obligations, and any inability or failure by the Founding Member to do so could materially and adversely affect the Company's operations, financial condition, and the value of its securities.

---

| |
|:---|
| 18 |
| *[**Table of Contents**](#Toc)* |

---

**Plan of Distribution and Terms of the Offering**

**Conditions Precedent of Public Offering**

The Company has developed a smart contract-based trading system, known as the List of Orders, which may eventually facilitate compliant secondary trading of its Shares using USDC with automated delivery-versus-payment ("**DVP**") settlement. However, no such trading is currently permitted, and no public market for the Company's Shares presently exists or is anticipated in the near term. The commencement of the public offering is expressly conditioned upon the satisfaction of three regulatory requirements: (1) qualification of the registration statement by the SEC; (2) registration of the Company as a transfer agent with the SEC, or alternatively, integration with a registered third-party transfer agent; and (3) integration of the List of Orders system with a registered ATS and broker-dealer in full compliance with applicable laws and regulations.

Until these conditions are fully satisfied, the Company will not accept any subscriptions, payments, or investor funds in connection with the public offering, nor will any Shares be deemed sold or closings occur under the registration statement. Consequently, offering proceeds will not be placed into escrow or held conditionally, as no investor funds will be received prior to the offering's formal commencement. If the Company elects not to serve as its own transfer agent, it may instead engage a duly registered third-party transfer agent, whose system will be technically integrated with the Company's smart contract-based registers. This approach will enable regulatory compliance while maintaining the use of on-chain records as the Company's final and authoritative source of ownership and membership data.

**Legal and Technical Characteristics of ComBoox**

ComBoox introduces several legal and technical innovations that distinguish it from traditional securities market infrastructures:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **On-Chain Recordkeeping**: All equity ownership, governance actions, and financial data are automatically recorded directly on the blockchain through the Company's smart contracts. These on-chain records serve as the legally authoritative source, while any off-chain records maintained by a transfer agent are treated as non-binding backups.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Direct Asset Custody**: Shareholders maintain direct custody of their Shares via blockchain wallet addresses. Upon trade execution, smart contracts automatically update the shareholder registry, eliminating the need for intermediaries or traditional post-trade settlement procedures.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Automated DVP Settlement**: The List of Orders system facilitates real-time, atomic DVP settlement. Both asset transfer and payment (in USDC) occur simultaneously within a single blockchain transaction, fully executed through user-controlled digital wallets without reliance on centralized exchanges.

---

| |
|:---|
| 19 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Smart Contract-Based Governance and Disclosure**: Governance actions, equity transactions, and corporate financial records are executed and recorded through smart contracts. This automated process significantly reduces the need for manual post-transaction disclosures, as material information is immediately and transparently available on-chain.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Regulatory Compliance via Identity Mapping APIs**: To satisfy KYC, AML, and CTF requirements, ComBoox includes dedicated APIs that link real-world identities to blockchain wallet addresses through off-chain verification. Additional smart contract-based APIs enforce compliance functions such as investor accreditation and sanctions screening, though integration with registered ATS or exchange platforms remains necessary to meet full regulatory standards.

**Trading Mechanism of the List of Orders**

The List of Orders smart contract implements a trading system that incorporates features analogous to a central counterparty structure. It supports both market and limit orders for buying and selling, with orders prioritized based on price and then time-buy orders are arranged in descending bid price order, and sell orders in ascending ask price order. Market orders are matched against the best available counter-orders until fully executed or no further matches are available.

Order execution requires pre-funding: buyers must deposit USDC as collateral, while sellers initiate a reduction in the "Clean Paid" amount of the Shares they offer. Orders include expiration periods and are automatically removed from the order book upon expiry. Trades are matched when the bid price equals or exceeds the ask price, and settlement occurs atomically within the same blockchain transaction through a DVP mechanism. All transactions follow a strict price-time priority model to promote fairness and transparency.

**Legal Compliance Considerations**

The List of Orders system has been developed to reflect key principles of U.S. federal securities law through its smart contract-based architecture. It ensures accurate and tamper-resistant recordkeeping by maintaining immutable ownership and transaction data directly on-chain. Order execution follows publicly accessible and pre-defined rules, promoting fair access and full transparency. Trades are executed based on price-time priority, supporting best execution practices and efficient order handling.

Investor protection is addressed through API-enforced identity verification and real-time on-chain data availability, with future integration options for automated disclosures. The system facilitates instantaneous and atomic DVP settlement, reducing traditional clearing delays and counterparty risks. Moreover, the transparent nature of on-chain transactions, when combined with wallet-to-identity mapping, may enable effective oversight and enforcement against insider trading and other forms of market abuse.

---

| |
|:---|
| 20 |
| *[**Table of Contents**](#Toc)* |

---

**Public Offering and Distribution Plan**

Subject to the satisfaction of the regulatory conditions outlined above, the Company intends to conduct its IPO exclusively through an automated, smart contract-based mechanism known as the List of Orders on Arbitrum One. The offering will be conducted at a fixed price of $0.0001 per Share on a first-come, first-served basis, without involvement from underwriters, brokers, or intermediaries. Investors must submit USDC-deemed to have a constant value of $1.00-as collateral along with their Buy Orders. Orders are automatically matched and settled using a price-time priority protocol. Upon matching, Shares are issued and USDC is transferred to the Company's on-chain treasury (i.e. the smart contract Cashier) through an atomic DVP process. Excess or unmatched collateral is either refunded immediately or held in a smart contract-governed escrow, inaccessible by any human actor.

The offering is designed for full automation and transparency, with all transactions and order book data recorded and accessible on-chain. Unmatched Buy Orders may be canceled at any time, triggering an automatic refund of USDC. Additionally, the List of Orders supports secondary trading, allowing Sell Orders from members to be automatically matched with Buy Orders from investors without brokers or market-makers. These trades are executed through smart contracts that manage share issuance and payment distribution directly to the seller's on-chain wallet, ensuring that the entire process remains decentralized and trustless.

**Best Efforts Offering**

The Company confirms that its offering will be conducted on a best efforts basis without the involvement of underwriters, placement agents, or broker-dealers, and there is no guarantee that the full offering amount will be sold. The offering is made directly to the public under an effective registration statement, with no minimum aggregate subscription requirement. It will remain open until the earlier of the sale of the maximum number of Shares or 360 days from the commencement date, unless terminated earlier by the Company. Investor funds will not be placed in escrow, as there are no conditions precedent to closing; instead, funds will be delivered directly to the Company upon subscription acceptance.

This offering structure aligns with the Company's capital-light, royalty-based business model. Operating as a passive IPR holding entity with no employees or fixed overhead, the Company generates revenue through pre-deployed smart contracts that function independently of future development. The Company has adopted a flexible, capital-responsive strategy, adjusting the scale and scope of operations based on the total proceeds raised. While greater proceeds may support broader initiatives, a lower raise may necessitate phased or scaled-back development. Investors should be aware that the level of business activity-and associated returns-may vary depending on actual offering results.

---

| |
|:---|
| 21 |
| *[**Table of Contents**](#Toc)* |

---

**The Offering**

We are offering up to 37,600,000,000 Class B Shares at a price of $0.0001 per share. If all the Offered Shares are sold, the Company will receive $3,760,000 in gross proceeds, but there can be no assurance that all or any of the shares will be sold.

**Classes of Shares and Voting Power**

The Company has issued two Classes of Shares: Class A Shares and Class B Shares. Comparing with Class B Shares, Class A Shares have 40 times Voting Weight. All the Shares can be issued or traded in fractions with a minimum unit of a Share.

The Company has issued 2.5 billion Class A Shares and 500 million Class B Shares to the Founding Member at the price of $0.0001 per Share. All such Shares are subject to a lock-up period until June 30, 2027, during which time they may not be transferred, pledged, or otherwise disposed of except as permitted by a Special Resolution of the General Meeting.

**Deferred Evaluation of Royalty Interests**

In addition to the capital contributions made in ETH and USDC totaling $7,500 for the subscription of 75 million Class B Shares, the Founding Member also invested the Royalty Interests as a part of his capital contribution, however, the value of which is subject to a deferred valuation, recognition and adjustment as further discussed hereunder. Due to: (i) there are no similar DApps available in the market; (ii) ComBoox was developed solely by the Founding Member; and (iii) it has not generated material revenue, it is difficult to recognize the Royalty Interests value when the Founding Member contributed it to exchange for the Initial Shares. Thus, the value of Royalty Interests will be deferred recognition until a reliable valuation report is created based on the actual revenue of the Company after it has legally publicly issued its equity Shares and CBP, and received material revenue for more than one year.

If the appraised value of the Royalty Interests exceeds the outstanding balance of the subscription price payable by the Founding Member, the Founding Member shall have the right to either subscribe for Class B Shares at a price of $0.0001 per share or receive an equivalent value in USDC from the Company. In such a case, the Company shall be obligated to issue additional Class B shares or make an equivalent payment in USDC to the Founding Member, as requested.

If the appraised value of the Royalty Interests is lower than the outstanding balance of the subscription price payable by the Founding Member, the Founding Member may choose to pay the difference in USDC or opt to reduce excess amount of Initial Shares in the order of Class B to Class A.

To safeguard the interests of investors, the Company shall not make any distribution until the Royalty Interests valuation has been completed and the paid-in capital amount of the Founding Member's Class A Shares has been duly confirmed.

---

| |
|:---|
| 22 |
| *[**Table of Contents**](#Toc)* |

---

**Use of Proceeds**

The Company estimates that it will receive approximately $3,760,000 in net proceeds if all Offering Shares are sold. The principal purposes of this offering are multifaceted: (1) to comply with the SEC's legal requirements for the public issuance of security tokens; (2) to promote broader industry recognition-among both decentralized and traditional financial sectors-of the potential for smart contracts to automate legal processes, thereby advancing the concepts of "Code is Law" and "Decentralization"; (3) to establish a public market for both the Company's Shares and its platform utility token, CBP; (4) to enable future access to public equity markets; (5) to enhance public awareness and adoption of the ComBoox Platform; and (6) to raise additional capital for business development.

The Company intends to use the net proceeds primarily to support the development and promotion of the ComBoox Platform. This includes the procurement of advertising and promotion services (online and offline), blockchain infrastructure services (such as web application hosting, public storage, and cloud computation), and essential professional services (such as legal, accounting, audit, and registration services) to ensure lawful and sustainable operations. Additionally, a portion of the proceeds may be used to acquire IPR from developers of new Templates, subject to the developers' willingness to sell.

Importantly, in accordance with the provisions of the Operating Agreement and the algorithms embedded in the Company's smart contracts, all material decisions-including the allocation or adjustment of offering proceeds-must be approved by the General Meeting of members, the sole governing authority of the Company. As such, any modification to the intended use of proceeds will require a resolution adopted by the members, including those newly admitted through this offering.

#### 5 RISK FACTORS
5.1 Evolving regulatory environment may bring negative impact on ComBoox and the Company's revenue.

The novelty of ComBoox means that existing laws and regulations may not fully encompass or compatible the unique aspects of the business model. This can lead to ambiguities that affect how we conduct business. Automatic bookkeeping equity and corporate governance records means the company concerned will act as a transfer agent for its own shares, especially for public offered shares. Given the international nature of many blockchain and capital markets, ComBoox may face a complex web of global regulations. Navigating these varying legal requirements is a substantial challenge that could impact the acceptance to ComBoox solution, circulation of CBP, as well as the revenue of us. The Company actually is an on-chain passive income entity fully managed by members through public voting. Although the Company is incorporated in Wyoming, however, the jurisdiction in which the Shares and CBP is traded can lead to conflicts and ambiguities in regulatory compliance.

---

| |
|:---|
| 23 |
| *[**Table of Contents**](#Toc)* |

---

**&nbsp;&nbsp;&nbsp;&nbsp; 5.2 As a newly established entity, the Company may face revenue uncertainty due to lack of track record, and no current customers, impacting investment value and profitability potential.** 

As a newly established entity, we face significant revenue risks inherent to our early stage of operations. Our success is contingent upon the business mode of ComBoox to attract and retain users, which is uncertain given the innovation nature of the mode. Without a proven track record or existing user base, we may encounter challenges in convincing potential users to adopt concepts or Template Contracts of ComBoox. Furthermore, the absence of immediate revenue streams subjects us to financial pressures that can impact our ability to acquire new IPR, marketing, and other growth initiatives. Our survival and growth are heavily dependent on achieving market acceptance and generating sales, which are inherently uncertain processes. Investors should be aware that our lack of revenue to date increases the risk of not achieving profitability in the short term, or potentially at all, which could have a material adverse effect on our business and the value of their investment.

5.3 Market acceptance and CBP-based royalty model may impact revenue stability

The success of our operations is critically contingent upon the sustained market acceptance of ComBoox across both existing and emerging markets. Any decline in market acceptance could significantly impair our revenue and profitability.

Our business model is based on the collection of royalties for each Templates adopted by ComBoox Platform, and the commission splitting from the royalties paid to IPR holders other than the Company. Although the licensing rate is predefined by the original author of the Templates, all royalties and commission will be collected in CBP. The exchange price of CBP against USDC, the total supply of CBP, and the commission rate based on which to split the royalties from other copyright holders will be determined by the Company through Ordinary Resolution. We may be unsuccessful in changing these sales policies of ComBoox. Any increase in the portion of revenue attributable to commission or royalties will depend on our successful anticipation of users' willingness to use Templates of ComBoox.

5.4 Because we lack the name recognition, customer base and resources of other companies in the internet software market, we may be unable to compete successfully which would reduce our revenue and the value of your investment.

If we fail to promote ComBoox successfully or if we incur significant expenses promoting and maintaining ComBoox, we may experience a material adverse effect on our business, financial condition and operating results. Due in part to the still emerging nature of the market for block chain application and the substantial resources available to many of our competitors, we may have a time-limited opportunity to achieve and maintain market share.

We believe that developing and maintaining awareness of the ComBoox will be critical to achieving widespread acceptance of our concepts. We believe that brand recognition will become increasingly important as competition in the market for our revenue increases. Successfully promoting and positioning ComBoox will depend largely on the effectiveness of our marketing efforts. As a result, we may need to expand our financial commitment to creating and maintaining brand awareness among potential customers.

---

| |
|:---|
| 24 |
| *[**Table of Contents**](#Toc)* |

---

5.5 DAO Management Structures may impose investment risks.

As a DAO, our management structure inherently carries certain risks that are distinct from traditional corporate models. The decentralized nature of a DAO means that decision-making is typically governed by consensus among its members, which can sometimes lead to slower response times and less centralized control over strategic direction. This can result in a lack of clear leadership and accountability, potentially impacting the efficiency and effectiveness of operations. Although we have implemented a DAO governance framework featuring differentiated voting rights and managerial oversight to counteract the potential inefficiencies of decentralized management, the innovative and non-traditional aspects of this organizational model may continue to present risks to the interests of our shareholders.

5.6 Different legal requirements on statutory books may bring risks of uncertainty for the Company's revenue.

As an innovative application, ComBoox utilizes smart contracts to automatically maintain companies' book-entry records of equity transaction and corporate governance such as Register of Shares, Register of Shareholders, Register of Directors, General Meeting Minutes, and so on. Therefore, the different legal requirements for the said statutory books of companies in various jurisdictions will directly affect the market space and development speed of ComBoox platform, which in turn will affect the Company's revenue and its growth.

5.7 Different regulatory rules for public block chain and crypto assets may bring uncertainty risks for the Company's revenue.

The operation of the ComBoox Platform relies on the proper functioning of and free access to the Arbitrum One and Ethereum block chains, and the Company's primary assets are in form of crypto assets such as ETH and USDC. Therefore, if a jurisdiction restricts or prohibits the operation of the public blockchain network or prohibits the trading and circulation of the relevant native token assets, it will result in the ComBoox platform not being available to companies in that jurisdiction. As a result, different regulatory rules for public blockchain and crypto assets in jurisdictions around the world may bring risks of uncertainty for the Company's revenue.

5.8 There are no established trading markets for the Company's Share, which will bring risks of uncertainty in the Company's value.

As an on-chain book-entry certificate, the Company's equity currently has no legal trading exchange and it is likely that no such legal trading exchange may be established in a predictable future. The Company has already built its own automated listing and trading system on Arbitrum One with smart contracts to facilitate investors to trade the Company's shares by public bidding, but it needs to pass the SEC's filing and registration procedures regarding Transfer Agents in order to operate legally. The ability to trade the Company's shares under this model in the future will significantly impact the liquidity of the Company's Shares and, in turn, the value of the Company.

---

| |
|:---|
| 25 |
| *[**Table of Contents**](#Toc)* |

---

5.9 Volatility in crypto-asset prices may bring uncertain impacts on the value of the Company.

The Company will take ETH as one of its primary assets and payment instruments. Therefore, price volatility of crypto-assets, especially ETH, will bring an uncertain impact on the Company's value and revenue expectations.

5.10 Security vulnerabilities in Template Smart Contracts may pose an uncertainty risk to the Company's revenues

Smart contracts and blockchain protocols may have security vulnerabilities or logical flaws in business logic, data security, etc., may be subject to hacking or unexpected system crashes, and may fail to realize desired transaction results or asset disposition arrangements. In the event of such an incident, ComBoox's reputation and market prospects would be negatively impacted, which in turn may negatively impact the Company's revenue.

5.11 The open-source nature of smart contracts makes Template Contracts susceptible to illegal copying or imitation, which in turn will negatively impact the Company's revenue.

The reasons that smart contracts can gain trust and build credibility lye in making the source code publicly available. Stakeholders can clearly understand the logic and algorithms of the code and expect certainty in the outcome of the disposition of rights and interests through the automated execution of the code, thus building trust in the smart contracts. The attributes of open source code makes it easy for smart contracts to be illegally copied or imitated. Once illegally copied or imitated, the Company's royalty and commission income from the ComBoox platform will be negatively impacted. No company would accept to base its book-entry records on a platform with legally flawed intellectual property, so the Company is not so concerned about third parties competing in an infringing manner. However, this will inevitably have a negative impact on the Company's revenue any way.

5.12 Cyberattacks and security vulnerabilities could lead to reduced revenue, increased costs, liability claims, or harm to our reputation or competitive position.

Threats to IT security can take a variety of forms. Individual and groups of hackers and sophisticated organizations, including state-sponsored organizations or nation-states, continuously undertake attacks that pose threats to ComBoox and Smart Contracts adopted by the Company. These actors may use a wide variety of methods, which may include developing malicious smart contracts or exploiting vulnerabilities in hardware, software, or other infrastructure in order to attack smart contracts deployed based on Template Contracts of ComBoox or gain access to special write functions thereof, using social engineering techniques to induce users to disclose passwords or other sensitive information or take other actions to gain access to users' private key, or acting in a coordinated manner to launch distributed denial of service or other coordinated attacks. Nation state and state sponsored actors can deploy significant resources to plan and carry out exploits.

---

| |
|:---|
| 26 |
| *[**Table of Contents**](#Toc)* |

---

Cyberthreats are constantly evolving and becoming increasingly sophisticated and complex, increasing the difficulty of detecting and successfully defending against them. We may have no current capability to detect certain vulnerabilities, which may allow them to persist in the environment over long periods of time. Cyberthreats can have cascading impacts that unfold with increasing speed across Arbitrum One networks and systems and those of shareholders, managers, or users of Comboox. Breaches of our facilities and network, could disrupt the security of block chain systems and ComBoox Platform, impair ability of ComBoox to serve to users and protect the privacy of their private keys, result in harming our reputation or competitive position, result in theft or misuse of our intellectual property or other assets, adversely affect our business and income.

5.13 ComBoox may be deployed on other blockchains, which in turn will negatively impact the Company's revenue

Since collecting CBP across chains would add unnecessary technical difficulties, Founding Member only invested the beneficial rights to royalties and commission for Template Smart Contracts within the territory of Arbitrum One as a capital contribution to the company. In other words, Founding Member retained the rights to deploy and operate ComBoox Platform on other blockchains. Therefore, in the event that Founding Member deploys and operates ComBoox on other blockchains, there will be a competitive negative impact on the Company's revenue.

5.14 Legal changes, our evolving business model, piracy, and other factors may decrease the value of our intellectual property.

Protecting our intellectual property rights and combating unlicensed copying and use of Template Contracts of ComBoox and other intellectual property on a global basis is difficult. Reductions in the legal protection for software intellectual property rights could adversely affect revenue. Changes in the law may continue to weaken our ability to prevent the use of Template Contracts or collect revenue. These include legislative changes and regulatory actions that make it more difficult to obtain injunctions, and the increasing use of legal process to challenge illegal piracy. The royalties we can obtain to monetize our intellectual property may decline because of the evolution of technology, or the difficulty of discovering infringements.

5.15 Third parties may claim we infringe their intellectual property rights.

From time to time, others may claim we infringe their intellectual property rights. The number of these claims may grow because of constant technological change in the markets in which we compete, the extensive patent or copyright coverage of existing technologies, the rapid rate of deployment of smart contracts and issuance of new patents. To resolve these claims, we may have to defend these challenges. These outcomes may cause operating margins to decline. Besides money damages, in some jurisdictions plaintiffs can seek injunctive relief that may limit or prevent importing, marketing, and selling Template Contracts that have infringing technologies.

Although Founding Member is very confident of the cleanliness of the intellectual property of the Template Smart Contracts, as an inalienable right of action, any third party may still claim that we are infringing on their intellectual property rights, which in turn could have an uncertain impact on the value of the Royalties Interests and the Company's revenue.

---

| |
|:---|
| 27 |
| *[**Table of Contents**](#Toc)* |

---

5.16 The Company does not set specific decision-making mechanisms for related transactions, which may bring the related transaction risks to the investors.

The Company has not established any special withhold voting or similar procedures for related transactions and relies solely on the dispersion of shareholdings and the openness of voting to ensure the fairness of the price and terms of the transactions, which may expose investors to some degree of related transaction risks.

**5.17. Our Founding Member will maintain substantial voting control following the offering, which may limit your ability to influence corporate decisions.**

Upon completion of this offering, our Founding Member, Mr. Li Li, is expected to beneficially own and control approximately 72.77% of our total voting rights, while continuing to hold 100% of our Class A Shares. As a result, he will retain decisive influence over all matters requiring member approval, including the appointment or removal of managers, approval of operating policies, amendments to governing agreements, and other significant corporate actions.

Under our Shareholders Agreement, the approval of an Ordinary Resolution requires at least 75% of the voting power and the approval of a Special Resolution requires at least 80% of the voting power. Accordingly, no Ordinary Resolution or Special Resolution can be passed without the affirmative support of Mr. Li Li. This concentration of voting power will effectively give him a veto over all shareholder decisions, thereby limiting your ability as an investor to influence the governance or direction of the Company.

Our Operating Agreement is designed to safeguard minority investors by requiring supermajority approvals for key corporate actions. Specifically, an Ordinary Resolution requires at least 75% of the votes cast, meaning that proposals supported by Mr. Li Li can be blocked if other members act collectively. For even more significant matters-such as amendments to the Shareholders Agreement, capital increases, or replacement of our smart contract systems-a Special Resolution requiring over 80% approval is mandated. These high approval thresholds serve to enhance investor protection and ensure that major corporate decisions reflect broad consensus among members.

**5.18. Although our governance structure minimizes managerial discretion, investors may face significant challenges in pursuing legal actions against our foreign-based managers.**

Our governance system is built around transparent, automated, and tamper-resistant smart contracts that control all corporate acts, including financial transactions, asset transfers, and governance decisions. Managers are structurally limited to performing purely technical or administrative functions in accordance with member-approved on-chain resolutions. They hold no unilateral authority, possess no access to Company assets, and receive no remuneration. These safeguards are designed to reduce traditional legal risks associated with insider control, managerial abuse, or fiduciary breaches.

---

| |
|:---|
| 28 |
| *[**Table of Contents**](#Toc)* |

---

However, our manager, i.e. the Founding Member, currently resides outside the United States. As a result, investors may encounter substantial difficulties in serving legal process, enforcing U.S. court judgments, or initiating legal proceedings based on U.S. federal securities laws. While service of process in China is permitted under the Hague Service Convention, whoever, enforcement of U.S. judgments in China is rare, and subject to reciprocity, procedural validity, and public policy review.

In addition, China does not have treaties providing for the recognition and enforcement of judgements of courts with the U.S. and many other countries and regions, and Chinese courts do not generally recognize the extraterritorial application of U.S. securities laws and are unlikely to permit original actions under such statutes. These jurisdictional and legal limitations may substantially impair investors' ability to assert claims, recover damages, or obtain injunctive relief against managers residing in foreign countries like China.

The foregoing discussion concerning the enforceability in the PRC of U.S. judgments based on U.S. securities laws relates to issues of PRC civil procedure and judgment enforcement, and does not constitute an interpretation of U.S. law. The disclosure is based on publicly available and generally applicable PRC laws, regulations, and is not tailored to, nor dependent on, any specific facts or circumstances of the Company. This is fundamentally different from rendering a legal opinion based on the Company's particular factual situation.

The Founding Member, who also serves as a Manager, is a PRC-licensed attorney with professional experience in corporate and commercial law. In light of the general and non-fact-specific nature of the discussion described above, the inclusion of risk disclosures that may be adverse to the Company's capital-raising prospects does not give rise to a direct conflict of interest.

Similar disclosures regarding the uncertainty of enforcing U.S. securities law judgments in the PRC have been made by PRC-based issuers listed in the United States, and are commonly included as risk disclosures in U.S. securities filings. The Company acknowledges that such disclosure may negatively affect the attractiveness of its equity offering.

For these reasons, the Company provides the above disclosure without reliance on any formal legal opinion from PRC or U.S. counsel, and solely on the basis of the Founding Member's general understanding of PRC civil procedure law and related publicly available legal materials.

---

| |
|:---|
| 29 |
| *[**Table of Contents**](#Toc)* |

---

**5.19. If no member or manager is willing to advance fiat currency payments, the Company may face operational delays or service disruptions.**

Because the Company does not maintain any off-chain bank accounts and operates under an on-chain-only asset policy, it does not directly make payments in fiat currency. Instead, fiat-based obligations-such as state filing fees, registered agent services, or legal retainers-must be prepaid by a designated member or manager and subsequently reimbursed in USDC through smart contracts, subject to approval by the General Meeting.

If, at any time, no member or manager is willing or able to advance fiat funds for these purposes, the Company may be unable to pay required administrative fees, retain necessary professional services, or satisfy legal obligations. This could result in delays in regulatory compliance, legal filings, or the maintenance of good standing in its jurisdiction of formation.

To mitigate this risk, the Founding Member, Mr. Li Li-who holds a substantial equity interest in the Company-has expressed a willingness to enter into a written commitment (see. Exhibit-32.3) to use best efforts to advance fiat payments in accordance with legal agreements or budgets that have been formally approved by the General Meeting. While this commitment does not guarantee coverage of all fiat obligations, it reflects the Founding Member's alignment of interest with the Company and its investors. Nevertheless, there can be no assurance that such prepayments will always be timely, sufficient, or feasible under all circumstances.

**5.20. We are conducting this offering on a best efforts basis without a minimum offering amount, which may limit our ability to execute our business plan and increase risks to investors.**

This offering is being conducted on a best efforts basis, and there is no minimum offering amount that must be sold for the offering to proceed. No underwriter, placement agent, or broker-dealer has agreed to purchase or distribute any specific quantity of our securities. As a result, the Company may raise only a limited amount of proceeds, or none at all, and there is no assurance that we will raise sufficient capital to achieve our business objectives.

Because we do not have a pre-defined minimum amount to be raised, and because we operate a capital-light business model based on passive royalty collection from deployed smart contracts, we do not depend on specific capital thresholds to maintain our going concern status. However, our ability to implement strategic initiatives-including product expansion, licensing partnerships, marketing campaigns, and third-party integrations-will depend on the amount of proceeds ultimately raised.

If we raise substantially less than the maximum offering amount, we may need to defer or scale back some of our proposed business activities, which could delay execution, reduce competitiveness, and adversely affect potential returns for investors.

---

| |
|:---|
| 30 |
| *[**Table of Contents**](#Toc)* |

---

**5.21. Risks Related to Our Technology and Reliance on Third-Party Blockchain Networks (Arbitrum One and Ethereum)**

Our operations rely on the proper functioning and continued development of Arbitrum One, a public layer-2 scaling network that records transaction data and state roots on the Ethereum blockchain. If Arbitrum One or Ethereum were to experience disruptions, degradation in performance, delays, forks, vulnerabilities, or other adverse events, our systems could be impaired. For example, outages of the Arbitrum sequencer, congestion in block production or settlement, or failures in data availability could delay or prevent on-chain recordkeeping, governance actions, or settlement of transactions.

In addition, because Arbitrum One depends on Ethereum for finality and security, any disruption, material change, or vulnerability in Ethereum could adversely affect the integrity and reliability of Arbitrum One. The governance of both Arbitrum One and Ethereum is decentralized and outside our control, and protocol-level changes or upgrades could impose additional requirements, necessitate significant modifications to our smart contracts, or introduce unforeseen risks.

Moreover, vulnerabilities in cross-chain bridges, rollup infrastructure, or within our own smart contracts could lead to security incidents, loss of assets, or interruption of services. If Arbitrum One or Ethereum do not perform as expected, become unavailable, or otherwise experience adverse changes, our business, financial condition, and results of operations could be materially and adversely affected.

 **5.22. Risks Related to the Dispute Resolution Provision in Our Amended and Restated Operating Agreement** 

Our Amended and Restated Operating Agreement contains a dispute resolution provision that designates the United States District Court for the District of Wyoming or the state courts located in Wyoming as the exclusive forums for substantially all disputes arising out of or relating to the agreement, and members irrevocably waive, to the fullest extent permitted by law, any objection to venue in such courts. We adopted this forum selection clause in light of our formation under the Supplement, which provides a unique statutory framework tailored to blockchain-based and decentralized entities and expressly recognizes the prevailing effect of smart contracts. By designating Wyoming courts, we sought to ensure that disputes are adjudicated in a jurisdiction most familiar with the Supplement.

Nevertheless, this exclusive forum provision may increase the cost or difficulty of bringing a claim, particularly for investors located outside of Wyoming, and may discourage lawsuits or limit investors' ability to bring claims in judicial forums that they consider more convenient or favorable. In addition, there is uncertainty as to whether a court would enforce this type of exclusive forum provision in all contexts.

---

| |
|:---|
| 31 |
| *[**Table of Contents**](#Toc)* |

---

This dispute resolution provision does not apply to claims arising under the Securities Act of 1933, as amended, or the Securities Exchange Act of 1934, as amended. Section 22 of the Securities Act provides for concurrent jurisdiction of federal and state courts over claims under the Securities Act, while Section 27 of the Exchange Act provides for exclusive federal jurisdiction over claims under the Exchange Act. To the extent that the exclusive forum provision is ever interpreted to apply to claims under the Securities Act or the Exchange Act, there is uncertainty as to whether a court would enforce such provision, and investors cannot waive compliance with the federal securities laws and the rules and regulations promulgated thereunder.

 **5.23. Our strategy to avoid incurring liabilities by relying on prepaid arrangements and a passive business model may fail, resulting in unexpected obligations that could adversely affect our business and securities.** 

We intend to minimize our assumption of liabilities by not borrowing funds, not hiring employees, and contracting for services only on a prepaid basis. There can be no assurance, however, that these measures will be effective in all circumstances. Unexpected claims, regulatory requirements, or unforeseen expenses may arise that cannot be addressed solely through prepayments. If we are required to assume liabilities that we have not anticipated, we may not have the resources to satisfy them, and our financial condition and the value of our securities could be materially and adversely affected.

Our reliance on prepaid arrangements with service providers may also create risks. Because we pay in advance for services such as marketing or advisory work, we are unable to defer or renegotiate payment obligations if services are not performed as expected. If a counterparty fails to deliver services for which we have prepaid, we may be unable to recover the funds, which could result in financial losses and operational disruptions.

In addition, our business model depends on the assumption that our smart contracts, which generate licensing revenues, will not require ongoing maintenance or support. These smart contracts are licensed on an "AS IS" basis, without any representation or warranty as to defects, security, or future upgrades. Nonetheless, defects, vulnerabilities, or disputes may arise that could expose us to claims or remediation costs. Any such liabilities could negatively affect our operations, financial condition, and the value of our securities.

**5.24. The Company relies on the Founding Member to advance fiat currency payments for prepaid third-party service obligations, and any inability or failure by the Founding Member to do so could materially and adversely affect the Company's operations, financial condition, and the value of its securities.**

The Company's operating model is designed to minimize the assumption of liabilities by entering into service agreements strictly on a prepaid basis. To facilitate this, the Founding Member has undertaken to use his best efforts to advance any fiat currency payments required under approved third-party service agreements. This mechanism ensures that the Company will not approve any contract that it cannot financially support, and that, once a contract is approved, the Founding Member is fully capable of advancing the necessary funds for the associated prepayment commitment.

---

| |
|:---|
| 32 |
| *[**Table of Contents**](#Toc)* |

---

However, the Company is dependent on the Founding Member's ability and commitment to advance such payments. If, for any reason, the Founding Member is unable or unwilling to advance the required funds, the Company may be unable to satisfy its prepaid obligations, which could materially and adversely affect its operations, financial condition, and the value of its securities.

#### &nbsp;&nbsp;&nbsp;&nbsp; 6 USE OF PROCEEDS
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; We estimate that our net proceeds from the offering will be approximately $3,760,000 if all the Offering Shares are sold. We intend to use the net proceeds from the offering as follows:

The principal purposes of this offering are to: (1) comply with the SEC's legal requirements for the public issuance of security tokens;(2) encourage both the crypto and traditional financial industries to seriously consider the broader implications of using smart contracts to automate legal actions-thereby advancing the concepts of "Code is Law" and "Decentralization"; (3) create a public market for our Shares and CBP;(4) facilitate future access to public equity markets; (5) increase awareness of ComBoox Platform among potential customers and end-users; and (6) raise additional capital.

We intend to use the net proceeds for the following purpose:

&nbsp;&nbsp;&nbsp;&nbsp; (1) to purchase online or offline advertising services, promotion services, code audit services or other services to promote ComBoox Platform;

&nbsp;&nbsp;&nbsp;&nbsp; (2) to purchase the web application platform services, block chain access services, public storage services, cloud storage and calculation services, and other necessary services for ComBoox Platform to operate legally, smoothly and healthily;

&nbsp;&nbsp;&nbsp;&nbsp; (3) to purchase necessary accounting services, financial auditing services, legal services, registration agent services or other necessary professional services to make the Company, as well as ComBoox Platform, be able to operate and develop in compliance with the governing laws and regulations; and

&nbsp;&nbsp;&nbsp;&nbsp; (4) to purchase the IPR derived from any new Templates that may be adopted by ComBoox in the future, provided that the relevant developers are willing to sell.

&nbsp;&nbsp;&nbsp;&nbsp; This expected use of the net proceeds from the offering represents our intentions based upon our current plans and business conditions. As of the date of this prospectus, we cannot predict with certainty all of the particular uses for the net proceeds to be received upon the completion of the offering or the amounts that we will actually spend on the uses set forth above.

The amounts and timing of our actual expenditures may vary significantly depending on numerous factors, including the number of potential IPR we intend to acquire, the status of negotiations for such IPR, and any unforeseen needs.

---

| |
|:---|
| 33 |
| *[**Table of Contents**](#Toc)* |

---

However, as per the provisions of the OA, as well as the algorithm predefined in the smart contracts, unlike many traditional listed companies, all material decisions of the Company, including the use of offering proceeds, are subject to the authority of the General Meeting, the ONLY decision-making authority of the Company which consists of all members. Accordingly, any allocation or adjustment to the use of proceeds will require prior approval through resolutions adopted by the members, including any new investors admitted through this offering.

Notwithstanding the foregoing, for illustrative purposes and to assist investors in understanding the Company's intended capital allocation, the Company has provided below a projected budget breakdown and a table illustrating the planned use of proceeds in scenarios where 25%, 50%, 75%, and 100% of the maximum offering is sold.

&nbsp;&nbsp;&nbsp;&nbsp; **Preliminary Budget Estimates**

---

| | | |
|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S.No.**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Use of Proceeds**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Estimated Budget Range(USD)**  |
| (a) | KYC/AML Service (5 yrs) | $100000 - $200000 |
| (b) | ATS Collaboration (5 yrs) | $150000 - $300000 |
| (c) | Blockchain Network Access (5 yrs) | $50000 - $100000 |
| (d) | Dapp Vercel Server (5 yrs) | $50000 - $100000 |
| (e) | Dapp Database (5 yrs) | $50000 - $100000 |
| (f) | Smart Contract Codes Audit | $25000 - $30000 |
| (g) | Cybersecurity Audit | $25000 - $30000 |
| (h) | Financial Audit (5 yrs) | $50000 - $100000 |
| (i) | Legal & Administrative Fees (5 yrs) | $100000 - $200000 |
| (j) | Dapp UI Design and Upgrades | $100000 - $200000 |
| (k) | Marketing and Advertisement | $200000 - $500000 |
| (l) | Reserve for New Templates | $200000 - $500000 |
|  | **Residual Proceeds** | **$2660000 - $1400000** |
|  | **Total Estimated Range** | **$1100000 - $2360000** |

---

---

| |
|:---|
| 34 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; **Allocation Principles**

&nbsp;&nbsp;&nbsp;&nbsp; • **Type i (Scalable)**: Items (a) through (e) are flexible and may scale according to user volume and network activity.

&nbsp;&nbsp;&nbsp;&nbsp; • **Type ii (Optional/Contingent)**: Item (g) may depend on the nature of collaboration with an ATS.

&nbsp;&nbsp;&nbsp;&nbsp; • **Type iii (Annualized)**: Items (h) and (i) are recurring yearly costs.

&nbsp;&nbsp;&nbsp;&nbsp; • **Type iv (Discretionary)**: Items (f), (j) and (l) are discretionary enhancements and will be initiated only if 75% or more of the maximum offering is achieved.

&nbsp;&nbsp;&nbsp;&nbsp; • **Type v (Adjustable)**: Item (k) is scalable based on available funding.

&nbsp;&nbsp;&nbsp;&nbsp; • **Type vi (Working Capital)**: Any residual proceeds not allocated above will be used as general working capital.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Use of Proceeds Table (Illustrative) (Thousand USD)**

---

| | | | | |
|:---|:---|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Category**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25% Proceeds**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 50% Proceeds**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 75% Proceeds**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100% Proceeds**  |
| Type i (a-e) | 100 - 200 | 200 - 400 | 300 - 600 | 400 - 800 |
| Type ii (g) |  |  | 15 - 18 | 25 - 30 |
| Type iii (h,i) | 37.5 - 75 | 75 - 150 | 112.5 - 225 | 150 - 300 |
| Type iv (f, j, l) |  |  | 165 - 368 | 325 - 730 |
| Type v (k) | 50 - 125 | 100 - 250 | 150 - 375 | 200 - 500 |
| **Residual Proceeds** | 540 - 752.5 | 1080 - 1505 | 1234 - 2027.5 | 1400 - 2660 |
| **Total Proceeds** | 940 | 1880 | 2820 | 3760 |

---

&nbsp;&nbsp;&nbsp;&nbsp; *Note: Figures above are approximations and subject to modification based on final General Meeting resolutions and actual proceeds received.* 

#### &nbsp;&nbsp;&nbsp;&nbsp; 7 DETERMINATION OF OFFERING PRICE
&nbsp;&nbsp;&nbsp;&nbsp; The offering price of the Offering Shares is determined by us considering our capital structure, prevailing market conditions, and overall assessment of our business.

#### 8 PLAN OF DISTRIBUTION AND TERMS OF THE OFFERING
8.1 Offering

We are offering up to 37,600,000,000 Class B Shares at a price of $0.0001 per share. There is no minimum number of shares we are required to sell nor is there a minimum amount of money we are required to raise from this offering. If we sell all the shares offered, we will receive $3,760,000 in gross proceeds, but there can be no assurance that all or any of the shares will be sold.

---

| |
|:---|
| 35 |
| *[**Table of Contents**](#Toc)* |

---

8.2 Conditions Precedent of Public Offering

Although a public market for the Company's Shares does not currently exist, and no such legal market is anticipated in the near term, the Company has developed a smart contract-based trading system that may eventually support compliant secondary trading. This system, known as the smart contracts List of Orders, enables trading of Shares in USDC with automated DVP settlement. However, no such trading is currently permitted until appropriate regulatory requirements are satisfied.

The Company confirms that the commencement of the public offering is contingent upon the satisfaction of three regulatory conditions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) The registration statement, of which this prospectus forms a part, is qualified by the SEC;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) The registration of the Company as a transfer agent with the SEC, or alternatively, the establishment of formal cooperation and technical integration with a registered third-party transfer agent; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) The integration of List of Orders system with a registered ATS and broker-dealer, in a manner compliant with applicable regulations.

No subscriptions, payments, or investor funds will be accepted under the public offering unless and until all of the above conditions are fully satisfied. The Company confirms that no shares will be deemed sold under the registration statement, and no closings will occur, unless and until all specified conditions precedent to the offering are satisfied. No investor funds (including USDC) related to the public offering will be received or accessed by the Company until the offering is formally commenced. Accordingly, the offering proceeds will not be placed into escrow or otherwise conditionally held, as no subscriptions will be accepted until the offering becomes active.

The Company also clarifies that, should it determine not to act as its own registered transfer agent, it may instead enter into a service agreement with a duly registered third-party transfer agent, whose system will be integrated with the Company's smart contract-based registers (e.g., Register of Shares, Register of Members). This arrangement would allow the Company to comply with applicable transfer agent rules, while preserving the use of on-chain records as the final and legally conclusive record keeping system.

Importantly, the Company confirms that this restriction on the commencement of the public offering does not preclude the Company from engaging in a private placement of securities prior to the IPO, in reliance on applicable exemptions from registration under the Securities Act, such as Regulation D. Any such private placements would be conducted separately, with distinct investor communications, documentation, and processes, and would be targeted solely to qualified investors as permitted by law. The Company will take appropriate measures to ensure that any private placement is not integrated with the registered offering, including maintaining a clear separation in timing, offering terms, and investor base.

---

| |
|:---|
| 36 |
| *[**Table of Contents**](#Toc)* |

---

8.3. AML/KYC Validation Process

The Company has designed a hybrid on-chain/off-chain process to ensure that only qualified investors who have satisfied applicable AML and KYC requirements may subscribe for, acquire, or transfer the Company's Shares.

**8.3.1. On-Chain Investor Whitelisting**

Within the Register of Investors smart contract, the Company has established a dedicated mapping and array structure that records investor identifiers and their qualification status. This operates as a dynamic whitelist to ensure that only approved investors may hold or transact in the Company's Shares.

**8.3.2. Smart Contract Functions for Investor Qualification**

There are three write functions specifically designed to manage AML/KYC status:

**(1) "Reg Investor" Function:** This function may be called by a user seeking to participate in the Company's shares. It registers the applicant's user number, the representative's user number of its concert party group, and the hash value of the applicant's off-chain KYC documentation.

**(2) "Approve Investor" Function:** This function approves a registration request or reinstates a previously revoked qualified investor. It may only be called by a user assigned the role of "Verifier," thereby granting the investor the ability to hold or transfer shares.

**(3) "Revoke Investor" Function:**This function revokes an investor's qualified status and may only be called by a Verifier.

For more detailed information about the three APIs mentioned above, as well as the logic flowcharts, please refer to Section 6.11 of the White Paper.

**8.3.3. Verifier Role and Governance**

A "Verifier" is defined in the Company's Shareholders Agreement, which also incorporates the Company's listing rules. Verifiers may include directors, officers, shareholders, external KYC service providers, transfer agents, or ATS operators. The allocation of Verifier roles is expressly approved by the Members when they adopt the Shareholders Agreement.

---

| |
|:---|
| 37 |
| *[**Table of Contents**](#Toc)* |

---

Please refer to Section 3.3.1(6) of the White Paper for a detailed explanation of the attributes of the listing rules; Section 3.3.3 for the editorial APIs of the Shareholders Agreement to add, update or remove the rules; Section 7.2 for the procedures and flowcharts governing updates to the Shareholders Agreement; and Section 6.1 for the relevant APIs and associated logic flowcharts applicable to such updates.

**8.3.4. Whitelist Mechanism**

This governance framework ensures that the whitelist is controlled by authorized parties, and that membership approval, revocation, or reinstatement of investor qualification is subject to Members' approved delegation of authority.

**8.3.5. Integration with Third-Party Automated KYC Providers**

The Company intends to engage third-party automated KYC service providers or cooperate with the transfer agent or ATS operator that use facial recognition, OCR, and remote photo ID verification technologies to validate nationality, age, identity, and other personal details. The provider will remotely verify investor information, bind such information to the investor's wallet address, and store personal data securely within the United States. The results of this review and a hash value of the applicant's data will be provided as inputs to the above said functions of the List of Orders. The Verifier will then, either automatically or with manual oversight, use these results to approve, revoke, or reinstate the investor's qualified status.

**8.3.6. Transaction Controls and Freeze Capability**

All write functions related to the disposition of the Company's shares are subject to qualification checks. If an investor is not whitelisted, the smart contract will automatically block the transaction process. This structure also enables the Company to comply with lawful directives: upon receipt of a judicial or regulatory order, a Verifier may revoke an investor's qualification, thereby freezing the account's trading privileges.

**8.3.7. Timing of the Process**

With the integration of automated KYC service APIs into the centralized web application interface of ATS or transfer agent, investor qualification can typically be completed within minutes for each applicant. Prior to the IPO, the Company expects to complete this integration in cooperation with its ATS operator or transfer agent. Post-IPO, this automated process will continue to be maintained jointly by the Company's KYC provider, ATS operator, and transfer agent.

---

| |
|:---|
| 38 |
| *[**Table of Contents**](#Toc)* |

---

**8.3.8. Data Protection**

To comply with U.S. federal requirements concerning privacy, national security, data security, and cybersecurity, all applicant KYC documentation and personal data will be securely stored, backed up, and maintained within the United States by the Company's third-party KYC provider, ATS operator, or transfer agent.

**8.3.9. logical flowcharts and operational process**

To facilitate the potential investors' understanding of the Company's governance and operational framework, the Company has filed, as Exhibit-32.1 to this statement, the White Paper. It includes complete APIs lists, function definitions, functional summaries, and logic flowcharts for all write operations. (Please refer to Section 7.1 - "Apply for Qualified Investor Status", Section 7.4 - "Trade Equity by Listing (in USDC)", and Section 6.12 - "APIs routed to LOO Keeper" for detailed explanation.)

The Company believes these clarifications provide a comprehensive explanation of its governance, shareholder recordkeeping, equity trading, and AML/KYC compliance arrangements as implemented through smart contracts.

8.4. Share Recordkeeping And Use of a Transfer Agent

The Company intends to maintain a hybrid share record-keeping system that combines blockchain-based smart contracts with the services of a duly registered third-party transfer agent.

The Company's smart contract-based register records share issuance, ownership, transfers, and corporate governance actions automatically and immutably on a blockchain by reference to digital wallet addresses. These on-chain records provide real-time, tamper-resistant documentation of share ownership and governance activity, but do not contain personally identifiable information.

If remote KYC/AML service providers are not available to provide permanent off-chain storage of PII and ongoing AML monitoring services, the Company will probably not be able to act as a transfer agent by itself. Instead, the Company intends to engage a transfer agent registered with the SEC pursuant to Section 17A(c) of the Securities Exchange Act of 1934. The transfer agent will maintain off-chain shareholder account records and perform the functions required under Exchange Act Rules 17Ad-1 through 17Ad-20, including recordkeeping, record retention, monitoring and reporting of record differences, safeguarding of records, and lost securityholder searches. Through this engagement, the Company will comply with applicable transfer agent rules without itself acting as a transfer agent.

---

| |
|:---|
| 39 |
| *[**Table of Contents**](#Toc)* |

---

8.5. Personally Identifiable Information and KYC/AML Compliance

All PII of shareholders, including information collected for KYC/AML and sanctions screening purposes, will be obtained, processed, stored, and retained off-chain by the transfer agent or regulated service providers engaged by the transfer agent or ATS operator. The Company's blockchain records are pseudonymous and do not store personal data.

Because PII is held off-chain, the transfer agent's activities are subject to applicable U.S. privacy, data security, and AML regulations, including Regulation S-P, Regulation S-ID, the Gramm-Leach-Bliley Act, the Bank Secrecy Act, FinCEN rules, and OFAC sanctions requirements.

8.6. Integration of On-Chain and Off-Chain Records

The on-chain and off-chain systems are linked through the shareholder's blockchain wallet address, which serves as the primary key connecting share ownership records to shareholder identity records.

In the event of any discrepancy between the Company's smart contract-based registers and the records maintained by the transfer agent:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the on-chain smart contract records will control with respect to share ownership, transfer history, and corporate governance matters, as they constitute the first-hand and authoritative source of such information; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the transfer agent's off-chain records will control with respect to shareholder identity, KYC/AML status, and other personally identifiable information, as they constitute the first-hand and authoritative source of such information.

This structure is designed to combine the transparency and immutability of blockchain-based recordkeeping with compliance with U.S. securities, transfer agent, privacy, and AML regulations.

8.7. Legal and Technical Characteristics of ComBoox

ComBoox incorporates several legal and technical distinctions from traditional securities markets, as outlined below.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **On-Chain Recordkeeping**: Equity ownership, governance acts, and financial records are recorded directly on-chain through the Company's smart contracts. These on-chain records are deemed the legally authoritative source of truth. Any off-chain records maintained by a transfer agent serve solely as non-binding backups.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Direct Asset Custody by Investors**: In contrast to traditional custodial models, shareholders hold Shares directly through blockchain-based wallet addresses. Upon execution of a trade, the relevant smart contracts automatically update the shareholder registry to reflect the new owner, eliminating the need for intermediary custodians and post-trade settlement layers.

---

| |
|:---|
| 40 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Automated DVP Settlement**: The List of Orders system enables atomic, real-time DVP settlement, meaning that the delivery of Shares and payment (in USDC) occur simultaneously within a single blockchain transaction. All trades are executed directly through user-controlled digital wallets, with no reliance on centralized accounts or exchange infrastructure.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Smart Contract-Based Governance and Disclosure**: Corporate governance actions, equity transactions and financial records are initiated and recorded automatically via smart contracts. This reduces or eliminates the need for post hoc manual disclosures, as relevant material information is transparently and instantly available on-chain.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Real Name Authentication and Regulatory APIs**: In compliance with KYC, AML and CTF obligations, the system sets out special APIs to map real-world identities to wallet addresses via off-chain verification processes. Smart contract APIs are implemented to enforce investor verification, accreditation, and sanction list screening, although integration with regulated exchange or ATS platforms is still required for full compliance.

8.8. Trading Mechanism of the List of Orders

The List of Orders implements a central counterparty-like structure with the following features:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**(1) Order Types and Matching**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A. Buy and Sell Orders may be either market or limit orders.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B. Orders are sorted by price and time: Buy Orders in descending bid order; and sell orders in ascending ask order.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C. Market orders match against all available counter-orders until fully executed or until no further matches exist.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(2) Order Execution and Margin Requirements**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A. Buy Orders require pre-funded USDC as collateral.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B. Sell Orders trigger a decrease in the Clean Paid amount of the subject Shares.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C. Orders include a defined expiration period and are automatically removed from the order book upon expiry.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D. Matching occurs when the bid price equals or exceeds the ask price, and transactions are executed at the seller's price.

---

| |
|:---|
| 41 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(3) Settlement and Order Handling**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A. Settlement occurs atomically via DVP in the same blockchain transaction as order execution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B. All trades follow "price-time priority" to ensure fairness and transparency.

8.9. Peer-to-Peer Transactions and Order-Book Trading

The Company's shares may be issued or transferred only through mechanisms implemented by the Company's smart-contract system and subject to applicable securities laws, transfer restrictions, and compliance controls. Transactions may occur through one of the following two mechanisms, each of which is subject to a unified compliance and supervisory framework administered by a registered ATS operator.

**(1) Peer-to-Peer Transactions**

Shares may be issued or transferred on a peer-to-peer basis through a bilateral contractual process that does not involve automated order matching. In such transaction, a transferor (or, in the case of an issuance, the controlling shareholder acting on behalf of the Company) and transferee (or subscriber) enter into an investment agreement smart contract specifying the material terms of the transaction, including the number and class of shares, consideration, and settlement conditions. Such investment agreement is created, registered, and executed through the Register of Agreements smart contract, with settlement and corresponding updates to share ownership effected through the Register of Shares smart contract.

Participation in peer-to-peer transaction is limited to investors who have completed KYC and AML onboarding and have been approved as qualified investors. KYC/AML onboarding, ongoing monitoring, and the designation and maintenance of verified investor status are intended to be administered by the ATS operator. If an investor or shareholder is determined to be non-compliant, including due to concerns relating to market manipulation, sanctions, or AML risk, the ATS operator may revoke the verified investor status of such user. Upon revocation, the user's account will be restricted from buying or selling the Company's shares, including through peer-to-peer transfers.

In accordance with the Voting Rules set out in the Shareholders Agreement, investment agreements relating to capital increase transactions require approval by the General Meeting with the affirmative vote of at least 80% of the total voting points, whereas investment agreements relating to secondary share transfer transactions are not subject to approval by the General Meeting.

---

| |
|:---|
| 42 |
| *[**Table of Contents**](#Toc)* |

---

The detailed conditions, procedures, and operational processes applicable to the peer-to-peer issuance, subscription, and transfer of shares are set out in Sections 7.3 and 6.6 of the White Paper. Further details regarding the attributes of the Voting Rules applicable to different types of transactions (Rule No.1~7) are provided in Section 3.3.1(2) of the White Paper.

**(2) Order-Book Trading and ATS Integration**

Shares may also be issued or transferred through an on-chain order-book mechanism implemented by the List of Orders smart contract, which facilitates price discovery and automated order matching based on price-time priority.

Following integration with a registered ATS, transfers effected through the order-book trading mechanism will occur on the ATS and will be subject to the control and supervision of the ATS operator. All participants eligible to submit buy or sell orders through the order-book mechanism are required to complete KYC and AML onboarding administered by the ATS operator and to maintain verified investor status.

The ATS operator controls the externally owned account assigned the authority role within the smart-contract system, which authorizes the operator to approve, revoke, or reinstate user eligibility to trade the Company's shares. Through this Authority role, the ATS operator may freeze, suspend, or reinstate trading accounts and may halt or resume order-book trading in response to compliance, regulatory, or supervisory requirements.

Any issuance or trading of shares by way of listing must be conducted in accordance with a specific Listing Rule set out in the Shareholders Agreement. The creation and addition of any new Listing Rule requires approval by the General Meeting with affirmative votes representing at least 80% of the total voting points. The procedures, applicable interfaces (APIs), and logical process flowcharts for the issuance, subscription, and trading of shares by listing in USDC are described in Sections 7.4 and 6.12 of the White Paper. Further details regarding the attributes of the Voting Rules applicable to update the Shareholders Agreement (Rule No.8) are provided in Section 3.3.1.(2) of the White Paper, and the attributes of the Listing Rules are set out in Section 3.3.1.(6) thereof.

Currently, the Shareholders Agreement provides for only one Listing Rule (Rule No. 1024), which governs this public offering and the subsequent listing and trading of Class B shares.

**(3) Unified Compliance and Supervisory Framework**

Both peer-to-peer transfers and order-book trading of the Company's Shares are subject to a unified compliance and supervisory framework administered by the ATS operator. This framework includes KYC and AML onboarding, ongoing monitoring, the ability to revoke verified investor status, and the ability to restrict or suspend trading activity at the account level. As a result, all transactions involving the Company's shares-whether conducted on a peer-to-peer basis or through the order-book mechanism-are capable of being supervised and controlled by the ATS operator.

---

| |
|:---|
| 43 |
| *[**Table of Contents**](#Toc)* |

---

8.10. Legal Compliance Considerations

The List of Orders system is designed to align with key principles of U.S. federal securities law, as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Books and Records**: Immutable smart contracts ensure accurate and tamper-proof recordkeeping for ownership and transaction history.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Fair Access and Transparency**: Orders are executed according to transparent, pre-coded rules that are publicly auditable on-chain.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Best Execution and Order Handling**: The system ensures that orders are filled at the best available prices, according to price-time priority logic.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Investor Protection and Disclosure**: Smart contract APIs enforce identity verification, and real-time on-chain data ensures transparency. Future integrations may support automated AI driven investor verification.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Clearing and Settlement**: DVP settlement occurs instantly and atomically, eliminating traditional clearing delays and reducing counterparty risk.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Insider Trading and Market Abuse Prevention**: The transparency of on-chain transactions, combined with wallet-based identity mapping, creates the potential for effective monitoring and enforcement against unlawful trading practices.

8.11. Public Offering and Distribution Plan

Subject to satisfaction of the conditions precedent discussed in Section 8.2, the Company intends to conduct its initial public offering exclusively through an on-chain mechanism known as the "List of Orders," implemented via smart contracts deployed on the Arbitrum One blockchain network.

The initial offering price has been fixed at $0.0001 per Share. The offering will not involve a book-building process, underwriter syndication, or allocation procedures. All Shares will be sold at this fixed price on a first-come, first-served basis through the automated smart contract system. For purposes of the offering, USDC will be deemed to maintain a constant value of 1.00 U.S. dollar.

When submitting a Buy Order, an investor must transmit a sufficient amount of USDC, included with the transaction call, as collateral to cover the full subscription price for the desired number of Shares. The offering smart contracts will verify the adequacy of the submitted collateral in real time and will automatically reject any Buy Order that is undercollateralized.

Upon successful placement, the Buy Order will be automatically matched against Initial Offers (as defined in Section 1(26)) using a price-time priority protocol encoded in the List of Orders smart contract. All matched transactions will be executed at the fixed offering price of $0.0001 per Share.

---

| |
|:---|
| 44 |
| *[**Table of Contents**](#Toc)* |

---

Each matched transaction will be settled through an atomic DVP mechanism, whereby:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the subscribed Shares are simultaneously issued to the Verified Investor's on-chain account; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the corresponding USDC consideration is transferred directly to the Company's on-chain treasury smart contract, the "Cashier".

Any USDC provided as collateral in excess of the amount to fulfill a matched Buy Order will be automatically refunded to the investor's designated "primary key" wallet address, i.e. the account address used by the investor to register the user number with ComBoox.

If a Buy Order is not fully matched at the time of placement, the unmatched portion will be recorded on the open order book, and the full amount of USDC collateral will be transferred into a dedicated, on-chain escrow account governed entirely by the offering smart contracts system.

Critically, no members or managers of the Company have access to or control over escrowed USDC. The escrow account is implemented through immutable smart contract logic, and the funds held in escrow cannot be accessed or redirected by any human actor or private key holder.

The smart contract permits only two possible outcomes for escrowed funds:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Transfer to the Company's Cashier upon successful matching of the Buy Order with an Initial Offer; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Refund to the investor's wallet upon full or partial cancellation of the Buy Order.

These outcomes are executed automatically and without manual intervention.

Investors may cancel any unmatched Buy Order at any time prior to execution. Upon cancellation, the full amount of the associated USDC collateral will be immediately refunded.

To avoid pricing volatility risks for both the Company and investors, the Company has elected not to accept ETH or other volatile digital assets for payment in the offering. By limiting payment methods to USDC-a stablecoin pegged 1:1 to the U.S. dollar-the offering ensures that the value of consideration is stable, transparent, and not subject to intra-transaction fluctuation.

The offering will not involve underwriters, brokers, dealers, or other financial intermediaries. The entire offering process-including order submission, matching, settlement, share issuance, and payment-will be executed automatically and transparently via on-chain smart contracts deployed on the Arbitrum One network. No post-trade clearing, reconciliation, or manual processing will be required.

---

| |
|:---|
| 45 |
| *[**Table of Contents**](#Toc)* |

---

All offering-related transactions and order book data will be visible on-chain and accessible to investors. Any proposed material changes to the offering mechanics, smart contract architecture, or accepted forms of consideration will be communicated publicly and, where required, filed with the Commission as an amendment to this registration statement.

The offering is intended to commence promptly following the effectiveness of this Registration Statement and the satisfaction of the conditions precedent described in Section 8.2. The offering will remain open for up to 360 days from commencement, unless extended or terminated in accordance with applicable law.

Furthermore, the List of Orders also can list all Sell Orders placed by members and automatically match and close deals against the Buy Orders placed by investors. During the listing trade, no brokers, dealers or market-makers will involve. Shares will be created, adjusted or revoked under the automatic control of smart contracts, and consideration in USDC will be booked under the name of seller with his or her exclusive control.

8.12. Best Efforts Offering

The Company confirms that the offering will be conducted on a best efforts basis. No underwriter, placement agent, or broker-dealer has committed to purchase or sell any specific quantity of securities, and there is no assurance that the full amount of the offering will be sold. The securities are being offered directly by the Company to the general public, including both accredited and non-accredited investors, pursuant to an effective registration statement under the Securities Act of 1933.

The Company has not established any minimum aggregate offering amount and this offering will remain open until the earlier of (i) the date on which the maximum offering amount is sold or (ii) the date that is 360 days following the commencement of the offering, unless earlier terminated by the Company in its sole discretion.

This approach is consistent with the Company's business model and capital structure. As previously disclosed, the Company operates as a passive IPR holding entity, with no employees, executive compensation, or fixed operating overhead. Its revenue is intended to be generated through the automated collection of royalties from its deployed and functional blockchain-based smart contract templates. These smart contracts have already been developed, tested, and deployed, and are capable of generating licensing income without reliance on future operational milestones.

Because the Company is capital-light and not dependent on external development, staffing, or infrastructure buildout, it is capable of continuing as a going concern regardless of the total amount of proceeds raised. Accordingly, the Company has not arranged for investor funds to be placed in an escrow, trust, or similar account, as there are no conditions precedent to closing that would warrant a contingency or escrow arrangement. Subscribed funds will be delivered directly to the Company upon acceptance of each investor's subscription.

---

| |
|:---|
| 46 |
| *[**Table of Contents**](#Toc)* |

---

Importantly, the Company does not maintain a pre-determined or fixed business plan. Instead, the Company has adopted a flexible, capital-responsive development approach, whereby the scope, timing, and scale of any prospective business development or partnership strategies will be determined based on the actual amount of capital raised in the offering. Should the capital raised be substantial, the Company may pursue more expansive initiatives; if proceeds are modest, it will implement a correspondingly smaller or phased strategy. This proportional planning model allows the Company to maintain operational integrity and fiscal discipline under varying capital scenarios.

Investors are accordingly advised that the Company's ability to pursue business development activities-such as licensing arrangements, marketing outreach, or partnership programs-will depend on the final offering proceeds. While the Company intends to deploy funds prudently to maximize long-term value, there can be no assurance that the amount raised will be sufficient to fund all envisioned initiatives. A smaller-than-expected raise may result in the deferral, modification, or reduction of certain strategic plans, which could affect the timing and magnitude of potential returns.

#### 9 DILUTION
&nbsp;&nbsp;&nbsp;&nbsp; As per the Operating Agreement, members shall enjoy their voting rights based on the aggregate Voting Points of their Shares and may claim profits distribution or residual assets of the Company based on the aggregate Distribution Points of their Shares as well.

To date, the Company has issued the following Class A Shares and Class B Shares to the Founding Member. In addition to the Royalty Interests, the Founding Member has made a capital contribution in ETH and USDC equivalent to $7,500.00:

---

| | | | |
|:---|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Certificate No.**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of Shares**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3000000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Par Value per Share**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Par Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $250000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $50000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $300000.00  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Paid Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $7500.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $7500.00  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4,000 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Voting Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100000000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100500000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Distribution Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3000000000  |

---

---

| |
|:---|
| 47 |
| *[**Table of Contents**](#Toc)* |

---

Due to: (i) there are no similar DApps available in the market; (ii) ComBoox was developed solely by the Founding Member; and (iii) it has not generated material revenue, it is difficult to recognize the Royalty Interests value when the Founding Member contributed it to exchange for the Initial Shares. Thus, the value of Royalty Interests will be deferred recognition until a reliable valuation report is created based on the actual revenue of the Company after it has legally publicly issued its equity Shares and CBP, and received material revenue for more than one year.

Once the value of the Royalty Interests is recognized, it shall be booked in the account of "Intangible Assets" on the debit side, and in the account of "Paid In Capital" on the credit side, as paid in capital contributed by the Founding Member. If it is greater than the unpaid subscription amount of the Initial Shares, the Company shall further issue such number of new Class B Shares whose Paid Value and Par Value are all equal to the excess amount; or, if it is less than the unpaid subscription amount of the Initial Shares, the Founding Member may, at its discretion: (i) pay the outstanding amount in USDC; or (ii) cause the Company to decrease the excess amount of Initial Shares in the order of Class B to Class A.

Prior to the recognition of the Royalty Interests value, the Company shall NOT distribute any profits or assets to members and the Voting Points and Distribution Points of all Shares shall be calculated on the basis of their Par Value, whether or not the Shares are paid up.

If you purchase Class B Shares in the Offering, your interest will be diluted to the extent of the difference between the initial public offering price and the pro forma as adjusted Equity Entitlement per Share of Class B immediately after the Offering.

Equity Entitlement per Share of Class B is determined by allocating our total Paid In Capital in proportion to the Distribution Points of Class B Shares outstanding.

Dilution per Dollar Par Value of Class B Shares to investors participating in the Offering represents the difference between the per Dollar Par Value price paid by purchasers in the Offering and the pro forma as adjusted Equity Entitlement per Dollar Par Value of Class B immediately after completion of the Offering.

If all the Offered Shares are sold in the offering at an initial public offering price of $0.0001 per share, our pro forma as adjusted Equity Entitlement as of [ ], 2026 would have been $278,386.70. This represents an immediate increase in Equity Entitlement to Founding Member and immediate dilution in Equity Entitlement to purchasers of shares in the Offering. The following table illustrates the foregoing calculations.

---

| | |
|:---|:---|
|  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Per Dollar Par Value of Class B**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPO price**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $1.0000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Equity Entitlement before IPO**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Equity Entitlement after IPO**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.9280  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dilution to Investors of IPO**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0720  |

---

---

| |
|:---|
| 48 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | | | | |
|:---|:---|:---|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Shareholder**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Founding Member**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Founding Member**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Founding Member**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Investors Of IPO**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; All Members**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sub-Total  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of Shares**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3000000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 37600000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40600000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Par Value per Share**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0001  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Par Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $250000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $50000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $300000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3760000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $4060000.00  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4000 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Voting Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100000000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 37600000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 138100000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Points Ratio**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 72.41%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.36%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 72.77%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 27.23%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Distribution Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3000000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 37600000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40600000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Points Ratio**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.16%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.23%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.39%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 92.61%  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Paid In ETH/USDC**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $7500.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $7500.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3760000.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3767500.00  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Equity Entitlement before IPO**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $6250.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $1250.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $7500.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.00  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $7500.00  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Equity Entitlement before IPO <br> per Dollar Par Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0250  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.0250  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Equity Entitlement after IPO**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $231988.92  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $46397.78  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $278386.70  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3489113.30  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $3767500.00  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Equity Entitlement after IPO<br> per Dollar Par Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.9280  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.9280  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.9280  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.9280  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0.9280  |

---

---

| |
|:---|
| 49 |
| *[**Table of Contents**](#Toc)* |

---

#### 10 THE COMPANY'S BUSINESS
The Company is a Wyoming limited liability company electing to be a DAO pursuant to the Act and the Supplement, formed on November 8, 2023. We are engaged in the business of acquiring, holding, and commercializing the IPR related to the ComBoox Platform-a block chain-based infrastructure for automating corporate record keeping and governance through smart contracts.

**10.1. ComBoox Platform**

**10.1.1. System Overview**

Human civilization has entered the 21st century. Most wealth exists in the form of book-entry interests. To regulate these wealth and their trading activities, various laws, charters and contracts are established, and different centralized intermediaries are involved. However, in case these laws, charters or contracts are violated, people can only rely on judicial remedies, which are proven to be costly and time-consuming.

The emergence of block chain technology offers a new solution. That is, to define the rules and terms in smart contracts, and use the distributed systems to automatically keep the book-entry records. By implementing the basic concepts of "Code Is Law" and "Decentralization", the terms and conditions defined by legal documents can be implemented by rigid code, and the human management of centralized intermediaries can be replaced by consensus protocols and smart contracts with automated operation.

This establishes an automated mode of asset bookkeeping and transaction management in which owners can directly manage and dispose their assets without relying on any intermediaries or counter parties.

Among the book-entry interests, except for deposit currency, company equity is probably the most important and critical category. The company is the carrier of various assets and also the investment target of capital. Its external legal acts are the main components of modern commercial activities, while its internal governance involves the rights and interests of many investors. Therefore, company equity is the critical joint linking the capital and assets, commercial activities and corporate governance.

---

| |
|:---|
| 50 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) right holders may directly exercise their rights;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) obligors have no chance to default or violate; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) real time full disclosure of each legal acts.

From a legal and technical perspective, the ComBoox Platform replaces ex post judicial remedies with ex ante consensus on smart contracts. By embedding legal logic into smart contracts-aligned with the principles of "Code is Law" and "Decentralization"-ComBoox reduces reliance on human intermediaries and judicial enforcement. Every digital act leaves a verifiable, immutable record, thereby enabling real-time compliance and disclosure.

Among the book-entry interests, except for currency, company equity is probably the most important and critical category. A company is both the carrier of various assets and also the investment target of capital. Its external legal behaviour is the core component of modern commercial activities, while its internal governance activities involve the rights and interests of many investors. Therefore, company equity is the critical node linking the capital and assets, commercial activities and corporate governance. ComBoox enables these relationships to be governed transparently and consistently, while reducing the risks of insider control, misrepresentation, and transactional disputes that have historically challenged capital markets.

All source code for the ComBoox Templates and user interface scripts is publicly available on GitHub, and all deployed smart contracts can be verified via Arbiscan. Testing scripts are also published on GitHub, enabling any user to reproduce, audit, and independently verify the behavior and legal logic of the system. This commitment to transparency ensures that users can fully understand the functionality and compliance characteristics of the smart contracts they rely on.

**10.1.2. Scope and Limits of "Legal Acts" Conducted Through Smart Contracts**

Unlike common law, which usually develops legal rules and principles step by step from court cases and precedents, civil law takes a more top-down approach. It starts with general, abstract legal concepts written into legislation and then applies those concepts to specific cases. This method focuses on clear definitions, structured categories, and logical consistency in both lawmaking and court decisions.

This abstract, model-driven method of legal reasoning is closely aligned with the formalized, rule-based, and state-oriented logic of computer programming, particularly as applied in smart contract systems. Accordingly, ComBoox adopts a civil law-style abstract definition of "legal acts" as the conceptual foundation for determining which legal acts may appropriately be formalized, automated, and controlled on-chain.

---

| |
|:---|
| 51 |
| *[**Table of Contents**](#Toc)* |

---

Under this framework, a legal act shall satisfy the following conditions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) it is based on an **expression of intent**, which may be manifested either expressly through natural language or implicitly through acts of performance, such as delivery or payment;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) it is undertaken with the purpose of creating, modifying, or terminating **legal relationships**; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) it results in definite, identifiable, and recognizable **legal consequences**.

Within the ComBoox system, such legal acts are reflected as changes to the subject company's corporate state, including, without limitation, its ownership and property records, governance and shareholder registers, and/or its contractual rights and obligations. Specifically:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Expressions of intent** embodied in contracts, motions or votes, are recorded by the contractual smart contracts (such as shareholders agreement or investment agreement), as well as governance record smart contracts (such as general meeting minutes or board meeting minutes);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Legal relationships** concerning shareholder rights, creditor rights, and pledge interests are defined and automatic recorded by registry-type smart contracts, including register of shares, register of members, register of pledges, and other similar ledgers; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Legal consequences** of the legal acts, subjected to a rigorous and comprehensive process of formal abstraction, are resulted in a clearly defined change to a property-right state or governance-records state.

We further clarify that the concept of "legal acts" as used in ComBoox must not be expansively construed to encompass all activities that may give rise to legal responsibility or legal significance.

For example, disclosure and reporting activities under the Exchange Act involve legal responsibilities relating to accuracy, timeliness, and completeness. However, such activities do not themselves intend to create, modify, or terminate legal relationships, nor do they effect changes to corporate states. Accordingly, they do not constitute "legal acts" within the narrow sense adopted by ComBoox.

The exclusion of such activities from the definition of on-chain legal acts is not due to any technical limitation of smart contract technology, but rather because these activities do not affect the subject company's present or future property interests, governance rights, or governance rules, and do not give rise to determinate legal consequences. Substantively, they involve the collection, aggregation, and presentation of historical data, which can be implemented more efficiently and economically through centralized computing systems (such as front-end web applications) that reference on-chain data where appropriate.

**10.1.3. Preparation of Expressions of Intent**

Another concept that may cause confusion is the difference between preparing or drafting expressions of intent, and carrying out legal acts that give those expressions legal effect, such as proposing, voting and executing resolutions, which actually alter legal relationships and produce legal consequences.

---

| |
|:---|
| 52 |
| *[**Table of Contents**](#Toc)* |

---

ComBoox deliberately leaves the preparation and formation of some "open-end" expressions of intent to the relevant stakeholders, who may conduct such preparatory activities off-chain at their own discretion. In contrast, all legal acts-including proposing, voting, signing and execution-are strictly confined to on-chain processes that are automatically controlled and enforced by smart contracts.

By rigorously constraining and governing those dispositive legal acts that produce legal consequences, confer legal effect, or alter legal state, ComBoox ensures that all open-ended preparatory expressions of intent are ultimately consolidated and effectuated exclusively through the automated control of smart contracts.

For open-ended expressions of intent, ComBoox provides two mechanisms within the smart contracts of general meeting minutes and board meeting minutes:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) a dedicated attribute for storing the hash value of a natural-language document associated with each motion, thereby enabling the fixation of such content prior to legal effect being given through proposal and voting; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) an open interface allowing motions to specify and invoke external smart contracts, including the address, input parameters, and any required ETH value, thereby enabling the subject company, acting through approved governance processes, to interact with external smart contracts to accommodate future and diverse intent-expression requirements.

**10.1.4. Scenarios of Corporate Legal Acts**

To assist potential investors in understanding the governance structure of ComBoox and the operation of its smart contracts, the Company has submitted, as special exhibits to this statement, the ComBoox White Paper (Exhibit-32.1) and the ComBoox source codes (Exhibit-32.2).

In the course of a company's ordinary operations and financing activities, corporate legal acts can be categorized into 12 representative scenarios. Collectively, these scenarios can encompass all the possible legal acts undertaken by a company and its stakeholders, including, without limitation, the issuance and transfer of equity, amendments to constitutional documents, corporate governance actions, execution of financing arrangements, external payments, and the exercise of contractual and shareholder rights. The thirteen scenarios are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Application for Qualified Investor Status;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Update and Activation of the Shareholders' Agreement;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Equity Subscription or Transfer by Agreement;

---

| |
|:---|
| 53 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Equity Trading by Listing (Settlement in USDC);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Election or Removal of Directors;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Election or Removal of Officers;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) External Transfer of Funds;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) Distribution of Profits;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) Execution of External Smart Contracts;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) Pledge of Equity for Debt Obligations;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) Exercise of Special Investor Rights under the Shareholders' Agreement; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) Exercise of Put and Call Options.

Please see Section 7 of the White Paper for each scenario through structured procedural descriptions and logical process flows (including swimlane-style sequencing). It demonstrates how a company's stakeholders-acting in their respective legal capacities as shareholders, directors, officers, investors, or other authorized rights holders-may invoke the external APIs of the ComBoox system to complete such legal acts in a rigorous, rule-based, and auditable manner.

**10.1.5. Use of Smart Contracts in Governance**

Shareholder voting is one of core governance activities, and the process is implemented through predefined smart contracts as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Voting Rules.** The rules governing shareholder voting are defined in the shareholders agreement smart contract, which is subject to approval through a members' vote. Each rule (a "Rule") is encoded as a 256-bit string definition and specifies the applicable body (general meeting or board of directors), the voting points weight threshold, headcounts weight threshold, timetable (create date, proposal date, voting window etc.), and other attributes concerned. Common voting rules are covered by Rules No.1-No.12, and additional special rules may be created as needed. Please refer to Section 3.3.1.(2) of the White Paper for detailed introduction on Voting Rules.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Motions.** Subject issues for voting are presented as "motion" data objects, categorized into different types such as the election or removal of officers, approval of legal documents, authorization of payments in CBP or USDC, profit distribution, triggering of external smart contracts etc. Each motion type is subject to a validation algorithm embedded in the relevant Sub keeper controlling the relevant legal acts, ensuring consistency between the motion parameters and the corresponding legal act to execute. Please refer to Section 3.1.2.(3) of the White Paper for detailed introduction on structure of data object Motion.

---

| |
|:---|
| 54 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Voting Procedure.** The procedure generally includes (1) creation of a motion (creating a motion object and allocating a unique sequence number to it) by a member; (2) submission of the motion to the general meeting of members; (3) casting vote by members; (4) counting the vote result, which may be called by any user; and (5) execution of the approved motion by the designated executor, with the relevant sub keeper confirming the specific motion's "passed" status and parameter consistency before execution. Please refer to Sections 6.3 and 6.5 of the White Paper for a detailed explanation of the voting interfaces and procedures applicable to Board Meetings and General Meetings of Members, and to Sections 7.2 through 7.9 thereof for a description of how the voting mechanism operates across various corporate business scenarios.

**10.2. CBP and its Function**

**10.2.1. Overview of CBP**

CBP is an ERC-20 non-redeemable utility token issued by the Company and recorded in Registration Center. It is not intended to represent equity, voting, or ownership interest in the Company, nor does it entitle holders to share in profits, participate in governance, or receive distributions upon the liquidation, sale, or merger of the Company.

CBP serves a singular functional purpose: it is used to measure and collect royalties for using the Templates. Each time when a user calls specific function of the clone copies of Templates, an amount of CBP will be automatically transferred from the user to the account of the Template owner. The royalty rate is predefined by the original author in the respective Template, and the beneficiary rights can be transferred on-chain to any other party.

Users may acquire CBP through the following methods:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Automated Rewards**: New users are awarded a small quantity of CBP as part of the registration process.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Purchase with USDC**: Users may acquire CBP by calling the Fuel Tank smart contract, which internally triggers the Cashier to collect the accompanying USDC payment. The exchange rate between CBP and USDC is determined and may be adjusted by the Company pursuant to an Ordinary Resolution adopted by the General Meeting through a public vote.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Transfers or Gifts**: Users may also receive CBP from third parties via standard ERC-20 wallet transfers.

---

| |
|:---|
| 55 |
| *[**Table of Contents**](#Toc)* |

---

![](comboox_s1img2.jpg)

CBP operates within the platform as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Minting**: CBP is minted by the Company through the Registration Center smart contract.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Deployment**: Minted CBP is deposited into the Fuel Tank smart contract for sale to users.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Acquisition**: Users obtain CBP via purchase, reward, or third-party transfers.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Usage**: CBP is automatically deducted and transferred to Template owners when users call clone contracts.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Burning**: CBP may be burned voluntarily by users or by the Company pursuant to an ordinary resolution.

The Company does not commit to redeem CBP for fiat currency, digital assets, or services. All Templates are provided on an "As Is" basis and do not include any commitment by the Company for upgrades, maintenance, or support.

CBP is freely transferable between wallets and is not subject to any contractual or technical transfer restrictions. Users may sell, gift, or burn CBP at their discretion. CBP is divisible to 18 decimal places (i.e., the smallest unit is 10<sup>-18</sup> CBP), consistent with the ERC-20 standard, allowing for fractional use.

---

| |
|:---|
| 56 |
| *[**Table of Contents**](#Toc)* |

---

While CBP currently functions solely as a royalty payment mechanism, the Company may in the future consider using CBP holders' non-binding voting results-collected through off-chain governance tools-as a reference when determining whether to include a proposed smart contract into the ComBoox Template library. However, such votes will carry no legal effect and shall not bind the Company in any respect.

CBP confers no voting rights, ownership interest, equity participation, or residual claims against the Company. Holders are not entitled to any proceeds in the event of liquidation, merger, or sale of the Company. Because the operation and royalty rates of each Template are permanently encoded upon deployment to the blockchain, and remain functional in a decentralized and immutable manner, the rights of CBP holders are unaffected by changes in Company control or corporate structure.

**10.2.2. Authority to Determine Supply and Price of CBP**

Pursuant to resolutions adopted by the General Meeting of Members on June 19, 2025, the Company has implemented a revised mechanism for the issuance, pricing, and distribution of CBP. Under this mechanism, CBP may be acquired only by payment of USDC, and CBP is no longer sold in exchange for ETH.

At the same time, the General Meeting approved a fixed price of US$2,816.15 per CBP, which was calculated by reference to the highest ETH price recorded during the ten calendar days preceding the adoption of the resolution. The Company adopted a fixed U.S. dollar price in order to maintain its books and records in U.S. dollars and to eliminate exposure to ETH price volatility in connection with CBP distributions.

**10.2.3. Policies Relating to the Supply and Price of CBP**

The Company does not operate CBP under a free-floating or algorithmic pricing model. Instead, the supply and price of CBP are managed pursuant to internal policies approved by the General Meeting of Members and implemented through smart contracts.

The Company's current policies with respect to CBP supply management include the following:

(1). General Keeper Balance Limit.

The General Keeper smart contract, which receives CBP as licensing fees from users of the Company's smart contract templates, is not intended to hold more than 100 CBP at any time. If the CBP balance of the General Keeper exceeds this amount, a proposal must be submitted to the General Meeting of Members to transfer the excess CBP to the Fuel Tank smart contract.

(2). Minimum Fuel Tank Balance.

The Fuel Tank smart contract is intended to maintain an unsold balance of no less than 100 CBP. If the balance of CBP held by the Fuel Tank falls below this threshold, a proposal must be submitted to the General Meeting of Members to either (i) transfer CBP from the General Keeper to the Fuel Tank or (ii) mint additional CBP into the Fuel Tank.

---

| |
|:---|
| 57 |
| *[**Table of Contents**](#Toc)* |

---

(3). Aggregate Supply Cap.

The combined CBP balance held by the General Keeper and the Fuel Tank is not intended to exceed 10,000 CBP. If this threshold is exceeded, a proposal must be submitted to the General Meeting of Members to burn the excess CBP.

(4). Member Approval Requirement.

Any minting, burning, or inter-contract transfer of CBP requires approval by a Special Resolution of the General Meeting of Members, which requires the affirmative vote of at least 80% of the total voting points. Absent such approval, no CBP may be minted, burned, or transferred between smart contracts.

**10.2.4. Automation Versus Discretion in Controlling CBP Supply and Price**

The Company's smart contracts automate the execution of CBP-related actions, including the recording of balances, the transfer of CBP, and the distribution of CBP in exchange for USDC. However, the determination of whether CBP should be minted, burned, transferred, or repriced is not automated.

All substantive decisions regarding CBP supply and pricing are made by the General Meeting of Members through formal resolutions. The smart contracts do not independently adjust supply or price based on market conditions and do not exercise discretionary judgment. Instead, they execute only those actions that have been expressly authorized by approved Member resolutions.

**10.2.5. Fuel Tank Smart Contract and Management of CBP Supply**

The Fuel Tank smart contract is a dedicated contract used to store unsold CBP and to distribute CBP to users in exchange for USDC. It does not independently mint or burn CBP.

The Fuel Tank implements three principal write functions relevant to CBP supply management:

(1). "Set Rate" Function. This function updates the internal price variable ("Rate") used to calculate the amount of CBP distributed per unit of USDC. The function may be called only by the owner of the Fuel Tank, which is the General Keeper smart contract acting on behalf of the Company.

(2). "Withdraw Fuel" Function. This function transfers a specified quantity of CBP from the Fuel Tank to the General Keeper. It may be called only by the owner of the Fuel Tank.

(3). "Refuel" Function. This function may be called by any user. It allows the user to pay USDC to the Company's Cashier smart contract at the fixed CBP price and automatically receive the corresponding amount of CBP. Any USDC paid in excess of the required amount is automatically returned to the user.

---

| |
|:---|
| 58 |
| *[**Table of Contents**](#Toc)* |

---

**10.2.6. Fuel Tank Smart Contract and Pricing of CBP**

The Fuel Tank smart contract does not determine the price of CBP autonomously. The CBP price is set exclusively by resolution of the General Meeting and is implemented by invoking the Fuel Tank's "Set Rate" function.

All invocations of the "Set Rate" and "Withdraw Fuel" functions are executed exclusively through the execActionOfGM() interface of the General Keeper smart contract. Transfers of CBP into the Fuel Tank are executed through the transferFund() interface of the General Keeper. Each such invocation must reference a specific motion that has been duly approved by the General Meeting, and the authorization for the action is automatically verified by the relevant Sub-Keeper smart contract.

As a result, while the Fuel Tank smart contract mechanically enforces the approved CBP price during CBP distributions, the Company retains discretion over CBP pricing solely through Member governance and not through unilateral or automated adjustments.

 **10.3. Principal Products and Services** 

The Founding Member, currently as the sole developer of ComBoox, has invested the following rights and interests into the Company as capital contribution:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the beneficiary right to collect royalties of the Templates within the territory of Arbitrum One;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the beneficial right to collect commission of ComBoox Platform; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the exclusive right to mint CBP.

Therefore, the Company has the right to collect the following passive income in CBP as revenue: (1) royalties for the use of Templates; and (2) commission splitting from the payment of royalties.

The Company's business model is designed to generate passive, on-chain income through rights associated with the ComBoox Platform. The Company has no employees, does not actively provide operational services; rather, it passively earns income through smart contract-defined mechanisms embedded in the platform.

**10.4. Owner's rights to Registration Center**

In exchange of the Initial Shares, the Founding Member transferred to the Company the owner's rights to Registration Center as part of his capital contribution. From both legal and technical perspectives, the "owner's right to the Registration Center" encompasses two exclusive rights:

---

| |
|:---|
| 59 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) The minting right of CBP; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) The beneficial right to receive a share of commission derived from third-party royalty income.

The term "minting right of CBP" refers specifically to the exclusive authority to invoke a designated function within the Registration Center smart contract that creates and assigns a specified quantity of CBP to a recipient's blockchain address.

In the Arbitrum One blockchain network, both externally owned accounts ("**EOAs**") and contract accounts ("**CAs**") are uniquely identified by their respective Ethereum addresses. These addresses are essential for identity verification and access control within smart contracts. To enforce the exclusivity of the owner's rights, the Registration Center includes a dedicated variable to store the owner's address. Each time a protected function (such as minting CBP or transferring ownership) is called, the smart contract first checks whether the message sender's address matches the stored owner address. If the verification succeeds, the function proceeds; otherwise, execution is halted.

At deployment, the Registration Center was initialized with the EOA address of the Founding Member as the owner. Upon completion of the Company's book-entry system-including the deployment of the General Keeper smart contract (which represents the Company as a legal entity on the ComBoox system)-the Founding Member exercised his authority to transfer ownership. He did so by invoking the ownership transfer function, thereby updating the stored owner address to that of the General Keeper's contract address.

Importantly, all dynamic actions initiated by the General Keeper must be based on a prior resolution duly adopted by the General Meeting. As the General Keeper does not contain a predefined function for the subsequent transfer of ownership of the Registration Center, any such future transfer would require the General Meeting to adopt a resolution expressly authorizing the full transaction payload. This ensures that any future change in ownership can only be executed pursuant to a formal, member-approved resolution via public vote.

In summary, ownership of the Registration Center was transferred from the Founding Member to the Company during the initial configuration of the book-entry system. Given that the CBP minting right and the right to receive commission are core corporate rights and assets, the Company does not anticipate transferring these rights to any third party.

**10.5. Liabilities**

**10.5.1. Operating Model and Avoidance of Liabilities**

We will take all measures possible to keep the Company away from assuming or incurring any liabilities. Therefore, the Company will not borrow any loan or enter into any contracts that may incur payable liabilities. No employees will be hired, and no managers or members will be paid for remuneration either. In case the Company intends to hire any experts or to buy any services, it shall be arranged in a prepaid mode. The Company will not redeem any Shares it issued, and has no obligation to redeem any CBP it minted or sold.

---

| |
|:---|
| 60 |
| *[**Table of Contents**](#Toc)* |

---

As a result of this model, the Company does not expect to incur ordinary-course liabilities associated with payroll, rent, vendor financing, or trade payables.

**10.5.2. Identification of Service Needs and Initiation of Agreements**

The Company does not maintain a standing operational team or management structure responsible for ongoing procurement of services. Instead, the potential need for services-such as legal, advisory, or marketing services-is identified on an ad hoc basis by the Founding Member or Members acting in their individual capacities and not as agents of the Company.

The identification of a potential service need, or preliminary discussions with third parties, does not create any obligation on the part of the Company. No person has authority to bind the Company to any agreement unless and until the proposed arrangement has been approved in accordance with the Company's governance procedures.

**10.5.3. Prepaid Mode of Contracting and Satisfaction of Obligations**

If the Company determines that a service is necessary, it will enter into an agreement only on a fully prepaid basis. Prior to the execution of any such agreement:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the scope of services and prepaid structure must be approved by the General Meeting; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Company must have access to sufficient funds to prepay or reimburse the full consideration required under the agreement.

In circumstances where payment in fiat currency is required and the Company does not maintain fiat reserves, the Founding Member will try its best efforts, advance funds to complete the prepayment. Any reimbursement to the Founding Member is subject to General Meeting approval and is not automatic, guaranteed, or contractual in nature. The Company does not recognize any obligation to reimburse such advances unless and until reimbursement is formally approved in accordance with its governance procedures.

The Company does not enter into service arrangements that would result in deferred payment obligations, accounts payable, or other accrued liabilities.

**10.5.4. Limitations and Risk Considerations**

Although the Company intends to operate exclusively on a prepaid basis, there can be no assurance that this strategy will be effective in all circumstances. Certain regulatory obligations, disputes, or unforeseen events may arise that cannot be addressed solely through prepaid arrangements. If the Company is required to incur liabilities in such circumstances, it may not have sufficient resources to satisfy them, which could materially and adversely affect its business, financial condition, and the value of its securities. These risks are described in greater detail under "Risk Factors," including Risk Factor 5.23.

---

| |
|:---|
| 61 |
| *[**Table of Contents**](#Toc)* |

---

**10.6. No Bank Accounts and Payment Mechanism**

All payments of the Company will be made in ETH or USDC though General Keeper subject to a prior approval of members by Ordinary Resolution.

To mitigate the risk of insider misuse of the Company's assets and to ensure that all expenditures are subject to transparent, member-approved governance, the Company has adopted a strict on-chain asset policy as set forth in the Operating Agreement. Specifically, the Operating Agreement provides that all assets of the Company must be held on-chain, meaning they must be directly or indirectly controlled by smart contracts.

As a result, the Company does not maintain any off-chain bank accounts and will not make payments in fiat currency. All payments by the Company must be made in ETH or USDC through smart contracts. This policy applies universally, including to payments for government fees (such as annual Wyoming LLC fees), services rendered by the Company's registered agent, and legal, accounting, or other professional services.

The Company believes that with the increasing acceptance and regulatory recognition of stable coins, such as USDC, more service providers will accept on-chain assets as payment. However, recognizing that this transition is still ongoing, the Company has implemented a prepay-and-reimburse workaround to address circumstances where fiat payments are required.

To handle fiat obligations while maintaining its on-chain-only asset policy, the Company has established the following process:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Approval**: The underlying agreement requiring payment (e.g., for legal fees, state filing fees) is first submitted to the General Meeting and must be approved by a vote of the members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Advance Payment**: A designated member or the manager is authorized to make the fiat payment directly to the service provider or third party.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Reimbursement Proposal**: The member or manager then submits a reimbursement proposal to the General Meeting, specifying the fiat amount paid and requesting reimbursement in USDC.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Reimbursement Approval**: The proposal is subject to member approval by public vote.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Execution**: Upon approval, the authorized member or manager inputs the specific motion ID into the smart contract system to request reimbursement.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Smart Contract Settlement**: The smart contract verifies the approved motion and automatically transfers the specified amount of USDC from the Company's treasury (i.e. the smart contract Cashier) to the designated wallet address of the payor. This process ensures that no fiat currency is held by the Company itself, and that all financial activity is conducted transparently on-chain, subject to members' governance. However, if no member or manager is willing to advance fiat currency payments, the Company may face operational delays or service disruptions.

---

| |
|:---|
| 62 |
| *[**Table of Contents**](#Toc)* |

---

**10.7. Transparency, Automation, and On-Chain Corporate Governance**

In accordance with Section 17-31-109 of the Supplement, management of a DAO "shall be vested in its members or the members and any applicable smart contracts". To comply with this statutory framework, the Company's Operating Agreement includes the following governance provisions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Decision-Making Authority**: The General Meeting, comprising all members, is the sole decision-making body of the Company (OA §9.1.1).

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Managerial Powers**: Managers do not hold decision-making authority. They are limited to executing administrative, commercial, or technical functions as explicitly authorized by the OA or approved by the General Meeting (OA §10.4.1).

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Officer Appointments**: The inauguration or impeachment of any manager shall become effective only upon approval by the General Meeting through a public vote (OA §10.4.3).

&nbsp;&nbsp;&nbsp;&nbsp; (4) **Legal Acts**: All legal acts undertaken on behalf of the Company shall require prior approval by the General Meeting through a public vote (OA §9.1.1).

&nbsp;&nbsp;&nbsp;&nbsp; (5) **Legal Documents**: all off-chain legal documents become legally binding on the Company only upon the approval by the General Meeting though a public vote (OA §9.1.1);

&nbsp;&nbsp;&nbsp;&nbsp; (6) **Assets**: The Company's assets are limited to the on-chain assets that capable of being held, controlled, and disposed, directly or indirectly, by the smart contracts General Keeper or Cashier (OA §6.5).

To ensure practical implementation of the above provisions, the following commercial and technical measures have been adopted:

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Passive Revenue Model**: The Company's revenue is derived from the automatic collection of intellectual property royalties for using the Templates of ComBoox. This passive model requires no active management;

---

| |
|:---|
| 63 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; (2) **No Traditional Banking**: The Company does not maintain a traditional bank account. It uses only USDC and ETH to procure services or reimburse expenses, eliminating the need for off-chain human intervention;

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Smart Contract - Based Resolutions**: All voting of members is conducted through a smart contract named "General Meeting Minutes," which automatically calculates outcomes and generates resolutions;

&nbsp;&nbsp;&nbsp;&nbsp; (4) **Manager Elections**: An individual may assume the role of manager (i.e. whose user number is recorded in the smart contract named "Register of Directors") only if the resolution quoted in the calling command can be retrieved from the General Meeting Minutes with the voting status as "passed";

&nbsp;&nbsp;&nbsp;&nbsp; (5) **Asset Transfers**: Transfers of ETH or USDC from the Company (i.e. from the smart contracts of General Keeper or Cashier) are permitted and feasible only if the resolution quoted in the calling command can be retrieved from the General Meeting Minutes with the voting status as "passed";

&nbsp;&nbsp;&nbsp;&nbsp; (6) **Legal Acts Execution**: any on-chain legal acts on behalf of the Company (i.e. calling commands sent from the smart contract of General Keeper) can be triggered only if the relevant resolution quoted can be retrieved from the General Meeting Minutes with the voting status as "passed".

For transparency and public accountability, the Company has implemented the following disclosure measures:

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Source Code Publication**: All ComBoox platform smart contract source code is publicly accessible on GitHub;

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Testing Script Disclosure**: Complete test scripts for various scenarios are also disclosed on GitHub, enabling independent verification;

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Deployment Verification**: All deployed bytecode on the Arbitrum One blockchain is verified on the public explorer Arbiscan.io to confirm that it matches the disclosed source code.

In light of the above, the Company asserts its status as an "on-chain" company. Its governance and operations are executed exclusively via blockchain-based smart contracts, as specified in the OA. All material actions-including asset transfers, expenditures, managerial election, and operational changes-are subject to approval by members through on-chain voting.

Members holding more than 10% of the outstanding Voting Points may submit proposals to a General Meeting. A quorum is achieved when over 25% of Voting Points are cast on a motion.

Resolutions are classified as either Ordinary or Special. An Ordinary Resolution passes only if at least 75% of the Voting Points cast are in favor. A Special Resolution-required for significant matters such as amending governance provisions or replacing core smart contracts-requires at least four times as many votes in favor as against to be approved.

---

| |
|:---|
| 64 |
| *[**Table of Contents**](#Toc)* |

---

Managers act solely to implement decisions and manage operations as delegated by Resolutions and have no autonomous decision-making power.

To mitigate moral hazard arising from off-chain human intervention, the Company has deliberately simplified its business model, asset composition, decision-making scope, and governance procedures. For example, open-ended preparatory processes for the formulation of expressions of intent are conducted off-chain, whereas the actions that confer legal effect on such expressions-specifically, the submission of proposals and the conduct of voting-are strictly confined to on-chain processes that are automatically governed and enforced by smart contracts.

Similarly, any advance of fiat currency by stakeholders necessarily occurs off-chain. However, the approval of such advance arrangements, the related proposal and voting actions, and the disbursement of Company assets, including payments in USDC, are all required to be executed exclusively through on-chain smart contracts. Through this structure, the Company seeks to ensure that all actions capable of producing legal or economic effects with respect to the Company are subject to smart contracts' automated, rule-based execution and control.

For example, where the Company engages an external auditor, the Founding Member may negotiate and prepare a draft engagement agreement with the auditor, and then, submit a special proposal encompassing:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) execution of the engagement agreement;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) advancement of audit fees by the Founding Member; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) reimbursement of such fees by the Company in USDC.

The hash value of the draft engagement agreement is submitted as a designated attribute associated with the relevant motion recorded in the General Meeting Minutes smart contract. As any modification to the engagement agreement would result in a materially different hash value, referencing the hash value enables the draft agreement to be uniquely identified and its contents to be fixed for purposes of review, and voting.

Upon approval of such motion, the Founding Member may execute the engagement agreement, advance the audit fees, and subsequently invoke the USDC reimbursement function, specifying the serial number of the approved motion as an input parameter.

Thereafter, the Founding Member may receive the reimbursed USDC only if the system automatically verifies that:

---

| |
|:---|
| 65 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the proposal, including the execution of the engagement agreement, the advancement of audit fees, and the reimbursement thereof, has been duly approved by the General Meeting;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the reimbursement recipient is the Founding Member; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the reimbursement amount does not exceed the amount approved by the General Meeting.

As illustrated above, although certain preparatory actions-such as drafting an engagement agreement or advancing audit fees-are conducted off-chain, the legal acts that result in the Company assuming legal obligations or experiencing an outflow of economic interests, namely the approval of the engagement agreement and the reimbursement of advanced expenses, are strictly controlled by the on-chain smart contract. Such legal acts may only be effected upon obtaining explicit voting approval from the General Meeting and are executed automatically in accordance with the predefined logic of the smart contract.

Accordingly, by rigorously ensuring that all legal acts remain subject to the automated control of smart contracts, the Company is able to operate smoothly in a fully on-chain manner, in strict compliance with the provisions of its constitutional document, namely the Operating Agreement.

With respect to the convening of the General Meeting, the Operating Agreement expressly eliminates any off-chain, discretionary convening mechanism. Instead, Members are required to independently monitor the proposal submissions and voting schedules published through the General Meeting Minutes smart contract. Following the establishment in the Operating Agreement of appropriate procedural safeguards-such as proposal thresholds (10% of voting points) and mandatory review periods (15 natural days)-the Company is designed to operate effectively under an autonomous system of member-driven proposals and transparent, on-chain voting, without reliance on centralized or off-chain coordination.

Not all activities involving legal responsibility or expressions of intent are subject to on-chain automation. At the same time, the system is designed to reduce reliance on off-chain human intervention by streamlining governance and business processes, while still allowing different forms of intent to be expressed and executed through a clear, rule-based and automated structure.

Please refer to the following sections of the White Paper for a comprehensive understanding of the Company's rules and mechanisms relating to governance and voting activities, including rule configuration, voting procedures, operational methods, and logical workflows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Section 3.3.1(1) - for an explanation of the attribute settings in the Governance Rules, including proposal rights and quorum requirements;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Section 3.3.1(2) - for an overview of the attribute settings in the Voting Rules, covering voting timelines, procedural steps, and the methodology for calculating voting outcomes;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Section 3.3.3 - for guidance on creating, adding, or removing Governance Rules or Voting Rules within a Shareholders Agreement's draft;

---

| |
|:---|
| 66 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Sections 7.2-7.9 for detailed descriptions of the operational procedures and step-by-step workflows applicable to different voting scenarios and corporate matters; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Section 6.5 - for a detailed discussion of the external APIs related to voting and the implementation of resolutions, including the logic governing precondition verification and the mechanisms by which legal effects are effected and enforced.

**10.8. Markets and Distribution Model**

ComBoox is designed as a permissionless, blockchain-native platform intended to serve public companies, private entities, startups, and DAOs. It offers modular Templates for corporate registries, governance automation, and shareholder services via smart contracts deployed on the Arbitrum One network. Access is entirely decentralized-users interact directly with ComBoox smart contracts to create, manage, and operate their legal and financial structures.

The Company does not directly engage in marketing or sales of services. Instead, revenue is generated automatically via the use of ComBoox Templates, with smart contracts collecting CBP from users and directing those proceeds to the Royalty Interest holders of the relevant Templates.

The Company operates a passive licensing business model. The Company does not actively solicit customers, target specific jurisdictions, or directly provide individualized services to users. Instead, the Company makes standardized smart contract templates available on public blockchains, and users independently decide whether to access and use such templates and to pay applicable license fees in accordance with the terms embedded in the smart contracts.

Because the Company's smart contract templates are deployed on public blockchains, access to and use of the templates are not subject to inherent geographic or territorial limitations. The Company does not restrict access based on the physical location of users, and users may interact with the smart contracts from any jurisdiction where access to the applicable public blockchain is technically available and lawful.

As a result of this structure, the Company does not expect to conduct business activities in any single, specific geographic market, nor does it expect to acquire customers from any particular jurisdiction through targeted marketing or outreach. Instead, the Company expects that its users may be located across a broad range of jurisdictions globally, subject to applicable local laws and regulations governing the users' activities.

Given the substantial convergence of company law principles across major global economies-particularly with respect to shareholder registration, share transfers, and corporate governance-the Company expects that its smart contract templates may be used by users in a wide range of jurisdictions. These jurisdictions may include, among others, common law jurisdictions (such as the United States, the United Kingdom, Canada, Australia, New Zealand, Singapore, Hong Kong, and Ireland), civil law jurisdictions in Europe (such as Germany, France, Italy, the Netherlands, Luxembourg, Belgium, Spain, Switzerland, Denmark, and Finland), jurisdictions that have adopted modern corporate law frameworks (including China, Japan, Korea, Israel, and Switzerland), and other jurisdictions where similar legal principles apply, notwithstanding differences in local implementation or regulatory requirements.

---

| |
|:---|
| 67 |
| *[**Table of Contents**](#Toc)* |

---

The Company does not represent that its smart contract templates are suitable for use in every jurisdiction or that use of the templates will comply with all applicable laws in all jurisdictions. Users are responsible for determining whether their use of the smart contract templates complies with applicable local laws and regulations.

**10.9. Development Stage and Technical Deployment**

The ComBoox Platform is fully operational and open-source. All smart Templates, testing scripts, and users interfaces have been published on GitHub. The Company's own equity records, governance framework, and financial systems are implemented exclusively through these smart contracts, demonstrating live usage.

No additional technical milestones are required for commercialization. However, the Company expects to develop community contributions, and potentially acquire new Templates subject to members approval and funding.

**10.10. Competitive Position and Differentiation**

To our knowledge, ComBoox is the first public platform offering fully on-chain smart contracts for equity and corporate governance management. While various software as a service tools and blockchain registries exist, no direct competitor currently offers the same degree of automation, decentralization, and legal integration through autonomous smart contracts. We expect to compete on the basis of technological innovation, transparency, automation, and cost-efficiency rather than through traditional customer relationships or service models.

**10.11. Customer Base and Revenue Sources**

The Company does not rely on any major customers. All revenues are derived from anonymous, permissionless use of the ComBoox Platform and collected via automated smart contracts. The nature of the system allows for a highly diversified and scalable user base. Accordingly, there is no customer concentration risk at this time.

**10.12. Intellectual Property and Royalties**

The Company holds exclusive royalty and commission interests in a defined set of Templates as well as minting and pricing rights to CBP within Arbitrum One blockchain network. These interests and rights were developed and contributed by the Founding Member. However, he retains the right to deploy ComBoox on other blockchains. The Company does not currently own any patents or registered trademarks but may acquire additional IPR from external developers if approved by members vote. The source code for all Templates is publicly available, but the royalty logic embedded in smart contracts ensures enforceable monetization.

---

| |
|:---|
| 68 |
| *[**Table of Contents**](#Toc)* |

---

The Company's core intellectual property consists primarily of smart contract templates and related computer programs. The Company relies principally on copyright law to protect these assets.

Copyright protection for computer programs is recognized in jurisdictions that are parties to the Berne Convention for the Protection of Literary and Artistic Works and the Agreement on Trade-Related Aspects of Intellectual Property Rights. These international agreements require signatory countries to provide copyright protection for computer programs as literary works and together cover the vast majority of the world's principal economies. The Company believes that, as a result, its smart contract templates are eligible for copyright protection in these jurisdictions.

In addition, when the Company's smart contracts are deployed on public blockchains, the source code, compiled bytecode, and time of publication are recorded in an immutable and verifiable manner. The Company believes that this on-chain deployment supports evidentiary proof of authorship and creation date in jurisdictions recognizing copyright protection, although the legal treatment of such evidence may vary by jurisdiction.

Separately, with respect to certain key innovative algorithms and technical solutions, the Founding Member has filed patent applications through the Patent Cooperation Treaty international filing process, with national phase entries in, among other jurisdictions, the United States and the People's Republic of China. All such patent applications are currently under examination, and no patent rights have been granted to date. There can be no assurance that any of these patent applications will be approved, that any patents will ultimately be issued, or that any issued patents will provide meaningful protection, competitive advantage, or commercial benefit.

Notwithstanding the foregoing, the Company's use of the relevant technology and its business model will not be affected regardless of whether such patents are ultimately granted, as the Company has already obtained an exclusive license to use and commercially exploit the ComBoox system within the Arbitrum One blockchain network, which license is sufficient to support the Company's current operations and its reasonably contemplated future activities independently of the outcome of the patent application process.

**10.13. Regulatory Environment and Legal Compliance**

The ComBoox Platform is a set of smart contract tools. It can be used by listed companies or private entities, subject to the discretion and compliance responsibilities of each user. The Company does not provide legal advice, governance services, or regulatory compliance on behalf of any platform user.

---

| |
|:---|
| 69 |
| *[**Table of Contents**](#Toc)* |

---

As the IPR holder and a passive royalty recipient, the Company is not responsible for how users adopt or apply the Templates. Our own regulatory obligations are limited to securities compliance as a public issuer and our pending registration as a transfer agent for our own shares. We maintain automated on-chain recordkeeping and voting to ensure transparency and support for federal disclosure requirements.

We acknowledge that blockchain-based business models exist within a developing legal framework and will continue to monitor and comply with applicable U.S. securities regulations, including the Securities Exchange Act of 1934.

**10.14. Government Approvals**

There are no government licenses or approvals currently required for operation of the ComBoox Platform. However, our offering and any secondary market trading will be subject to SEC registration. The Company intends to pursue SEC registration as its own transfer agent in connection with its on-chain share issuance and trading mechanisms.

**10.15. Employees**

To date, the Company had no employees. We do not intend to hire employees and seek to operate, to the extent permitted by applicable law, as a passive intellectual property holding entity with no active business operations. All material business decisions are made collectively by the Company's members through smart contract-enabled voting processes in accordance with the Operating Agreement.

Any execution of approved resolutions will be carried out by an authorized member or designated manager acting without remuneration. In the event that legal, accounting, audit, tax, or similar administrative functions are required to maintain the Company's legal status or regulatory compliance, the General Meeting of members may consider and approve specific motions authorizing the necessary budget and prepayment for such services.

**10.16. Facilities**

As an on-chain company, we do not have and have no intents to acquire or lease any facilities for the Company.

**10.17. Legal Proceeding**

We are not currently a party to any material legal proceedings.

**10.18. Feasibility of Bring Legal Action Against Foreign Managers**

The Company believes that its unique smart contract-based governance architecture and legal-operational model may essentially minimize risks commonly associated with managerial misconduct, insider control, misrepresentation or insider trading. In response to the concerns on feasibility of bring legal actions against foreign managers, the Company respectfully provides the following disclosure regarding the enforceability of civil liabilities under U.S. Federal securities laws against managers residing in foreign jurisdictions, particularly China. This section also discusses investors' ability to effect service of process and enforce judgments or initiate original actions based on U.S. law in foreign jurisdictions.

---

| |
|:---|
| 70 |
| *[**Table of Contents**](#Toc)* |

---

Key points are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) The Company's managers have no discretionary power or direct access to assets, preventing exposure to conventional liability;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Service of process on managers located in China is permitted under the Hague Service Convention;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Enforcement of U.S. judgments in China is not assured and depends on reciprocity and public policy review; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Chinese courts generally do not apply U.S. securities laws in original actions due to sovereignty and legal doctrine.

 **10.18.1. Overview of Governance and Legal Architecture**

In conventional corporate practice, the disposition of off-chain assets, such as bank deposits, real estate, equity interests, receivables, or other financial instruments, requires human intervention by corporate officers or directors. Even where such authority is nominally constrained by board or shareholder resolutions, the existence of human agency creates a risk of unauthorized, ultra vires, or even fraudulent disposition of corporate assets.

By contrast, the Company's assets consist solely of on-chain assets, especially USDC and ETH. USDC is recorded on-chain and credited exclusively to the Company's Cashier contract address, while ETH is held as the account-level balance of the General Keeper contract. This means that, in the Ethereum world state, each contract account has a dedicated balance attribute that records the amount of ETH it holds. All external transfers or dispositions of these assets must be executed strictly through the interfaces of the General Keeper contract, which enforces, as part of its logic, that the serial number of the relevant motion duly approved by the General Meeting is provided as an input parameter to authorize the transfer.

Each such motion contains two critical elements: (i) the unique user number of the designated executor; and (ii) a hash digest representing all proposed instructions, including the addresses of any external contracts to be called, together with the associated function selectors, ETH amounts to be sent with the calling command, and input parameters. When a transfer of USDC or ETH is initiated, the relevant Sub Keeper contract verifies both the executor's user number and the precise hash of the proposed instructions, and further confirms that the motion itself has been passed by the General Meeting. This mechanism ensures that every transaction involving Company assets has been formally authorized by Members and that the content of the approved motion matches exactly with the executed instructions.

---

| |
|:---|
| 71 |
| *[**Table of Contents**](#Toc)* |

---

Accordingly, managers have no technical capacity to access or dispose of Company assets on their own initiative. They are limited to performing administrative or technical functions within the framework of Member-approved motions. There is no room for subjective discretion or unilateral authority. This design structurally eliminates the conventional risks of asset misappropriation, unauthorized transactions, or managerial abuse that are inherent in traditional corporate governance models.

The core concept of ComBoox is to utilize transparent, tamper-resistant blockchain to maintain book-entry records of equity, rights, interests, financial data, and governance documents, and to employ smart contracts to automatically control and execute legal acts. This approach empowers right holders to exercise their entitlements directly, eliminates opportunities for obligors to default, and ultimately exclude moral hazard arising from human intervention. In doing so, it aims to replace the inefficient and costly reliance on ex-post judicial remedies with ex-ante consensus on predefined smart contracts.

The Company's governance and legal architecture is specifically designed to eliminate risks associated with insider control, including unauthorized asset transfers, decision-making abuse, or manipulation of financial or governance disclosures. By embedding decision-making processes in transparent, automated, and immutable smart contracts, the Company excludes the potential for discretionary misuse of authority and enhances investor protection.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(1) Company Assets are Fully On-Chain and Technically Restricted**

Company assets are held solely through smart contracts deployed on public blockchain networks. No manager holds keys or has technical capacity to unilaterally transfer or dispose of assets. All asset dispositions require a public vote of the General Meeting, transparently recorded and executed on-chain.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(2) Off-Chain Legal Acts Require On-Chain Member Approval**

The Operating Agreement explicitly bars managers from binding the Company to any off-chain contracts unless approved by a public member vote. This precondition eliminates unauthorized corporate representations and significantly limits exposure to liability for misstatements or fiduciary breaches.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(3) Governance and Legal Acts are Fully Disclosed On-Chain in Real Time**

Legal acts and corporate decisions are executed and disclosed simultaneously via smart contracts. There is no lag between decision-making and public disclosure, preventing claims related to delayed filings, omissions, or misrepresentations.

---

| |
|:---|
| 72 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(4) Insider Information Misuse is Technically Prevented**

All proposals must undergo a public review period before voting and execution. This precludes managers from accessing or using material non-public information for personal gain, structurally mitigating insider trading risks.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(5) Managers Have No Discretionary Authority**

Managers perform only technical and administrative functions in accordance with member-approved instructions. This absence of discretionary authority precludes liability from independent decision-making or misconduct.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(6) Managers has NO Remuneration**

Under the Operating Agreement, managers receive no remuneration from the Company. There is no opportunity for excessive compensation claims.

 **10.18.2. Service of Process in the United States** 

Service of process on Company managers located in China may be effected under *the Convention on the Service Abroad of Judicial and Extrajudicial Documents in Civil or Commercial Matters* ("**Hague Service Convention**"). Both China and the United States are contracting states. Service procedure are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) U.S. court prepares judicial documents in English and provides certified Chinese translations.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Documents are submitted to the Chinese Central Authority: Department of Judicial Assistance and Foreign Affairs, Ministry of Justice of China (the "**Ministry**").

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) The Ministry reviews compliance and forwards to the competent Intermediate People's Court (the "**Local Court**").

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) The Local Court executes service and returns proof via official channels.

This process complies with Chinese domestic law and ensures the enforceability of the service within China.

 **10.18.3. Enforcement of U.S. Judgments in China**

Chinese law does not automatically recognize U.S. court judgments. Enforcement is governed by the Civil Procedure Law of China and is subject to:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Reciprocity**: Chinese courts require evidence that U.S. courts recognize Chinese judgments. To date, this reciprocity remains limited and uncertain.

---

| |
|:---|
| 73 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Public Policy Compliance**: Judgments must not contravene Chinese legal principles or harm national interests.

Enforcement process are generally as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Application to Intermediate People's Court in the jurisdiction of the manager's residence or assets.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Submission of notarized judgment, certificate of finality, certified translations, and evidence of reciprocity.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Court reviews for procedural validity, jurisdictional conflicts, and public policy violations.

Chinese courts have historically been reluctant to enforce U.S. judgments, particularly those involving punitive damages, class actions, or regulatory penalties. Thus, enforceability of U.S. securities law judgments in China remains highly limited.

**10.18.4. Bringing Original Actions in Chinese Courts Based on U.S. Securities Laws**

Chinese courts generally do not allow the extraterritorial application of foreign public laws, including U.S. securities laws. According to Supreme People's Court guidance, foreign regulatory statutes are not enforceable in Chinese judicial proceedings.

Factors preventing such actions include:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Public Law Classification**: U.S. securities laws are deemed regulatory/punitive and not suitable for private enforcement under Chinese civil procedure.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Sovereignty Concerns**: Allowing enforcement of foreign securities laws may undermine Chinese jurisdiction over domestic financial regulation.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Public Policy Barriers**: Chinese courts apply strict scrutiny to foreign claims to avoid conflict with domestic legal and political interests.

Accordingly, investors are unlikely to succeed in bringing original actions in China based on U.S. securities laws. This limitation reflects China's broader policy of judicial non-recognition of extraterritorial regulatory enforcement.

 **10.19. Implications of Being an Emerging Growth Company**

We are and we will remain an "emerging growth company" as defined under The Jumpstart Our Business Startups Act, or the JOBS Act, until the earliest to occur of (i) the last day of the fiscal year during which our total annual revenues equal or exceed $1.07 billion, (ii) the last day of the fiscal year following the fifth anniversary of our initial public offering, (iii) the date on which we have, during the previous three-year period, issued more than $1 billion in non-convertible debt securities, or (iv) the date on which we are deemed a "large accelerated filer" (with at least $700 million in public float) under the Exchange Act.

As an "emerging growth company", we may take advantage of specified reduced disclosure and other requirements that are otherwise applicable generally to public companies. These provisions include:

---

| |
|:---|
| 74 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) preliminary omission financial information relates to a historical period that we reasonably believe will not be required to be included in this Form at the time of the contemplated offering;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) only two years of audited financial statements in addition to any required unaudited interim financial statements with correspondingly reduced "Management's Discussion and Analysis" disclosure;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) reduced disclosure about our executive compensation arrangements;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) no requirement that we hold non-binding advisory votes on executive compensation or golden parachute arrangements; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) exemption from the auditor attestation requirement in the assessment of our internal control over financial reporting.

We have taken advantage of some of these reduced burdens, and thus the information we provide you may be different from what you might receive from other public companies in which you hold securities.

In addition, Section 107 of the JOBS Act also provides that an emerging growth company can take advantage of the extended transition period provided in Section 7(a)(2)(B) of the Securities Act for complying with new or revised accounting standards. In other words, an emerging growth company can delay the adoption of certain accounting standards until those standards would otherwise apply to private companies.

Notwithstanding the above, we are also currently a "smaller reporting company," meaning that we are not an investment company, an asset-backed issuer, or a majority-owned subsidiary of a parent company that is not a smaller reporting company and that had a public float of less than $250 million or annual revenues of less than $100 million during the most recently completed fiscal year. In the event that we are still considered a smaller reporting company, at such time as we cease being an emerging growth company, the disclosure we will be required to provide in our SEC filings will increase, but it will still be less than it would be if we were not considered either an emerging growth company or a smaller reporting company. Specifically, similar to emerging growth companies, smaller reporting companies are able to provide simplified executive compensation disclosures in their filings; are exempt from the provisions of Section 404(b) of the Sarbanes-Oxley Act requiring that independent registered public accounting firms provide an attestation report on the effectiveness of internal control over financial reporting; and have certain other decreased disclosure obligations in their SEC filings, including, among other things, only being required to provide two years of audited financial statements in annual reports.

---

| |
|:---|
| 75 |
| *[**Table of Contents**](#Toc)* |

---

 **10.20. Information Required by Item 101(h)(5) of Regulation S-K** 

The following information is required by Item 101(h)(5) of Regulation S-K, and is recommended to be read together with the more detailed disclosure in the section "10 THE COMPANY'S BUSINESS" of this prospectus.

&nbsp;&nbsp;&nbsp;&nbsp; (1) Principal Products and Services

The Company's principal product is the IPR related to the ComBoox Platform, a blockchain-based system for corporate recordkeeping and governance through smart contracts. The Company also issues CBP, a utility token used solely as a royalty payment mechanism for Template smart contracts. Therefore, the Company has the right to collect the following passive income in CBP as revenue: (1) royalties for the use of Templates; and (2) commission splitting from the payment of royalties.

See Section 10.1 - ComBoox Platform, Section 10.2 - CBP and its Function, and Section 10.3 - Principal Products and Services.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Methods of Distribution

The ComBoox Platform is distributed in a decentralized, permissionless manner through deployment on the Arbitrum One blockchain. Users access Templates directly by interacting with smart contracts. The Company does not operate sales or marketing channels; all usage and royalty payments are collected automatically on-chain.

See Section 10.8 - Markets and Distribution Model

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Status of Publicly Announced New Products or Services

The ComBoox Platform is fully deployed, operational, and open-source. No new products or services have been publicly announced that remain in development. Future Templates may be proposed by community developers and adopted through member approval, but no such proposals are pending at this time.

See Section 10.9 - Development Stage and Technical Deployment.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Competitive Business Conditions and Position

To the Company's knowledge, ComBoox is the first publicly available on-chain smart contract system that integrates equity recordkeeping and governance automation. Competition includes centralized SaaS platforms and other blockchain governance tools. The Company competes primarily on automation, decentralization, transparency, and cost efficiency.

---

| |
|:---|
| 76 |
| *[**Table of Contents**](#Toc)* |

---

See Section 10.10 - Competitive Position and Differentiation.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Sources and Availability of Raw Materials

The Company does not rely on physical raw materials. Its operations depend on blockchain infrastructure (primarily the Arbitrum One network), which is publicly available and maintained by independent third parties.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Importance of Patents, Trademarks, Licenses, Franchises, and Concessions

The Company does not currently own patents or trademarks. Its intellectual property rights consist of smart contract royalty and commission interests and exclusive CBP minting rights within Arbitrum One. These rights were contributed by the Founding Member.

See Section 10.12 - Intellectual Property and Royalties.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Seasonality of the Business

The Company's business is not seasonal. Usage of the ComBoox Platform and associated royalty income may fluctuate with overall blockchain activity and corporate governance trends, but no material seasonal effects are expected.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) Practices Regarding Working Capital

The Company does not maintain conventional working capital accounts. We will take all measures possible to keep the Company away from assuming or incurring any liabilities. All assets are held on-chain in ETH or USDC and disbursed only pursuant to member-approved resolutions. The Company's revenue is collected automatically in CBP, which may be converted to USDC through smart contracts. All payments by the Company must be made in ETH or USDC through smart contracts.

See Section 10.5 - Liabilities, and Section 10.6 - No Bank Accounts and Payment Mechanism.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) Dependence on Major Customers

The Company does not depend on any single customer or small group of customers. All revenues are generated automatically from permissionless usage of ComBoox Templates by a diversified, anonymous user base.

See Section 10.11 - Customer Base and Revenue Sources.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) Backlog of Orders

The Company has no backlog orders. Revenue is earned automatically and immediately upon the use of ComBoox Templates.

See Section 10.11 - Customer Base and Revenue Sources.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) Government Contracts

---

| |
|:---|
| 77 |
| *[**Table of Contents**](#Toc)* |

---

The Company is not a party to any government contracts.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) Number of Employees

The Company currently has no employees and does not intend to hire employees. All governance, operational, and technical functions are executed automatically through smart contracts or pursuant to member-approved resolutions.

See Section 10.15 - Employees.

11. PRINCIPAL AND SELLING SECURITYHOLDERS

&nbsp;&nbsp;&nbsp;&nbsp; As long as permitted by law, we will not engage any underwriter or dealer for the Offering. Moreover, as the only shareholder, the Founding Member will not sell any of his Shares in the Offering. On the contrary, the Founding Member voluntarily locks up the Initial Shares till June 30, 2027. Therefore, all proceeds of issuance will be received by the Company.

#### &nbsp;&nbsp;&nbsp;&nbsp; 12 MANAGEMENT'S DISCUSSION AND ANALYSIS OF FINANCIAL CONDITION AND RESULTS OF OPERATIONS
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *You should read the following discussion and analysis of our financial condition and results of operations together with our financial statements included elsewhere in this prospectus. This discussion and other parts of this prospectus contain forward-looking statements that involve risk and uncertainties, such as statements of our plans, objectives, expectations and intentions. See "Cautionary Statement Regarding Forward-Looking Statements". Our actual results could differ materially from those discussed in these forward-looking statements. Factors that could cause or contribute to such differences include, but are not limited to, those discussed in the section of this prospectus entitled "Risk Factors."* 

#### &nbsp;&nbsp;&nbsp;&nbsp; 12.1 Overview
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; We are engaged in the business of acquiring, holding, and commercializing the IPR related to the ComBoox Platform-a block chain-based infrastructure for automating corporate record keeping and governance through smart contracts. We are founded as a Wyoming limited liability company electing to be a DAO on November 8, 2023.

---

| |
|:---|
| 78 |
| *[**Table of Contents**](#Toc)* |

---

We are not responsible for developing, testing, auditing, or maintenance of any of the Template Smart Contracts of ComBoox. Users are licensed to use the Template Smart Contracts as well as ComBoox on an "AS IS" basis.

#### &nbsp;&nbsp;&nbsp;&nbsp; 12.2. Result of Operations
&nbsp;&nbsp;&nbsp;&nbsp; Our operations to date have been limited. We were incorporated in November, 2023. Other than the Royalty Interests invested by Founding Member as contribution, and the deferred revenue incurred during the configuration process of the Platform and the book-entry system of the Company, we have no other assets or liabilities. We have no employees and do not intend to hire any employees.

#### &nbsp;&nbsp;&nbsp;&nbsp; 12.3 Liquidity and Capital Resources
&nbsp;&nbsp;&nbsp;&nbsp; To date, we have no resources for liquidity or working capital. We are not committed to any capital expenditures. We expect that, after the closing of the offering, the net proceeds from the offering will be sufficient to cover our operating expenses, including compliance and other administrative functions.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current versions of the Template Smart Contracts have fully covered the anticipated functions that a company may need to book their equity shares or corporate governance records. Therefore, even if the offering proceeds are not so sufficient as expected, our business will still be able to operate and develop independently. Therefore, at present, we do not have further financing plan after the Offering.

&nbsp;&nbsp;&nbsp;&nbsp; As an alternative solution, we may issue new Shares to exchange for new Template Smart Contracts, promotion services or professional services. It will result in dilution of our existing shareholders. However, as per the Operating Agreement of the Company, any capital increase shall be subject to a prior approval of members by Special Resolution.

#### &nbsp;&nbsp;&nbsp;&nbsp; 12.4 Significant Accounting Policies
&nbsp;&nbsp;&nbsp;&nbsp; The Company is engaged in the business of acquiring, holding the IPR and collecting royalties generating therefrom. In regard of accounting records and accounting policies, we have the following special character:

&nbsp;&nbsp;&nbsp;&nbsp; (1) **No Cash or Off-Chain Assets:**

As the first company registered on ComBoox and a true DAO, the Company will not open traditional bank accounts or hold off-chain assets. This ensures that all economic interests are directly controlled and disposed of by the Company in accordance with the voting decisions of its members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **ETH and USDC as General Equivalence:**

The Company adopts ETH and USDC as its primary payment instruments and value carrier. In other words, the Company treats ETH and USDC as special "general equivalents" for exchanging value with other entities or members. Therefore, the Company has prepared an Cryptos Flow Statement to describe the inflow and outflow of economic interest.

---

| |
|:---|
| 79 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Utility Token:**

&nbsp;&nbsp;&nbsp;&nbsp; (4) **Deferred Revenue:** 

The Company sells CBP to users in exchange for USDC via Fuel Tank at a ExRate. As a promotional measure, a certain amount of CBP is minted and granted to newly registered users as "prepaid vouchers." All CBP minted or transferred to other entities is booked as "deferred revenue" of the Company and is subsequently written off against the royalty income collected.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Deferred Recognition Value of Royalty Interests**:

Due to the following factors: (i) there are no similar decentralized applications (DApps) available on the market; (ii) ComBoox was solely developed by the sole Founding Member; and (iii) it has not yet generated material revenue, it is difficult to recognize the value of Royalty Interests when the Founding Member contributes it in exchange for the initial capital. Therefore, the value of the Royalty Interests will be recognized and amortized only after the Company has legally and publicly issued its equity shares and CBP and has generated material revenue for more than one year.

&nbsp;&nbsp;&nbsp;&nbsp; (6) **Unpaid Subscription of Initial Shares:**

&nbsp;&nbsp;&nbsp;&nbsp; Corresponding to the deferred recognition of the Royalty Interests value, when the Initial Shares is issued to the Founding Member, it will be booked with the same amount ($300,000.00) simultaneously in Cr. Subscribed Capital and Dr. Unpaid Subscription. And, the latter will also be used to record and track the payable amount of the Initial Shares under the general account of "Owners Equity".

&nbsp;&nbsp;&nbsp;&nbsp; (7) **Smart Contract Events:**

All economic interests flowing into or out of the Company are automatically recorded in the relevant smart contracts as "events", which are publicly, immutably and permanently stored on block chain. These events can be accessed by client applications globally and in real time. The Company has developed specialized modules in the ComBoox web application to facilitate users in retrieving these events and converting them into human-readable financial reports. Additionally, other client applications can freely access these records.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) **Real Time Reports**:

Stakeholders can access the above financial reports and accounting records by visiting the ComBoox website (https://comboox.vercel.app/app). The accounting records are updated at the same frequency as the blockchain itself, currently every second. This means that the balance sheet date and the financial reporting period can be set to the smallest possible time unit of one second.

---

| |
|:---|
| 80 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) **ETH Price:**

The exchange rate between ETH and USD is provided on-chain by the ChainLink Price Feed service and off-chain by CoinGecko, both of which are automatically updated in seconds. This ensures that all on-chain transactions are executed at accurate ETH prices and that off-chain accounting records can be properly maintained in USD. Any currency exchange gains or losses are calculated based on the USD value difference between the ETH price at the transaction time and the ETH price at the reporting time.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) **Off-Balance Sheet Arrangement** 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; During the periods presented and as of the current date, we have not engaged in any off-balance sheet arrangements, as defined in the rules and regulations of the SEC.

#### &nbsp;&nbsp;&nbsp;&nbsp; 13 DIRECTORS, EXECUTIVE OFFICERS AND SIGNIFICANT EMPLOYEES
&nbsp;&nbsp;&nbsp;&nbsp; As per the Operating Agreement, the day-to-day operation of the Company will be managed by members though public on-chain voting. Some important issues need to be approved by Special Resolution, while, most of the daily affairs only need to be approved by Ordinary Resolution. The manager has no decision making power and will only be responsible for duties set out by the Operating Agreement, or executing resolutions of General Meeting.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Due to the facts that the Founding Member: (1) is the developer of ComBoox; (2) holds substantial ratio of Shares of the Company; and (3) has nomination right for the position of manager, he may be deemed has and will keep having significant influences to the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mr. Li Li is the Founding Member of the Company, who is 48 years old and a corporate, securitization & data compliance lawyer of China with 18+ years experiences. He earned his bachelor of economics in Nankai University and Juris Master in Peking University. He is a senior expert of Beijing FinTech Industry Alliance, holding two blockchain patent applications registered and granted by China Intellectual Property Office, and two blockchain patent applications registered with WIPO pursuant to the Patent Cooperation Treaty. He won the first prize in "2021 China Merchants Bank Blockchain Application Innovation Competition" for his "ABS Cash Flow Tracking System" developed on Hyperledger Fabric 2.0, and was awarded as "Best Contributor to the Smart Contract Library" by FISCO BCOS Community for his "Equity Shares Book-Entry System" developed in Solidity

---

| | | | | |
|:---|:---|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Position**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Age**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Term of Office (Start Date)**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Term of Office (End Date)**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Li Li <sup>\*</sup>**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Manager**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 48**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; June 11, 2024**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; December 31, 2026**  |

---

*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* Domicile of Mr. Li Li: 34/F, 3rd Building, No. 77 Jianguo Road, Beijing, China* 

---

| |
|:---|
| 81 |
| *[**Table of Contents**](#Toc)* |

---

#### 14 COMPENSATION OF MANAGERS
&nbsp;&nbsp;&nbsp;&nbsp; In order for the Company to operate under the concept of DAO and to remain as a passive income entity, no remuneration will be paid to managers or members.

#### 15 CERTAIN RELATIONSHIPS AND RELATED TRANSACTIONS
On May 18, 2024, we entered into a Capital Contribution Agreement with our Founding Member, Mr. Li Li. Pursuant to this agreement, Mr. Li contributed all intellectual property rights related to the ComBoox Platform to the Company. In exchange, the Company issued to Mr. Li 2,500,000,000 Class A Shares and 500,000,000 Class B Shares. As a result, Mr. Li currently owns 100% of the Company's outstanding equity prior to this offering.

&nbsp;&nbsp;&nbsp;&nbsp; Mr. Li is our Founding Member and therefore a related party. The Capital Contribution Agreement is filed as Exhibit 10.1 to this Registration Statement.

#### 16 SECURITY OWNERSHIP OF CERTAIN BENEFICIAL OWNERS AND MANAGEMENT
&nbsp;&nbsp;&nbsp;&nbsp; In exchange of the Royalty Interests and CBP's Minting Right on Arbitrum One, the Company has issued 2,500,000,000 Class A Shares and 500,000,000 Class B Shares to Founding Member.

The following table sets forth the number, percentage and voting points of each class of shares beneficially owned as of September 30, 2025 and upon completion of this offering, by:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) each person known to us to beneficially own more than 5% of any of the shares; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) each of our managers.

As the sole Member and the only Manager, the Founding Member holds all the Shares before this offering.

---

| |
|:---|
| 82 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | | | | | | | | | | | |
|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|
| **Name of Beneficial Owner** | **Prior to this offering** | **Prior to this offering** | **Prior to this offering** | **Prior to this offering** | **Prior to this offering** | **Prior to this offering** | **After to this offering** | **After to this offering** | **After to this offering** | **After to this offering** | **After to this offering** | **After to this offering** |
| **Name of Beneficial Owner** | **Class A** | **Class A** | **Class B** | **Class B** | **Voting Points** | **Voting Points** | **Class A** | **Class A** | **Class B** | **Class B** | **Voting Points** | **Voting Points** |
| **Name of Beneficial Owner** | **Shares** | **%** | **Shares** | **%** | **Number** | **%** | **Shares** | **%** | **Shares** | **%** | **Number** | **%** |
| **5% or Greater Shareholder:** | | | | | | | | | | | | |
| Li Li<sup>\*</sup> | 2500000000 | 100 | 500000000 | 100 | 100500000000 | 100 | 2500000000 | 100 | 500000000 | 1.31 | 100500000000 | 72.77 |
| **Managers:** |  |  |  |  |  |  |  |  |  |  |  |  |
| Li Li | 2500000000 | 100 | 500000000 | 100 | 100500000000 | 100 | 2500000000 | 100 | 500000000 | 1.31 | 100500000000 | 72.77 |

---

*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* Domicile of Mr. Li Li: 34/F, 3rd Building, No. 77 Jianguo Road, Beijing, China* 

---

| |
|:---|
| 83 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp; 17 DESCRIPTION OF SECURITIES
**17.1. Attributes of Shares**

"**Share**" means a member's minimum unit of ownership interests and rights in the Company, par value of which is $0.0001. Shares will be booked automatically on Register of Shares in form of a digital object named "**Certificate of Contribution**" with the following key attributes:

&nbsp;&nbsp;&nbsp;&nbsp; (1) "**Shareholder**" means the ownership title holder of the subject Shares (i.e. a member of the Company), who will be booked and indicated in form of its User Number;

&nbsp;&nbsp;&nbsp;&nbsp; (2) "**Par Value**" represents the subscribed contribution amount of the subject Shares, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp; (3) "**Paid Value**" represents the paid-in contribution amount of the subject Shares that actually received by the Company, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) "**Clean Paid**" represents the paid-in contribution amount of the subject Shares that has no encumbrances attached and can be freely disposed by the Shareholder, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) "**Price of Par**" refers to the per share acquiring price for the unpaid Par Value of the subject Shares, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) "**Price of Paid**" means the per share acquiring price for the Paid Value of the subject Shares, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp; (7) "**Total Value**" means the total acquiring value of the subject Shares indicated in USD, which shall be calculated as following:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Value = Price of Paid \* Paid Value + Price of Par \* (Par Value - Paid Value)

&nbsp;&nbsp;&nbsp;&nbsp; (8) "**Voting Weight**" means percentage weight of each Share when calculating the voting rights of the subject Shares, and the calculation result shall be called as "**Voting Points**" which shall be the basis to calculate the aggregate voting rights of a member. The minimum unit of Voting Weight is one percent. Therefore, the total Voting Points of the subject Shares shall be calculated as:

&nbsp;&nbsp;&nbsp;&nbsp; Voting Points = Voting Weight \* Par Value / 100

&nbsp;&nbsp;&nbsp;&nbsp; (9) "**Distribution Weight**" means percentage weight of each Share when calculating the distribution rights of the subject Shares, and the calculation result shall be called as "**Distribution Points**", which shall be the basis to calculate the aggregate distribution rights of a member for distributing profits or residual assets, or assuming loss or liabilities of the Company. The minimum unit of Distribution Weight shall be one percent. Therefore, the total Distribution Points of the Shares shall be calculated as:

&nbsp;&nbsp;&nbsp;&nbsp; Distribution Points = Distribution Weight \* Par Value / 100

---

| |
|:---|
| 84 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; **17.2. Automatic Adjustment of Amount Attributes**

The smart contracts may automatically adjust certain amount attributes of the Shares under specified conditions. For example, the smart contracts is designed to dynamically modify the Par Value, Paid Value, and Clean Paid status of Shares during transactions, based on predefined logic embedded in the smart contracts. These automatic adjustments ensure accurate and transparent share accounting and are further explained below, and will not result in any unintended modification to the total number of shares outstanding.

&nbsp;&nbsp;&nbsp;&nbsp; (1) When a shareholder completes a capital payment for subscribed Shares, both the Paid Value and Clean Paid attributes of the relevant Certificate of Contribution are increased accordingly.

&nbsp;&nbsp;&nbsp;&nbsp; (2) When a shareholder enters into a binding share transfer agreement, the Clean Paid is reduced by the transfer amount to prevent multiple commitments over the same interest.

&nbsp;&nbsp;&nbsp;&nbsp; (3) Upon full payment by the transferee, a portion of the Par Value and Paid Value in the transferor's Certificate of Contribution is reduced, and a new one is created for the transferee, reflecting the transferred amount in all three attributes.

&nbsp;&nbsp;&nbsp;&nbsp; (4) If the original Certificate of Contribution's balance in Par Value and Paid Value reaches zero, that Certificate of Contribution is revoked and removed from the Register of Shares.

These operations are executed automatically through smart contracts and represent mechanical adjustments to existing digital records. They do not result in any change to the total number of issued shares, do not alter the type or class of securities concerned and do not affect voting rights, dividend rights, liquidation rights, or conversion privileges thereof. Such adjustments are intended solely to maintain accurate share accounting and do not constitute a new issuance of securities under the Securities Act of 1933. Section 3(a)(9) is therefore not applicable.

Please refer to Exhibit 32.1 for the flowchart and description of the relevant APIs, and to Exhibit 32.2 for the corresponding source code. In particular, the transferShare() function of the Register of Shares smart contract, together with the regShare() and subAmtFromShare() functions of the Shares Repo smart contract, set forth the detailed algorithms governing share transfer transactions.

---

| |
|:---|
| 85 |
| *[**Table of Contents**](#Toc)* |

---

As of the date hereof, 2,500,000,000 Class A shares and 500,000,000 Class B shares have been issued to the Founding Member. In addition, up to 37,600,000,000 Class B shares may be issued through listing in accordance with Listing Rule (No.1024 Rule) of the Shareholders' Agreement. Any amendment to such Listing Rule would require a corresponding amendment to the Shareholders' Agreement, which may only be effected by a Special Resolution approved by holders representing at least 80% of the voting rights. Please refer to Section 8.9 of this statement for general introduction concerning the possible transaction modes and procedures for issuing new shares.

To the extent a transfer of securities occurs and results in a new share record being created in the name of a new holder, such transfer is made exclusively in exchange for existing securities from the same issuer and on terms not involving any consideration other than the securities themselves, along with the performance of obligations arising under pre-existing agreements (e.g., capital contributions or payments).

**17.3. Classes of Shares**

The Company has issued two Classes of Shares: Class A Shares and Class B Shares. Comparing with Class B Shares, Class A Shares have 40 times Voting Weight. All the Shares can be issued or traded in fractions with a minimum unit of a Share.

The Company has issued 2.5 billion Class A Shares and 500 million Class B Shares to the Founding Member in exchange for the Royalty Interests and minting rights to CBP. All such Shares are subject to a lock-up period until June 30, 2027, during which time they may not be transferred, pledged, or otherwise disposed of except as permitted by a Special Resolution of the General Meeting.

Please see "**Dilution**" Section of this prospectus for detailed information in this regard.

**17.3.1. Key Terms of Class A Shares**

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Voting Rights**: Each Class A Share carries forty (40) Voting Points, used for governance purposes within the ComBoox smart contract system. Voting Points are allocated in proportion to the Par Value of subscribed (but not necessarily paid-in) capital.

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Distribution Rights**: Each Class A Share carries one (1) Distribution Point. Class A shareholders are entitled to receive distributions declared by the Company in accordance with their Distribution Points, which are also calculated based on the Par Value of subscribed capital.

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Liquidation Rights**: Upon any liquidation or winding up of the Company, Class A shareholders are entitled to receive liquidation proceeds pro rata in accordance with their Distribution Points, after payment of all liabilities.

&nbsp;&nbsp;&nbsp;&nbsp; (4) **Conversion Rights**: Class A Shares are not convertible into other classes of equity.

---

| |
|:---|
| 86 |
| *[**Table of Contents**](#Toc)* |

---

**17.3.2. Key Terms of Class B Shares**

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Voting Rights**: Each Class B Share carries one (1) Voting Points, used for governance purposes within the ComBoox smart contract system. Voting Points are allocated in proportion to the Par Value of subscribed (but not necessarily paid-in) capital.

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Distribution Rights**: Each Class B Share carries one (1) Distribution Point. Class B shareholders are entitled to receive distributions declared by the Company in accordance with their Distribution Points, which are also calculated based on the Par Value of subscribed capital, at the same sequence with Class A Shares.

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Liquidation Rights**: Upon any liquidation or winding up of the Company, Class B shareholders are entitled to receive liquidation proceeds pro rata in accordance with their Distribution Points, after payment of all liabilities, and at the same sequence with Class A Shares.

&nbsp;&nbsp;&nbsp;&nbsp; (4) **Conversion Rights**: Class B Shares are not convertible into other classes of equity.

**17.4. Deferred Evaluation and Profits Distribution Restriction**

Following a qualified appraisal of the Royalty Interests contributed by the Founding Member as part of its capital, if the evaluated Royalty Interests value exceeds the payable amount of the subscribed Initial Capital (i.e., the 2.5 billion Class A and 500 million Class B Shares minus the $7,500 paid in capital), the Founding Member may apply the excess value to purchase additional Class B Shares at a price of $0.0001 per share.

If the Royalty Interests appraisal is less than the payable amount of the subscribed Initial Capital, the Founding Member may either (i) contribute the shortfall in USDC, or (ii) request a proportionate reduction in equity, with Class B Shares reduced before Class A Shares.

No distributions of profit shall be made until:

&nbsp;&nbsp;&nbsp;&nbsp; (1) the Company has legally publicly offered its Shares and CBP for more than one year,

&nbsp;&nbsp;&nbsp;&nbsp; (2) the Royalty Interests contributed by the Founding Member has been duly appraised based on the actual income of the Company by a qualified third-party evaluation institution, and

&nbsp;&nbsp;&nbsp;&nbsp; (3) An Ordinary Resolution has been approved by the General Meeting.

---

| |
|:---|
| 87 |
| *[**Table of Contents**](#Toc)* |

---

#### 18 SHARES ELIGIBLE FOR FUTURE SALE
Prior to the Offering, there has been no public market for our Shares, and a liquid trading market for our Shares may not develop or be sustained after the offering. Future sales of our Shares in the public markets, or the availability of such Shares for sale in the public markets, could adversely affect market prices prevailing from time to time.

On condition that the Company successfully completed all registration or exemption procedures with SEC pursuant to the relevant laws and regulations, all of the Shares sold in this Offering will be freely tradable on-chain, by means of Trade Mode as defined in the Operating Agreement and implemented in Smart Contracts, without restriction or further registration under the Securities Act, unless such shares are held by any of our "affiliates" as such term is defined in Rule 144 under the Securities Act.

On condition that the offering statement, of which this prospectus is a part, and the Form TA submitted by the Company for acting as the transfer agent of its own Shares, are both qualified by the SEC, an initial public offering will be organized on our List of Orders, the specific smart contract adopted by the Company to facilitate Verified Investors to trade Shares on Arbitrum One.

Verified Investors may use USDC to directly acquire Offered Shares at the offering price on the List of Orders. Upon closing, new Shares will be automatically issued to the buyer and the consideration paid in form of USDC will be received and held by the Company directly. During the entire process of the initial offering, no underwriters, brokers, dealers or other intermediaries will be involved.

Furthermore, the List of Orders also can list all Sell Orders placed by shareholders and automatically match and close deals against the Buy Orders placed by Verified Investors. During the listing trade, no brokers, dealers or market-makers will involve. Shares will be created, altered or revoked under the automatic control of Smart Contracts, and consideration in USDC will be booked under the name of seller with his or her exclusive control.

Founding Member voluntarily locks up all Class A Shares from resale till the date of June 30, 2027, which has already been implemented and set up in the effective Shareholders Agreement.

The Founding Member does not have the unilateral ability to directly, secretly, or separately amend or waive the lock-up restriction applicable to the Class A Shares. The only mechanism through which the lock-up provisions could be modified or eliminated is by the adoption of an entirely new Shareholders Agreement, implemented through the deployment of a new set of smart contracts. Such action is expressly and technically subject to approval by the Members through a Special Resolution of the General Meeting, requiring the affirmative vote of at least 80% of all voting points held by the Members.

---

| |
|:---|
| 88 |
| *[**Table of Contents**](#Toc)* |

---

Accordingly, any modification to the lock-up terms would necessarily follow the procedures below:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Drafting and deployment of a proposed new Shareholders Agreement containing revised provisions (including, potentially, the removal of the lock-up Term);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Submission of the proposed Shareholders Agreement as a formal Motion to the General Meeting;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Voting by Members on such Motion in accordance with Voting Rule No. 8;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Public counting of votes through the blockchain-based voting function; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) In the event that the Motion is approved by the requisite 80% supermajority, activation of the new Shareholders Agreement on the blockchain, thereby replacing the prior agreement in its entirety.

Please refer to Sections 7.2, 6.1, and 3.3.3 of the White Paper for detailed procedures, APIs, and logic flowcharts relating to the updating, proposal, voting, and activation of a new version of the Shareholders Agreement.

Please also refer to Section 3.3.2(2) for the data structures and parameter settings of the Lock-Up smart contract, and to Section 6.6 (APIs 41, 42, 44 and 46) and Section 6.12 (APIs 80) for the interfaces governing share transfers, which illustrate how the Lock-Up smart contract restricts the transferability of the relevant shares.

All of the foregoing steps are conducted exclusively and transparently on the blockchain. Each stage of the process, including the creation, submission, and adoption of any new Shareholders' Agreement, is permanently recorded on the blockchain and becomes publicly available at the time of occurrence. The terms of any proposed Shareholders' Agreement are accessible to all stakeholders immediately upon deployment. Accordingly, we believe that no separate or supplemental notice to investors is required, as all materials and records are already accessible in real time through the blockchain.

Moreover, these procedures are expressly set forth in our Operating Agreement, implemented through our publicly verifiable smart contracts, and supported by the open-source publication of all relevant source code and testing scripts on GitHub. In our view, this governance framework provides transparency and safeguards comparable to, and in certain respects exceeding, those available to investors in traditional corporate structures, including public companies.

---

| |
|:---|
| 89 |
| *[**Table of Contents**](#Toc)* |

---

#### 19 WHERE YOU CAN FIND MORE INFORMATION
We have filed with the SEC a Registration Statement on Form S-1 under the Securities Act with respect to the Offered Shares. This prospectus, which constitutes a part of the offering statement, does not contain all of the information set forth in the offering statement or the exhibits and schedules filed therewith.

For further information about us and the Offered Shares, we refer you to the offering statement and the exhibits and schedules filed therewith. Statements contained in this prospectus regarding the contents of any contract or other document that is filed as an exhibit to the offering statement are not necessarily complete, and each such statement is qualified in all respects by reference to the full text of such contract or other document filed as an exhibit to the offering statement.

You may read and copy the said information at the SEC's Public Reference Room, 100 F Street, N.E., Room 1580, Washington, D.C. 20549. You may obtain information on the operation of the Public Reference Room by calling the SEC at 1-800-SEC-0330. The SEC also maintains an Internet website that contains reports, proxy statements and other information about issuers, including us, that file electronically with the SEC. The domain name of this site is (https://www.sec.gov).

&nbsp;&nbsp;&nbsp;&nbsp; Additional information about ComBoox, may be found on the project's website at (https://comboox.vercel.app). However, the information on such website is not part of this prospectus and should not be relied upon in making an investment decision.

---

| |
|:---|
| 90 |
| *[**Table of Contents**](#Toc)* |

---

#### INDEX TO FINANCIAL STATEMENTS

---

| | |
|:---|:---|
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Audited Financial Statements for the year ended December 31, 2024**  |  |
| [1 Report of Independent Registered Public Accounting Firm (PCAOB #6445)](#Report of Independent Registered Public Accounting Firm)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-2  |
| [2 Balance Sheet](#Audited Balance Sheet)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-3  |
| [3 Statements of Operations](#Audited Statements of Operations)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-4  |
| [4 Statement of Changes in Members' Equity](#Audited Statement of Changes in Members' Equity)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-5  |
| [5 Statements of Cash Flows](#Audited Statements of Cash Flows)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-6  |
| [6 Notes To The Audited Financial Statements](#Audited Notes To The Audited Financial Statements)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-7  |

---

---

| | |
|:---|:---|
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Unaudited Financial Statements for the year ended December 31, 2025**  |  |
| [1 Balance Sheet](#Unaudited Balance Sheet of June 30, 2025)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-42  |
| [2 Statements of Operations](#Unaudited Statements of Operations for the First Six Months of 2025)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-43  |
| [3 Statement of Changes in Members' Equity](#Unaudited Statement of Changes in Members' Equity for the First Six Months of 2025)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-44  |
| [4 Statements of Cash Flows](#Unaudited Statements of Cash Flows for the First Six Months of 2025)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-45  |
| [5 Condensed Notes to the Unaudited Financial Statements](#Condensed Notes to the Unaudited Financial Statements For the six months ended June 30, 2025)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F-46  |

---

---

| |
|:---|
| F-1 |
| *[**Table of Contents**](#Toc)* |

---

 **REPORT OF INDEPENDENT REGISTERED PUBLIC ACCOUNTING FIRM**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To the Members of

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ComBoox DAO LLC

**Opinion on the financial statements** 

We have audited the accompanying balance sheets of ComBoox DAO LLC (the "**Company**") as of December 31, 2024, the related statements of operations, changes in members' equity and cash flow, for the period ended December 31, 2024, and the related notes to the financial statements. In our opinion, the financial statements present fairly, in all material respects, the financial position of the Company as of December 31, 2024, and the results of its operations and its cash flows for the period ended December 31, 2024, in conformity with U.S. generally accepted accounting principles (GAAP).

**Basis for opinion** 

These financial statements are the responsibility of the Company's management. Our responsibility is to express an opinion on the Company's financial statements based on our audits. We are a public accounting firm registered with the Public Company Accounting Oversight Board (United States) ("**PCAOB**") and are required to be independent with respect to the Company in accordance with the U.S. federal securities laws and the applicable rules and regulations of the Securities and Exchange Commission and the PCAOB.

We conducted our audits in accordance with the standards of the PCAOB. Those standards require that we plan and perform the audit to obtain reasonable assurance about whether the financial statements are free of material misstatement, whether due to error or fraud. Our audits included performing procedures to assess the risks of material misstatement of the financial statements, whether due to error or fraud, and performing procedures that respond to those risks. Such procedures included examining, on a test basis, evidence regarding the amounts and disclosures in the financial statements. Our audits also included evaluating the accounting principles used and significant estimates made by management, as well as evaluating the overall presentation of the financial statements. We believe that our audits provide a reasonable basis for our opinion.

**Critical Audit Matters**

We determined that there are no critical audit matters. <br>

*/s/ Kustov & Associates, Inc.*

San Francisco, California

March 12, 2025 <br>

We have served as the Company's auditor since 2024.<br>

---

| |
|:---|
| F-2 |
| *[**Table of Contents**](#Toc)* |

---

 **Balance Sheets**

---

| | | |
|:---|:---|:---|
| | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** |
| | **2024** | **2023** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Intangible Assets - IPR  | $0.00 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Intangible Assets - ETH | 0.00 | 0.00 |
| **Total Assets** | $**0.00** | **0.00** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Deferred Revenue  | 53420.55 | 0.00 |
| **Total Liabilities** | $**53420.55** | **0.00** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subscribed Capital  | 300000.00 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Less: Unpaid Subscription  | (300000.00) | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Retained Earnings  | (53420.55) | 0.00 |
| **Total Equity** | $**(53420.55)** | **0.00** |
| **Total Liabilities and Equity** | $**0** | **0** |

---

&nbsp;&nbsp;&nbsp;&nbsp; *The accompanying notes are an integral part of the financial statements.* <br> *See Report of Independent Registered Public Accounting Firm.*

---

| |
|:---|
| F-3 |
| *[**Table of Contents**](#Toc)* |

---

 **Statements of Operations**

---

| | | |
|:---|:---|:---|
| | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2023** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Royalty Income  | $112.90 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Gross profit** | **112.90** | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Selling, General, and Administrative | **37561.12** | **0.00** |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Gain and Loss on Digital Assets  | 15972.33 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Total Operating Expenses** | **53533.45** | **0.00** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Income Before Taxes**  | **(53420.55)** | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Income Tax Expense  | 0.00 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Net Income (Loss)**  | $**(53420.55)** | 0.00 |

---

 *The accompanying notes are an integral part of the financial statements.* <br> *See Report of Independent Registered Public Accounting Firm.*

---

| |
|:---|
| F-4 |
| *[**Table of Contents**](#Toc)* |

---

 **Statements of Changes in Members' Equity**

---

| | | | | | |
|:---|:---|:---|:---|:---|:---|
| | **Class A <br> Paid-In Capital** | **Class B <br> Paid-In Capital** | **Additional <br> Paid-In Capital** | **Retained Earnings** | **Total Equity** |
| **Balance at November 8, 2023** | $**0** | **0** | **0** | **0** | **0** |
| Net Income |  |  |  |  |  |
| **Balance at December 31, 2023** | 0 | 0 | 0 | 0 | 0 |
| Net Income | **-** | **-** | **-** | (53420.55) | (53420.55) |
| **Balance at December 31, 2024** | $0 | 0 | 0 | (53420.55) | (53420.55) |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *The period from November 8, 2023, to December 31, 2023, is a short reporting period as the Company was incorporated on November 8, 2023. For further details, refer to 3.7. The accompanying notes are an integral part of these audited financial statements.* <br> *See Report of Independent Registered Public Accounting Firm.*

---

| |
|:---|
| F-5 |
| *[**Table of Contents**](#Toc)* |

---

 **Statements of Cash Flows**

---

| | | |
|:---|:---|:---|
| | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2023** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Increase Deferred Revenue  | $0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Other Income | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sales, General & Administrative | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Net Inflow from Operating Activities**  | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Purchase of IPR | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Net Outflow for Investing Activities**  | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Proceeds From Share Issuance  | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution  | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Net Inflow from Financing Activities**  | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Net Inflow**  | $**0** | **0** |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *The Company operates exclusively with digital assets and does not maintain traditional cash or bank accounts. All transactions, including those related to the minting, exchange, and transfer of assets, are conducted using on-chain digital assets. As a result, the Statement of Cash Flows reflects a zero balance, as there are no cash inflows or outflows in the conventional sense.*<br> *The accompanying notes are an integral part of these audited financial statements.*<br> *See Report of Independent Registered Public Accounting Firm.*

---

| |
|:---|
| F-6 |
| *[**Table of Contents**](#Toc)* |

---

# Notes to the Audited Financial Statements
As of December 31, 2024

**1. Description of Business**

Comboox DAO LLC (the **"Company"**) is a Wyoming limited liability company that has elected to be a decentralized autonomous organization pursuant to the Wyoming Limited Liability Company Act and the Wyoming Decentralized Autonomous Organization Supplement. The Company was formed on November 8, 2023.

ComBoox (**"ComBoox"** or the **"Platform"**) is a corporate book-entry platform consisting of a core smart contract called the "Registration Centre" and a set of template smart contracts (the **"Templates"**) deployed on the public blockchain network, Arbitrum One. It is designed to automatically record share transactions and corporate governance activities of companies, enabling stakeholders to exercise their legal rights in a self-service manner.

The Company is engaged in the business of acquiring and holding the beneficiary rights to Templates within Arbitrum One (the **"IPR"**) and collecting royalties generated therefrom. Additionally, the Company is entitled to collect up to a 20% commission on each royalty payment collected by future authors on ComBoox. The Company is categorized as a passive income entity that holds IPR of Templates and collects relevant royalties and commissions derived therefrom.

Under the automatic control of predefined smart contracts, companies registered on ComBoox can have their share transactions and corporate governance activities fully managed, monitored, and recorded by smart contracts. No agents or intermediaries are required; rights holders can directly exercise their rights, obligors have no opportunity to default, and a full range of information can be disclosed in real-time along with the relevant legal acts.

The Company has the following special characteristics regarding the accounting records and policies:

&nbsp;&nbsp;&nbsp;&nbsp; (1) **No Cash or Off-Chain Assets:** As the first company registered on ComBoox and a true DAO, the Company will not open traditional bank accounts or hold off-chain assets. This ensures that all economic interests are directly controlled and disposed of by the Company in accordance with the voting decisions of its Members.

&nbsp;&nbsp;&nbsp;&nbsp; (2) **ETH as General Equivalence:** The Company adopts ETH as its primary payment instrument and value carrier. In other words, the Company treats ETH as a special "general equivalent" for exchanging value with other entities or Members. Therefore, the Company has prepared an ETH Flow Statement to describe the inflow and outflow of economic interests to and from itself.

*[**Table of Contents**](#Toc)*

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4) **Deferred Revenue:** The Company sells CBP to users in exchange for CBP via a smart contract called "fuel tank" (the **"Fuel Tank"**) at a predetermined exchange rate set by the Company (the **"ExRate"**), which is currently 1:1 (ETH/CBP). As a promotional measure, a certain amount of CBP is minted and granted to newly registered users as "prepaid vouchers." All CBP minted or transferred to other entities is booked as "deferred revenue" of the Company and is subsequently written off against the royalty income collected.

&nbsp;&nbsp;&nbsp;&nbsp; (5) **Deferred Recognition Value of IPR:** Due to the following factors: (i) there are no similar decentralized applications (DApps) available on the market; (ii) ComBoox was solely developed by the sole founding member (the **"Founding Member"**); and (iii) it has not yet generated material revenue, it is difficult to recognize the value of IPR when the Founding Member contributes it in exchange for the initial capital. Therefore, the value of the IPR will be recognized and amortized only after the Company has legally and publicly issued its equity shares and CBP and has generated material revenue for more than one year.

&nbsp;&nbsp;&nbsp;&nbsp; (6) **Unpaid Subscription of Initial Capital:** Corresponding to the deferred recognition of IPR, when the Initial Capital is issued to the Founding Member, it will be recorded as $300,000.00 in Cr. Subscribed Initial Capital and Dr. Unpaid Subscription of Initial Capital. The latter will also be used to record and track the payable amount of the Initial Capital under the general account of "Owner's Equity."

&nbsp;&nbsp;&nbsp;&nbsp; (7) **Smart Contract Events:** All economic interests flowing into or out of the Company are automatically recorded in the relevant smart contracts as "events," which are publicly, immutably, and permanently stored on the blockchain. These events can be accessed by client applications globally and in real time. The Company has developed specialized modules in the ComBoox web application to facilitate users in retrieving these events and converting them into human-readable financial reports. Additionally, other client applications can freely access these records.

*[**Table of Contents**](#Toc)*

&nbsp;&nbsp;&nbsp;&nbsp; (8) **Real Time Reports:** Stakeholders can access the above financial reports and accounting records by visiting the ComBoox website (https://comboox.vercel.app/app). The accounting records are updated at the same frequency as the blockchain itself, currently every second. This means that the balance sheet date and the financial reporting period can be set to the smallest possible time unit of one second.

&nbsp;&nbsp;&nbsp;&nbsp; (9) **ETH Price:** The exchange rate between ETH and USD is provided on-chain by the Chainlink Price Feed service and off-chain by CoinGecko, both of which are updated automatically in seconds. This ensures that all on-chain transactions are executed at accurate ETH prices and that off-chain accounting records can be properly maintained in USD. To calculate the value of CBP transactions, the ExRate is used to first convert CBP into ETH and then into USD. Any currency exchange gains or losses are calculated based on the USD value difference between the ETH price at the transaction time and the ETH price at the reporting time.

This report, along with the accounting records of the Company, is prepared based on the principles outlined above.

**2. Summary of Significant Accounting Policies**

**2.1. Estimates and Assumptions**

The preparation of financial statements in conformity with U.S. GAAP requires management to make estimates based on assumptions about current economic and market conditions, as well as, for some estimates, future conditions. These estimates affect the reported amounts and related disclosures in the financial statements. The Company bases its estimates and judgments on historical experience and various other assumptions and information that it believes to be reasonable under the circumstances.

Although the Company's estimates consider current and expected future conditions, actual conditions could differ from expectations, which could materially affect the Company's results of operations, financial position, and cash flows.

Estimates are used for, but are not limited to, determining the valuation of intangible assets and the useful lives applied in amortization.

---

| |
|:---|
| F-9 |
| *[**Table of Contents**](#Toc)* |

---

**2.2. Revenue Recognition**

The Company's revenue primarily consists of royalties from IPR licensing and commissions derived therefrom. It uses a utility token called "ComBoox Points" (**"CBP"**) to measure and collect royalties. Users of ComBoox can establish a comprehensive bookkeeping system for their company on the platform using smart contracts cloned from Templates. Thereafter, stakeholders may conduct various legal acts related to equity rights and corporate governance on the blockchain in a self-service mode.

**2.2.1. Revenue Recognition Policy**

The Company recognizes revenue in accordance with ASC 606, "Revenue from Contracts with Customers," which follows a five-step model:

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Identify the contract with a customer:** The Company's customers enter into a contract upon utilizing itssmart contract system, which requires the transfer of CBP as royalty payments. These transactions are executed automatically via the ComBoox Platform and the blockchain infrastructure.

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Identify the performance obligations in the contract:** The Company's performance obligation is to provide access to its intellectual property (**"IP"**) and smart contract services. When a customer executes their legal rights via smart contract APIs, the corresponding royalty fees (CBP) are transferred as compensation for the license granted.

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Determine the transaction price:** The transaction price is determined based on the quantity of CBP transferred, multiplied by the predefined CBP/ETH exchange rate of 1:1 set by the Company. The equivalent ETH amount is then converted to USD using the latest available CoinGecko ETH/USD exchange rate, which represents the fair value of the transaction.

---

| |
|:---|
| F-10 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; (4) **Allocate the transaction price to the performance obligations:** The entire transaction price is allocated to the licensing of the Company's intellectual property and smart contract services, as this constitutes the sole deliverable in the transaction.

&nbsp;&nbsp;&nbsp;&nbsp; (5) **Recognize revenue when (or as) the performance obligation is satisfied:** The performance obligation is satisfied when CBP is transferred from the user to the Company's address in the Registration Center. Revenue is recognized at that point, as the Company has provided the customer with access to its smart contract system.Simultaneously, an equivalent amount is written off from Deferred Revenue, ensuring proper revenue recognition.

**2.2.2. Disaggregation of Revenue**

The Company's revenue is derived from royalty revenue, which is recognized at the point in time when the CBP is transferred to the Company address and recorded on the blockchain. Since the smart contract executes transactions automatically, revenue recognition occurs in real-time upon each transfer event.

---

| | | |
|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31, 2024** | **For the year ended 23:59:59 December 31, 2024** |
| | **CBP** | **USD** |
| **Revenue by Timing of revenue recognition** | 0.04218 | 112.9 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Revenue at a Point in Time | 0.04218 | 112.9 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Revenue Over Time | 0 | 0 |

---

**2.2.3. Breakdown of Revenue Sources**

The Company's revenue consists of two primary sources:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Royalty Revenue:** Payments collected from users executing their legal rights through smart contracts, transferred to the Company's address in CBP and converted to USD.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Commission Revenue:** A 20% commission on royalty payments collected by future authors of Templates on ComBoox.

Revenue is recognized at the point in time when the CBP is transferred to the Company address and recorded on the blockchain. Since the smart contract executes transactions automatically, revenue recognition occurs in real-time upon each transfer event.

---

| |
|:---|
| F-11 |
| *[**Table of Contents**](#Toc)* |

---

**2.2.4. Revenue Calculation Process**

The revenue calculation process is automated and follows these steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Retrieve CBP transfer data from the "Transfer" event in the Registration Center.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Convert CBP to ETH using the predefined 1:1 ExRate.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Convert ETH to USD using the latest available CoinGecko ETH/USD price, which represents a volume-weighted average price across multiple digital assets exchanges.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Recognize revenue and write off the corresponding amount from Deferred Revenue.

This methodology ensures accurate, consistent, and real-time revenue recognition in compliance with ASC 606. The Company continuously monitors and updates its pricing methodology to reflect fair market values for accurate financial reporting.

**2.3. Deferred Revenue**

Deferred Revenue is the only type of liability of the Company, representing the value of CBP held by entities other than the Company. In other words, it quantifies the rights to use the smart contracts cloned from the Templates.

The Company may mint or transfer CBP as a utility token to external entities through the following methods:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1) Transfer CBP to buyers automatically through the Fuel Tank at the exchange rate predefined by the Company when they call the "refuel" function of the Fuel Tank and pay an equivalent amount in ETH.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2) Automatically mint CBP to new users as "New User Awards" in an amount predefined or adjusted from time to time by the Company when they sign up with the Registration Center.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3) Transfer a specified amount of CBP to a designated address pursuant to a relevant Simple Majority Resolution of the General Meeting of Members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4) Mint CBP to the Founding Member to enable him to set up and configure the book-entry system for the Platform and the Company.

Deferred Revenue is recognized when CBP is minted or transferred and recorded under the recipient's address in the Registration Center. When CBP is held by the Company, it is considered a special voucher with no intrinsic value. However, the Company will still calculate and publicly disclose the balance of CBP held by the Company as well as its total supply amount on ComBoox.

---

| |
|:---|
| F-12 |
| *[**Table of Contents**](#Toc)* |

---

**2.4. Fair value measurements**

The Company measures and reports certain financial and digital assets at fair value in accordance with ASC 820 and ASU 2023-04 - Fair Value Measurements and Disclosures. Fair value is determined based on market participant assumptions and categorized into the following levels within the fair value hierarchy:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1) Level 1: Inputs are quoted prices in active markets for identical assets, such as the publicly available market price of ETH on digital asset exchanges. The Company uses the ETH/USD exchange rate provided by Chainlink Price Feeds (on-chain) and CoinGecko (off-chain) to determine the fair value of ETH.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2) Level 2: Inputs are observable market data other than quoted prices included in Level 1. The Company does not currently utilize Level 2 inputs for valuation purposes.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3) Level 3: Inputs are unobservable data for the asset or liability, typically used for complex or illiquid valuations. The Company does not use Level 3 inputs for digital asset valuation.

**2.4.1. Valuation Methodology**

The fair value of ETH is determined based on the latest available price from Chainlink Price Feeds (for smart contract-based transactions) and CoinGecko (for off-chain reporting). ETH is primarily used by the Company as a payment instrument and value carrier, and its fair value is recorded in USD at the reporting date based on the ETH/USD exchange rate at that time.

The fair value of CBP is determined using the ExRate of CBP to ETH, as predefined by the Company in the Fuel Tank, and then converted to USD using the ETH/USD price from CoinGecko at the transaction date. CBP is not actively traded on an open market; therefore, it does not fall under Level 1 valuation and is instead measured based on the Company's predefined ExRate, which serves as an observable input.

---

| |
|:---|
| F-13 |
| *[**Table of Contents**](#Toc)* |

---

**2.4.2. Unrealized Gains and Losses**

Unrealized gains and losses on digital assets arise from fluctuations in ETH/USD exchange rates. The Company calculates the Gain and Loss on Digital Assets based on the difference between the ETH price at the reporting date and the ETH price at the transaction date. Any appreciation in CBP held by third parties is measured using the same methodology, with valuation based on the ETH/USD price at the reporting date.

However, any gains or losses resulting from Additional Paid-In Capital transactions are excluded from operational costs or expenses and are instead recognized directly in Owners' Equity.

The Company ensures that all transactions are accounted for at the correct and accurate fair value by using real-time on-chain price feeds for ETH and structured off-chain data from reputable sources such as CoinGecko.

**2.5. Income tax treatment**

The Company is organized as a Wyoming Limited Liability Company (LLC) and has elected to be treated as a pass-through entity for U.S. federal income tax purposes under Section 701 of the Internal Revenue Code. As a result, the Company is not subject to federal income tax; instead, taxable income, deductions, credits, and other tax attributes are passed through to its members, who report them on their individual tax returns.

Wyoming state law does not impose state income tax on LLCs or individuals. Therefore, no state income tax liability arises at the Company level. Members are solely responsible for reporting and paying any applicable federal or other jurisdictional income taxes based on their share of the Company's income.

Under ASC 740 - Income Taxes, the Company does not recognize a Deferred Tax Asset (DTA) because it does not directly incur income tax liabilities. Any potential tax benefits or obligations associated with net operating losses or tax credits are allocated to the individual members rather than retained by the Company.

---

| |
|:---|
| F-14 |
| *[**Table of Contents**](#Toc)* |

---

**2.6. Expense classification**

The Company's primary current expenses are SG&A, which specifically include New User Awards, Startup Costs, and General Meeting Approved Payments.

**2.6.1. New User Awards**

As a marketing promotion, the Company automatically mints CBP for new users of the ComBoox platform as a "New User Award". When they sign up with the Registration Centre, a predefined amount of CBP is automatically minted to the user's address. Such transactions are recorded as "Deferred Revenue" on the credit side and as "SG&A" on the debit side.

**2.6.2. Startup Cost**

To facilitate the Founding Member in setting up and configuring the Platform, the Company minted a sum of CBP to the Founding Member. Such transactions are recorded as "Deferred Revenue" on the credit side and as "SG&A" on the debit side.

**2.6.3. General Meeting Approved Payment**

The Company may pay ETH or CBP to other parties with the approval of the General Meeting of members. Such transactions will be recorded as "ETH" or "Deferred Revenue" on the credit side and as "SG&A" on the debit side.

**3. Details of Significant Balance Sheet and Income Statement Items**

**3.1. Cash and Cash Equivalentss**

As per the Operating Agreement, the Company is not permitted to open traditional bank accounts or hold any off-chain assets. The Company intends to use ETH as a payment instrument and value carrier to pay for services or the IPR of Templates, or to distribute as profits or assets to members. Therefore, cash and cash equivalents as of the Report Time were $0.

---

| |
|:---|
| F-15 |
| *[**Table of Contents**](#Toc)* |

---

**3.2. Receivables**

The Company has no trade receivables or any other types of receivables. The Company does not extend credit to customers and operates on a prepayment basis for all services rendered. Therefore, receivables as of the Report Time were $0.

**3.3. Revenue**

**3.3.1. Royalty Revenue**

Revenue is recognized when the royalties collected in CBP are booked under the address of the Company in the Registration Center (i.e., the record-keeping smart contract of CBP). Such transactions will be recorded as "Royalty Revenue" on the credit side and as "Deferred Revenue" on the debit side.

The Royalty Revenue is recognized entirely at a point in time, with no revenue recognized over time.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **CBP** | **USD** | **CBP** | **USD** |
| **Royalty Revenue** | 0.04218 | 112.9 | 0 | 0 |

---

Royalty Revenue is recorded by the Transfer event in the Registration Center with the following filter conditions.

(a) CBP is transferred to the address of the Company (i.e., the address of the General Keeper, representing the legal entity of the Company); and

(b)The sender's address is not the "zero" address (otherwise, it would be a mint transaction).

&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91<br> event Transfer(address indexed from, address indexed to, uint256 indexed value);<br> The Company: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d<br>

---

| |
|:---|
| F-16 |
| *[**Table of Contents**](#Toc)* |

---

**3.3.2. CBP Sales Income**

To supply CBP to the users of the ComBoox Platform, the Company will sell CBP in exchange for ETH via the Fuel Tank. Buyers may call the "refuel" function of the Fuel Tank and pay their consideration in ETH. The Fuel Tank will then automatically transfer CBP to the buyers at a predefined ExRate. This will be the Company's primary source of ETH inflow.

Such transactions will be recorded with "ETH" on the debit side and "Deferred Revenue" on the credit side. During the Report Period, no CBP was sold via the Fuel Tank.

The Sales Income will be also recognized entirely at a point in time.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **CBP** | **USD** | **CBP** | **USD** |
| **CBP Sales Income - ETH** | 0 | 0 | 0 | 0 |

---

CBP Sales Income is recorded through the "Refuel" event in the smart contract of the Fuel Tank. The address of the Fuel Tank and the interface of the Refuel event are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Address of Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0<br> event Refuel (address indexed buyer, uint indexed amtOfEth, uint indexed amtOfEth); <br>

 **3.3.3. Other Income**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Other Income is recognized when ETH is received without calling a specific function of the General Keeper. Such transactions will be recorded as "Other Income" on the credit side and as "ETH" on the debit side. The Income will be also recognized entirely at a point in time.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| **Other Income** | 0 | 0 | 0 | 0 |

---

---

| |
|:---|
| F-17 |
| *[**Table of Contents**](#Toc)* |

---

Other Income is recorded by the "ReceivedCash" event in the General Keeper, with the condition that the ETH is not paid from the Fuel Tank (otherwise, it will be recorded as CBP Sales Income).

&nbsp;&nbsp;&nbsp;&nbsp;<br> General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d<br> event ReceivedCash(address indexed from, unit indexed amt);<br>

**3.4. Deferred Revenue**

At the Report Time, the Company's Deferred Revenue is <u>16.04782 CBP</u> or <u>53,420.55 USD</u>. To convert the value of CBP into USD, the Company adopts the ExRate of 1:1 ETH/CBP and applies the ETH price at the Report Time.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **CBP** | **USD** | **CBP** | **USD** |
| **Deferred Revenue** | 16.04782 | 53420.55 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; CBP Total Supply | 104.09 | 346498.45 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; - CBP of General Keeper | 0.04218 | 140.41 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; - CBP of Fuel Tank | 88 | 292937.49 | 0 | 0 |
| **Total Deferred Revenue** | **16.04782** | **53420.55** | 0 | 0 |

---

As an ERC-20 token, CBP's total supply and the balance of a specific holder can be retrieved by calling the "totalSupply" and "balanceOf" functions of its registration smart contract, i.e., the Registration Center.

&nbsp;&nbsp;&nbsp;&nbsp; (1) **CBP Total Supply:** can be retrieved by calling the "totalSupply" function of the Registration Center with a filter condition for the block number whose timestamp is the latest but still precedes the Report Time.

---

| |
|:---|
| F-18 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91 <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function totalSupply() external view returns(uint256) <br> blockNumber: 290687173n <br>

&nbsp;&nbsp;&nbsp;&nbsp; (2) **CBP held by the General Keeper:** can be retrieved by calling the "balanceOf" function of the Registration Center with the following filter conditions: (a) the target account must be the address of the General Keeper, and (b) the checkpoint must be at block number 290687173n, i.e., the block number whose timestamp is the latest but still precedes the Report Time.

&nbsp;&nbsp;&nbsp;&nbsp; <br> Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91 <br> function balanceOf (address account) external view returns (uint256); <br> General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> blockNumber: 290687173n <br>

&nbsp;&nbsp;&nbsp;&nbsp; (3) **CBP held by the Fuel Tank:** can be retrieved by calling the "balanceOf" function of the Registration Center with the following filter conditions: (a) the target account must be the address of the Fuel Tank, and (b) the checkpoint must be at block numbered 290687173n, i.e. the block number whose timestamp is the latest but still precedes the Report Time.

---

| | | |
|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31, 2024** | **For the year ended 23:59:59 December 31, 2024** |
| | **CBP** | **USD** |
| **CBP Flow of Fuel Tank** | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp; Add CBP | 176 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; - Withdraw CBP | 88 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; - Refuel CBP | 0 | 0 |
| **Sub Total of CBP Flow of Fuel Tank** | **88** | **0** |

---

---

| |
|:---|
| F-19 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91 <br> function balanceOf (address account) external view returns (uint256); <br> Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 <br> blockNumber: 290687173n <br>

**3.5. Intangible Assets**

**3.5.1 IPR of ComBoox**

In exchange for the initial capital, the Founding Member invested the following IPR into the Company as a capital contribution:

&nbsp;&nbsp;&nbsp;&nbsp; (1)The partial beneficiary right to the Templates to collect royalties within the territory of Arbitrum One;

&nbsp;&nbsp;&nbsp;&nbsp; (2) The owner's right to the Platform to collect commissions;

&nbsp;&nbsp;&nbsp;&nbsp; (3) The owner's right to the Registration Center for minting CBP.

The Company may mint and transfer a certain amount of CBP to the Fuel Tank as per prior approvals of an Ordinary Resolution, through which the Company may sell CBP to the market and receive sales income in ETH. The Company has no obligation to redeem any CBP.

Under US GAAP, when the Founding Member contributed the above IPR to the Company, it was difficult to recognize the value concerned for the following reasons:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) There are no similar software or business models available in the market, making it impossible to identify comparable fair value measurement targets;

&nbsp;&nbsp;&nbsp;&nbsp;(2) ComBoox has not generated material revenue, so there is no reasonable basis for valuation under the revenue method;

&nbsp;&nbsp;&nbsp;&nbsp; (3) ComBoox was developed solely by the Founding Member, meaning that there are no arm's-length transactions or third-party payment records to support the development costs;

---

| |
|:---|
| F-20 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; (4) The cost method alone is unlikely to be accepted as a sound basis for valuing the IPR.

For the above reasons, the value of the IPR will be deferred for recognition and amortization until the Company has legally publicly issued its equity shares and CBP, and received material revenue for more than one year. At the Report Time, the recognized value of IPR is zero.

---

| | | |
|:---|:---|:---|
|  | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** |
| | **2024** | **2023** |
|  | **USD** | **USD** |
| Beginning Value of IPR | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Amortization | 0 | 0 |
| Net Value of IPR | 0 | 0 |

---

**3.5.2. ETH of the Company**

In exchange for the initial capital, the Founding Member invested the following IPR into the Company as a capital contribution:

ETH is adopted by the Company to act as a paying instrument and value carrier. In other words, the Company takes ETH as a special "general equivalence" to exchange value with other entities or members.

The Company's ETH mainly comes from its CBP sales income via Fuel Tank, which will be booked as "Deferred Revenue" on the credit side and as "Intangible Assets - ETH" on the debit side.

The Company may hold ETH through two smart contracts: (a) General Keeper, representing the legal entity of the Company; or (b) Fuel Tank, the special vehicle to supply CBP to users of ComBoox. Therefore, the total ETH of the Company shall be the sum of the ETH held by the said two smart contracts.

The exchange rate between ETH and USD is provided on-chain by the ChainLink Price Feed service and off-chain by CoinGecko, both of which are automatically updated in seconds. In this way, the Company can ensure that all on-chain transactions are closed at the correct and accurate ETH price, and that off-chain accounting records can be prepared in USD. A gain or loss of digital assets is calculated based on the USD value difference derived from the ETH price at the reporting time and the ETH price at the transaction time.

To convert ETH into USD and calculate the Gain and Loss of Digital Assets, the Company adopted the most recent ETH price at the Report Time, provided by CoinGecko, which is **<u>3,328.8351 USD/ETH</u>** (the **"ETH Price of Report Time"**).

---

| |
|:---|
| F-21 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| ETH of Company | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; ETH in General Keeper | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Less: ETH as Deposits | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; ETH in Fuel Tank | 0 | 0 | 0 | 0 |
| **Total ETH of Company** | **0** | **0** | **0** | **0** |

---

The ETH of the Company can be retrieved by querying the Registration Center for the ETH balance of a specific address at a particular block or by calling the relevant smart contracts with the respective parameters.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)**ETH in General Keeper:** can be retrieved by querying the ETH balance of the General Keeper address at the block number with a timestamp that is earlier, but closest to, the Report Time.

&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br> import { usePublicClient } from "wagmi" ; <br> const client = usePublicClient (); <br> const balaOfGK = await client . getBalance ({ <br> address: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d , <br> blockNumber: 290687173n , <br> }); <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)**ETH as Deposits:** can be retrieved by calling the "totalDeposits" function of the General Keeper with the block number whose timestamp is earlier, but closest to, the Report Time.

&nbsp;&nbsp;&nbsp;&nbsp; <br>General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> function totalDeposits () external view returns (uint); <br> blockNumber: 290687173n <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)**ETH in Fuel Tank:** can be retrieved by querying the ETH balance of the Fuel Tank address with the block number whose timestamp is earlier, but closest to, the Report Time.

---

| |
|:---|
| F-22 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br> import { usePublicClient } from "wagmi" ; <br>const client = usePublicClient (); <br> const balaOfFT = await client . getBalance ({ <br> address: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 , <br> blockNumber: 290687173n , <br> });<br>

**3.6. Selling, General and Administrative**

**3.6.1. New User Awards**

To date, all five new users that received this "New User Award" are accounts controlled by the Founding Member, making these transactions related party transactions under ASC 850.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **CBP** | **USD** | **CBP** | **USD** |
| **New User Awards** | 0.09 | 210.10 | 0 | 0 |

---

"New User Awards" are recorded by the "Transfer" event in the Registration Center with the following filter conditions: (a) CBP is transferred from the zero address, and (b) the receiver is not the address of the Company.

&nbsp;&nbsp;&nbsp;&nbsp; <br> Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91 <br> event Transfer (address indexed from , address indexed to , uint256 indexed value); <br> Address of Zero: 0x00 <br> Address of Company : 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br>

---

| |
|:---|
| F-23 |
| *[**Table of Contents**](#Toc)* |

---

**3.6.2. Startup Cost**

To facilitate the Founding Member in setting up and configuring the Platform, the Company minted 16 CBP to the Founding Member.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **CBP** | **USD** | **CBP** | **USD** |
| **Startup Cost** | 16 | 37351.02 | 0 | 0 |

---

"Startup Cost" is recorded by the event "Transfer" in the Registration Center under the following conditions: (a) CBP is transferred from the address of the Company, and (b) the recipient is either User No. 1 or User No. 2, both of whom are controlled by the Founding Member.

&nbsp;&nbsp;&nbsp;&nbsp; <br> Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91 <br> event Transfer (address indexed from , address indexed to , uint256 indexed value); <br> Company: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> User No.1 : 0xc12c20fd7B50DA0909500dc9bb6758376398F8a8 <br> User No.2 : 0x4399b515FdF8E050CAd4282CE94BA99fe3c844bc <br>

**3.6.3. General Meeting of Members Approved Payment**

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH/CBP** | **USD** | **ETH/CBP** | **USD** |
| GMM Approved Payment | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GMM Approved Payment - ETH | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GMM Approved Payment - CBP | 0 | 0 | 0 | 0 |
| **Sub Total of GMM Approved Payment** | **0** | **0** | **0** | **0** |

---

A GMM-approved payment is recorded by the 'TransferFund' event in the smart contract of 'GMMKeeper.' If the payment is made in ETH, the 'isCBP' argument will be recorded as 'false'; otherwise, it will be recorded as 'true' for payments made in CBP.

---

| |
|:---|
| F-24 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> GMMKeeper: 0x7256b47ff39997355ecEC2deFB7C7B332FcFDd42 <br> event TransferFund (address indexed to , bool indexed isCBP , uint indexed amt , uint seqOfMotion , uint caller); <br>

**3.7. Equity accounts and ownership structure**

The Company was established on November 8, 2023 and the period from November 8, 2023, to December 31, 2023, represents a short reporting period.

The Company commenced operational activities on May 18, 2024. In exchange for the IPR of ComBoox contributed by the Founding Member, the Company issued to him the Initial Capital with a par value amounting to $300,000.00, which consists of $250,000.00 in Class A Shares and $50,000.00 in Class B Shares. Class A shares have 40 times the voting weight compared to Class B shares.

Subject to successful registration with the SEC and other governing authorities, the Company may publicly issue new equity shares to investors for subscription by ETH, with or without a premium. These transactions will be recorded in the "ETH" account on the debit side and in the "Paid-In Capital" account (for the par value) and "Additional Paid-In Capital" account (for the premium amount) on the credit side. During the Report Period, no new shares were issued.

---

| | | |
|:---|:---|:---|
|  | **As of 23:59:59 December 31** | **As of 23:59:59 December 31** |
| | **2024** | **2023** |
|  | **USD** | **USD** |
| Subscribed Capital | 300,000.00 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Less: Unpaid Subscription of Capital | (300,000.00) | 0 |
| Paid In Capital | 0 | 0 |
| Additional Paid In Capital | 0 | 0 |

---

The amount of Subscribed Capital and Paid-In Capital can be retrieved by calling the "capAtDate" function of the smart contract of the Register of Members, with a filter condition based on the timestamp of the Report Time.

---

| |
|:---|
| F-25 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> Register of Members: 0x9dc52b48454b0ab4bf493343eb1d20a2002e3c6a <br> function capAtDate (uint date) external view returns (Checkpoints.Checkpoint memory); <br> date: 290687173n <br>

The ETH consideration paid for subscribing to the issued shares will be recorded by four specific events for different scenarios.

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Paid-In Capital:** Indicates that a member has paid a certain amount of ETH to fulfill the obligation of previously acquired shares, which is recorded by the "PayInCapital" event in the smart contract of ROMKeeper.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROMKeeper: 0xEC20588b8d51C66c2BFaD4FB9A79673d92F6A5b0 <br> event PayInCapital (unit indexed seqOfShare, unit indexed amt, unit indexed valueOfDeal); <br>

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Pay Off Capital Increase Deal:** indicates that an Investor has paid the Company a certain amount of ETH to close a capital increase deal as per an investment agreement, which is recorded by the "PayOffCIDeal" event in the smart contract of "ROAKeeper".

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROAKeeper: 0x22914D23fA2cdBB78FBDBbaA46cc991873bD4A80 <br>event PayOffCIDeal(uint indexed caller event uint indexed valueOfDeal) <br>

&nbsp;&nbsp;&nbsp;&nbsp; (3)**Close Bid Against Initial Offer:** indicates that an Investor has paid the Company a certain amount of ETH to close a listed initial offer for issuing new equity shares, which is recorded by the "CloseBidAgainstInitOffer" event in the smart contract of "LOOKeeper".

---

| |
|:---|
| F-26 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> LOOKeeper 0xCAa4bda0fb0b2c6E50Cbf5F3C89c1C56C1820921 <br> event CloseBidAgainstInitOffer (unit indexed buyer, unit indexed amt) <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Close Initial Offer Against Bid:**indicates that a listed buy order has been closed by matching it with a newly placed initial offer for issuing new equity shares, resulting in the corresponding amount of ETH being released from the custody account to the Company.This transaction is recorded by the "ReleaseCustody" event in the General Keeper, with the specific reason "CloseInitOfferAgainstBid" codified in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event ReleaseCustody (unit indexed from, unit indexed to, unit indexed amt, bytes32 reason); <br> reason: //bytes32 format for string "CloseInitOfferAgainstBid" 0x436c6f7365496e69744f66666572416761696e73744269640000000000000000 <br>

**3.8. Distribution**

Subject to the resolution of the General Meeting of members, the Company may distribute ETH to members.Such transactions will be recorded with "ETH" on the credit side and "Distribution" on the debit side. During the reporting period, the Company made no distributions. <br>

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| Distribution | 0 | 0 | 0 | 0 |

---

---

| |
|:---|
| F-27 |
| *[**Table of Contents**](#Toc)* |

---

Distributions are recorded by the "SaveToCoffer" event in the General Keeper, with the filter condition that the reason is "DistributeProfits" (in Bytes32 format).

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event SaveToCoffer (unit indexed acct, unit indexed value, bytes32 indexed reason); <br> reason: ethers. encodeBytes32String ("DistributeProfits") <br>

**3.9.Deposits and Custody**

&nbsp;&nbsp;&nbsp;&nbsp; To facilitate equity trading and profit distribution, the Company has set up special deposit accounts in the General Keeper. These accounts are exclusively controlled by their respective holders. No other entities, including the Company, may transfer, withdraw, or freeze ETH stored in these accounts. Therefore, these deposits are not recognized as assets of the Company.

When a limit buy order is listed on the smart contract of "List of Orders", the corresponding ETH paid by the buyer will also be stored in deposit accounts as "custody". As long as the limit buy order remains listed, the ETH in custody will be frozen as a special guarantee for transfer to the seller as consideration. It can only be released from custody if the buy order is withdrawn or expires.

During the reporting period, no deposit inflows or outflows occurred.

**3.9.1 Deposits Inflow**

The seller's consideration, the buyer's refunded over payments, and distributions to members will all be paid into deposit accounts.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| **Deposits Inflow** | **0** | **0** | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Consideration | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Refund Over Payment | 0 | 0 | 0 | 0 |
| **Sub Total of Deposits Inflow** | **0** | **0** | **0** | **0** |

---

---

| |
|:---|
| F-28 |
| *[**Table of Contents**](#Toc)* |

---

Deposit inflows are recorded by the "SaveToCoffer" event in the General Keeper, with their respective reasons.

&nbsp;&nbsp;&nbsp;&nbsp; (1) **Distribution:** the reason for which is recorded as "DistributeProfits" in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GeneralKeeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event SaveToCoffer (unit indexed acct, unit indexed value bytes32 indexed reason); <br> reason: ethers. encodeBytes32String ("DistributeProfits") <br>

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Consideration:** the reasons for which are recorded as "DepositConsiderationOfSTDeal", "CloseBidAgainstOffer", "DepositConsiderationOfSwap", "DepositConsiderationOfRejectedDeal", or "CloseOfferAgainstBid" in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GeneralKeeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event SaveToCoffer (unit indexed acct, unit indexed value bytes32 indexed reason); <br> reason:<br> [ ethers. encodeBytes32String ("DepositConsiderationOfSTDeal") <br> ethers. encodeBytes32String ("CloseBidAgainstOffer") <br> ethers. encodeBytes32String ("DepositConsiderationOfSwap") <br> ethers. encodeBytes32String ("DepositConsiderOfRejectedDeal") <br> ethers. encodeBytes32String ("CloseOfferAgainstBid") ] <br>

---

| |
|:---|
| F-29 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)**Refund Over Payment:**reasons of which are recorded as "DepositBalanceOfOTCDeal", "DepositBalanceOfPayInCap", "DepositBalanceOfSwap", "DepositBalanceOfBidOrder", "DepositBalanceOfRejectedDeal", or "RefundValueOfBidOrder" in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GeneralKeeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event SaveToCoffer (unit indexed acct, unit indexed value bytes32 indexed reason); <br> reason:<br> [ ethers. encodeBytes32String ("DepositBalanceOfOTCDeal"), <br> ethers. encodeBytes32String ("DepositBalanceOfPayInCap"), <br> ethers. encodeBytes32String ("DepositConsiderationOfSwap"), <br> ethers. encodeBytes32String ("DepositBalanceOfBidOrder"), <br> ethers. encodeBytes32String ("DepositBalanceOfRejectedDea"), <br> ethers. encodeBytes32String ("RefundValueOfBidOrde") ] <br>

**3.9.2. Deposits Outflow**

Deposits can be withdrawn by the relevant account holder, constituting an outflow of deposits.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| Deposits Outflow | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pickup Deposits | 0 | 0 | 0 | 0 |
| **Sub Total of Deposits Outflow** | **0** | **0** | **0** | **0** |

---

Deposit outflows are recorded by the "PickupDeposit" event in the General Keeper.

---

| |
|:---|
| F-30 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event PickupDeposit (address indexed to, unit indexed caller, unit indexed amt); <br>

**3.9.3. Custody Inflow**

The Custody Value of a Bid Order is the only inflow of custody. When a limit buy order is placed on the "List of Orders" smart contract, an equivalent amount of ETH must be paid along with the call command. The ETH will be stored in the deposit account as custody. <br>

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| Custody Inflow | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Custody Value of Bid Order | 0 | 0 | 0 | 0 |
| **Sub Total of Custody Inflow** | **0** | **0** | **0** | **0** |

---

The Custody Value of a Bid Order is recorded by the "SaveToCoffer" event in the General Keeper, with the reason specified as "CustodyValueOfBidOrder" in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event SaveToCoffer (unit indexed acct, unit indexed value, bytes32 reason); <br> reason: ethers. encodeBytes32String ("CustodyValueOfBidOrder") <br>

---

| |
|:---|
| F-31 |
| *[**Table of Contents**](#Toc)* |

---

**3.9.4. Custody Outflow**

There are three scenarios that may cause an outflow of custody: (a) Released to the seller as consideration; (b) Refunded to the buyer as an overpaid balance; or (c) Released to the Company as capital contribution.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| Custody Outflow | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pay Consideration | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Refund Balance | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Close Initial Offer | 0 | 0 | 0 | 0 |
| **Sub Total of Custody Outflow** | **0** | **0** | **0** | **0** |

---

These three scenarios of custody outflow are recorded by the "ReleaseCustody" event in the General Keeper smart contract, with different reasons in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; (1)**Pay Consideration:** the reason for which is recorded as "CloseOfferAgainstBid" in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event ReleaseCustody (unit indexed from, unit indexed to, bytes32 reason); <br> reason: ethers. encodeBytes32String ("CloseOfferAgainstBid") <br>

&nbsp;&nbsp;&nbsp;&nbsp; (2) **Refund Balance:** the reason for which is recorded as "RefundValueOfBidOrder" in Bytes32 format.

---

| |
|:---|
| F-32 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event ReleaseCustody (unit indexed from, unit indexed to, bytes32 reason); <br> reason: ethers. encodeBytes32String ("RefundValueOfBidOrder") <br>

&nbsp;&nbsp;&nbsp;&nbsp; (3) **Close Initial Offer:** the reason for which is recorded as "CloseInitOfferAgainstBid" in Bytes32 format.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> event ReleaseCustody (unit indexed from, unit indexed to, bytes32 reason); <br> reason: ethers. encodeBytes32String ("CloseInitOfferAgainstBid") <br>

 **4. Income Taxes**

As a pass-through entity, The Company has evaluated its tax positions in accordance with ASC 740-10 (Accounting for Uncertainty in Income Taxes) and has determined that it has no uncertain tax positions requiring disclosure. The Company's tax returns remain subject to examination by the Internal Revenue Service (IRS) and other tax authorities for the statutory period of limitations applicable to each jurisdiction.

No provision for income taxes is reflected in the accompanying financial statements, and the Statement of Income does not include income tax expense or benefit.

 **5. Digital Assets**

**5.1. CBP and ETH** <br>

---

| |
|:---|
| F-33 |
| *[**Table of Contents**](#Toc)* |

---

The Company uses CBP to measure and collect royalties and receives ETH as consideration for selling CBP. For Sales, General, and Administrative ("SG&A") expenses or template purchase consideration, the Company may pay either CBP or ETH as consideration to the counterparty. Moreover, the Company also accepts ETH as capital contributions from members or as transfer consideration to be settled against listing offers or contractual share transfer deals.

Chainlink Data Feeds were introduced in ComBoox so that the exchange rate of ETH/USD can be retrieved in real-time. As for the exchange rate between CBP and ETH, the Company uses the refuel rate in Fuel Tank (i.e. the ExRate), as this rate serves as the anchor price for supplying CBP to the market.

The Company supplies CBP through the Fuel Tank. Therefore, the Fuel Tank regularly holds an inventory of CBP and ETH. These inventories are recorded as the Company's assets.

**5.1.1. CBP Flow of Fuel Tank**

CBP can be added to or withdrawn from the Fuel Tank. Together with refuel transactions, these activities form the CBP flows of Fuel Tank.

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **CBP** | **USD** | **CBP** | **USD** |
| **CBP Flow of Fuel Tank** | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Add CBP | 176 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Withdraw CBP | 88 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Refuel CBP | 0 | 0 | 0 | 0 |
| **Sub Total of Custody Outflow** | **88** | **0** | **0** | **0** |

---

&nbsp;&nbsp;&nbsp;&nbsp; Adding CBP is recorded by the "Transfer" event in the Registration Center, with the following conditions: (a) The sender is the General Keeper; and (b) The recipient is the Fuel Tank.

---

| |
|:---|
| F-34 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Registration Center: 0x18F7AE56d1e04B95A2C50AFd528aC3FCb6F23f91 <br> event Transfer (address indexed from, address indexed to, uint256 indexed value); <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; General Keeper: 0x68233e877575e8c7e057e83ef0d16ffa7f98984d <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 <br>

Withdrawing CBP is recorded by the "WithdrawFuel" event in the Fuel Tank.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 <br> event WithdrawFuel (address indexed owner, unit indexed amt); <br>

Refueling CBP is recorded by the "Refuel" event in the Fuel Tank.

&nbsp;&nbsp;&nbsp;&nbsp; <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 <br> event Refuel (address indexed buyer, unit indexed amtOfEth unit indexed amtOfCbp); <br>

**5.1.2. ETH Flow of Fuel Tank**

The ETH flows of the Fuel Tank include: (a) Collecting ETH as consideration for CBP sales; and (b) Withdrawing ETH from Fuel Tank to General Keeper.

During the Reporting Period, no ETH inflows or outflows occurred.

---

| |
|:---|
| F-35 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | | | |
|:---|:---|:---|:---|:---|
|  | **For the year ended 23:59:59** | **For the year ended 23:59:59** | **For the year ended 23:59:59** | **For the year ended 23:59:59** |
| | **2024** | **2024** | **2023** | **2023** |
|  | **ETH** | **USD** | **ETH** | **USD** |
| **ETH Flow of Fuel Tank** | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Refuel ETH | 0 | 0 | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Withdraw ETH | 0 | 0 | 0 | 0 |
| **Sub Total of ETH Flow of Fuel Tank** | **0** | **0** | **0** | **0** |

---

Refueling ETH is recorded by the "Refuel" event in the Fuel Tank smart contract.

&nbsp;&nbsp;&nbsp;&nbsp; <br> Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 <br> event Refuel (address indexed buyer , uint indexed amtOfEth , uint indexed amtOfCbp); <br>

Withdrawing ETH back to the General Keeper is recorded by the "WithdrawIncome" event in the Fuel Tank.

&nbsp;&nbsp;&nbsp;&nbsp; <br> Fuel Tank: 0x1ACCB0C9A87714c99Bed5Ed93e96Dc0E67cC92c0 <br> event WithdrawIncome (address indexed owner , uint indexed amt); <br>

**5.2. Gain and Loss on Digital Assets**

The Company records the USD value of ETH/CBP transactions based on the ETH price at the earliest and latest timestamps of the transactions. The Gain or Loss of Digital Assets is calculated using the ETH price at the Report Time. However, any Gain or Loss of Digital Assets resulting from Paid-In Capital transactions will not be included in operational costs or expenses; instead, they will be recognized solely in Owners' Equity.

---

| |
|:---|
| F-36 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
|  | **For the year ended 23:59:59 December 31** | **For the year ended 23:59:59 December 31** |
| | **2024** | **2023** |
|  | **USD** | **USD** |
| Gain (Loss) on Digital Assets | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ETH Other Income - G/L | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - ETH GMM Payment - G/L | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CBP Royalty Revenue - G/L | 27.51 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- CBP New User Awards - G/L | (89.50) | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - CBP Startup Cost - G/L | (15910.34) | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - CBP GMM Payment - G/L | 0 | 0 |
| **Total Gain (Loss) on Digital Assets** | **(5972.33)** | **0** |

---

&nbsp;&nbsp;&nbsp;&nbsp; **6. Related Party Transactions**

&nbsp;&nbsp;&nbsp;&nbsp; The Company has engaged in the following related party transactions with the Founding Member, in accordance with ASC 850 - Related Party Disclosures:

**6.1. IPR Contribution by the Founding Member**

As part of the initial capital contribution, the Founding Member transferred certain Intellectual Property Rights (IPR) to the Company and the Company has deferred recognition and amortization of the IPR. For further details, refer to Section 3.5.1.

 **6.2. Issuance of CBP Tokens to the Founding Member**

To facilitate the configuration and setup of the Platform, the Company minted CBP tokens to the Founding Member. For further details, refer to Section 3.6.2 and 5.1.1.

**6.3. Marketing Promotions and New User Awards**

As part of a marketing strategy, the Company automatically mints CBP tokens for new users of the ComBoox platform as a "New User Award". Upon signing up with the Registration Center, users receive a predefined amount of CBP. For further details, refer to Section 3.6.1.

---

| |
|:---|
| F-37 |
| *[**Table of Contents**](#Toc)* |

---

**7. Commitments and Contingencies**

In accordance with ASC 450-20 - Loss Contingencies, the Company has evaluated its legal, contractual, and regulatory obligations and determined that:

&nbsp;&nbsp;&nbsp;&nbsp; (1) As of the reporting time, the Company has no known commitments requiring future financial obligations;

&nbsp;&nbsp;&nbsp;&nbsp; (2) There are no pending or threatened legal proceedings, regulatory investigations, or other contingencies that would require disclosure or accrual under ASC 450-20; and

&nbsp;&nbsp;&nbsp;&nbsp; (3) The Company has not entered into any contractual agreements that create material contingent liabilities.

The Company will continue to monitor and assess any potential commitments or contingencies and will disclose any material changes in subsequent reporting periods as required by US GAAP and PCAOB standards.

**8. Management's Discussion and Analysis (MD&A)**

**8.1. Business Overview**

&nbsp;&nbsp;&nbsp;&nbsp; The Company operates within the emerging Web3 and blockchain industry, leveraging smart contracts and decentralized finance (DeFi) models to facilitate legal rights execution, governance, and value transfer. The core business model is built on ComBoox, a system integrating smart contract Templates, an automated Registration Center, and a digital accounting framework. The Company's main revenue source is royalty payments in CBP, an on-chain utility token, which is recognized when recorded in the Company's Registration Center and offset against deferred revenue.

**8.2. Industry Trends and Business Outlook**

&nbsp;&nbsp;&nbsp;&nbsp; The Web3 ecosystem continues to expand into traditional industries, creating new business models for corporate governance, financial record-keeping, and decentralized organization structures. The Company is strategically positioned in this space through its decentralized legal execution framework, which may gain widespread adoption due to:

&nbsp;&nbsp;&nbsp;&nbsp; (1) Unstoppable Web3 Growth: The increasing adoption of blockchain by enterprises will drive demand for decentralized governance and automated compliance tools, aligning with the Company's core products, which address critical needs for transparency and security in corporate governance.

---

| |
|:---|
| F-38 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; (2) Recognition of the ComBoox Model: The Turing Machine-inspired design of ComBoox leveraging Registers for state recording, Shareholder Agreements (or Code of Conduct) for state transitions, and Book Keepers for legal automation has the potential to be recognized by enterprises and regulatory bodies as an innovative compliance and governance solution.

&nbsp;&nbsp;&nbsp;&nbsp; (3) DAO and Digital Corporate Governance: The automation of corporate structures and digital securities represents a critical Web3 breakthrough. The Company's framework for handling equity registration, governance acts, and corporate transactions via smart contracts is likely to gain traction.

**8.3. Risks and Uncertainties**

**8.3.1. Liquidity Risks**

&nbsp;&nbsp;&nbsp;&nbsp; The Company operates entirely on-chain, eliminating the need for traditional bank accounts or cash reserves. Current version of the Template Smart Contracts fully supports the anticipated functions required for companies to manage equity shares and corporate governance records, which ensures that the Company can continue to operate and develop its business independently.

**8.3.2. Legal and Regulatory Uncertainty**

&nbsp;&nbsp;&nbsp;&nbsp; Regulatory clarity on blockchain-based corporate governance is evolving. The Company must continuously adapt to jurisdictional differences and update its smart contract architecture accordingly. The Wyoming DAO LLC framework provides an initial regulatory foundation, but further legal challenges and adjustments may arise as Web3 laws mature.

**8.3.3. Accounting, Tax, and Compliance Risks**

&nbsp;&nbsp;&nbsp;&nbsp; The pass-through entity structure (per ASC 740) shifts tax obligations to individual members, which requires clear disclosure and tracking of distributable earnings. The valuation of contributed IPR (per ASC 850) is deferred due to the lack of comparable market data. This presents a unique challenge for financial reporting and potential investor scrutiny. The fair value measurement of ETH and CBP (per ASC 820) introduces complexity, particularly in determining unrealized gains and losses due to digital market volatility.

---

| |
|:---|
| F-39 |
| *[**Table of Contents**](#Toc)* |

---

**8.3.4. Intellectual Property Risks**

&nbsp;&nbsp;&nbsp;&nbsp; Open-source smart contract development enables transparency but also exposes the Company's IP to unauthorized use and imitation. Although ComBoox's legal compliance focus provides a deterrent against pirated versions, the Company will need to continuously innovate to maintain its competitive edge.

**8.3.5. Operational and Market Risks**

&nbsp;&nbsp;&nbsp;&nbsp; Token price volatility affects financial performance, requiring robust risk management to stabilize revenue and expense recognition. The adoption curve for blockchain-based legal solutions is uncertain, requiring strategic partnerships and continuous market education efforts.

**8.3.6. Dependence on Future CBP Sales**

&nbsp;&nbsp;&nbsp;&nbsp; The Company's business strategy is heavily reliant on the adoption of its CBP platform to generate revenue. Key drivers for revenue growth include:

&nbsp;&nbsp;&nbsp;&nbsp; (1) SEC Recognition and Offering Proceeds: The Company expects that, following recognition by the SEC, the net proceeds from the offering will be sufficient to cover operating expenses, including compliance and administrative functions.

&nbsp;&nbsp;&nbsp;&nbsp; (2) Platform Adoption and Clients Expansion: Revenue growth is contingent on increased adoption of the CBP platform and the expansion of the Company's client base, particularly among corporations seeking to automate share transactions and governance activities.

**8.3.7. Management's Plans**

&nbsp;&nbsp;&nbsp;&nbsp; Given the current market landscape and risk considerations, the Company is committed to:

&nbsp;&nbsp;&nbsp;&nbsp; (1) Enhancing ComBoox's Regulatory Compliance: Adapting the smart contract framework to meet evolving legal requirements across jurisdictions.

&nbsp;&nbsp;&nbsp;&nbsp; (2) Strengthening Financial Reporting Mechanisms: Ensuring GAAP and PCAOB compliance, refining fair value accounting, and maintaining transparent disclosures.

&nbsp;&nbsp;&nbsp;&nbsp; (3) Securing Intellectual Property: Implementing IP protection strategies, such as license-based monetization and proprietary extensions to open-source elements.

&nbsp;&nbsp;&nbsp;&nbsp; (4) Driving Market Adoption: Expanding the user base through DAO partnerships, legal tech collaborations, and blockchain enterprise solutions.

---

| |
|:---|
| F-40 |
| *[**Table of Contents**](#Toc)* |

---

**9. Going Concern**

&nbsp;&nbsp;&nbsp;&nbsp; The management has evaluated the Company's ability to continue in the foreseeable future, including the company's business model and future plans, with the following key points:

&nbsp;&nbsp;&nbsp;&nbsp; (1) As a passive interest-holding vehicle, the Company automatically collects royalty revenues from template contracts and does not engage in any other development activities.

&nbsp;&nbsp;&nbsp;&nbsp; (2) Templates are provided to users on an "As Is" basis. The Company is not responsible for upgrades, iterations, or post-sale development. If necessary, the Company may procure templates from third-party authors, subject to approval by the members' meeting.

&nbsp;&nbsp;&nbsp;&nbsp; (3) Pursuant to the Operating Agreement, the Company will use its best efforts to avoid incurring any liabilities. No members or managers will be paid any remuneration, and the Company has no employees and has no plans to hire any employees.

&nbsp;&nbsp;&nbsp;&nbsp; (4) In the event of a successful IPO, members may decide to expand operations through the procurement of specialized services (e.g., marketing, blockchain integration). Absent an IPO, the Company's existing business model is able to support normal operations.

&nbsp;&nbsp;&nbsp;&nbsp; Therefore, management concluded that there was no substantial doubt about the entity's ability to continue as a going concern that required disclosure in such financial statements.

**10. Subsequent Event**

&nbsp;&nbsp;&nbsp;&nbsp; Additionally, subsequent to the reporting period, the Company's management has continued its efforts to file supplemental materials related to its registration statement on Form S-1 with the U.S. Securities and Exchange Commission (SEC).

&nbsp;&nbsp;&nbsp;&nbsp; The Company evaluated subsequent events through the date of this audit report. The Company did not have any subsequent events affecting the amounts reported in the financial statements for the year ended December 31, 2024.

---

| |
|:---|
| F-41 |
| *[**Table of Contents**](#Toc)* |

---

## **Unaudited Financial Statements for the year ended December 31, 2025** 
**Balance Sheets<br> (Unaudited)**

---

| | | |
|:---|:---|:---|
| | **As of 23:59:59** | **As of 23:59:59** |
| | **December 31, 2025** | **December 31, 2024** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Intangible Assets - IPR  | $0.00 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Intangible Assets - ETH | 27.59 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Intangible Assets - USDC | 2.5 | 0.00 |
| **Total Assets** | **30.09** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Deferred Revenue  | 44867.66 | 53420.55 |
| **Total Liabilities** | **44867.66** | **53420.55** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subscribed Capital  | 300000.00 | 300000.00 |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Less: Unpaid Subscription  | (292435.00) | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Paid In Capital  | 7500.00 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ETH Gain/Loss In Equity  | 1362.54 | 0.00 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Retained Earnings  | (53765.11) | (53420.55) |
| **Total Equity** | **(44837.57)** | **(53420.55)** |
| **Total Liabilities and Equity** | $**30.09** | **0.00** |

---

---

| |
|:---|
| F-42 |
| *[**Table of Contents**](#Toc)* |

---

 **Statements of Operations <br> (Unaudited)**

---

| | | |
|:---|:---|:---|
| | **For the Year ended 23:59:59** | **For the Year ended 23:59:59** |
| | **December 31, 2025** | **December 31, 2024** |
| Royalty Income | $275.16 | 112.90 |
| **Gross profit** | **275.16** | **112.90** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Selling, General, and Administrative  | (7651.83) | (37561.12) |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Gain and Loss on Digital Assets  | (1195.37) | (15972.33) |
| **Total Operating Expenses** | **(8847.20)** | **(53533.45)** |
| **Income Before Taxes** | **(8572.04)** | **(53420.55)** |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Income Tax Expense  | 0.00 | 0.00 |
| **Net Income(Loss)** | $**(8572.04)** | **(53420.55)** |

---

---

| |
|:---|
| F-43 |
| *[**Table of Contents**](#Toc)* |

---

 **Statements of Changes in Members' Equity <br>(Unaudited)**

---

| | | | | | | |
|:---|:---|:---|:---|:---|:---|:---|
| | **Class A <br> Paid-In Capital** | **Class B <br> Paid-In Capital** | **Additional <br> Paid-In Capital** | **ETH Gain/Loss <br> In Equity** | **Retained Earnings** | **Total Equity** |
| **Balance at July 1, 2024** | **$0** | **$0** | **$0** | **$0** | **$0** | **$0** |
| Net Income |  |  |  |  | (53420.55) | (53420.55) |
| **Balance at December 31, 2024** | **0** | **0** | **0** | **0** | **(53420.55)** | **(53420.55)** |
| Net Income |  |  |  |  | (8572.04) | (8572.04) |
| ETH Gain/Loss Adjustment |  |  |  |  | 8227.48 | 8227.48 |
| Paid In Capital Contribution | 0 | 7565 | 0 | 1362.54 |  | 8927.54 |
| **Balance at December 31, 2025** | **$0** | **$7565** | **$0** | **$1362.54** | **$(53765.11)** | **$(44837.57)** |

---

---

| |
|:---|
| F-44 |
| *[**Table of Contents**](#Toc)* |

---

 **Statements of Cash Flows <br>(Unaudited)** 

---

| | | |
|:---|:---|:---|
| | **For the Year ended 23:59:59** | **For the Year ended 23:59:59** |
| | **December 31, 2025** | **December 31, 2024** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Deferred Revenue From CBP Sales  | $0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Other Income  | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sales, General & Administrative  | 0 | 0 |
| **Net Inflow from Operating Activities** | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Purchase of IPR  | 0 | 0 |
| **Net Outflow for Investing Activities** | **0** | **0** |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Proceeds From Share Issuance  | 0 | 0 |
| &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution  | 0 | **0** |
| **Net Inflow from Financing Activities** | **0** | **0** |
| **Net Inflow** | $**0** | **0** |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *The Company operates exclusively with digital assets and does not maintain traditional cash or bank accounts. All transactions, including those related to the minting, exchange, and transfer of assets, are conducted using on-chain digital assets. As a result, the Statement of Cash Flows reflects a zero balance, as there are no cash inflows or outflows in the conventional sense.* 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *The accompanying notes are an integral part of these audited financial statements.* 

---

| |
|:---|
| F-45 |
| *[**Table of Contents**](#Toc)* |

---

 **Condensed Notes to the Unaudited Financial Statements<br> For the Year ended December 31, 2025**

**Basis of presentation and disclaimer**

The accompanying condensed notes are unaudited and have been prepared by management of ComBoox DAO LLC (the "**Company**") in accordance with U.S. generally accepted accounting principles for interim financial information and pursuant to the requirements applicable to interim disclosures in registration statements filed with the U.S. Securities and Exchange Commission. They are condensed and do not include all of the information and footnote disclosures required by U.S. GAAP for complete financial statements. These condensed notes should be read in conjunction with the audited financial statements and notes included in the Company's audited financial statements as of and for the year ended December 31, 2025.

**1. Description of business (condensed)**

The Company is a Wyoming limited liability company that operates the ComBoox platform, a blockchain-based corporate book-entry system deployed on Arbitrum One. The Company issues and uses a utility token called ComBoox Points ("**CBP**") to measure and collect royalties and may sell CBP to users through a smart contract referred to as the "Fuel Tank." The Company historically accepted ETH as consideration for CBP sales and used ETH as a principal payment instrument.

**2. Summary of significant accounting policies (condensed)**

The accounting policies summarized below are condensed from those disclosed in the Company's audited financial statement notes as of December 31, 2025 and are applied consistently in preparing these condensed interim financial statements, except for the change in accounting policy described in Note 2.1 below.

**2.1 Change in accounting policy - CBP pricing and Fuel Tank update (highlight)**

On June 19, 2025, pursuant to a resolution adopted by the Company's members, the Company deployed an updated Fuel Tank smart contract that sells **CBP** for **USDC** rather than ETH. Concurrently, the members approved a fixed USD price of **USD 2,816.15 per CBP** (the "**CBP Fixed Price**"), determined by reference to the 20-calendar-day highest ETH-based equivalent price around the adoption date. The CBP Fixed Price became effective for accounting purposes on June 19, 2025.

The accounting consequences of this policy change are summarized below and have been applied prospectively from the effective date (June 19, 2025).

---

| |
|:---|
| F-46 |
| *[**Table of Contents**](#Toc)* |

---

**2.2 Recognition of CBP and deferred revenue (specific guidance)**

* **CBP held by the Company** is not recognized as an asset on the Company's balance sheet. The Company views CBP retained in on-chain contract addresses that are under the Company's control as a protocol token and not a separate recognized asset for purposes of the Company's financial statements.

* **Deferred revenue** is recognized only in respect of CBP that are held by entities other than the Company (for example, CBP that have been sold to customers). In such cases, deferred revenue is measured in USD using the CBP Fixed Price of USD 2,816.15 per CBP for reporting periods on or after June 19, 2025.

**2.3 Measurement of CBP-denominated expenses and exchange gain/loss mechanics**

Certain operating costs and awards to users are paid or denominated in CBP ("CBP-denominated expenses"), including new user awards and startup costs issued to founding members. The accounting treatment for such items is as follows:

* **Measurement at occurrence date:** At the date the CBP-denominated expense is incurred, the expense is measured in USD by reference to the CBP-to-ETH exchange rate (ExRate) and the observable ETH/USD price at that occurrence date.

* **Re-measurement at reporting date:** For reporting and presentation purposes, the Company re-measures the USD equivalent of the CBP-denominated items at the reporting date using the CBP Fixed Price of USD 2,816.15 per CBP.

* **Exchange gain or loss recognition:** The difference between (a) the USD amount initially recorded at the occurrence date (as measured using ExRate and ETH/USD price) and (b) the USD amount determined at the reporting date using the CBP Fixed Price is recognized as an **exchange gain or loss** in retained earnings.This gain or loss represents the remeasurement effect arising from fixing the reporting price at the CBP Fixed Price while the underlying expense was measured using market-based ETH exchange rates.

**2.4 Interaction between deferred revenue, royalty income and retained earnings (impact analysis)**

Because the CBP Fixed Price is used to measure deferred revenue and retained earnings is adjusted for the exchange gain or loss described above, the same CBP valuation movement will be reflected concurrently in both deferred revenue and retained earnings. In addition, **royalty income** recognized before June 19, 2025, which was previously measured based on ETH-denominated CBP pricing, will also be remeasured in retained earnings for the reporting date. Any price differences arising from the transition from ETH-based pricing to the CBP Fixed Price will therefore also be included in retained earnings.

Taken together - including new user awards, startup costs, deferred revenue, and the remeasurement of pre-June 19, 2025 royalty income - these concurrent adjustments offset within equity, and management has concluded that there will be **no material effect on the Company's balance sheet** as a result of the CBP pricing policy change from ETH-based pricing to a fixed USD price.

---

| |
|:---|
| F-47 |
| *[**Table of Contents**](#Toc)* |

---

**2.5 Other measurement matters**

ETH that are held by the Company and not characterized as CBP are measured in USD in accordance with the Company's existing fair-value policy, which uses observable market rates (for example, Chainlink or other market price feeds) under ASC 820. Any unrealized gains or losses arising from those balances continue to be recognized in accordance with the Company's policies described in the audited financial statements.

**3. Prospective application and comparative periods**

The change described in Note 2.1 is applied prospectively from June 19, 2025. The amounts presented for the year ended December 31, 2025 reflect the policy change only for transactions and balances effective on or after June 19, 2025. Historical amounts prior to the effective date have not been retrospectively restated.

**4. Estimated quantitative impact**

As of the issuance date of these condensed notes, management has not identified any material quantitative impact that would require separate pro forma disclosure. The Company will continue to evaluate and, if material, disclose the quantitative effect of the change in subsequent filings.

**5. Other condensed disclosures (condensed)**

Except as described above, there have been no material changes to the Company's significant accounting policies or other matters that would require disclosure in these unaudited condensed interim notes compared with the audited notes as of December 31, 2025.

Management has evaluated subsequent events through the date these condensed notes were issued and determined that no further disclosure is required beyond the matters described herein.

---

| |
|:---|
| F-48 |
| *[**Table of Contents**](#Toc)* |

---

# COMBOOX DAO LLC

## PROSPECTUS
&nbsp;&nbsp;&nbsp;&nbsp; **________, 2026** 

 **Until _______, 2026 (90 calendar days after the date of this Prospectus) all dealers that effect transactions in these securities, whether or not participating in this offering, may be required to deliver a prospectus. This is in addition to the dealers' obligation to deliver a prospectus when acting as underwriters and with respect to their unsold allotments or subscriptions.** 

---

| |
|:---|
| vii |
| *[**Table of Contents**](#Toc)* |

---

#### Part II INFORMATION NOT REQUIRED IN PROSPECTUS

#### Item 13. Other Expenses of Issuance and Distribution
The following table sets forth all costs and expenses, payable by us in connection with the sale of the shares being registered. All amounts shown are estimates except for the SEC registration fee:

---

| | |
|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expenses**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expenses**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Legal Fees**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $________.00**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Blue Sky Qualifications**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $________.00**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Accounting Fees**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $________.00**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total\*:**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $________.00**  |

---

\*All amounts are estimates. For the interests of and on behalf of the Company, the Founding Member has already paid approximately $[•] of expenses and will pay the remaining expenses from his cash on hand. The Company may reimburse these expenses actually incurred and paid in form of USDC, provided that such costs and expenses are approved by Ordinary Resolution. If the motion is rejected by the General Meeting, all the costs and expenses will be assumed by the Founding Member.

#### Item 14. Indemnification of Directors and Officers.
The Operating Agreement provides for the indemnification of a present or former member, manager or agent who is or was serving the Company upon request and approval. Such indemnification shall include, but not necessarily be limited to, expenses, including attorney's fees actually or reasonably incurred by him or her. We may indemnify such individual against all costs, expenses, and liabilities incurred in a threatened, pending or completed action, suit, or proceeding brought because such individual is served for the Company. Such individual must have conducted himself/herself in good faith and reasonably believed that his/her conduct was in, or not opposed to, our best interests. In a criminal action, he/he must not have had a reasonable cause to believe his/her conduct was unlawful.

---

| |
|:---|
| II-1 |
| *[**Table of Contents**](#Toc)* |

---

At present, there is no litigation or proceeding involving a member or manager of ours as to which indemnification is being sought, nor are we aware of any threatened litigation that may result in claims for indemnification by any manager or member.

#### &nbsp;&nbsp;&nbsp;&nbsp; Item 15. Recent Sales of Unregistered Securities.
&nbsp;&nbsp;&nbsp;&nbsp; In exchange of Royalty Interests and CBP's Minting Right on Arbitrum One, the Company has issued 2,500,000,000 Class A Shares and 500,000,000 Class B Shares to Founding Member.

&nbsp;&nbsp;&nbsp;&nbsp; Other than the securities mentioned above, the Company has not issued or sold any securities.

#### &nbsp;&nbsp;&nbsp;&nbsp; Item 16. Exhibits Index.

---

| | |
|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Index to Exhibits <br> Exhibit No.**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br> Exhibit Description**  |
| [3.1](comboox_ex31.htm)  | [Certificate of Organization](comboox_ex31.htm)  |
| [3.2](comboox_ex32.htm)  | [Articles of Organization](comboox_ex32.htm)  |
| [3.3](comboox_ex33.htm)  | [Amendment to The Articles of Organization](comboox_ex33.htm)  |
| [3.4](comboox_ex34.htm)  | [Amended and Restated Operating Agreement](comboox_ex34.htm)  |
| [10.1](comboox_ex101.htm)  | [Amended and Restated Capital Contribution Agreement by and between the Founding Member and the Company](comboox_ex101.htm)  |
| [23.1](comboox_ex231.htm)  | [Consent of Kustov & Associates, Inc](comboox_ex231.htm)  |
| [23.2\*](comboox_ex101.htm)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Consent of U.S. Counsel  |
| [32.1](comboox_ex321.htm)  | [White Paper of ComBoox](comboox_ex321.htm)  |
| [32.2](comboox_ex322.htm)  | [Source Codes of ComBoox](comboox_ex322.htm)  |

---

\* To be filed by amendment.

---

| |
|:---|
| II-2 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp; Item 17. Undertakings.
The undersigned registrant hereby undertakes:

&nbsp;&nbsp;&nbsp;&nbsp; (1) To file, during any period in which offers or sales are being made, a post-effective amendment to this registration statement:

&nbsp;&nbsp;&nbsp;&nbsp; (i) To include any prospectus required by Section 10(a)(3) of the Securities Act of 1933;

&nbsp;&nbsp;&nbsp;&nbsp; (ii) To reflect in the prospectus any facts or events arising after the effective date of the registration statement (or the most recent post-effective amendment thereof) which, individually or in the aggregate, represent a fundamental change in the information set forth in the registration statement. Notwithstanding the foregoing, any increase or decrease in volume of securities offered (if the total dollar value of securities offered would not exceed that which was registered) and any deviation from the low or high end of the estimated maximum offering range may be reflected in the form of prospectus filed with the Commission pursuant to Rule 424(b) if, in the aggregate, the changes in volume and price represent no more than a 20 percent change in the maximum aggregate offering price set forth in the "Calculation of Registration Fee" table in the effective registration statement;

&nbsp;&nbsp;&nbsp;&nbsp; (iii) To include any material information with respect to the plan of distribution not previously disclosed in the registration statement or any material change to such information in the registration statement;

(2) That, for the purpose of determining any liability under the Securities Act of 1933, each such post-effective amendment shall be deemed to be a new registration statement relating to the securities offered therein, and the offering of such securities at that time shall be deemed to be the initial bona fide offering thereof.

(3) To remove from registration by means of a post-effective amendment any of the securities being registered which remain unsold at the termination of the offering.

(4) That, for the purpose of determining liability under the Securities Act of 1933 to any purchaser, each prospectus filed pursuant to Rule 424(b) as part of a registration statement relating to an offering, other than registration statements relying on Rule 430B or other than prospectuses filed in reliance on Rule 430A, shall be deemed to be part of and included in the registration statement as of the date it is first used after effectiveness. Provided, however, that no statement made in a registration statement or prospectus that is part of the registration statement or made in a document incorporated or deemed incorporated by reference into the registration statement or prospectus that is part of the registration statement will, as to a purchaser with a time of contract of sale prior to such first use, supersede or modify any statement that was made in the registration statement or prospectus that was part of the registration statement or made in any such document immediately prior to such date of first use.

---

| |
|:---|
| II-3 |
| *[**Table of Contents**](#Toc)* |

---

(5) That, for the purpose of determining liability of the registrant under the Securities Act of 1933 to any purchaser in the initial distribution of the securities, the undersigned registrant undertakes that in a primary offering of securities of the undersigned registrant pursuant to this registration statement, regardless of the underwriting method used to sell the securities to the purchaser, if the securities are offered or sold to such purchaser by means of any of the following communications, the undersigned registrant will be a seller to the purchaser and will be considered to offer or sell such securities to such purchaser:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (i) Any preliminary prospectus or prospectus of the undersigned registrant relating to the offering required to be filed pursuant to Rule 424;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ii) Any free writing prospectus relating to the offering prepared by or on behalf of the undersigned registrant or used or referred to by the undersigned registrant;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (iii) The portion of any other free writing prospectus relating to the offering containing material information about the undersigned registrant or its securities provided by or on behalf of the undersigned registrant; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (iv) Any other communication that is an offer in the offering made by the undersigned registrant to the purchaser.

Insofar as indemnification for liabilities arising under the Securities Act of 1933 may be permitted to directors, officers and controlling persons of the registrant pursuant to the foregoing provisions, or otherwise, the registrant has been advised that in the opinion of the Securities and Exchange Commission such indemnification is against public policy as expressed in the Act and is, therefore, unenforceable. In the event that a claim for indemnification against such liabilities (other than the payment by the registrant of expenses incurred or paid by a director, officer or controlling person of the registrant in the successful defense of any action, suit or proceeding) is asserted by such director, officer or controlling person in connection with the securities being registered, the registrant will, unless in the opinion of its counsel the matter has been settled by controlling precedent, submit to a court of appropriate jurisdiction the question whether such indemnification by it is against public policy as expressed in the Act and will be governed by the final adjudication of such issue.

---

| |
|:---|
| II-4 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp; SIGNATURES
&nbsp;&nbsp;&nbsp;&nbsp; Pursuant to the requirements of the Securities Act of 1933, the registrant has duly caused this registration statement to be signed on its behalf by the undersigned, thereunto duly authorized in the City of Beijing, China, on [ ], 2026.

 **Comboox DAO LLC** <br>By: <br> Name: Li Li <br> Title: the Founding Member and Manager

&nbsp;&nbsp;&nbsp;&nbsp; Pursuant to the requirements of the Securities Act of 1933, this offering has been signed by the following person in the capacities indicated on the date of [ ], 2026.

Name: **Li Li** <br>By: <br> Title: the Founding Member and Manager

---

| |
|:---|
| II-5 |
| *[**Table of Contents**](#Toc)* |

---

## Ex-3

![](comboox_ex31img1.jpg)

## Ex-3

![](comboox_ex32img1.jpg)

------

![](comboox_ex32img2.jpg)

------

![](comboox_ex32img3.jpg)

------

![](comboox_ex32img4.jpg)

## Ex-3

![](comboox_ex33img1.jpg)

## Ex-3

### AMENDED AND RESTATED

## OPERATING AGREEMENT

## FOR

# COMBOOX DAO LLC
![](comboox_s1img1.jpg)

## A DECENTRALIZED AUTONOMOUS ORGANIZATION
**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PROSPECTIVE INVESTORS ARE NOT TO CONSTRUE THE CONTENTS OF THIS AGREEMENT OR ANY PRIOR OR SUBSEQUENT COMMUNICATIONS FROM THE COMPANY, THE MEMBER OR THEIR AFFILIATES, OR ANY PROFESSIONAL ASSOCIATED WITH THIS OFFERING, AS LEGAL, TAX OR INVESTMENT ADVICE. EACH INVESTOR SHOULD CONSULT WITH AND RELY ON HIS OR HER OWN ADVISORS AS TO THE LEGAL, TAX AND/OR ECONOMIC IMPLICATIONS OF THE INVESTMENT DESCRIBED IN THIS AGREEMENT AND ITS SUITABILITY FOR SUCH INVESTOR.** 

**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AN INVESTMENT IN THE SHARES CARRIES A HIGH DEGREE OF RISK AND IS ONLY SUITABLE FOR AN INVESTOR WHO CAN AFFORD LOSS OF HIS OR HER ENTIRE INVESTMENT IN THE SHARES. THE SHARES HAVE NOT BEEN REGISTERED UNDER THE UNITED STATES SECURITIES ACT OF 1933. AS AMENDED OR THE SECURITIES LAWS OF ANY OTHER STATE. ACCORDINGLY, SHARES MAY NOT BE TRANSFERRED SOLD, PLEDGED OR HYPOTHECATED IN THE ABSENCE OF AN EFFECTIVE REGISTRATION STATEMENT OR A VALID EXEMPTION FROM SUCH REGISTRATION.** 

 **TABLE OF CONTENTS**

---

| | |
|:---|:---|
|  | **Page** |
| [ARTICLE 1. Definition](#ARTICAL 1.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1  |
| [ARTICLE 2. Formation](#ARTICAL 2.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8  |
| [ARTICLE 3. Shares](#ARTICAL 3.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13  |
| [ARTICLE 4. Trade of Shares](#ARTICAL 4.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16  |
| [ARTICLE 5. Pledge of Shares](#ARTICAL 5.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 22  |
| [ARTICLE 6. Capital Contributions, Assets, and Liabilities](#ARTICAL 6.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 25  |
| [ARTICLE 7. Profits, Lossess and Distribution](#ARTICAL 7.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 32  |
| [ARTICLE 8. Members](#ARTICAL 8.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 34  |
| [ARTICLE 9. General Meeting](#ARTICAL 9.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 37  |
| [ARTICLE 10. Management](#ARTICAL 10.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 43  |
| [ARTICLE 11. Compensation and Reimbursement](#ARTICAL 11.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 47  |
| [ARTICLE 12. Bookkeeping](#ARTICAL 12.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49  |
| [ARTICLE 13. General Matters](#ARTICAL 13.)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 54  |
| [CERTIFICATION OF MEMBERS](#CERTIFICATION OF MEMBERS)  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 58  |

---

---

| |
|:---|
| iii |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; THIS OPERATING AGREEMENT (this "**Agreement**") is made, adopted and originally entered into effective as of May 18, 2024 (the "**Effective Date**"), and is amended and restated on the date of March 24, 2025 , by the members whose signatures appear at the end of this Agreement, for governing the operating of Comboox DAO LLC (the "**Company**"), a Wyoming limited liability company electing to be a decentralized autonomous organization.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WITNESSETH

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEREAS, the Company was formed as a decentralized autonomous organization under the Wyoming Limited Liability Company Act (the "**Act**") and the Wyoming Decentralized Autonomous Organization Supplement (the "**Supplement**") pursuant to a CERTIFICATE OF ORGANIZATION filed by Wyoming Secretary of State on November 8, 2023 .

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NOW THEREFORE, the OPERATING AGREEMENT of the Company is hereby stated in its entirety as follows:

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 1. Definition
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.1. "**Act**" means The Wyoming Limited Liability Company Act, as amended from time to time.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.2. "**Agreement**" means this decentralized autonomous organization operating agreement of the Company, which may be approved, adopted, and/or amended pursuant to this Agreement, as well as the Company's Articles of Organization.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.3. "**ArbitrumOne**" means the Ethereum Layer-2 public blockchain network operating under the name "**ArbitrumOne**", which is connected to the main net of Ethereum and uses a technology called "**Optimistic Rollups**" to improve the scalability and efficiency of Ethereum.

---

| |
|:---|
| 1 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.4. "**Articles**" means the Articles of Organization of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.5. "**Backup Key**" means the other account address added by a User into its ComBoox User account, which may also be recognized by Registration Center to retrieve the User Number for identification purpose.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.6. "**Buy Orders**" has the meaning defined in Section 4.5.4.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.7. "**Cashier**" has the meaning defined in Section 6.5.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.8. "**CBP**" or "**ComBoox Points**" means the ERC-20 token booked in Registration Center, the primary function of which is to act as the ComBoox Community's utility token to automatically calculate, collect and transfer royalties from Users of Templates to the relevant intellectual properties' holder.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.9. "**Certificate of Contribution**" or "**Certificate**" has the meaning defined in Section 3.1.3.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.10. "**Clean Paid**" has the meaning defined in Section 3.1.2(4).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.11. "**Closed Deals**" has the meaning defined in Section 4.5.5.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.12. "**ComBoox**" or "**ComBoox Platform**" means the company book-entry platform consisting of a core smart contract called "**Registration Center**" and a set of Templates deployed on ArbitrumOne, which is designed for equity registration and corporate statutory books-keeping, and aims to assist users to quickly establish a legal, secure, transparent, reliable and automatic system to enable the company's stakeholders to perform legal acts related to share transactions or corporate governance in a self-service mode.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.13. "**ComBoox Community**" means the open, unincorporated, loose organization of CBP holders, whose primary function is to decide, through public discussion and public voting, for reference purpose only, on whether new template contracts are suitable to be included into the ComBoox Platform as Template, so as to improve or expand the functionalities thereof.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.14. "**Contractual Transfer**" has the meaning defined in Section 4.3.2.

---

| |
|:---|
| 2 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.15. "**Creditor**" has the meaning defined in Section 5.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.16. "**Days**" means natural days, each consisting of 24 hours.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.17. "**Deed of Pledge**" has the meaning defined in Section 5.2.2.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.18. "**Distribution Weight**" has the meaning defined in Section 3.1.2(9).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.19. "**Distribution Points**" has the meaning defined in Section 3.1.2(9).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.20. "**Dollar**", "**USD**" or "**$**" means the legal currency of the United States.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.21. "**Due Date**" has the meaning defined in Section 5.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.22. "**ETH**" means the native utility token of the Arbitrum One network, issued 1:1 against Ether locked on the Ethereum mainnet bridge, used for paying transaction fees and transferable among accounts on Arbitrum One.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.23. "**Expired Orders**" has the meaning defined in Section 4.5.6.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.24. "**Founding Member**" means the Member who set up the Company and invested Royalty Interests as his initial capital contribution in exchange for his Shares.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.25. "**General Meeting**" has the meaning defined in Section 9.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.26. "**General Meeting Minutes**" has the meaning defined in Section 9.6.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.27. "**General Keeper**" has the meaning defined in Section 2.8.2.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.28. "**Initial Offers**" has the meaning defined in Section 4.5.2.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.29. "**Initial Shares**" has the meaning defined in Section 6.1.3.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.30. "**List of Orders**" has the meaning defined in Section 4.5.2.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.31. "**Listing Rule**" has the meaning defined in Section 4.3.5.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.32. "**Listing Transfer**" has the meaning defined in Section 4.3.3.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.33. "**Manager**" has the meaning defined in Section 10.4.1.

---

| |
|:---|
| 3 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.34. "**Members**" has the meaning defined in Section 8.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.35. "**Ordinary Resolution**" has the meaning defined in Section 10.2.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.36. "**Paid Value**" has the meaning defined in Section 3.1.2(3).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.37. "**Par Value**" has the meaning defined in Section 3.1.2(2).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.38. "**Pledge**" has the meaning defined in Section 5.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.39. "**Pledged Share**" has the meaning defined in Section 5.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.40. "**Pledgor**" has the meaning defined in Section 5.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.41. "**Price of Paid**" has the meaning defined in Section 3.1.2(6).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.42. "**Price of Par**" has the meaning defined in Section 3.1.2(5).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.43. "**Prime Key**" means the external account address or smart contract address used to register a User's account with ComBoox that can be recognized by Registration Center to automatically retrieve the relevant User Number for identification purposes.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.44. "**Registration Center**" means the core smart contract of ComBoox deployed on ArbitrumOne at the address as publicly disclosed on ComBoox's website and its white paper, which has the following primary functions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) User Registration: to register users of ComBoox against their Prime Key;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) CBP book keeping: to record balance amount of CBP for each account holder;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Document Registration: to register Templates and their clone copies according to the contract address; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.45. "**Register of Agreements**" has the meaning defined in Section 4.4.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.46. "**Register of Constitutions**" has the meaning defined in Section 13.7.1.

---

| |
|:---|
| 4 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.47. "**Register of Directors**" has the meaning defined in Section 10.5.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.48. "**Register of Members**" has the meaning defined in Section 8.3.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.49. "**Register of Pledges**" has the meaning defined in Section 5.2.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.50. "**Register of Shares**" has the meaning defined in Section 3.2.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.51. "**Royalty Interests**" means a type of beneficial right and passive (non-operational) interest which, invested by Founding Member as its capital contribution or acquired from other developers, provides the Company with the right to revenues generated from the use of ComBoox's Template Smart Contracts, consisting of: (1) royalties collected automatically, as the partial beneficiary of Templates within the territory of ArbitrumOne, from the User who invokes the corresponding write function of the smart contracts concerned; and (2) commissions collected automatically, as the owner of ComBoox, from splitting the royalty revenues of all beneficiaries concerned.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.52. "**Sell Orders**" has the meaning defined in Section 4.5.3.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.53. "**Share**" has the meaning defined in Section 3.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.54. "**Shareholder**" has the same meaning with "**Member**" as defined in Section 1.33.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.55. "**Shareholders Agreement**" has the meaning defined in Section 2.8.4.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.56. "**Smart Contracts**" has the meaning defined in Section 2.8.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.57. "**Special Resolution**" has the meaning defined in Section 10.3.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.58. "**Subject Debt**" has the meaning defined in Section 5.1.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.59. "**Supplement**" means The Wyoming Decentralized Autonomous Organization Supplement, as amended and in effect from time to time.

---

| |
|:---|
| 5 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.60. "**Template Contracts**" or "**Templates**" means the smart contracts adopted by the ComBoox Community and further approved by Ordinary Resolution and registered in Registration Center as templates to create clone copies for its Users to deploy and use on ComBoox.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.61. "**Trading Mode**" has the meaning defined in Section 4.3.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.62. "**USDC**" or "**USD Coin**" means a United States dollar-pegged stable coin issued and managed by Circle Internet Financial, LLC, recorded on Arbitrum One at the address "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", and designed to maintain a stable value of $1.00 per USDC.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.63. "**Users**" means the external account holder or the smart contract that has registered as a User with ComBoox by calling the specific function of Registration Center, each of which will be assigned a User Number that represents their unique identity against their Prime Key.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.64. "**User Number**" means a User's identity number in ComBoox, which is automatically assigned by Registration Center during the registration process. Both the Prime Key and the Backup Key can be recognized by Registration Center to automatically return the corresponding User Number, which can be further used by other smart contracts for identity verification, access control or confirmation of legal rights.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.65. "**Verified Investor**" means the User that already has his or her identity and other relevant materials verified: (1) by the relevant service provider engaged by the Company; or (2) by the Manager in person. Only Verified Investor can participate in Listing Transfer, or acquire Shares of the Company to become a Member, and the Manager may revoke the qualification of Verified Investor, according to the suggestion of the relevant service provider, or pursuant to any applicable laws or regulations.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.66. "**Voting Weight**" has the meaning defined in Section 3.1.2(8).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.67. "**Voting Points**" has the meaning defined in Section 3.1.2(8).

---

| |
|:---|
| 6 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.68. Unless otherwise clearly indicates, words used in the singular include the plural, the plural includes the singular, and the neuter gender includes the masculine and the feminine.

---

| |
|:---|
| 7 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 2. Formation
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1. **FORMATION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Company was formed on November 8, 2023 in the State of Wyoming by CERTIFICATE OF ORGANIZATION filed by the Wyoming Secretary of State with assigned filing number 2023-001358375 , pursuant to the Act and the Supplement. Except as expressly provided to the contrary in this Agreement, the rights, duties, liabilities and obligations of the Members and the administration, dissolution and termination of the Company shall be governed by the Act and the Supplement.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2. **NAME.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The name of the Company shall be Comboox DAO LLC .

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3. **REGISTERED OFFICE & AGENT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3.1. The name and location of the registered agent is: <br> Registered Agents Inc <br> 30 N Gould St Ste R <br> Sheridan, WY 82801 <br>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3.2. The registered office and agent may be changed from time to time as the Members may see fit, by filing a change of registered agent or office form with the Wyoming Secretary of State. It will not be necessary to amend this provision of the operating agreement if and when such a change is made.

---

| |
|:---|
| 8 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.4. **TERM.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Company will continue perpetually unless:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) decided by Special Resolution for dissolution;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) an event occurs which causes the Company's business to become unlawful; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) any other event causes the Company's dissolution under either the Act or the Supplement.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.5. **CONTINUATION OF THE COMPANY.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; In the event of an occurrence described in Section 2.4, if there is at least one remaining Member, the remaining Member has the right to continue the business of the Company, unless that right to continue has been terminated. The remaining Member's successor, assignee, or transferee may continue the business of the Company, provided the successor, assignee, or transferee consents to the continuation in writing and submits any necessary filings to the office of the Secretary of State.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.6. **BUSINESS PURPOSE.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.6.1.The business purpose of the Company shall include:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) to hold the Royalty Interests invested by Founding Member as its capital contribution, or copyrights of other Templates acquired by the Company from time to time;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) to collect the Templates' royalty and the platform's commission of ComBoox within the territory of ArbitrumOne in form of CBP as general income;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) to mint and/or transfer CBP directly or indirectly to potential users so as to facilitate them to use the Templates adopted by and registered in ComBoox;

---

| |
|:---|
| 9 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) to purchase the copyright of other Templates newly adopted by ComBoox for the territory of ArbitrumOne;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) to purchase online or offline advertising services, promotion services, code audit services or other services to promote ComBoox Platform; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) to purchase necessary accounting services, auditing services, legal services, registration agent services or other necessary professional services to make the Company, as well as ComBoox Platform, be able to operate and develop in compliance with the governing laws and regulations.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.6.2. In addition to the above, the Company may conduct any and all lawful business appropriate in carrying out the Company's objectives, as permitted under Section 17-29-104 of the Act and Section 17-31-105 of the Supplement.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.7. **PRINCIPAL PLACE OF BUSINESS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Company's principal place of business is: <br> 30 N Gold St Ste R <br> Sheridan, Wyoming 82801

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8. **UNDERLYING SMART CONTRACTS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.1. "**Underlying Smart Contracts**" or "**Smart Contracts**" means the set of smart contracts adopted by the Company, from time to time, for automatically registering the equity shares of the Company and keeping records of corporate governance thereof, which shall be created and deployed by cloning Templates.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.2. "**General Keeper**" is the core Smart Contract that represents the legal entity of the Company to hold crypto assets, to receive revenue incurred from Royalty Interests, to elect or impeach any Managers, to make payments, and to conduct any legal acts on behalf of the Company on ArbitrumOne. Therefore, contract address of General Keeper shall be specified as and can be retrieved from, directly or indirectly, the "**public available identifier**" in the Articles in accordance with Section 17-31-106(b) of the Supplement.

---

| |
|:---|
| 10 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.3. In the event that Members intend to replace General Keeper with other smart contract deployed at different address, such address will be set out in the deprecated General Keeper's events as a special reference, so that the original General Keeper's address will still be used as the public available identifier of the Company without updating the Articles.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.4. "**Shareholders Agreement**" is the constitutional Smart Contract that defines all rules and terms for equity registration and corporate governance of the Company, which will be queried by other Smart Contracts for retrieving specific rules or terms in runtime so as to automatically control the conditions and procedures of legal acts of the Company. It shall be deemed as and construed into an amendment to this Agreement. Detailed provisions in regard of the relationship between Shareholders Agreement and this Agreement are set forth in Section 13.6.1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.5. The Members acknowledge and agree that, pursuant to Section 17-31-106 of the Supplement, the Underlying Smart Contracts govern the operations of the Company, even in the absence of any equivalent agreements, resolutions or any other documents in natural language. Any Underlying Smart Contracts related to the disposition of the Company's equity or assets shall be valid and effective solely upon resolutions by Members in accordance with the pre-defined on-chain voting procedures.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.6 In the event of any conflict or discrepancies between the Articles and any of the Underlying Smart Contracts, the Smart Contract shall prevail. In the event of any conflict or discrepancies between the Articles and this Agreement, the Articles shall prevail. In the event of any conflict or discrepancies between this Agreement and any of the Underlying Smart Contracts, the Smart Contract shall prevail.

---

| |
|:---|
| 11 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.8.7. The addresses of Smart Contracts are publicly registered in and can be retrieved from General Keeper, which will be automatically updated when Members replace one or more Smart Contracts by Special Resolution. It will not be necessary to update or revise any provisions of this Agreement if and when such a change is made.

---

| |
|:---|
| 12 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 3. Shares
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1. **SHARES.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1.1. "**Share**" means a Member's minimum unit of ownership interests and rights in the Company, par value of which is $0.0001.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1.2. Shares will be booked automatically in Register of Shares in form of a digital object called "**Certificate of Contribution**" with the following key attributes:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) "**Shareholder**" means the ownership title holder of the subject Shares (i.e. a Member of the Company), who will be booked and indicated in form of its User Number;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) "**Par Value**" represents the subscribed contribution amount of the subject Shares, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) "**Paid Value**" represents the paid-in contribution amount of the subject Shares that actually received by the Company, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) "**Clean Paid**" represents the paid-in contribution amount of the subject Shares that has no encumbrances attached and can be freely disposed by its Shareholder, the minimum unit of which shall be 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) "**Price of Par**" refers to the per share acquiring price for the unpaid Par Value of the subject Shares, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) "**Price of Paid**" means the per share acquiring price for the Paid Value of the subject Shares, the minimum unit of which is 0.0001 USD;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) "**Total Value**" means the total acquiring value of the subject Shares indicated in USD, which shall be calculated as following:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Value = Price of Paid \* Paid Value + Price of Par \* (Par Value - Paid Value)

---

| |
|:---|
| 13 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) "**Voting Weight**" means percentage weight of each Share when calculating the voting rights of the subject Shares, and the calculation result shall be called as "**Voting Points**" which shall be the basis to calculate the aggregate voting rights of a Member. The minimum unit of Voting Weight shall be one percent. Therefore, the total Voting Points of the subject Shares shall be calculated as:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Points = Voting Weight \* Par Value / 100

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) "**Distribution Weight**" means percentage weight of each Share when calculating the distribution rights of the subject Shares, and the calculation result shall be called as "**Distribution Points**", which shall be the basis to calculate the aggregate distribution rights of a Member for distributing profits or residual assets, or assuming loss or liabilities of the Company. The minimum unit of Distribution Weight shall be one percent. Therefore, the total Distribution Points of the subject Shares shall be calculated as:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Points = Distribution Weight \* Par Value / 100

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1.3. "**Certificate of Contribution**" or "**Certificate**" means the digital object acting as the conclusive evidence of the subject Shares booked in Register of Shares, which will be automatically created and issued to the buyer upon closing of capital increase deals or share transfer deals, and will be updated by decreasing the amount of Par Value and/or Paid Value upon closing of share transfer deals. When the subject Shares are transferred to other party with full amount, the Certificate of Contribution concerned will be removed from Register of Shares automatically.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2. **REGISTER OF SHARES.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.1. "**Register of Shares**" means the Smart Contract adopted by the Company to automatically book and maintain the public record of Shares, i.e. the Certificate of Contribution concerned. Any creation, alteration or revocation of any Share can only be effective and legally binding to the Company and Members upon its entry into Register of Shares.

---

| |
|:---|
| 14 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.2. Upon closing of the subject Shares transaction, no matter it is a capital increase deal or a share transfer deal, a new Certificate of Contribution will be automatically created and issued to the buyer in Register of Shares.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.3. When a Shareholder pays in capital contribution for the called-up Par Value of the subject Shares, the Paid Value of the relevant Certificate of Contribution will be automatically increased by the same amount.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.4. When a Shareholder transfers Shares, the relevant Certificate of Contribution will be automatically updated with its Par Value and Paid Value being reduced by the same amount.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.5. Once the full amount of Par Value of the subject Shares is sold out, the relevant Certificate of Contribution will be automatically removed from Register of Shares.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.6. The information stored in Register of Shares is publicly accessible to all of the world. Everybody can check and read the Certificate of Contribution booked in Register of Shares.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.7. Register of Shares will not be deleted from ArbitrumOne even after the termination of the Company.

---

| |
|:---|
| 15 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 4. Trade of Shares
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1. **SHARE TRANSFER.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1.1. Shares can only be transferred or traded by means of Trading Mode as specified in this Agreement and implemented by Templates of ComBoox.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1.2. Shareholders may transfer their Shares among each other freely, provided that both parties concerned are Verified Investors.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1.3. Subject to the requirements on Verified Investor set out in Section 4.2, Shareholders may transfer their Shares to external Verified Investors freely.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1.4. Share transfers are not subject to any approval of other Members or General Meeting, however, in case it is arranged in the way of Contractual Transfer, the relevant Investment Agreement shall still need to be submitted to General Meeting for records purpose.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1.5. No first refusal rights, drag along, tag along, or any other similar special Shareholders' rights are set on any Shares.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2. **REQUIREMENTS ON INVESTOR.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2.1. "Register of Investors" means the Smart Contract adopted by the Company to book and maintain the public records of Verified Investors. Any application, approval, or revocation of any Verified Investors shall only be effective and legally binding on the Company and Members upon its entry into Register of Investors.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2.2. If any buyer intends to purchase Shares to become a Member of the Company, he or she shall satisfy the following requirements:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the buyer shall be a registered User of ComBoox;

---

| |
|:---|
| 16 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the buyer shall have its identity verified:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. by the identification service provider engaged by the Company as per Section 8.1.4; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. by Manager;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the buyer shall honestly disclose the affiliation relationship with any existing Members by identifying the User Number of such Member's representative of group in the relevant attribute field:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. in the application form for Verified Investor;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. in the relevant deals in the Investment Agreement; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c. in the relevant Buy Orders to be placed on List of Orders.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2.3. If any Shareholder intends to transfer his or her Shares, by means of Contractual Transfer, to any party other than a Member, the seller shall be responsible to procure such potential buyer to satisfy the requirements stipulated in the above Section 4.2.1(2).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2.4. Manager shall exercise reasonable commercial efforts to ensure Verified Investors satisfying the requirements stipulated in the above Section 4.2.1(2).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3. **TRADING MODE.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3.1. "**Trading Mode**" means the permitted transaction method and mechanism for Shares with respect to price discovery, agreement conclusion and equity closing, which shall include at least Contractual Transfer and Listing Transfer as further defined in this Section.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3.2. "**Contractual Transfer**" means the transfer mode of Shares which shall be carried out in accordance with an Investment Agreement that the seller and the buyer entered into previously, in which the basic transaction elements shall be set out clearly such as Paid Price, Paid Value, Class of Share, payment method, and closing deadline etc.

---

| |
|:---|
| 17 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3.3. "**Listing Transfer**" means that the transfer mode of Shares which shall be arranged by listing, i.e. the seller may place Sell Orders on List of Orders with its acceptable offer price and sell amount, the buyer may place Buy Orders with its acceptable bid price and buy amount, and the system will automatically match and settle the Buy Order with the available Sell Orders according to their price and amount.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3.4. Subject to any requirements of applicable laws and regulations, Shares approved by Members for trading by "**Listing Transfer**" may also be transferred by "**Contractual Transfer**". The Listing Transfer attributes may only be allocated to a particular Class of Shares in accordance with a Listing Rule of the effective Shareholders' Agreement.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3.5. "**Listing Rule**" means the rule governing the Listing Transfer of specific Class of Shares with respect to the title of issuer, Class of Shares, maximum Par Value, title of verifier, maximum quantity of Investors, ceiling price, floor price, lockup days, off listing price, Voting Weight, Distribution Weight and other attributes concerned, which shall be incorporated in a Shareholders Agreement and approved by Special Resolution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4. **REGISTER OF AGREEMENTS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.1. "**Register of Agreements**" means the Smart Contract adopted by the Company to automatically book and maintain the public records of Investment Agreements, which shall set forth the address, status, transaction type and detailed arrangements, parties, procedural schedules for exercising special rights, so as to enable users or smart contracts to check and retrieve, execute or terminate the relevant Investment Agreements. Any creation, modification, execution, performance or termination of any Investment Agreements shall only be effective and legally binding for the Company, Members or parties concerned upon its entry into Register of Agreements.

---

| |
|:---|
| 18 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.3. Upon signing by any sellers on an Investment Agreement, the subject Shares' Clean Paid will be automatically reduced by the relevant amount as per the deals concerned. In the event any of the deals concerned fails to be closed after the relevant closing dead line, the seller may request to terminate the deal so as to recover the Clean Paid of the subject Shares back to its original level.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.4. Upon closing of any deals of an Investment Agreement, a new Certificate of Contribution will be created and issued to the buyer in Register of Shares, and the subject Shares' Certificate of Contribution will be reduced by the relevant amount of Par Value and Paid Value or be removed entirely if no amount left.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.5. The information stored in Register of Agreements is publicly accessible to all of the world. Everybody can check and read the Investment Agreements booked in Register of Agreements.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.6. Register of Agreements will not be deleted from ArbitrumOne even after the termination of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5. **LIST OF ORDERS.**

---

| |
|:---|
| 19 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.1. "**List of Orders**"means the Smart Contract adopted by the Company to book and maintain the public records of Listing Trade in USDC, which will automatically record the Initial Offers, Sell Orders, Buy Orders, as well as the closed deals concerned.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Any placement, withdraw, matching, closing, and revocation of Initial Offers, Sell Orders or Buy Orders shall only be effective and legally binding upon the Company, its Members and Verified Investors concerned once entered into the respective List of Orders.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.2. "**Initial Offers**" means the limit sell orders created and placed on the List of Orders by the authorized issuer on behalf of the Company to issue new Shares of the relevant Class at a specific offer price (Price of Paid) with a specific amount (Par Value and Paid Value) and the available hours thereof, in accordance with the relevant Listing Rule, which shall also set forth other necessary elements of a capital increase deal, such as Voting Weight and Distribution Weight.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.3. "**Sell Orders**" means the limit sell orders and market sell orders created and placed on the List of Orders by the Shareholders to transfer their Shares at a specific offer price or market price (Price of Paid) with a specific amount (Par Value and Paid Value) and available hours thereof, in accordance with the relevant Listing Rule.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.4. "**Buy Orders**" means the limit buy orders and market buy orders created and placed on the List of Orders by the Verified Investors, together with sufficient USDC paid as consideration or margin, to purchase the offered Shares in Initial Offers or Sell Orders at a specific bid price or market price (Price of Paid) with a specific amount (Paid Value), in accordance with the relevant Listing Rule.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.5. "**Closed Deals**" means the deals established and settled automatically via List of Orders under the principle of "price priority and time priority", which will be automatically recorded as events in List of Orders.

---

| |
|:---|
| 20 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.6. "**Expired Orders**" means the Initial Offers or Sell Orders that has been expired when matching any Buy Orders, or the Buy Orders that has been expired when matching any Sell Orders or Initial Offers. They will be removed from List of Orders and be recorded as events thereon automatically.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.7. Any Buy Orders or Sell Orders placed on the List of Orders will be firstly matched with their counter orders under the principle of "price priority and time priority" automatically, thereafter, any balance amount left in limited orders will be listed on the List of Orders accordingly.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.8. Upon the settlement of any Closed Deals, the subject Shares will be automatically issued or transferred to the buyer. The consideration in USDC will be automatically transferred to the sellers or the Cashier.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.9. Any USDC margin from expired Buy Orders or USDC balance from market Buy Orders will be refunded directly to the buyer.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.10. Any subject Shares of expired Sell Orders or Shares balance of market Sell Orders will be released back to their shareholders with respect to their Clean Paid.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.11. The information stored in List of Orders is publicly accessible to all of the world. Everybody can check and read the Orders, Deals and events booked in List of Orders.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5.12. List of Orders will not be deleted from ArbitrumOne even after the termination of the Company.

---

| |
|:---|
| 21 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 5. Pledge of Shares
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.1. **SHARE PLEDGE.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.1.2. A Pledge shall only be validly created and binding on the Company and the Members if the following conditions are satisfied:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) a Deed of Pledge has been created and registered in Register of Pledge;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Creditor has been approved as a Verified Investor;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the Subject Share has sufficient Clean Paid to cover the Pledged Paid Value of the Pledge; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) the Subject Debt is not due when creating the Pledge.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.1.3. The Creditor of a Pledge may transfer the Subject Debt together with the Pledge to other Users, provided that the buyer has already been approved as a Verified Investor.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.1.4. If the Creditor confirms that the Subject Debt has been partially repaid by a certain amount, the attached Pledge will be automatically released proportionately. If the Subject Debt is confirmed by the Creditor having been fully repaid, the Pledge concerned will be automatically released in full and the relevant Deed of Pledge will be removed from Register of Pledges.

---

| |
|:---|
| 22 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.1.5. Before expiration of a Pledge, the Pledgor may extend the Number Of Guarantee Days at its full discretion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.1.6. The creation, transfer, alteration or extension of any Pledges are NOT subject to any approval of other Members or the Company. All relevant legal acts can be carried out on ArbitrumOne without execution any paper documents off-chain.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2. **REGISTER OF PLEDGES.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.1. "**Register of Pledges**" means the Smart Contract adopted by the Company to automatically book and maintain the public record of Pledges. Any creation, transfer, alteration or revocation of any Deed of Pledge can only be effective and legally binding to the Company and Members upon its entry into Register of Pledges.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.2. "**Deed of Pledge**" means the digital object acting as the conclusive evidence of a Pledge, which will be automatically created and registered in Register of Pledges when the Pledgor sets up a Pledge on the Pledged Share concerned. It shall set forth the following basic elements of the Pledge:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Certificate Number of the Pledged Share;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the User Number of the Creditor, Pledgor, and Debtor;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the Due Date, and Guaranteed Amount of the Subject Debt; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) the Sequence Number, Pledged Paid Value, Pledged Par Value, Issue Date and Number of Guarantee Days of the Pledge.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.3.When the Creditor confirms a repayment of the Subject Debt, the relevant Pledge will be automatically updated by reducing its Pledged Par Value and Pledged Paid Value proportional to the repaid ratio of the Guaranteed Amount.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.4.The Creditor may transfer the Pledge to any other Verified Investor, upon which the Creditor indicated in the Deed of Pledge will be automatically revised into the buyer.

---

| |
|:---|
| 23 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.5.Before expiration of a Pledge, the Pledgor may extend the valid period thereof by increasing the Guarantee Days concerned, upon which the Deed of Pledge will be updated automatically to reflect such extension.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.6.Once the Subject Debt is confirmed by the Creditor having been fully repaid, the relevant Deed of Pledge will be automatically removed from Register of Pledges.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.7.The information stored in Register of Pledges is publicly accessible to all of the world. Everybody can check and read the Deed of Pledge booked in Register of Pledges.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2.8.Register of Pledges will not be deleted from ArbitrumOne even after the termination of the Company.

---

| |
|:---|
| 24 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 6. Capital Contributions, Assets, and Liabilities
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1. **INITIAL CONTRIBUTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1.1. As of Effective Date, Founding Member has contributed to the Company the following Intellectual Property Rights (the "IPR") in exchange for the Initial Shares as set out in Section 6.1.3:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Royalty Interests of the Templates developed by Founding Member within the territory of ArbitrumOne, so that the Company may collect royalty on those Templates in form of CBP as general income;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) owner's right to Registration Center, so that the Company may collect platform commission of ComBoox in form of CBP as general income;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) mint rights of CBP within the territory of ArbirumOne, so that the Company may adjust total supply of CBP; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) owner's right to the Smart Contract named "**Fuel Tank**", so that the Company may:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. set the Fuel Tank's selling price of CBP in USD; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. receive selling revenue of CBP in USDC from Fuel Tank.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1.2. Under US GAAP, when the Founding Member contributed the IPR to the Company, it is difficult to recognize its value due to the following reasons:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) there are no similar software or business models available in the market, making it impossible to identify comparable fair value measurement targets;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) ComBoox has not generated any actual revenue, so there is no reasonable basis for valuation under the revenue method;

---

| |
|:---|
| 25 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) ComBoox was developed solely by the Founding Member, meaning that there are no arm's length transactions or third-party payment records to support the development costs; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) the cost method alone is unlikely to be accepted as a sound basis for valuing a DApp like ComBoox.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1.3. Due to the reasons identified in Section 6.1.2, in exchange of the IPR contributed to the Company described in Section 6.1.1, the Company has issued the following subscribed but not paid Shares (the "**Initial Shares**") to Founding Member:

---

| | | |
|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Certificate No.**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Par Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 250,000 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 50,000 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Paid Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Price of Par**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Price of Paid**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0001 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0001 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4,000 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Voting Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100000000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Distribution Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1.4. As long as the following conditions are all fulfilled, the Company shall have the IPR to be valued:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Company has already legally issued its equity shares to the public, as well as the CBP as a utility token;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Company has been receiving automatically collected royalties from parties other than the Founding Member for more than one year; and

---

| |
|:---|
| 26 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) a Special Resolution has been passed by the General Meeting, with the support vote of the Founding Member counted in the voting result, regarding the valuation firm to be engaged to assess the value of the IPR, as well as the valuation base date thereof.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1.5. When the final valuation report is issued as per Section 6.1.4, then:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the value of the IPR shall be recognized in the account of "Intangible Assets" on the debit side, as per the arithmetic or weighed average of the upper and lower boundaries of the valuation range identified in the valuation report, whichever is higher;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the value of the IPR shall also be booked in the account of "Paid In Capital" on the credit side, as paid in capital contributed by the Founding Member, therefore:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. if the value of the IPR is greater than the unpaid subscription amount of the Initial Shares, the Company shall update the Paid Value of the Initial Shares as equal to their Par Value, and shall further issue such number of new Class B Shares whose Paid Value and Par Value are all equal to the excess amount thereof; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. if the value of the IPR is lower than the unpaid subscription amount of the Initial Shares, the Company shall update the Paid Value of the Initial Shares as equal to the recognized IPR value, and the Founding Member may elect to: (i) pay the outstanding balance amount in USDC; or (ii) cause the Company to decrease the equivalent amount of the Initial Shares in the order of Class B to Class A.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1.6. Before the value of the IPR is recognized in the accounts of "Intangible Assets" and "Paid In Capital" as per Section 6.1.5:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Company shall NOT distribute any profits or assets to the Members; and

---

| |
|:---|
| 27 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Voting Points and Distribution Points of all Shares shall be calculated based on Par Value thereof, no matter the Shares are paid up or not.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2. **ADDITIONAL CONTRIBUTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2.1. No Member is obligated to make any additional contribution to the Company beyond their initial contribution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2.2. Members may, from time to time, approve Investment Agreements containing capital increase deals, by Special Resolution, so as to decide:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the amount of the increasing capital of the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Price of Paid, Voting Weight, Distribution Weight, and other classified attributes of the new Shares or new Classes to be issued; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the subscriber, the pay in deadline, the closing deadline, and other conditions of the deals concerned.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2.3. Members may, by Special Resolution, add one or more Listing Rules to the Shareholders Agreement, so as to:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) authorize Manager to issue certain number of new Shares by way of listing in order to increase the capital of the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) approve the Voting Weight, Distribution Weight, and other classified attributes of the new Shares to be issued by way of listing; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) approve the ceiling and floor offering price, the off listing price, the max number of investors, the lock-up days and other conditions for offering or trading Shares by way of listing.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2.4. Members may use the following assets or services to make capital contributions to the Company:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) cryptocurrencies other than CBP (like USDC) that the Company may effectively hold, control, dispose and exchange for other assets via General Keeper directly or indirectly;

---

| |
|:---|
| 28 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) copyright of other Templates; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) professional services that is necessary for the Company, and can produce material work outcomes like audit reports or investigation reports.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2.5. All capital contributions shall be valued and denominated in USD, the amount of which shall be specified in the relevant Certificate of Contribution as Paid Value. Value of the contribution shall be determined by the following method as per their different type:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) value of cryptocurrencies shall be calculated by multiplying their amount by the USD price of the relevant currency at the time of delivery, which shall be automatically retrieved from one or more reliable price information providers such as Chainlink Price Feeds; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) value of copyrights or professional services shall be determined by a prior approval of Ordinary Resolution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2.6. The method and mechanism for determining the contribution value set out in Section 6.2.5, shall be deemed as and construed to be a conclusive process. Once the value of a capital contribution is confirmed on its Certificate of Contribution as Paid Value, it cannot and shall not be altered any more. Members agree and undertake that, the subscription or acquisition of Shares in the Company is an acknowledgement of all their historical contributions and therefore no Member shall challenge the adequacy of any paid-in contributions of any other Member.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.3. **FAILURE TO CONTRIBUTE.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; All capital contributions must be made upon or before the issue of the relevant Certificate of Contribution and therefore no called up Par Value exists for any Shares.

---

| |
|:---|
| 29 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.4. **RETURN OF CAPITAL CONTRIBUTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.4.1.The Members agree that if the Company does not have sufficient assets to repay the capital contributions, the Members shall have no recourse against the Company or the other Members. As an exception to the foregoing, recourse does exist if a Member owes an outstanding debt to the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.4.2.Pursuant to Section 17-25-107 of the Supplement, Members are only entitled to demand and receive Shares of the Company in exchange for their capital contributions, regardless of the form or nature of the Member's actual capital contribution(s).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.5. **ASSETS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "**Cashier**" means the Smart Contract adopted by the Company to hold USDC on its behalf and to automatically record, maintain and publicly document payment and receipt transactions in USDC.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Members agree that the Company shall only hold by General Keeper or Cashier on ArbitrumOne the following types of on-chain assets:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) USDC and ETH;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Royalty Interests to receive CBP as royalty or commission;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Mint rights to create new CBP;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Setting right to determine the USD price of CBP in Fuel Tank; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Exclusive right to receive USDC from Fuel Tank as sales consideration of CBP.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To keep its unique role as an on-chain DAO, the Company will not open off-chain bank accounts. All assets that the Company can posses shall be limited to the extent that such assets are able to be held, controlled and disposed, directly or indirectly, by General Keeper or Cashier.

---

| |
|:---|
| 30 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.6. **LIABILITIES.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Company shall not borrow any loan or enter into any contracts that may incur payable liabilities. No employees will be hired, and no Managers or Members will be paid for remuneration either. If the Company intends to hire any experts or purchase any services, such arrangements shall be made on a prepaid basis, or by reimbursing the advanced fees paid by the authorized Member or Manager, within the budget approved by Ordinary Resolution. To the extent permitted by law, the Company has no obligation to repurchase any CBP minted or transferred to any party.

---

| |
|:---|
| 31 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 7. Profits, Losses and Distribution
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.1. **PROFITS/LOSSES.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For accounting and tax purposes, the net profits or net losses of the Company will be determined annually. Pursuant to Section 17-25-110 of the Supplement, and as provided in Section 12.3 below, profits and losses will be allocated to the Members in proportion to each Member's aggregate Distribution Points in the Company and in accordance with Treasury Regulation 1.704-1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.2. **DISTRIBUTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.2.1. Members may determine to distribute available assets annually, provided that the distribution proposal has been approved by Ordinary Resolution, and further provided that there are sufficient assets remaining to cover the total liabilities of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.2.2. Distributions shall be made proportionally to each Member's Distribution Points by depositing a specified amount of USDC into the designated account allocated to that Member in the Cashier. Thereafter, each Member may withdraw its USDC deposits from the Cashier at its discretion, without interest.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.2.3. Prior to the recognition of the IPR value, the Company shall NOT distribute any profits or assets to Members and the Voting Points and Distribution Points of all Shares shall be calculated on the basis of their Par Value, whether or not the Shares are paid up.

---

| |
|:---|
| 32 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.3 **NO INTEREST.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.3.1. Distributions made to Members will be initially stored in Cashier under the specific account assigned to each Member.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.3.2. No interests will be paid on USDC stored in Cashier.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.3.3. Members or sellers who have their USDC stored in Cashier may pick up their deposits at any time by triggering the specific API freely.

---

| |
|:---|
| 33 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 8. Members
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1. **MEMBERS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.1. "**Members**" means the equity owners of the Company, who may enjoy and exercise the distribution rights to the profits and residual assets in proportion to the aggregate Distribution Points of each Member and may enjoy and exercise the voting rights in proportion to the aggregate Voting Points of each Member. For the purposes of this Agreement and in most contexts relating to the Company, the term "**Member**" may usually be used interchangeably with the term "**Shareholder**".

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.2. Only registered Users of ComBoox may purchase Shares of the Company and thus become Members. The User Number is the only identifying information of a Member that is automatically kept and updated in Register of Members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.3. Once a User obtained a Certificate of Contribution in exchange for a capital contribution, he or she will automatically become a Member of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.4. In order to comply with the legal requirements of Know Your Client, Anti-Money Laundering, and other similar requirements about identity verification requirements, Members agree that the Company may engage one or more third party service providers to check, verify, validate, timely renew and store the identity information of Members and such providers may be requested to provide real time confirmation on chain or on line of the identity information against the Prime Key / Backup Key of the Member concerned. In case such service providers charge any service fees, such fees shall be borne and paid by the Members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.5. There is no limit to the total number of Members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.6. A Member can purchase and hold one or more Shares of one or more Classes. The Voting Points or Distribution Points of different Classes of Shares shall be calculated on an aggregate basis to determine a Member's voting weight or distribution weight.

---

| |
|:---|
| 34 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.1.7. As long as a Member loses its last Certificate of Contribution as a result of a Share transfer, he or she will automatically loose the legal identity as a Member of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.2. **MEMBERS DUTIES AND LIABILITY.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.2.1. To the extent permitted by Section 17-29-304 of the Act, no Member shall be personally liable for the obligations of the Company. Pursuant to Section 17-29-407 of the Act, Members may participate in the control, management, direction, or operation of the affairs of the Company pursuant to this Agreement and under the automatic control of Smart Contracts.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.2.2. Pursuant to Section 17-31-110 of the Supplement, no Member has any fiduciary duty to the Company or to any other Member. Unless otherwise agreed among the Members, no Member has any duty to act. Any attempt to grant special rights to one or more Members, must adhere to the underlying Smart Contracts.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3. **REGISTER OF MEMBERS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3.1. "**Register of Members**" means the Smart Contract adopted by the Company to automatically book and maintain the public records of Members and their shareholding. Any admission, alteration or revocation of any Member shall only be effective and legally binding on the Company and Members upon its entry into Register of Members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3.2. Once a User obtains its first Certificate of Contribution it will be automatically included and booked into Register of Members. Once a Member loses its last Certificate of Contribution, it will be removed from Register of Members accordingly.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3.3. When a Member pays in capital contribution for called-up Par Value of the subject Shares of a Certificate of Contribution, the records of the Member in Register of Members will be automatically updated by increasing the amount of Paid Value against the payment.

---

| |
|:---|
| 35 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3.4. When a Member transfers its Shares, the records of the Member in Register of Members will be updated automatically by decreasing the sold out amount of Par Value and Paid Value upon closing.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3.5. The information stored in Register of Members is publicly accessible to all of the world. Everybody can check and read the Members' User Number and their shareholding situation booked and maintained in Register of Members.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.3.6. Register of Members will not be deleted from ArbitrumOne even after the termination of the Company.

---

| |
|:---|
| 36 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 9. General Meeting
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1. **GENERAL MEETING.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.1. "**General Meeting**" means the ONLY decision-making authority of the Company which consists of all Members. All legal acts conducted on behalf of the Company shall be subject to prior approval by the General Meeting, either through an Ordinary Resolution or a Special Resolution, and any off-chain legal documents shall only become legally effective and binding on the Company upon such approval.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.2. **RECORDS.** The Company will NOT convene on-sight meeting, real time video or audio meeting. All motions will be created, proposed, voted and recorded in a Smart Contract called "**General Meeting Minutes**". A discussion or debates concerning the subject matters may be organized on public forum online, if the proposer or any Member thinks proper.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.3. **IDENTIFIER OF CONTENTS.** Each motion shall have a unique identifier appointing to its contents and be recorded in General Meeting Minutes, which could be:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the contract address of the subject Investment Agreement or Shareholders Agreement to be reviewed and approved by voting;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the sequence number of the subject position to be elected by voting;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) the hash value generated via keccat-256 with source data of on-chain actions of the Company to be made via General Keeper to:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. transfer ETH, USDC, CBP or other cryptocurrencies to other account;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. distribute certain amount of USDC held by the Company to Members in proportion to each Member's Distribution Points; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c. make other on-chain actions for other purposes, the key elements of which can be represented and consisting of target contracts' address to be called, ETH value to be carried with such call, and the payload data of the call indicating the target function's selector as well as the input parameters' value concerned.

---

| |
|:---|
| 37 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.4. **QUORUM.** A resolution can be legally effective and have binding force upon the Company and Members only if the aggregate Voting Points represented by the Members who voted on the subject motion, in person or through proxy, is equal or greater than 25% of the total Voting Points of all outstanding Shares in the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.5. When voting on a motion, Members may choose one of the following three options: "**for**", "**against**" or "**abstain**". The Voting Points of "**abstain**" shall be counted in when calculating quorum of a vote. Subject to the provisions of Section 9.1.4, if the Voting Points of "**for**" received by a motion is more than the ones of "**against**", it shall be deemed to be supported by simple majority. If the Voting Points of "**for**" received by a motion is more than four times of "**against**", it shall be deemed to be supported by a special majority.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.6. The voting result of a motion shall be calculated based on the number of Voting Points it received, i.e. the aggregate Voting Points represented by the Members who voted on the subject motion, in person or through proxy. A Member's Voting Points shall be the total number of Voting Points of all Shares owned by such Member on the specific registration date of the subject motion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.7. The registration date shall be earlier or equal to the start time of the voting period, and only Members can participate in a vote. Therefore, if a Member transferred its Share before the registration date, the Voting Points of the transferred Share will not be counted under the name of the seller, but will be counted under the name of the buyer instead. If a Member obtained any Share after the registration date, the Voting Points of such Share will not be counted under the name of such Member, but will be counted under the name of the seller (provided that the seller still holds any Shares to be qualified to cast vote), or will lose the opportunity to be counted (if the seller has no Shares in hand during the voting period concerned).

---

| |
|:---|
| 38 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1.8. For proposals to approve any Investment Agreement or Shareholders Agreement, the signing parties of the subject agreements will be deemed as consent to the proposal concerned, therefore, all Voting Points held by the parties on the registration date will be counted as vote in favor of the proposal.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.1. **DELEGATE AND PROXY.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.2.1. Any Member may appoint another Member as their proxy to cast a vote on their behalf in relation to a proposal. Within the same voting process for a motion, a Member can only appoint one proxy to represent them. In addition, a delegate representing either an individual or an organization shall be entitled to exercise the same voting power as the principal itself.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.2.2. A Member can solicit proxies from other Members so as to collect sufficient Voting Points to make a proposal. A proxy established in the proposal stage will remain effective till the vote casting stage. This means the proxy who made the proposal will continue to represent its principals and cast votes for the proposal.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.2.3. A proxy of other principals may further entrust another Member as their common proxy. In this case, the entrusted proxy will be able to represent the aggregate Voting Points of the former proxy and its principals collectively.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.3. **PROPOSAL RIGHTS OF MOTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.3.1. Any Member who has entered into an Investment Agreement or Shareholders Agreement may submit the smart contract address of the relevant agreement to General Meeting as a proposal for the purpose of seeking approval or for inclusion in the records.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.3.2. The Member authorized by the Shareholders Agreement to nominate a candidate for the position of Manager may submit a nomination with the candidate's User Number to the General Meeting as a proposal for commencing an election to vote for the position of Manager. Once the inauguration has taken place, the nominating Member may also submit a motion for the removal of the Manager from their position to the General Meeting for the commencement of an impeachment vote.

---

| |
|:---|
| 39 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.3.3. In addition to the above, a motion may be proposed to General Meeting for review and voting purpose only if it is proposed by Members holding at least 10% of total Voting Points of the outstanding Shares in the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.4. **NO NOTIFICATION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As all corporate governance records of the Company are publicly available and automatically maintained on ArbitrumOne in a decentralized mode, Members shall be responsible for taking effective measures to continuously monitor the updates of General Meeting Minutes, as well as the timetable of each proposal concerning the review period, registration date, and voting period thereof. Neither the Company nor any Members have obligation or duties to notify any Member for execute legal rights or taking legal acts on any motions or proposals. Although the Company will construct a public UI of ComBoox on its main page so as to facilitate Members to conduct their legal rights, however, Members are advised not to rely solely on such UI or Web App for monitoring or executing any legal rights.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.5. **REGISTRATION DATE AND VOTING PERIOD.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.5.1. Registration date of a proposal for voting in General Meeting will be scheduled on the 15th day after the proposal date of the motion concerned. The voting period of such proposal shall be commenced on the registration date and shall be terminated 3 days thereafter.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.5.2. Notwithstanding the above stipulation, in case the Company only has sole Member when a proposal is submitted for voting, the registration date of such proposal shall be scheduled on the proposal date thereof, and the voting period of such proposal shall be commenced on the proposal date and shall be terminated one day thereafter.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.5.3.In case all Members vote for a proposal, any entity may trigger the relevant function to get the proposal to be passed so as to form a resolution before expiration of the voting period.

---

| |
|:---|
| 40 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.6. **GENERAL MEETINGS MINUTES.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.6.1. "**General Meeting Minutes**" means the Smart Contract adopted by the Company to automatically book and maintain the public record of the motions and voting results at General Meetings. Each proposal, proxy, vote and resolution shall only be legally effective and have binding forces on the Company and the Members upon its entry into General Meeting Minutes.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.6.2. Once a motion is created, it will be simultaneously included into General Meeting Minutes. Upon the motion's proposal, a specific timetable will be automatically created, in accordance with the voting rule adopted, so as to be used as a reference to monitor the time requirements for each step of the General Meeting procedure.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.6.3. Each ballot cast will be automatically recorded in General Meeting Minutes. This will include the User Number of the voter, total number of Voting Points represented, total number of Members delegated by the voter, and the specific attitude of the vote.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.6.4. The information stored in Genera Meeting Minutes is publicly accessible to all of the world. Everybody can check and read the information on motions, proposals, votes, resolutions, and the execution results of the resolutions booked and maintained in General Meeting Minutes.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.6.5. General Meeting Minutes will not be deleted from ArbitrumOne even after the termination of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.7. **SELF-DEALING.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Unless entered into in bad faith, no contract or transaction between the Company and one or more of its Members, Managers or officers, or between the Company and any other entity or organization in which one or more of its Members, Managers, or officers have a financial interest or are owners, managers, directors, officers, or employees, shall be voidable solely for this reason or solely because such Member, Managers or officer was present or participated in the authorization of such contract or transaction. No Member, Manager, or officer interested in such contract or transaction, because of such interest, shall be considered to be in breach of this Agreement or liable to the Company or any Member for any loss or expense incurred by reason of such contract or transaction or shall be accountable for any gain or profit realized from such contract or transaction. While not required, approval or ratification by a majority of the Members having no interest in the transaction constitutes circumstantial evidence that such transaction is permitted under this section.

---

| |
|:---|
| 41 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.8. **PERMITTED TRANSACTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Each Member, and their respective affiliates and other related parties, shall be free to engage in any activity on their own or by the means of any entity so long as neither the Member or their respective affiliates and other related parties refrains from engaging in bad faith in dealing with the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.9. **INFORMATION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pursuant to Section 17-31-112 of the Act, due to all equity transaction records and corporate governance records are available on ArbitrumOne, Members have no right to separately inspect or copy records of the Company and the Company is not obligated to furnish any records to requesting Members.

---

| |
|:---|
| 42 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 10. Management
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.1. **MANAGEMENT OF THE BUSINESS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pursuant to Section 17-29-407 of the Act and Section 17-31-109 of the Supplement, and as stated in its Articles, the Company's day to day affairs are managed by the Members. The Members are responsible for the daily operations of the business.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.2. **ORDINARY RESOLUTION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.2.1. "**Ordinary Resolution**" means a resolution passed at a General Meeting by a special majority of the Members voting in person or by proxy on the relevant motion, where the total number of Voting Points represented by the votes in favour of the motion exceeds three times the number of votes cast against it.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.2.2. The following matters shall be determined or approved by an Ordinary Resolution of General Meeting:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) to elect, replace or impeach Manager;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) to approve any budget for purchase copyrights, services or assets for the Company;

---

| |
|:---|
| 43 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) to authorize a specific User to make payment on behalf of the Company by triggering the specific API of General Keeper to transfer certain amount of ETH, USDC or CBP from General Keeper to a specific account;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) to authorize a specific User to take actions on behalf of the Company by triggering the specific API of General Keeper to call the specific smart contracts with predefined payload and/or ETH attached; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) To grant authorization to a designated User to distribute the Company's assets by activating a specific API to allocate a designated amount of USDC to each Member's internal account maintained in the Cashier, in proportion to each Member's Distribution Points.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.3. **SPECIAL RESOLUTION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.3.1. "**Special Resolution**" means a resolution passed at a General Meeting by a special majority of the Members voting in person or by proxy on the relevant motion, where the total number of Voting Points represented by the votes in favor of the motion exceeds four times the number of votes cast against it.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.3.2. The following matters shall be determined or approved by a Special Resolution of General Meeting:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) to increase or decrease capital of the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) to amend or restate Shareholders Agreement;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) to update or replace any Smart Contracts;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) to deprecate General Keeper and transfer the residual ETH and/or CBP to the new General Keeper; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) to dissolute, liquidate the Company or applying for bankruptcy for the Company or change the corporate form thereof.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.4. **MANAGERS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.4.1. "**Manager**" means the administrative officer elected by Ordinary Resolution, who have NO decision-making powers but may execute any administrative, commercial or technical matters authorized by this Agreement or approved by Ordinary Resolution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.4.2. Manager shall have the following powers:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) to approve a User as an "**Accredited Investor**" by triggering the corresponding API of List of Orders, in accordance with applicable laws and regulation, directly at its own discretion, or, indirectly as per the assessment and confirmation of other professional institutions;

---

| |
|:---|
| 44 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) to create, configure and initiate a new General Keeper, as well as all its surrounding Smart Contracts based on Templates of ComBoox, so as for the Company to move its entire corporate governance records as well as all assets to the new system, provided that the movement is subject to a prior approval of Special Resolution; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) any other executive, commercial or technical matters authorized by Shareholders Agreement, Ordinary Resolution or Special Resolution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.4.3. Candidates for the position of Manager shall be nominated by the Members authorized by the effective Shareholders Agreement through its Position Allocation Rules. The Member who nominated the Manager shall also be entitled to propose to remove it from the position. Inauguration and impeachment of Manager shall only be effective upon approval of Ordinary Resolution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.4.4. Managers shall hold office for a period of three years and are eligible for re-election.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.5. **REGISTER OF DIRECTORS.** 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.5.1. "**Register of Directors**" means the Smart Contract adopted by the Company to book and maintain the public records of Directors, Managers and other administrative officers. Any inauguration, impeachment or resignation of Directors, Managers or other officers can only be effective and legally binding on the Company and Members upon its entry into Register of Directors.

---

| |
|:---|
| 45 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.5.2. Once a User takes the relevant position, his or her User Number will be automatically booked in Register of Directors. Once a Director, Manager or other officer leaves his or her position, its User Number will be removed from Register of Directors automatically.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.5.3. The information stored in Register of Directors is publicly accessible to all of the world. Everybody can check and read the officer' User Number, title and sequence number of the position, as well as the start date and end date of the tenure concerned from Register of Directors.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.5.4. Register of Directors will not be deleted from ArbitrumOne even after the termination of the Company.

---

| |
|:---|
| 46 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 11. Compensation and Reimbursement
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11.1. **REIMBURSEMENT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subject to Section 10.2, the Company shall reimburse the Members or Managers for all direct out-of-pocket expenses reasonably incurred in managing the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11.2. **EXCULPATION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pursuant to Section 17-29-304 of the Act, NO Member or Manager shall be personally liable, directly or indirectly, for any debt, obligation, or liability of the Company by sole reason of a being a Member or Manager. Any debt, obligation, or liability of the Company is strictly and solely the liability of the Company.

---

| |
|:---|
| 47 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11.3. **INDEMNIFICATION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Company will indemnify any person who was or is a party defendant or is threatened to be made a party defendant, in a pending or completed action, suit or proceeding, whether civil, criminal, administrative, or investigation (other than an action by or in the right of the Company) by reason of the fact that the person is or was a Member of the Company, Manager or agent of the Company, or is or was serving at the request of the Company, for instant expenses (including attorney's fees), judgments, fines, and amounts paid in settlement actually and reasonably incurred in connection with such action, suit or proceeding if the Members determine that the person acted in good faith and in a manner he or she reasonably believed to be in or not opposed to the best interest of the Company, and with respect to any criminal action proceeding, has no reasonable cause to believe his or her conduct was unlawful. The termination of any action, suit, or proceeding by judgment, order, settlement, conviction, or upon a plea of "**no lo Contendere**" or its equivalent, does not in itself create a presumption that the person did or did not act in good faith and in a manner which he or she reasonably believed to be in the best interest of the Company, and, with respect to any criminal action or proceeding, had reasonable cause to believe that his or her conduct was lawful.

---

| |
|:---|
| 48 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 12. Bookkeeping
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.1. **ACCOUNTING.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.1.1. The Company's fiscal year is the calendar year.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.1.2. All of the Company's assets are on-chain public digital assets, which are defined, managed, recorded, and tracked through smart contracts in a transparent and automated manner. All assets of the Company will either be held in the Smart Contract of General Keeper (such as ETH of the Company), or be registered under the contract address thereof (such as USDC).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.1.3. In accordance with Section 6.6, the Company shall make every effort to avoid any liabilities.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.1.4. All income and expenditures of the Company in ETH or CBP shall be received or disbursed through the General Keeper, while income and expenditures in USDC shall be received or disbursed through the Cashier.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.1.5. The Company's accounting records are automatically maintained by relevant smart contracts, ensuring they are complete, accurate, and publicly accessible.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.2. **RECORDS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Members will keep the following public records in form of Smart Contracts at their specific contract address on ArbitrumOne:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Register of Constitutions**: records all editions of Shareholders Agreements with respect to their contract address, legal force status, procedural schedules for creation, review and voting, and other relevant information;

---

| |
|:---|
| 49 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Register of Directors**: records all information about the positions of Directors, Executive Officers, or Managers with respect to their candidate's User number, nominator, the Voting Rules applied for election, the start and end date of tenure, and other relevant information;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Register of Members**: records all information about Members or Shareholders with respect to their equity Shares, total Voting Points, total Distribution Points, as well as the aggregate amount of Par Value, Paid Value, Clean Paid, and other relevant information;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **General Meeting Minutes**: records all the motions created and submitted to the General Meeting for approval with respect to their proposer, proposal time, voting start and end time, voting results, proxy arrangements, executor, execution state, and other relevant information;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Register of Agreements**: records all the Investment Agreements with respect to their address, status, transaction type and detailed arrangements, parties, procedural schedules for exercising special rights, and other relevant information;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Register of Pledges**: record all Pledges with respect to their creditor, debtor, pledgor, pledged Share, pledged amount, guaranteed amount, due date of Subject Debt, guarantee period, and other relevant information;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) **Register of Shares**: record all Shares issued by the Company with respect to their Shareholders, Class, Voting Weight, issue date, paid-in deadline or actual paid-in date, Par Value, Paid Value, acquiring price, and other relevant information;

---

| |
|:---|
| 50 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) **Cashier**: records all payment and receipt transactions of the Company in USDC, as well as the USDC deposit balance of each Member arising from the Company's distributions; and.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) **List of Orders**:records all information related to the Listing Trade of Shares in USDC, including the subject Shares' Class, Certificate Number, Investors, Sell Orders, Buy Orders, Closed Deals, Expired Orders, and other relevant details.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.3. **ELECTRONIC SIGNATURE.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.3.1. By purchasing Shares of the Company, Members consent to conducting all transactions related to Shares, as well as legal actions concerning the corporate governance of the Company, electronically. The following provisions set forth the terms and conditions governing the use of electronic signatures in connection with Shares or records within the Company:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Electronic Transactions**: By purchasing Shares of the Company, Members acknowledge and agree that all documents, agreements, disclosures, and notices related to Shares or corporate governance of the Company may be executed electronically.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Consent to Use Electronic Signatures**: Purchase of Shares in the Company constitutes the voluntary consent of such Member to the use of electronic signatures for all documents and transactions associated with the Shares or the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Legal Validity**: Members understand and agree that electronic signatures used in connection with transactions related to Shares and the Company have the same legal validity and enforceability as handwritten signatures.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Technical Requirements**: Members are responsible for ensuring that they have the necessary hardware, software, and internet connectivity to electronically sign documents related to the Shares or the Company.

---

| |
|:---|
| 51 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Authentication**: Members agree to provide accurate and complete information during the electronic signature process and to take reasonable measures by themself to protect the security of the electronic signature concerned.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Legal Review**: Members or Verified Investors are strongly recommend seeking professional legal advice for any questions or concerns about the use of electronic signatures or the rights and obligations under this consent.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.3.2. Purchase of Shares in the Company shall be deemed as the Members' acceptance of these terms and consent to use electronic signatures for all transactions related to Shares or corporate governance of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.4. **MEMBER'S ACCOUNT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The aggregate amount of Distribution Points automatically booked and maintained in Register of Members for each Member shall be deemed as and construed to be such Member's capital account determined and maintained in the manner set forth in Treasury Regulation 1.704-1(b)(2)(iv), which consists of:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Member's initial capital contribution (i.e. Paid Value of the Shares in exchange of such contribution) multiply the specific Distribution Weight of the Share concerned;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) increased by any additional capital contribution made by the Member (i.e. Paid Value of the Shares in exchange of such additional contribution) multiply the specific Distribution Weight of the Shares concerned; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) decreased by Paid Value of any Shares transferred by the Member as Shareholder multiply the specific Distribution Weight of the Shares concerned.

---

| |
|:---|
| 52 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12.5. **REPORTS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Members shall look to the open records on Register of Members, Cashier and General Keeper, for the aggregate amount of Distribution Points, the balance amount of deposits in USDC, ETH and any other statements of that Member's distributive share of income and expense for income tax reporting purposes.

---

| |
|:---|
| 53 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARTICAL 13. General Matters
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.1. **DISSOLUTION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Members may dissolve the Company at any time by a Special Resolution. Per Section 17-29-701 of the Act, the Company shall be dissolved if there are no Members for a consecutive period of ninety (90) days and the underlying smart contract is unable to continue as designed.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.2. **DISTRIBUTIONS AFTER DISSOLUTION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Upon dissolution, the Company must pay its debts before distributing residual assets to Members. Members agree that any distributions occurring after the dissolution of the Company shall follow the process outlined in this Agreement and Section 17-29-708 of the Act.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.3. **MULTIPLE ORIGINALS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This Agreement may be signed in any number of counterparts, each of which will be deemed an original.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.4. **BINDING EFFECT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subject to the restrictions on transfer in this Agreement, this Agreement binds and inures to the benefit of the Members and to their respective successors, personal representatives, heirs, and assigns.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.5. **CONSTRUCTION OF HEADINGS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The headings contained in this Agreement are included solely for the reader's convenience and reference.

---

| |
|:---|
| 54 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.6. **AMENDING OPERATING AGREEMENT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.6.1. "**Shareholders Agreement**" means the Smart Contract adopted by the Company to record and maintain the public records of this Agreement, its amendments and any restated new edition thereof. In case there is any discrepancies between this Agreement and the effective Shareholders Agreement, the Shareholders Agreement shall prevail.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.6.2. Any creation, alteration or revocation of any Rules or Terms of Shareholders Agreement can only be effective and legally binding to the Company and Members at the time when the restated new Shareholders Agreement is approved by Special Resolution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.6.3. The contract address of each edition of the Shareholders Agreements will be booked and maintained in Register of Constitutions.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.6.4. A new Shareholders Agreement can only go into force upon execution by all Members or upon approval of Special Resolution. When a new Shareholders Agreement comes into force, the previous version is automatically revoked.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.7. **REGISTER OF CONSTITUTIONS.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.7.1. "**Register of Constitutions**" means the Smart Contract adopted by the Company to book and maintain the public records of Shareholders Agreements. It records all editions of Shareholders Agreements with respect to their contract address, legal force status, procedural schedules for creation, review and voting, enabling Users or smart contracts to retrieve or check the currently valid version of Shareholders Agreement, as well as all its historical revoked versions. Any creation, amendments, restatements or termination of any Shareholders Agreements can only be effective and legally binding to the Company, Members or parties concerned upon its entry into Register of Constitutions.

---

| |
|:---|
| 55 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.7.2.The information stored in Register of Constitutions is publicly accessible to all of the world. Everybody can check and read the Shareholders Agreement booked and maintained in Register of Constitutions.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.7.3.Register of Constitutions will not be deleted from ArbitrumOne even after the termination of the Company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.8. **GOVERNING LAW.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This Agreement shall be governed, construed, and administered according to the laws of the State of Wyoming, which may be amended from time to time.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.9. **COMPLIANCE WITH THE ACT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; All matters related to the operations of the Company not specifically addressed herein must be addressed in accordance with the Act and the Supplement. The Company shall comply with all other provisions of the Act and the Supplement in order to stay compliant with the law.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.10. **SEVERABILITY.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If any provision of this Agreement is determined invalid by any court of competent jurisdiction, it is the specific intent of Members that such provisions shall be modified to the minimum extent necessary to make it or its application valid and enforceable.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.11. **DISPUTES RESOLUTION.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Any disputes arising from or in connection with this Agreement shall be submitted to either the United States District Court for the State of Wyoming or in a Wyoming state court where the Company's Registered Office is located. Members irrevocably waive, to the fullest extent permitted by law, any objection the party may have to the laying of venue for any such suit, action or proceeding brought in such court. Notwithstanding the foregoing, this dispute resolution provision shall not apply to actions arising under the Securities Act of 1933, as amended, or the Securities Exchange Act of 1934, as amended, and investors shall not be deemed to have waived compliance with the federal securities laws and the rules and regulations promulgated thereunder.

---

| |
|:---|
| 56 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13.12. **ENTIRE AGREEMENT.**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This Agreement, together with the Articles of Organization (as may be amended) and all related exhibits, schedules, attachments, etc., constitute the sole and entire agreement by and among the Members. Subject to Section 2.8.5 , this Agreement supersedes all prior and contemporaneous understandings, agreements, representations, and warranties, written or oral, with respect to the subject matter.

---

| |
|:---|
| 57 |
| *[**Table of Contents**](#Toc)* |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CERTIFICATION OF MEMBERS
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The undersigned hereby agree, acknowledge, and certify that the foregoing Operating Agreement is adopted and approved by each Member. The agreement consisting of 56 pages, constitutes the Operating Agreement of Comboox DAO LLC, adopted by the Members as of March 24, 2026 .

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Members:

---

| | |
|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Signature:**  | **/s/ LI LI**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Printed Name:**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LI LI**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Points Ratio:**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Points Ratio:**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%**  |

---

---

| |
|:---|
| 58 |
| *[**Table of Contents**](#Toc)* |

---

## Ex-10

## UPDATED AND RESTATED

## CAPITAL CONTRIBUTION AGREEMENT
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This Capital Contribution Agreement (this "**Agreement**") is originally enterned into effective as of May 18, 2024, and is amended and restated on the date of March 28, 2026, by and between the following parties:

Comboox DAO LLC, a limited liability company incorporated pursuant to the Wyoming Limited Liability Company Act (the "**Act**") and the Wyoming Decentralized Autonomous Organization Supplement (the "**Supplement**"), with its entity identification number as 2023-001358375 (the "**Company**"); and

Li Li, the sole founding member of the Company and also the author who developed and deployed ComBoox Platform (the "**Contributor**").

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **RECITALS**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEREAS, the Contributor is the Founding Member of the Company and intends to invest the beneficial rights of ComBoox to collect the royalties of Templates within ArbitrumOne (the "IPR") as his capital contribution into the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEREAS, the Company intends to accept such capital contribution and to issue Shares in exchange;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEREAS the Contributor has already set certain configurations in the relevant smart contracts so as to transfer the beneficial and control rights of the IPR to the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEREAS, under US GAAP, it is difficult to recognize the value of IPR when the Founding Member contributed it to the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHEREAS both parties agree to defer the recognition of the value of the IPR and the determination of the paid-in amount of the Shares issued in exchange until the key conditions for the valuation of the IPR have been met;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NOW, THEREFORE, in consideration of the mutual covenants and agreements contained herein, the parties agree as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. **Definition**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.1. "**ArbitrumOne**" means the Ethereum Layer-2 public blockchain network operating under the name "ArbitrumOne", which is connected to the main net of Ethereum and uses a technology called "Optimistic Rollups" to improve the scalability and efficiency of Ethereum.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.2. "**CBP**" or "**ComBoox Points**" means the ERC-20 token booked in Registration Center, the primary function of which is to act as the ComBoox Community's utility token to automatically calculate, collect and transfer royalties from Users of Template Contracts to the relevant intellectual properties' holder.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.3. "**ComBoox**" or "**ComBoox Platform**" means the company book-entry platform consisting of a core smart contract called "Registration Center" and a set of Template Contracts deployed on ArbitrumOne, which is designed for equity registration and corporate statutory books-keeping, and aims to assist users to quickly establish a legal, secure, transparent, reliable and automatic system to enable the company's stakeholders to perform legal acts related to share transactions or corporate governance in a self-service mode.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.4. "**ComBoox Community**" means the open, unincorporated, loose organization of CBP holders, whose primary function is to decide, through public discussion and public voting, on whether new template contracts are suitable to be included into the ComBoox Platform as Template Contract, so as to improve or expand the functionalities thereof.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.5. "**Members** means the equity owners of the Company, who may enjoy and exercise the distribution rights to the profits and residual assets in proportion to the aggregate Distribution Points of each Member and may enjoy and exercise the voting rights in proportion to the aggregate Voting Points of each Member. For the purposes of this Agreement and in most contexts relating to the Company, the term "Member" may usually be used interchangeably with the term "Shareholder".

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.6. "**Operating Agreement**" means the Operating Agreement of the Company executed on the date of May 18, 2024, as amended and updated from time to time.

1.7. "**Par Value**" represents the subscribed contribution amount of the subject Shares, the minimum unit of which is $0.0001;

1.8. "**Paid Value**" represents the paid-in contribution amount of the subject Shares that actually received by the Company, the minimum unit of which is $0.0001;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.9. "**Registration Center**" means the core smart contract of ComBoox deployed on ArbitrumOne at the address as publicly disclosed on ComBoox's website and its white paper, which has the following primary functions:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) User Registration: to register users of ComBoox against their Prime Key;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) CBP book keeping: to record balance amount of CBP for each account holder;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Document Registration: to register Template Contracts and their clone copies according to the contract address; and

1.10."**Register of Shares**" means the Smart Contract adopted by the Company to automatically book and maintain the public record of Shares, i.e. the Certificate of Contribution concerned. Any creation, alteration or revocation of any Share can only be effective and legally binding to the Company and Members upon its entry into Register of Shares.

1.11."**Shares**" means a Member's minimum unit of ownership interests and rights in the Company, par value of which is $0.0001. Shares will be booked automatically in Register of Shares in form of a digital object called "Certificate of Contribution".

1.12."**Smart Contracts**" means the set of smart contracts adopted by the Company, from time to time, for automatically registering the equity shares of the Company and keeping records of corporate governance thereof, which shall be created and deployed by cloning Template Contracts.

1.13."**Template Contracts**"or "**Templates**" means the smart contracts adopted by the ComBoox Platform and registered in Registration Center as templates to create clone copies for its Users to deploy and use on ComBoox.

1.14."**Voting Weight**" means percentage weight of each Share when calculating the voting rights of the subject Shares, and the calculation result shall be called as "**Voting Points**" which shall be the basis to calculate the aggregate voting rights of a Member. The minimum unit of Voting Weight shall be one percent.

1.15."**Distribution Weight**" means percentage weight of each Share when calculating the distribution rights of the subject Shares, and the calculation result shall be called as "**Distribution Points**", which shall be the basis to calculate the aggregate distribution rights of a Member for distributing profits or residual assets, or assuming loss or liabilities of the Company. The minimum unit of Distribution Weight shall be one percent.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.16.Unless otherwise clearly indicates, words used in the singular include the plural, the plural includes the singular, and the neuter gender includes the masculine and the feminine.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. **Capital Contribution**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1. **Contribution.** The Contributor agrees to contribute, assign, and transfer to the Company the following intangible assets (the "**Contributed Assets**") as his capital contribution:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) beneficial rights of the Templates within the territory of ArbitrumOne on an "AS IS" basis, so that the Company may collect royalties on those Templates in form of CBP as general income;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) owner's right to Registration Center, so that the Company may collect platform commission of ComBoox in form of CBP as general income;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) owner's right to Registration Center, so that the Company may determine and adjust the total supply of CBP on ArbitrumOne; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) owner's right to the Smart Contract called "Fuel Tank", so that the Company may:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. set the Fuel Tank's selling price of CBP in USDC; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. receive selling revenue of CBP in USDC from Fuel Tank.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2. **Effective Date of Contribution.** The contribution of the Contributed Assets shall be effective as of the date of this Agreement or such earlier date on which the Contributor actually sets up the corresponding configurations in the relevant Smart Contract.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. **Issuance of Shares**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1. **Initial Shares.** In exchange for the Contributed Assets, the Company agrees to issue to the Contributor the following Shares (the "**Initial Shares**") as consideration:

---

| | | |
|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Certificate No.**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2**  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Par Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 250,000 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 50,000 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Paid Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Price of Par**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Price of Paid**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Value**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.00 USD  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Voting Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4,000 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Voting Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100000000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Distribution Weight**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100 %  |
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Total Distribution Points**  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000000  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000000  |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2. **Membership Interest.** The Contributor shall be admitted as a member of the Company with all the rights and obligations as set forth in the Operating Agreement.

**4. Evaluation of IPR**

4.1. **Conditions Precedent of Evaluation**. As long as the following conditions are all fulfilled, the Company shall have the IPR to be valued:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Company has already legally issued its equity shares to the public, as well as the CBP as a utility token;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Company has been receiving automatically collected royalties from parties other than the Founding Member for more than one year; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) a Special Resolution has been passed by the General Meeting, with the support vote of the Founding Member counted in the voting result, regarding the valuation firm to be engaged to assess the value of the IPR, as well as the valuation base date thereof.

4.2.**Paid In Capital Recognition.** When the final valuation report is issued as per Section 4.1, then:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the value of the IPR shall be recognized in the Company's account of "Intangible Assets" on the debit side, as per the arithmetic or weighed average of the upper and lower boundaries of the valuation range identified in the valuation report, whichever is higher;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the value of the IPR shall also be booked in the Company's account of "Paid In Capital" on the credit side, as paid in capital contributed by the Contributor, therefore:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A. if the value of the IPR is greater than the unpaid subscription amount of the Initial Shares, the Company shall update the Paid Value of the Initial Shares as equal to their Par Value, and shall further issue such number of new Class B Shares whose Paid Value and Par Value are all equal to the excess amount thereof; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B. if the value of the IPR is lower than the unpaid subscription amount of the Initial Shares, the Company shall update the Paid Value of the Initial Shares as equal to the recognized IPR value, and the Founding Member may elect to: (i) pay the outstanding balance amount in ETH or USDC; or (ii) cause the Company to reduce the equivalent amount of the Initial Shares in the order of Class B to Class A.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3.**No Distribution**. Before the value of the IPR is recognized in the accounts of "Intangible Assets" and "Paid In Capital" as per Section 4.2:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Company shall NOT distribute any profits or assets to the Members; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Voting Points and Distribution Points of the Initial Shares shall be calculated based on the Par Value.

5. **Representations and Warranties**

5.1. **Contributor's Representations.** The Contributor represents and warrants to the Company that:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) The Contributor is the owner of the Contributed Assets and has the right to transfer them to the Company free and clear of any liens, encumbrances, or claims;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) The Contributed Assets are transferred on an "**AS IS**" basis, and the Contributor makes no representations or warranties regarding the feasibility, security, or legal compliance of the Contributed Assets;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) The Contributor has the full power and authority to enter into this Agreement and to perform its obligations hereunder.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.2. **the Company's Representations.** the Company represents and warrants to the Contributor that:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) the Company is duly organized, validly existing, and in good standing under the laws of the State of Wyoming;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) the Company has the full power and authority to enter into this Agreement and to perform its obligations hereunder.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6. **Indemnification and Defense**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.1. **Defense of Claims.** In the event of any third party challenge or claim alleging that: (1) the Contributed Assets infringe the intellectual property rights of any third party; or (2) the Contributed Assets cause any loss or damage to any entity, the Company shall be responsible for and shall pay all costs and expenses incurred in connection with such claims, including attorneys' fees, and shall retain counsel to defend against such claims.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.2. **Indemnification.** The Company shall indemnify the Contributor in the event the Contributor is made a party or is threatened to be made a party to any pending or completed action, suit or proceeding, whether civil, criminal, administrative or investigative (other than an action by or in the right of the Company), by reason of the fact that the Contributor is or was an author of the Contributed Assets, is or was a member, manager or agent of the Company, or is or was serving at the request of the Company, against expenses (including attorneys' fees), judgments, fines and amounts paid in settlement actually and reasonably incurred in connection with such action, suit or proceeding. The termination of any action, suit or proceeding by judgment, order, settlement, conviction or upon a plea of "no lo contendere" or its equivalent shall not, of itself, create a presumption that the Contributor did or did not act in good faith and in a manner he or she reasonably believed to be in the best interests of the Company and, with respect to any criminal action or proceeding, had reasonable cause to believe that his or her conduct was lawful.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7. **Miscellaneous**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.1. **Governing Law.** This Agreement shall be governed by and construed in accordance with the laws of the State of Wyoming, without regard to its conflict of laws principles.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.2. **Disputes Resolution.** Any disputes arising from or in connection with this Agreement shall be submitted to either the United States District Court for the State of Wyoming or in a Wyoming state court where the Company's Registered Office is located. Parties irrevocably waive, to the fullest extent permitted by law, any objection the party may have to the laying of venue for any such suit, action or proceeding brought in such court.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.3. **Entire Agreement.** This Agreement constitutes the entire agreement between the parties with respect to the subject matter hereof and supersedes all prior agreements and understandings, whether written or oral, relating to such subject matter.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.4. **Amendments.** This Agreement may be amended or modified only by a written agreement signed by both parties.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.5. **Counterparts.** This Agreement may be executed in counterparts, each of which shall be deemed an original, but all of which together shall constitute one and the same instrument.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN WITNESS WHEREOF, the parties hereto have executed this Agreement as of the day and year first above written.

---

| | | | |
|:---|:---|:---|:---|
| **the Company:**  | **Comboox DAO LLC**  | **the Contributor:**  | **Li Li**  |
| **By: <br>**  | /s/ Li Li <br> Li Li  | **By: <br>**  | /s/ Li Li <br> Li Li  |
| **Title:** | the Sole Founding Member |  |  |

---

#### &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXHIBIT-I TEMPLATE SMART CONTRACTS LIST

---

| | | | |
|:---|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Smart Contract**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Contract Address on ArbitrumOne**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Smart Contract**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Contract Address on ArbitrumOne**  |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EnumerableSet  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x32Ad84b732285Fb9d36ED5c9A14874534fdFaff8  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DocsRepo  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xA5c361A235Be14Af53FCDBdF32314416798B8DcD  |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UsersRepo  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x3305D08c8D4D5650f1E6C36ed08217F6EFa0eeF4  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegCenter  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x40FF3E9DFd866a0ad408F28077d3208cbc7d9Dea  |
| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ArrayUtils  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x2f2c3361e9694a7165D838BA2251Cf5B70D65eD3  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BallotsBox  | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x67a68f5EBaf24F1ABb57DD88455d957958b2360d  |
| Checkpoints | 0x5c2CC3E89a73d8883bBDE26791CB82a5D08E483E | DelegateMap | 0xf5e3fb228dEe852854dEe6A12bEd3C44717ea72c |
| FRClaims | 0x7fb7BDD88b6b8A625302e39ae9A47e404698f730 | GoldChain | 0x843Fdd5A54d73c4beaf07FA177E9E71468f7A88A |
| RolesRepo | 0x1Da5A45fE46520d4aD60565089ddEbFD9053617f | RulesParser | 0x03E90eE2891DC62e99873E2a2830A12e63D592AF |
| SwapsRepo | 0xcFf4AAe59B9927C472aE4260857E51c70Fa4CC38 | TopChain | 0xBA08296e36755A21689541316b500bd353c9499B |
| InvestorsRepo | 0x40f07f41444c8c804b4dA0a96Dcfc9B60ce5Db9d | WaterfallsRepo | 0x0f6978127B105216A45737193CFB89F37D811971 |
| InterfacesHub | 0xBB294D570563A1DEE7B3417a974743266cfEDAE9 | CondsRepo | 0xe3adfA273ee2b067Bf9B395e85030703cc120899 |
| DTClaims | 0xC4A6FE9F80E96e6a80c84cbB807cF6af75a220D6 | FilesRepo | 0x8024b9ab358e7fb7EfEA7aBc11d59513fFc06820 |
| LockersRepo | 0x61617F4366D587A5a725f5F105Fd41edE0acCA91 | OfficersRepo | 0x5F42105299474da72946a6db4f9028CD9ebDC3Df |
| PledgesRepo | 0x093e217d5153c7081CdBB37aa937D60987Ae742d | SigsRepo | 0x096511A810c467De18B8863bCEB52A0C1Fe45516 |
| SharesRepo | 0x31296B6bC45c270645BfeD817EC00e249e927ec7 | RedemptionsRepo | 0x1887915f4A34619E5d381408135Cee37CB562fD5 |
| UsdLockersRepo | 0xDFF858473BcD121F6ADb077f8602Ae1563e6c3B1 | DealsRepo | 0xE56c4038c690e4Fee2acfb4F5521a2EE77567CFf |
| RoyaltyCharge | 0xAEE0aEEdbc6018542B5ff687c24792e16fEDA25E | OrdersRepo | 0x975511aa0A8CbCC85dA802a54D337aD26d1c4F3B |
| UsdOrdersRepo | 0x94e063459E8EaAc2524C88457248B6a0F9BfC210 | LinksRepo | 0x5c4C04925B8810571545b3df33bB4DeBb14A8375 |
| MembersRepo | 0x38c56Ab4ee1Bc4258F208b4c388CDF3A0554EE9B | MotionsRepo | 0xee77DE22B076E27A963150be2F300d748B16e02E |
| OptionsRepo | 0xf344689C2597dc4db268F9aB5E50872d7Cd40194 | CreateNewComp | 0x6D19411CED1EB03Ddfac48e96b526EC52F9f5D08 |
| CashLockers | 0xC3f98AF047028829a7bc68AF1818489C08E47841 | UsdFuelTank | 0xb83E5017BFFf9781E16F7fd8C6285c4A54397382 |

---

---

| | | | |
|:---|:---|:---|:---|
| **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Smart Contract**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Contract Address on ArbitrumOne**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Smart Contract**  | **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Contract Address on ArbitrumOne**  |
| KeepersRouter | 0x7E6eb94516Da3B2350537c2D7D6c975B03c4fE3d | GeneralKeeper | 0x2D221ed78B0A0dF0817feb6fB18863507996D8cd |
| ROOKeeper | 0x31E1BCD808bfae2d6AbcAfB77055FbF0118d7595 | ROMKeeper | 0xe2f89f52C27Ae9fB60A0F5EF9954E2616dac86D4 |
| RODKeeper | 0xF58C9F21A464E734452e4217d668468C381A2b32 | FundRORKeeper | 0xe76e2C2CF36108b6c570620bfe33F26eB74c14AE |
| Accountant | 0xfF23089f9ABE7814731e579AA349368a389C567F | SHAKeeper | 0xAac167b44e807b9a72e6FEd538C78fd9bD6854bb |
| LOOKeeper | 0x1c84FA1f1D368E38089879B4Ef4C418EeAcCDB54 | FundLOOKeeper | 0x244eC3bb14898dE4C569040Abc8F64F5173D5f41 |
| ROIKeeper | 0xa65194C4880564643802BF2E4D38e696c0F4BB9b | FundROIKeeper | 0x926bF2AE9666f831d27944d83de9Ad47fbA68Aab |
| FundAccountant | 0x7475f67a958cCda0e1C9e2B86ED657eA0d378Eef | GMMKeeper | 0x5347d31604DBFb4C9a322875EaE9Dd5604633E9B |
| FundGMMKeeper | 0x53B70c6C0360B9555811bbF1fC9774c831FB6A66 | BMMKeeper | 0x898adE37EC2e4400C810783F190e595f98fF54EA |
| ROAKeeper | 0xddd2E31f4c51f3821Df95Fb9D561616601a2FF6A | ROCKeeper | 0xf05c919308f2302A6C09dF3508d7211598D6Fa30 |
| FundROCKeeper | 0x2116D30d3DabE00d94306876986d3bBe4c13F5CF | ROPKeeper | 0x73971F549f7A76db1f2f0cc52DC152D113D2A2CF |
| InvestmentAgreement | 0xCEf7dF13E83A6904Bb5EF5f2c55ccf72657250d8 | ShareholdersAgreement | 0xC995CebEbCB956A8E7d8C8413dBF23172912F47e |
| AntiDilution | 0xf9Ca23B6BbdbB6665A30080358B48059F5bc0DCF | LockUp | 0x9F79dA582EEB39e143B56aeeEfF1403c5082ba5C |
| Alongs | 0x3b973498EF6bC2dd7673A2A10b9e7646a0e89845 | Options | 0xDcE6A9743EFCF205D9C6EdB9345E3F562e1EB006 |
| RegisterOfAgreements | 0x8866CB54C8eeE763Af1bE8a419C2224e39dB037d | RegisterOfDirectors | 0x028576ea709aD723978f38e050B9b895053C4818 |
| MeetingMinutes | 0x5A879f585593A46e2Fc333e6AaA34059397f9550 | RegisterOfConstitution | 0xe0AE2376A3D0B9B5CBF806d81823eF78d25FAE88 |
| RegisterOfOptions | 0xD38EA3870ea9fB82feA1716f9Af10Cbb840abDE0 | RegisterOfPledges | 0x7507E0c0B48f4ee13703DFC49fc83BA2e0D3C382 |
| RegisterOfShares | 0xBF48762F0B60617C0523042dde1490e6bF2C26A4 | RegisterOfMembers | 0xc2A7D2f3FF268B086e796E02a80742F439aF516d |
| RegisterOfInvestors | 0x72c604b95ACD45b1a472eBFA69C28A478B38Da19 | ListOfOrders | 0xaaF9B00D798DF0E83d50C0B7F3ec4bDdc87a540c |
| Cashier | 0xa5b9b11BF011B13750351F167334151Cc5346704 | RegisterOfRedemptions | 0x21e5081f0e369cCC141aa3798c119Bc68455aF90 |

---

## Ex-23

&nbsp;&nbsp;&nbsp;&nbsp; **CONSENT OF INDEPENDENT REGISTERED PUBLIC ACCOUNTING FIRM**

&nbsp;&nbsp;&nbsp;&nbsp; We hereby consent to the inclusion in this Registration Statement on Form S-1 of Comboox DAO LLC (the "Company") of our report dated March 12, 2025, with respect to the financial statements of the Company and the related notes as of and for the year ended December 31, 2024, which appears in this Registration Statement.

&nbsp;&nbsp;&nbsp;&nbsp; We also consent to the reference to our firm under the heading "Experts" in such Registration Statement.

&nbsp;&nbsp;&nbsp;&nbsp; /s/ Kustov & Associates, Inc.

&nbsp;&nbsp;&nbsp;&nbsp; San Francisco, California <br> March 12, 2025

## Ex-32

![](comboox_s1img1.jpg)

# ComBoox: A Blockchain-Based Company Book-Entry Platform

### **LI LI, Founding Member of Comboox DAO LLC** 

## **System Overview** 
**ComBoox** is a blockchain-based company records-keeping platform designed for registering equity shares and keeping corporate statutory books, which is aimed to assist users to quickly establish a legal, secure, transparent and reliable smart contracts system, so as to enable investors, shareholders, executive officers, business partners to conduct legal acts around equity rights in a self-service mode, including share subscription, share transfer, share pledge, paying consideration, signing contracts, proposing, voting, nominating, inauguration and resignation etc.

**Unlike** pure share certificates tokenization, **ComBoox** does **NOT** rely on legal documents to restrict off-chain behavior. Instead, it uses smart contracts to fully control **ALL** share transactions and corporate governance activities, enabling rights holders to conduct legal acts on chain in self-service mode, completely eliminating the possibility of default or violation.

Therefore, **ComBoox** provides a brand-new concept and solution to solve the problems of "**Insiders Control**" or "**Misleading Statements**" that have plagued the capital markets for many years, and may completely realize:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) right holders may **directly exercise** rights;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) obligors have **no chance** to default or violate;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **real-time** disclosure of full information; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **tokenization** of equity shares in a **complete** sense.

---

| | |
|:---|:---|
| Dapp (Arbitrum One) | https://comboox.vercel.app |
| Dapp Demo (Arbitrum Sepolia) | https://comboox-sepolia.vercel.app |
| Smart Contract Source Code | https://github.com/paul-lee-attorney/comboox |
| User Interface Source Code | https://github.com/paul-lee-attorney/comboox-client_V2 |
| Documentation | https://comboox.gitbook.io/whitepaper |

---

i

 **TABLE OF CONTENTS**

---

| | |
|:---|:---|
|  | **Page** |
| [1. System Overview](#System Overview) | 1 |
| [1.1. "Pain Points" of Corporate Governance](#Pain Points of Corporate Governance) | 3 |
| [1.2. Blockchain Solution](#Blockchain Solution) | 4 |
| [1.3. Tokenization and Company Evaluation](#Tokenization and Company Evaluation) | 6 |
| [1.4. Features and Advantages](#Features and Advantages) | 7 |
| [2. Computational Control Model](#Computational Control Model) | 8 |
| [2.1. State](#State) | 8 |
| [2.2. Transition Process](#Transition Process) | 8 |
| [2.3. Conditions and Process](#Conditions and Process) | 9 |
| [2.4. Write Operation Scripts](#Write Operation Scripts) | 9 |
| [3. System Architecture](#System Architecture) | 11 |
| [3.1. Registers](#Registers) | 12 |
| [3.2. Bookkeepers](#Bookkeepers) | 23 |
| [3.3. Shareholders Agreement](#Shareholders Agreement) | 29 |
| [3.4. Investment Agreement](#Investment Agreement) | 55 |
| [4. Identification and Access Control](#Identification and Access Control) | 60 |
| [4.1. Access Control Mechanism on smart contracts' level](#Access Control Mechanism) | 61 |
| [4.2. Commands Routing Mechanism within the company](#Commands Routing Mechanism) | 68 |
| [4.3. Users Identification Mechanism for entire platform](#Users Identification Mechanism) | 70 |
| [5. Templates and Version Control](#Templates and Version Control) | 77 |
| [5.1. Proxying and Cloning Technology](#Proxying and Cloning Technology) | 77 |
| [5.2. Documents Mapping of Reg Center](#Documents Mapping of Reg Center) | 80 |
| [5.3. Types of Template Contracts](#Types of Template Contracts) | 81 |
| [6. External Write APIs](#External Write APIs) | 83 |
| [6.1. APIs routed to ROC Keeper](#APIs routed to ROC Keeper) | 83 |
| [6.2. APIs routed to ROD Keeper](#APIs routed to ROD Keeper) | 89 |
| [6.3. APIs routed to BMM Keeper](#APIs routed to BMM Keeper) | 95 |
| [6.4. APIs routed to ROM Keeper](#APIs routed to ROM Keeper) | 106 |
| [6.5. APIs routed to GMM Keeper](#APIs routed to GMM Keeper) | 113 |
| [6.6. APIs routed to ROA Keeper](#APIs routed to ROA Keeper) | 125 |
| [6.7. APIs routed to ROO Keeper](#APIs routed to ROO Keeper) | 135 |
| [6.8. APIs routed to ROP Keeper](#APIs routed to ROP Keeper) | 141 |
| [6.9. APIs routed to SHA Keeper](#APIs routed to SHA Keeper) | 150 |
| [6.10. APIs routed to Accountant](#APIs routed to Accountant) | 157 |
| [6.11. APIs routed to ROI Keeper](#APIs routed to ROI Keeper) | 162 |
| [6.12. APIs routed to LOO Keeper](#APIs routed to LOO Keeper) | 171 |
| [7. Scenarios for Equity Transactions and Corporate Governance](#Scenarios for Equity Transactions and Corporate Governance) | 179 |
| [7.1. Apply for Qualified Investor Status](#Apply for Qualified Investor Status) | 181 |
| [7.2. Update Shareholders' Agreement](#Update Shareholders' Agreement) | 183 |
| [7.3. Trade Equity by Agreement](#Trade Equity by Agreement) | 186 |
| [7.4. Trade Equity by Listing (in USDC)](#Trade Equity by Listing (in USDC)) | 190 |
| [7.5. Elect or Remove Directors](#Elect or Remove Directors) | 194 |
| [7.6. Elect or Remove Officers](#Elect or Remove Officers) | 197 |
| [7.7. Transfer Fund](#Transfer Fund) | 199 |
| [7.8. Distribute Profits](#Distribute Profits) | 203 |
| [7.9. Call External Smart Contracts](#Call External Smart Contracts) | 205 |
| [7.10. Pledge Shares for Debts](#Pledge Shares for Debts) | 209 |
| [7.11. Execute Special Investor Rights of SHA](#Execute Special Investor Rights of SHA) | 212 |
| [7.12. Execute Options](#Execute Options) | 216 |
| [8. CBP and Economic Model](#CBP and Economic Model) | 219 |
| [8.1. Rate of Royalty](#Rate of Royalty) | 220 |
| [8.2. Collection of License Fee](#Collection of License Fee) | 220 |
| [8.3. Commission of Platform](#Commission of Platform) | 220 |
| [8.4. Promotion Policy](#Promotion Policy) | 221 |
| [8.5. New User's Gift](#New User's Gift) | 222 |
| [8.6. Transfer of Smart Contracts' Copyright](#Transfer of Smart Contracts' Copyright) | 222 |
| [8.7. Transfer of System's Ownership](#Transfer of System's Ownership) | 223 |
| [9. Financial Records](#Financial Records) | 224 |
| [9.1. Exchange Rate](#Exchange Rate) | 224 |
| [9.2. CBP Flow Records](#CBP Flow Records) | 226 |
| [9.3. USDC Flow Records](#USDC Flow Records) | 227 |
| [10. Key Legal Issues](#Key Legal Issues) | 228 |
| [10.1. Digital Identification Mechanism VS. Real-Name Requirements](#Digital Identification Mechanism) | 228 |
| [10.2. Real Time Information Disclosure VS. Trade Secret Protection](#Real Time Information Disclosure) | 230 |
| [10.3. Internal Book-Entry Records VS. Public Registration Information](#Internal Book-Entry Records) | 232 |
| [10.4. Give Legal Effects to On-Chain Books](#Give Legal Effects to On-Chain Books) | 234 |
| [11 Software License](#Software License) | 236 |

---

ii

**1. System Overview**

Since human civilization has entered the 21st century, most wealth exists in the form of book-entry interests. In order to regulate this wealth and transaction activities, various commercial legal rules, organizational by-laws and trading contracts have been established, and different centralized agents are involved in commercial activities. However, in the event that these rules, laws or contracts are violated, people can only rely on ex post facto judicial remedies to seek compensation for their losses. Such Judicial remedies have proven to be excessively expensive and time-consuming, and insufficient to fully recover for the incurred losses.

The emergence of blockchain technology provides a brand-new set of solutions for human beings, which is to define the bookkeeping rules and transaction arrangements for book-entry interests in codes, and to use distributed systems and cryptography to fix these bookkeeping records in terms of content and time sequence. In this way, the possibility of non-compliance or default can be eliminated by means of ex ante prevention.

By implementing the basic concepts of "code is law" and "decentralization", the legal logic defined by norms and contract terms can be realized by rigid code logic, and the human management of centralized organization can be replaced by automated consensus mechanisms and smart contracts. This establishes an automated asset bookkeeping and transaction management model, where rights holders can directly manage and dispose of their assets without having to rely on any intermediaries or counterparties. The only thing that needs to be considered is the logic and algorithms of the predefined smart contracts.

In all kinds of book-entry interests, apart from deposit, corporate equity is probably the most important and critical class of assets. The company is the vehicle for a variety of assets and the subject of capital investment. The external action of companies is an important part of modern business, and their internal governance involves the interests of many investors. Therefore, company equity is the key link between capital and assets, business activities and corporate governance.

---

| |
|:---|
| 1 |
| *[**Table of Contents**](#Toc)* |

---

Using blockchain and smart contract technology to automate the bookkeeping of corporate equity and governance behaviors, and replacing the legal logic of ex post facto judicial remedies with the rigid code logic of ex ante prevention, these concepts will be of great significance to the modern business in reducing disputes, eliminating irregularities, improving transparency, and enhancing efficiency.

Based on the above concepts, we developed and deployed the ComBoox platform.

**ComBoox** is a blockchain-based company records-keeping system to assist users to quickly establish a legal, secure, transparent, and reliable smart contracts system for automatically registering equity shares and keeping records of corporate governance.

---

| |
|:---|
| 2 |
| *[**Table of Contents**](#Toc)* |

---

 **1.1. "Pain Points" of Corporate Governance**

The capital markets have long been suffered from some "pain points" of corporate governance, which can be summarized into following three aspects:

**(1) Right holders can hardly exercise their rights smoothly**

No matter it is to replace executive managers, to change accounting policies, to convene an extraordinary shareholders' meeting, or to enforce a Put Option, Drag-Along, or Anti-Dilution of the shareholders agreement, when exercising their shareholders rights, investors will often inevitably need the cooperation of other parties like company secretary, actual controller, executives, registration agents and even the official registration offices. Sometimes, this could be very difficult and challenging, not only time-consuming and costly, but also may change into a protracted shareholders' disputes, even lead to a serious consequences like business shutdown.

**(2) Obligors sometimes deliberately violate their obligations**

During an equity share transaction, buyer may delay paying of the consideration, whereas, seller may maliciously retain the company's seal, license, or postpone the closing process; In a company's daily operation, managers may abuse their authority, actual controller may misappropriate operational funds... To sum up, all of such bad behaviors can be categorized as "acts of breach", either breaching a share transaction contract (such as share subscription agreement or share transfer agreement), or violating a constitutional document of the company (e.g. the articles of association, bylaws, shareholders agreement, or operational agreement).

**(3) Untimely and inaccurate information disclosure** 

Transfer of control rights, private placements, acquiring material voting shares exceeding reporting threshold ratio, such significant changes of shareholding structure of a company, as well as the company's governance records like shareholders meeting resolutions or board meeting minutes etc., all these information are crucial indicators for assessing a company's future strategy, profitability, and valuation of equity shares, and will directly influence the investment decisions of investors and the valuation of the company concerned. Untimely, inaccurate or incomplete information disclosure often becomes major reasons that caused shareholders disputes or securities transaction disputes.

---

| |
|:---|
| 3 |
| *[**Table of Contents**](#Toc)* |

---

 **1.2. Blockchain Solution**

The emergence of blockchain and smart contract technology presents a good opportunity to solve the above-mentioned problems. If using blockchain to book equity shares, and using smart contracts to define and automatically control share transactions and corporate governance activities, then, the potential human influences can be excluded to an extreme extent, so as to realize:

**(1) Rights holders directly exercise rights**

Rights holders may, by means of electronic signature technology, have their identities verified and send out their instruction calls of exercising rights, by triggering the specific API of smart contracts to call the relevant functions and methods, directly update the Register of Shares, Meeting Minutes, and other Book-Entry records in accordance with the predefined conditions and procedures, thereby achieves the desired legal consequences accordingly. Throughout this process, there is no need to seek assistance or engagement of secretary, agent, authority or any third party, to exercise rights as a representative, proxy or delegate, so that the actions of exercising rights will not be intervened or controlled by any third party.

**(2) Obligors have no chance to default**

The reason why defaults occurred is because the realization of contractual rights depends on obligors to make cooperation behaviors actively. When turning over the control rights of book-entry records like Register of Shares and Meeting Minutes to smart contracts for automatic operation, then, a lot of traditional "claim rights" requiring cooperation of obligors will be changed into "disposal rights" that can be unilaterally exercised by right holder, therefore, the possibility of defaults will be completely eliminated.

---

| |
|:---|
| 4 |
| *[**Table of Contents**](#Toc)* |

---

As for the constitutional documents like articles of association, bylaws or shareholders agreement, many defaults are actually Ultra Vires behaviors (either substantive or procedural) of the controlling shareholder or executive managers. Smart contracts have rigid and strict programming logic, and can precisely control the timeline, permissions, procedures and other conditions of business operations, which may fundamentally eliminate the said Ultra Vires challenges to corporate governance.

**(3) Real-time information disclosure**

Corporate governance behaviors can generally be categorized as signing documents, voting, paying consideration, nominating candidates, taking position, resigning and several other types, and the existing technologies are fully capable to implement all of these legal actions that takes "Expressing Intent" or "Updating Rights and Interests" as its core attributes on blockchain, i.e. using blockchain to book the digital tracks of these legal behaviors, and using smart contracts to automatically verify identity of the actors, determine the conditions precedent, and control the process and procedures.

Blockchain is a distributed system that synchronizes information in real-time among the nodes, therefore, legal behaviors conducted on blockchain will complete the information disclosure at the same time when updating the book-entry records or realizing the legal consequences concerned. Legal behavior and information disclosure are not separate activities any more, which will be integrated together and have no time lag or contents differences. Therefore, current disclosure issues like untimely delay, misrepresentation, or misleading statements etc. should become impossible to occur.

---

| |
|:---|
| 5 |
| *[**Table of Contents**](#Toc)* |

---

 **1.3. Tokenization and Company Evaluation**

Equity share is a typical kind of book-entry interests, and also an important trading object of capital markets.

**(1) IPO creates capital premium**

A company may select to list its shares on an open market, so as to facilitate public investors to buy in and sell out its equity more conveniently, which means to release the liquidity of its equity greatly, and as a direct consequence, the equity value of the company or its stock price will usually increase within a very short period of time dramatically. This is the basic principle that IPO can create capital premium.

**(2) Tokenization of Equity Shares** 

Similarly, if adopting blockchain to book companies' equity, it will become very convenient to use cryptocurrencies or Central Bank Digital Currencies to pay the equity consideration, and, under the automatic control of smart contracts, some concepts like "Delivery Versus Payment", "Payment as Settlement" and "No Clearing Transfer" etc. can be fully realized with a fairly low cost and much higher efficiency.

**(3) Web 3.0 Capital Markets**

However, tokenization of equity shares does not simply mean to define a structured digital object representing equity value or capital contribution, or to move the booking records of "Register of Shareholders" or "Register of Members" onto the blockchain. What's more important is to coordinate all facts that may influence the equity value of a company into the automatic system of blockchain, and to enable smart contracts to get full control over all activities of share transaction and corporate governance, so as to ensure all those legal behaviors can be carried out strictly in line with the internal governance rules (like the articles of association or bylaws), as well as the external governing laws and regulations (such as the Securities Act and the Securities Exchange Act). So that, the capital markets can rely on the rigid logic of smart contracts to automatically control the creation, change, exercising, and elimination of the equity rights of shareholders, i.e., by implementing the concept of "Code Is Law" to establish a decentralized and trustless "Web3.0 Capital Market" in real sense.

---

| |
|:---|
| 6 |
| *[**Table of Contents**](#Toc)* |

---

 **1.4. Features and Advantages**

To accommodate different demands, **ComBoox** adheres to the concept of "**dynamic configuration and plug-and-play**" to maintain the flexibility and scalability of its smart contract system. Specifically:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Operation Model**: is compatible to both the **members management model** of **DAO**, as well as the **managers management model** for regular companies.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Number of Owners**: the number of owners can be limited to 50 or fewer (for small-scale **limited liability companies**), or expanded to an unlimited level of public **listed companies**.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Equity Classification**: can implement ordinary equity structure of "**same shares, same rights**", and also can flexibly define **special classes of shares** so as to grant special rights or voting weights to them;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Governance Rules**: can flexible set general corporate governance rules like motion proposal rules, voting rules, (executive officials) position allocation rules, (affiliated members) grouping rules, and (equity) listing rules, and also can set out **special terms of members' right**, such as **First Refusal**, **Tag Along**, **Drag Along**, **Call Option**, **Put Option**, **Anti-Dilution**, **Lock Up**, so as to satisfy the requirements of private equity investment.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **Payment Methods**: the consideration for equity, pledge, or option can be paid on-chain with **native cryptocurrency**, or be paid off-chain or cross-chain with **fiats** or **central bank digital currencies**, by using technologies like **hash time lock**, so as to fully compatible with all kinds of payment requirements.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Legal Entities:** can book equities of the **direct invested companies**, and can also make further investments by controlling the first-tier companies to set up their **subsidiaries**, and to **indirectly control** the corporate governance activities of subsidiaries as well, so that forming a **complex network shareholding structure** accordingly.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) **Version Upgrades**: can create records-keeping system based on existing smart contract templates, and also allows **customization or upgrades to** new templates to satisfy special requirements.

---

| |
|:---|
| 7 |
| *[**Table of Contents**](#Toc)* |

---

**2. Computational Control Model**

**ComBoox** adopts the "**state machine model**" to simulate and control the share transactions and corporate governance activities, specifically:

 **2.1. State**

Information contents of the book-entry registers at each moment are deemed as different **states**, which will be stored in the smart contracts of **Registers** (such as **Register of Shares, Register of Members** and **Meeting Minutes** etc.).

 **2.2. Transition Process**

Share transactions, corporate governance behaviors and other relevant legal actions are considered as the **transition process** between different **states** of the book-entry **Registers**, and which will be defined and controlled by the smart contracts of **Bookkeepers** with respect to the subject's identity, action process, terms and conditions, as well as legal consequences thereof.

![](whitepaper_img1.jpg)

---

| |
|:---|
| 8 |
| *[**Table of Contents**](#Toc)* |

---

 **2.3. Conditions and Process**

The corporate governance rules (such as voting rules, nomination rules and other rules stipulated in the bylaws or other similar company constitutional documents), as well as the shareholders' special rights (such as First Refusal, Tag-Along and Drag Along, Anti-Dilution, Put Option and Call Option etc.) are deemed as **rules, conditions and procedures** to be followed in the **transition process** between the different **states**, which will be defined by the smart contract of **Shareholders Agreement** with respect to values of **attributes, duration** or **determination thresholds** for the said rules or rights. In runtime, **Shareholders Agreement** will timely answer the queries sent from **Bookkeepers** so as to provide parameters to automatically control the execution process of the legal behaviors concerned.

 **2.4. Write Operation Scripts**

**Investment Agreement** can be deemed as a special script or batch file consisting of a series of write operation commands to cause the states transition of **Register of Shares**. And, the transaction factors defined in **Investment Agreement** as attributes of object **Deal** (such as subject equity, parties concerned, quantities and price etc.) can be deemed as input parameters (or specific trigger events) of the said write operations concerned, which will be executed by the relevant **Bookkeepers** automatically.

---

| |
|:---|
| 9 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Data Structure of Deal** |
| <br> struct Head{<br> uint8 typeOfDeal;<br> uint16 seqOfDeal;<br> uint16 preSeq;<br> uint16 classOfShare;<br> uint32 seqOfShare;<br> uint40 seller;<br> uint32 priceOfPaid;<br> uint32 priceOfPar;<br> uint48 closingDeadline;<br> uint16 votingWeight;<br> }<br>struct Body {<br> uint40 buyer;<br> uint40 groupOfBuyer;<br> uint64 paid;<br> uint64 par;<br> uint8 state;<br> uint16 para;<br> uint16 distrWeight;<br> bool flag;<br> }<br>struct Deal {<br> Head head;<br> Body body;<br> bytes32 hashLock;<br> }<br>|

---

---

| |
|:---|
| 10 |
| *[**Table of Contents**](#Toc)* |

---

**3. System Architecture**

**ComBoox** consists of four major types of smart contracts: **Registers**, **Bookkeepers, Shareholders Agreements** and **Investment Agreements**.

**Diagram of System Architecture**

![](whitepaper_img2.jpg)

---

| |
|:---|
| 11 |
| *[**Table of Contents**](#Toc)* |

---

 **3.1. Registers**

**Registers** defined registration books to record the various book-entry interests (such as equities, pledges, options) or corporate governance documents (such as general meeting minutes and board meeting minutes). The core functions of which are to define the attributes composition of various bookkeeping objects, and the data structure, parameter and logical verification algorithm thereof, as well as the basic methods and APIs for adding, deleting, modifying and querying these objects.

**3.1.1. Functions of Registers**

When users exercise their rights:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) in accordance with the calling commands sent or routed from **Bookkeepers**, **Registers** will retrieve and provide specific states of book-entry interests or historical records of legal behaviors;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Based on the above feedback, **Bookkeepers** will verify or determine whether the conditions for exercising certain rights are fulfilled, or calculates values of the relevant parameters concerned; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Bookkeepers** will call specific **Register** to update the states of specific book-entry interests, or store the contents, consequences or historical records of the legal behaviors concerned.

---

| |
|:---|
| 12 |
| *[**Table of Contents**](#Toc)* |

---

For example, when a director takes his/her seat, he/she needs to call the "Take Seat" API of **General Keeper,** inputting the shareholders meeting resolution's sequence number which approved him/her to be director and the position number of the director, and then:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **General Keeper** will query and obtain the user number of the message sender account, and call the "Take Seat" API of **Register of Directors Keeper ("ROD Keeper")** so as to process the subsequent actions thereof;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **ROD Keeper** will firstly call the **General Meeting Minutes ("GMM")** to verify: whether the type of motion is to elect director and whether the motion has been approved;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) If the type and approval status of the motion are all verified, **ROD Keeper** will further call the **GMM** to verify whether the user number of the message sender is equal to the candidate's number as defined in the position's description of the motion of nomination, if yes, then update the state of the motion into "executed";

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) If the message sender's identity is verified, **ROD Keeper** will call **Register of Directors ("ROD")** to record the user number, timestamp, as well as the block number concerned, so as to complete the entire process of inauguration.

---

| |
|:---|
| 13 |
| *[**Table of Contents**](#Toc)* |

---

![](whitepaper_img3.jpg)

In the above process, **GMM** and **ROD** are the two types of **Registers. GMM** provides the motion's type and its voting results by answering the query request of **ROD Keeper**, so as to determine whether the conditions for exercising the rights have been fulfilled, thereafter, verifies the caller's identity against the user number of the motion's candidate. Then, **ROD Keeper** writes the user number, date and block number of inauguration into **ROD**, so as to write down the action records of "inauguration".

---

| |
|:---|
| 14 |
| *[**Table of Contents**](#Toc)* |

---

**3.1.2. Types of Registers**

Based on the types of information recorded, **Registers** can be divided into two basic categories: **Registers** of book-entry interests and **Registers** of governance records, which includes:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Register of Constitutions ("ROC")**: records all editions of **Shareholders Agreements** with respect to their address, legal force status, procedural schedules for creation, review and voting etc., so as to enable users or smart contracts to retrieve or check the currently valid version of **Shareholders Agreement**, as well as all its historical revoked versions;

---

| |
|:---|
| **Structure of Object File** |
| <br> struct Head{<br> uint48 circulateDate;<br> uint8 signingDays;<br> uint8 closingDays;<br> uint16 seqOfVR;<br> uint8 frExecDays;<br> uint8 dtExecDays;<br> uint8 dtConfirmDays;<br> uint48 proposeDate;<br> uint8 invExitDays;<br> uint8 votePrepareDays;<br> uint8 votingDays;<br> uint8 execDaysForPutOpt;<br> uint64 seqOfMotion;<br> uint8 state;<br> }<br>struct Ref {<br> bytes32 docUrl;<br> bytes32 docHash;<br> }<br>struct File {<br> bytes32 snOfDoc;<br> Head head;<br> Ref ref;<br> }<br>struct Repo {<br> mapping(address => File) files;<br> EnumerableSet.AddressSet filesList;<br> }<br>|

---

---

| |
|:---|
| 15 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Register of Directors ("ROD")**: records all information about the positions of directors or managers with respect to their candidate's user number, nominator, the voting rules applied for election, the start and end date of tenure etc., so as to enable users or smart contracts to search or verify the identity, authorities or duties of executive officers;

---

| |
|:---|
| **Structure of Object Position** |
| <br> struct Position{<br> uint16 title;<br> uint16 seqOfPos;<br> uint40 acct;<br> uint40 nominator;<br> uint48 startDate;<br> uint48 endDate;<br> uint16 seqOfVR;<br> uint16 titleOfNominator;<br> uint16 argu;<br> }<br>|

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Board Meeting Minutes ("BMM")**: records all the motions submitted to the Board of Directors for approval with respect to their proposer, proposal date, start and end time of voting, voting results, delegate arrangements, executor, execution status, etc, so as to enable users or smart contracts to check or verify the motions of Board;

---

| |
|:---|
| **Structure of Object Motion** |
| <br> struct Head{<br> uint16 typeOfMotion;<br> uint64 seqOfMotion;<br> uint16 seqOfVR;<br> uint40 creator;<br> uint40 executor;<br> uint48 createDate;<br> uint32 data;<br> }<br>struct Body {<br> uint40 proposer;<br> uint48 proposeDate;<br> uint48 shareRegDate;<br> uint48 voteStartDate;<br> uint48 voteEndDate;<br> uint16 para;<br> uint8 state;<br> }<br>struct Motion {<br> Head head;<br> Body body;<br> RulesParser.VotingRule votingRule;<br> uint contents;<br> }<br>|

---

---

| |
|:---|
| 16 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Register of Members ("ROM")**: records all information about members or shareholders with respect to their equity shares, voting rights, amount of subscribed / paid-in capital, so as to enable users or smart contracts to check or verify the shareholding status of a member;

---

| |
|:---|
| **Structure of Object Member** |
| <br> struct Checkpoint{<br> uint48 timestamp;<br> uint16 rate;<br> uint64 paid;<br> uint64 par;<br> uint64 points;<br> }<br>struct History {<br> mapping(uint256 => Checkpoint) checkpoints;<br> }<br>struct Member {<br> Checkpoints.History votesInHand;<br> // class => seqList<br> mapping(uint => EnumerableSet.UintSet) sharesOfClass;<br> EnumerableSet.UintSet classesBelonged;<br> }<br>|

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **General Meeting Minutes ("GMM")**: records all the motions submitted to the General Meeting of Shareholders for approval with respect to their proposer, proposal time, voting start and end time, voting results, delegate arrangements, executor, execution state, etc, so as to enable users or smart contracts to check or verify the relevant information of the motion submitted to General Meeting of Members;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Register of Agreements ("ROA")**: records all the **Investment Agreements** with respect to their address, status, transaction type and detailed arrangements, parties, procedural schedules for exercising special rights, so as to enable users or smart contracts to check and retrieve the relevant **Investment Agreements**, and, to enable the parties concerned to execute the deals under these **Investment Agreements**. Moreover, **ROA** also can mock the transaction results and calculate the ultimate controller of the company after closing of the deals concerned, so as to anticipate whether the conditions of drag-along or tag-along will be triggered (i.e. change of controlling power);

---

| |
|:---|
| 17 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) **Register of Options ("ROO")**: record all information of (call / put) options with respect to their right holders, obligors, execution period, closing period, trigger conditions, exercise price, class and amount of the subject equity, etc;

---

| |
|:---|
| **Structure of Object Option** |
| <br> struct Cond{<br> uint32 seqOfCond;<br> uint8 logicOpr;<br> uint8 compOpr1;<br> uint64 para1;<br> uint8 compOpr2;<br> uint64 para2;<br> uint8 compOpr3;<br> uint64 para3;<br> }<br>struct Head {<br> uint32 seqOfOpt;<br> uint8 typeOfOpt;<br> uint16 classOfShare;<br> uint32 rate;<br> uint48 issueDate;<br> uint48 triggerDate;<br> uint16 execDays;<br> uint16 closingDays;<br> uint40 obligor;<br> }<br>struct Body {<br> uint48 closingDeadline;<br> uint40 rightholder;<br> uint64 paid;<br> uint64 par;<br> uint8 state;<br> uint16 para;<br> uint16 argu;<br> }<br>struct Option {<br> Head head;<br> Cond cond;<br> Body body;<br> }<br>|

---

---

| |
|:---|
| 18 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) **Register of Pledges ("ROP"):** record all pledges attached to the equity shares with respect to their creditor, debtor, pledgor, pledged amount, guaranteed amount, debt expiration date, guarantee period etc.;

---

| |
|:---|
| **Structure of Object Pledge** |
| <br> struct Head{<br> uint32 seqOfShare;<br> uint16 seqOfPld;<br> uint48 createDate;<br> uint16 daysToMaturity;<br> uint16 guaranteeDays;<br> uint40 creditor;<br> uint40 debtor;<br> uint40 pledgor;<br> uint8 state;<br> }<br>struct Body {<br> uint64 paid;<br> uint64 par;<br> uint64 guaranteedAmt;<br> uint16 preSeq;<br> uint16 execDays;<br> uint16 para;<br> uint16 argu;<br> }<br>struct Pledge {<br> Head head;<br> Body body;<br> bytes32 hashLock;<br> }<br>|

---

---

| |
|:---|
| 19 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) **Register of Shares ("ROS")**: record all equity shares issued by the company with respect to their shareholders, class, voting weight, distribution weight, issue date, paid-in deadline / date, par value, paid-in amount, issue price and so on;

---

| |
|:---|
| **Structure of Share** |
| <br> struct Head{<br> uint16 class;<br> uint32 seqOfShare;<br> uint32 preSeq;<br> uint48 issueDate;<br> uint40 shareholder;<br> uint32 priceOfPaid;<br> uint32 priceOfPar;<br> uint16 votingWeight;<br> uint8 argu;<br> }<br>struct Body {<br> uint48 payInDeadline;<br> uint64 paid;<br> uint64 par;<br> uint64 cleanPaid;<br> uint16 distrWeight;<br> }<br>struct Share {<br> Head head;<br> Body body;<br> }<br>|

---

---

| |
|:---|
| 20 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) **List of Orders** (**"LOO"**): record all information about listing trade of shares in USDC with respect to the subject shares class, sequence number, investors, limited sell orders, limited buy orders, and deals closed etc.

---

| |
|:---|
| **Structure of Order** |
| <br> struct Node{<br> uint32 prev;<br> uint32 next;<br> uint40 issuer;<br> uint64 paid;<br> uint32 price;<br> uint48 expireDate;<br> uint16 votingWeight;<br> bool isOffer;<br> }<br>struct Data{<br> uint16 classOfShare;<br> uint32 seqOfShare;<br> uint40 groupRep;<br> uint16 votingWeight;<br> uint16 distrWeight;<br> uint128 margin;<br> bool inETH;<br> address pubKey;<br> uint48 date;<br> uint48 issueDate;<br> }<br>struct Order{<br> Node node;<br> Data data;<br> }<br>|

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) **Register of Investors** (**"ROI"**): record all information about investors who intend to invest in the Company with respect to their user number, group representative's user number, registration date, verifier's user number, approved date, registration state, and hash value of ID documents.

---

| |
|:---|
| 21 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of Investor** |
| <br> struct Investor{<br> uint40 userNo;<br> uint40 groupRep;<br> uint48 regDate;<br> uint40 verifier;<br> uint48 approveDate;<br> uint32 data;<br> uint8 state;<br> bytes32 idHash;<br> }  |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) **Bank**: the official address of the smart contract deployed by Circle Internet Financial that automatically records users' USDC balances and transaction records.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (13) **Cashier:** record all USDC payment transactions related to the Company, including details of the payer, payee, purpose of payment, authorization for USDC collection, and other relevant information.

---

| |
|:---|
| **Structure of Transfer Authorization** |
| <br> struct TransferAuth{<br> address from;<br> address to;<br> uint256 value;<br> uint256 validAfter;<br> uint256 validBefore;<br> bytes32 nonce;<br> uint8 v;<br> bytes32 r;<br> bytes32 s;<br> }<br>|

---

&nbsp;&nbsp;&nbsp;&nbsp; (14) **Register of Redemptions ("ROR")**: records all information relating to redemption requests for redeemable fund shares and the execution thereof, including, without limitation, the class number, share sequence number, net asset value (NAV) price, shareholder user number, amount of paid, redemption value in USDC, and the sequence of the relevant request package.

---

| |
|:---|
| **Structure of Redemption Request** |
| <br> struct Request{<br> uint16 class;<br> uint32 seqOfShare;<br> uint32 navPrice;<br> uint40 shareholder;<br> uint64 paid;<br> uint64 value;<br> uint8 seqOfPack;<br> }<br>|

---

---

| |
|:---|
| 22 |
| *[**Table of Contents**](#Toc)* |

---

 **3.2. Bookkeepers**

**Bookkeepers** defined dozens of APIs of legal behaviors regarding corporate governance and share transactions, so as to manage and control the identification of actors, conditions, procedures and legal consequences of the relevant legal behaviors.

**3.2.1. Functions of Bookkeepers**

When users exercise their rights, **Bookkeepers** will call **Shareholders Agreement** and the relevant **Registers** as per legal logic, so as to check what conditions need to be satisfied to conduct the relevant legal behaviors (or what parameters need to be relied on for the subsequent calculations), and, together with the input parameters obtained from the API, **Bookkeepers** will make decisions on whether the conditions are fulfilled or calculate the specific values of the intermediate parameters. If all conditions are fulfilled, **Bookkeepers** will call the relevant **Registers** to update the states of book-entry interests or record the contents of the legal behaviors, such as expression of intention, or action tracks of the behaviors.

For example, when a shareholder votes on a motion, it needs to call the "Cast Vote" API of **General Keeper**, input the subject motion number and express its attitude as support, against or abstain, thereafter, **General Keeper** will call **Reg Center** to retrieve the user number of shareholder and further call the "Cast Vote" API of **General Meeting Minutes Keeper** ("**GMM Keeper**") so as to hand over the control rights on the subsequent processing steps, and then, **GMM Keeper** will:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) retrieve the motion object from **General Meeting Minutes**;

---

| |
|:---|
| 23 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) retrieve the voting rule from **Shareholders Agreement** as per the voting rule number specified in the motion object, and deduce the voting period accordingly;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) determine whether it is in the voting period as per the current timestamp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) if within the voting period, call the **Register of Members** to verify whether the voter is a shareholder of the company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) If it is a shareholder, then check the entrust arrangements from the **Delegate Map** of the motion, and then call the **Register of Members** again to retrieve and calculate the total voting rights entrusted from the principals as well as represented by the voter;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Finally, store the voting information (user number, voting attitude, total voting rights, voting time, etc.) in the **General Meeting Minutes**.

From the above example, it can be deduced that **Bookkeeper** acts as the control center of verifying the conditions precedent and monitoring the logical flows of the legal behaviors.

In order to satisfy the size requirements of EIP-170, **ComBoox** defines two types of smart contracts, namely, **General Keeper** and several **Sub-Bookkeepers**.

**3.2.2. General Keeper**

**General Keeper** sits at the uppermost layer of the company book-entry system and has the following functions:

---

| |
|:---|
| 24 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Acts as the only entry of the company's book-entry system for write operation commands and is responsible for routing write commands to specific **Sub-Bookkeeper**;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Acts as the address registration center for **Registers**, and responses the address of specific **Register** as per its sequence number;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Represents the legal entity of the company and conducts legal behaviors on behalf the company on-chain, e.g. signing or executing smart contracts, making payments in tokens, exercising voting rights, etc;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Represents the company to hold cryptocurrencies such as ETH and CBP etc., and makes payments in accordance with the resolutions of General Meeting of Members or Board of Directors.

**3.2.3. Sub-Bookkeepers**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Sub-Bookkeepers** are the core computation layer controlling the identity verification, conditions, procedures and legal consequences of legal behaviors. They do not store any state variables and operate in a manner analogous to libraries. The General Keeper identifies and retrieves the address of the relevant Sub-Bookkeeper to be invoked by reference to the function selector (i.e., the first four bytes of the keccak256 hash of the function signature), and subsequently invokes the corresponding function of such Sub-Bookkeeper by means of a delegatecall. Accordingly, the specific algorithms defined in the functions of each Sub-Bookkeeper are executed within the context of the General Keeper, such that all computations are performed against the General Keeper's state. The Sub Keepers include the followings:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Register of Constitutions Keeper** ("**ROC Keeper**"): routes write commands to **Register of Agreements**, and controls the legal behaviors of creating, circulating, signing, activating, and accepting Shareholders**Agreements**;

---

| |
|:---|
| 25 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Register of Directors Keeper** ("**ROD Keeper**"): routes write commands to **Register of Directors**, and controls the legal behaviors of inauguration, dismissal, and resignation of directors or executive officers;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Board Meeting Minutes Keeper ("BMM Keeper")**: routes write commands to **Board Meeting Minutes**, and controls the legal behaviors of creating and proposing board motions, appointing voting delegate, casting vote, counting of vote results, and executing actions. The motions concerned include the appointing and removing managers, reviewing contracts, paying tokens, and calling on-chain smart contracts;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) **Register of Members Keeper ("ROM Keeper")**: routes write commands to **Register of Shares** and **Register of Members**, and controls the legal behaviors of setting the maximum number of shareholders, setting hash locks on paid-in shares, releasing and withdrawing paid-in shares, and decreasing registered capital;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) **General Meeting Minutes Keeper ("GMM Keeper")**: routes write commands to **General Meeting Minutes**, and controls the legal behaviors of creating and proposing motions, appointing voting delegate, casting votes, counting vote results, and executing resolutions. The motions include nominating and removing directors, reviewing contracts, paying tokens and calling smart contracts;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) **Register of Agreements Keeper ("ROA Keeper")**: routes write commands to **Register of Agreements** and **Register of Shares**, and controls the legal behaviors of creation, circulation, and signing of **Investment Agreements**, as well as locking the subject equity, releasing and withdrawing the subject equity, issuing new shares, transferring share, terminating transaction, and paying consideration;

---

| |
|:---|
| 26 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) **Register of Options Keeper ("ROO Keeper")**: routes write commands to **Register of Options** and **Register of Shares**, and controls the legal behaviors of inputting trigger events, exercising options, setting option's pledge, paying off option, executing option's pledge, requesting the against member to buy, paying consideration for the rejected deal's equity shares, and executing the against member's pledge;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) **Register of Pledges Keeper ("ROP Keeper"):** routes write commands to **Register of Pledges, Register of Shares**, and **Register of Agreements**, and controls the legal behaviors of refunding debts, extending secured period, creating, transferring, executing, locking, releasing, withdrawing and revoking pledges;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) **Shareholders Agreement Keeper ("SHA Keeper")**: routes write commands to **Register of Shares** and **Register of Agreements**, and controls the legal behaviors of exercising and accepting special shareholders' rights like Drag-Along, Tag-Along, Anti-Dilution and First Refusal;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) **List of Orders Keeper** (**"LOO Keeper"**): routes write commands to **List of Orders**, **Register of Shares**, and **Register of Members**, and controls legal behaviors of registering, approving and revoking investors, listing and withdrawing initial offers, sell orders, and placing buy orders to be settled in USDC;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) **Accountant**: routes write commands to **Cashier**, **General Meeting Minutes** and/or **Board Meeting Minutes**, and controls the legal behaviors of distribution of profits or income, and the transfer of funds;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) **Register of Redemptions Keeper ("ROR Keeper")**: routes write commands to **Register of Redemptions**, **Register of Shares**, and **Cashier**, and controls the legal behaviors of addition or removal of redeemable classes, submission of redemption request and the redemption of the requested shares.

---

| |
|:---|
| 27 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate user payments in USDC for equity consideration, margin deposits, and related expenses, the **ROA Keeper**, **ROM Keeper**, **LOO Keeper**, and **ROO Keeper** are designed to route write commands to **Cashier** to execute USDC payment transactions in connection with equity trades or capital contributions.

---

| |
|:---|
| 28 |
| *[**Table of Contents**](#Toc)* |

---

 **3.3. Shareholders Agreement**

**Shareholders Agreement** is to dynamically define rules and conditions relating to share transaction and corporate governance, which can be deemed as a constitutional document of the company.

When users exercise their rights, **Shareholders Agreement** will, as per the query request of **Bookkeepers,** search and obtain specific rules or terms, based on which a specific threshold value, parameter, or testing result will be parsed and reverted, so as for **Bookkeepers** to conduct further calculation or processing.

For example, when a shareholder casts vote for a motion, the relevant **Bookkeeper** will call **Shareholders Agreement** to query the voting period of certain governing voting rule, and then, based on the number of voting days obtained, the motion's proposal date, as well as the current block timestamp, **Bookkeeper** will determine whether it is in the voting period.

The detailed terms and rules of **Shareholders Agreement** are abstractly defined as different data objects and methods according to the legal logic of corporate governance. During the drafting process, different values can be dynamically set to the different attributes, so as to define the different rules of the legal behavior concerned. A draft **Shareholders Agreement** will become effective upon approval of the general meeting of shareholders.

For example, when setting voting rules for different types of share transaction, a 30-days' review period and a two-thirds voting threshold can be set for capital increase deals, while, a 15-days' review period and a one-half voting threshold can be set for share transfer deals. Thereafter, during the process when a transaction is submitted to the shareholders' meeting for reviewing and voting, **Bookkeeper** will calculate and determine the time period and voting results as per the transaction type accordingly.

In the **Shareholders Agreement**, the rules of corporate governance and share transaction can be categorized into "**Rules**" and "**Terms**" according to their respective complexity and governing matters.

---

| |
|:---|
| 29 |
| *[**Table of Contents**](#Toc)* |

---

**3.3.1. Rules**

"**Rules**" are defined in bytes32, which depend on the public library of **Rules Parser** to parse their key attributes, length of period or key threshold of conditions, so as to transform into structured objects.

Each rule has its own sequence number, so it's quite easy to set up a mapping from "sequence number" to the bytes32 "rule".

---

| |
|:---|
| **Rules Mapping** |
| <br> // seq => rule<br> mapping(uint256 => bytes32) rules;<br>|

---

Currently the rules include following types: **General Governance Rules**, **Voting Rules**, **Position Allocate Rules**, **First Refusal Rules**, **Grouping Update Orders**, and **Listing Rules**.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(1) Governance Rule (No. 0)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The **Governance Rule** specifies key corporate governance matters, including the company's legal form, operating term, the basis for calculating voting rights (whether based on paid-in capital or subscribed capital), quorum requirements for the General Meeting and the Board, proposal thresholds, the maximum number of shareholders or directors, the term of office of the Board, and the minimum shareholding percentage required for shareholder disclosure.

---

| |
|:---|
| 30 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of Governance Rule** |
| <br> // Object of GovernanceRule (No.0)<br> struct GovernanceRule{<br> uint32 fundApprovalThreshold; <br> bool basedOnPar;<br> uint16 proposeWeightRatioOfGM; <br> uint16 proposeHeadRatioOfMembers; <br> uint16 proposeHeadRatioOfDirectorsInGM;<br> uint16 proposeHeadRatioOfDirectorsInBoard;<br> uint16 maxQtyOfMembers;<br> uint16 quorumOfGM;<br> uint8 maxNumOfDirectors;<br> uint16 tenureMonOfBoard;<br> uint16 quorumOfBoardMeeting;<br> uint48 establishedDate;<br> uint8 businessTermInYears;<br> uint8 typeOfComp;<br> uint16 minVoteRatioOnChain;<br> }<br>function governanceRuleParser(bytes32 sn) public pure returns (GovernanceRule memory rule) {<br> uint _sn = uint(sn);<br>rule = GovernanceRule({<br> fundApprovalThreshold: uint32(_sn >> 224),<br> basedOnPar: uint8(_sn >> 216) == 1,<br> proposeWeightRatioOfGM: uint16(_sn >> 200),<br> proposeHeadRatioOfMembers: uint16(_sn >> 184),<br> proposeHeadRatioOfDirectorsInGM: uint16(_sn >> 168),<br> proposeHeadRatioOfDirectorsInBoard: uint16(_sn >> 152),<br> maxQtyOfMembers: uint16(_sn >> 136),<br> quorumOfGM: uint16(_sn >> 120),<br> maxNumOfDirectors: uint8(_sn >> 112),<br> tenureMonOfBoard: uint16(_sn >> 96),<br> quorumOfBoardMeeting: uint16(_sn >> 80),<br> establishedDate: uint48(_sn >> 32),<br> businessTermInYears: uint8(_sn >> 24),<br> typeOfComp: uint8(_sn >> 16),<br> minVoteRatioOnChain: uint16(_sn)<br> });<br> }<br>|

---

---

| |
|:---|
| 31 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **Governance Rule Attributes** | **Governance Rule Attributes** | **Governance Rule Attributes** |
| **Type** | **Name** | **Meaning** |
| uint32 | fundApprovalThreshold | The amount above which any fund payment shall be subject to approval by the General Meeting and at or below which fund payments may be approved by the Board of Directors. |
| bool | basedOnPar | The Boolean flag indicates whether voting points are calculated based on the par value (true) or the paid-in value (false) of shares. |
| uint16 | proposeWeightRatioOfGM | The minimum voting-points ratio that a Member must directly hold, or have obtained support for from other Members, in order to submit a proposal to the General Meeting. |
| uint16 | proposeHeadRatioOfMembers | The minimum headcount ratio that a Member must directly hold, or have obtained support for from other Members, in order to submit a proposal to the General Meeting. |
| uint16 | proposeHeadRatioOfDirectorsInGM | The minimum headcount ratio that a Director must directly hold, or have obtained support for from other Directors, in order to submit a proposal to the General Meeting. |
| uint16 | proposeHeadRatioOfDirectorsInBM | The minimum headcount ratio that a Director must directly hold, or have obtained support for from other Directors, in order to submit a proposal to the Board Meeting. |
| uint16 | maxQtyOfMembers | The Maximum number of Members permitted for the company. |
| uint16 | quorumOfGM | The minimum voting-points ratio that must be present for the General Meeting to validly adopt a resolution. |
| uint8 | maxNumOfDirectors | The Maximum number of Directors permitted for the company. |
| uint16 | tenureMonOfBoard | The number of Months for which a Board of the company serves. |
| uint16 | quorumOfBoardMeeting | The minimum headcount ratio that must be present for the Board Meeting to validly adopt a resolution. |
| uint48 | establishedDate | The date when the company established. |
| uint8 | businessTermInYears | The number of years for which the Company is intended to exist. |
| uint8 | typeOfComp | The type of legal entity to which the Company belongs. |
| uint16 | minVoteRatioOnChain | The minimum aggregate voting-points ratio held by a Member, together with its affiliates, that triggers its obligation to publicly disclose such holdings to securities market. |

---

---

| |
|:---|
| 32 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(2) Voting Rule (No. 1 ~ 255)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The **Voting Rules** set out the exercise periods for special shareholder rights in various decision-making procedures, and the methods for calculating voting outcomes. Specifically, Rules No.1 through No.7 prescribe the voting rules applicable to capital increase, transfers of equity to third parties, transfers of equity among existing shareholders, and the four hybrid transaction types formed by combinations of these three basic equity transactions. Rule No.8 establishes a special voting regime for amendments to **Shareholders Agreement**. Rules No.9 and No.10 govern the voting procedures for ordinary and special resolutions of the General Meeting, respectively, while Rules No.11 and No.12 govern the voting procedures for ordinary and special resolutions of the Board of Directors, respectively.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Where special requirements arise, additional customized **Voting Rules** may be freely introduced after Rule No.12, up to a maximum of Rule No.255. Once such rules are incorporated into the **Shareholders Agreement**, they may be mandatorily applied during the proposal and voting processes by reference to their corresponding rule sequence number. Any adoption or modification of voting rules constitutes an amendment to the **Shareholders Agreement** and, accordingly, must be approved by the **General Meeting** in accordance with Rule No.8 for the revised **Shareholders Agreement** to become effective.

---

| |
|:---|
| 33 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of Voting Rule** |
| <br> // VotingRule (No. 1 ~ 255) <br> struct VotingRule{<br> uint16 seqOfRule;<br> uint8 qtyOfSubRule;<br> uint8 seqOfSubRule;<br> uint8 authority;<br> uint16 headRatio;<br> uint16 amountRatio;<br> bool onlyAttendance;<br> bool impliedConsent;<br> bool partyAsConsent;<br> bool againstShallBuy;<br> uint8 frExecDays;<br> uint8 dtExecDays;<br> uint8 dtConfirmDays;<br> uint8 invExitDays;<br> uint8 votePrepareDays;<br> uint8 votingDays;<br> uint8 execDaysForPutOpt;<br> uint40[2] vetoers;<br> uint16 para;<br> }<br>function votingRuleParser(bytes32 sn) public pure returns (VotingRule memory rule)<br> {<br> uint _sn = uint(sn);<br> rule = VotingRule({<br> seqOfRule: uint16(_sn >> 240),<br> qtyOfSubRule: uint8(_sn >> 232),<br> seqOfSubRule: uint8(_sn >> 224),<br> authority: uint8(_sn >> 216),<br> headRatio: uint16(_sn >> 200),<br> amountRatio: uint16(_sn >> 184),<br> onlyAttendance: uint8(_sn >> 176) == 1,<br> impliedConsent: uint8(_sn >> 168) == 1,<br> partyAsConsent: uint8(_sn >> 160) == 1,<br> againstShallBuy: uint8(_sn >> 152) == 1,<br> frExecDays: uint8(_sn >> 144),<br> dtExecDays: uint8(_sn >> 136),<br> dtConfirmDays: uint8(_sn >> 128),<br> invExitDays: uint8(_sn >> 120),<br> votePrepareDays: uint8(_sn >> 112),<br> votingDays: uint8(_sn >> 104),<br> execDaysForPutOpt: uint8(_sn >> 96),<br> vetoers: [uint40(_sn >> 56), uint40(_sn >> 16)],<br> para: uint16(_sn) <br> });<br> }<br>|

---

---

| |
|:---|
| 34 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **Voting Rule Attributes** | **Voting Rule Attributes** | **Voting Rule Attributes** |
| **Type** | **Name** | **Meaning** |
| uint16 | seqOfRule | The sequence number of the specific Rule. For a Voting Rule, this sequence number ranges from 1 to 255. |
| uint8 | qtyOfSubRule | The total number of sub-rules contained within a Voting Rule category. |
| uint8 | seqOfSubRule | The sequence number of the specific Rule within the category of Voting Rule. |
| uint8 | authority | The sequence number of the governing body for a specific Voting Rule, where 01 represents the General Meeting and 02 represents the Board Meeting. |
| uint16 | headRatio | The minimum headcount ratio required for a proposal to be approved. |
| uint16 | amountRatio | The minimum voting-points ratio required for a proposal to be approved. |
| bool | onlyAttendance | The Boolean flag indicating whether only the attendance's voting points or headcounts are considered when calculating the voting result. |
| bool | impliedConsent | The Boolean flag indicating whether a voter absent from a vote is deemed to consent to the proposal. |
| bool | partyAsConsent | The Boolean flag indicating whether the signing party of a share transfer or capital increase agreement is deemed to consent to the proposal. |
| bool | againstShallBuy | The Boolean flag indicating whether a Member voting against a proposal assumes a potential obligation to purchase the relevant shares. |
| uint8 | frExecDays | The number of days within which a First Refusal right holder may exercise such right, calculated from the signing deadline of the relevant share transfer or capital increase agreement. |
| uint8 | dtExecDays | The number of days within which a Drag/Tag-Along right holder may exercise such right, calculated from the expiration date of the Right of First Refusal. |
| uint8 | dtConfirmDays | The number of days within which a Drag/Tag-Along obligator (i.e., the purchaser of the relevant transaction) may confirm acceptance of the transaction, calculated from the expiration date of the Drag/Tag-Along. |
| uint8 | invExitDays | The number of days within which a Member may sell its shares without registration, as a basis for voting on the relevant transaction, calculated from the date of the proposal. |
| uint8 | frExecDays | The number of days within which a First Refusal right holder may exercise such right, calculated from the signing deadline of the relevant share transfer or capital increase agreement. |
| uint8 | votePrepareDays | The number of days from the share registration date-calculated as the proposal date plus the investment exit period-until the commencement of voting. |
| uint8 | votingDays | The number of days during which votes may be cast. |
| uint8 | execDaysForPutOpt | The number of days during which the seller of a share transfer transaction may exercise the right to sell the subject shares to Members who voted against the transaction, calculated from the expiration date of the voting period. |
| uint40[2] | vetoers | The special Member(s) who hold veto power over the transaction governed by this voting rule. |
| uint16 | para | A reserved parameter for future use. |

---

---

| |
|:---|
| 35 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(3) Position Allocate Rule (No. 256 ~ 511)** 

The Position Allocation Rules specify the allocation of nomination rights for directors and officers, the Voting Rule applicable, and the terms thereof. By defining directors' nomination rights under this rule, the allocation of Board seats among shareholders may be achieved. Nomination rights may be vested in a specific user or in a designated title of positions (e.g. CEO may nominate CFO). If, under the Voting Rule applicable, both the voting points ratio and the headcount ratio are set to zero, this indicates that the nominator may directly appoint the candidate to the position without approval.

---

| |
|:---|
| **Structure of Voting Rule** |
| <br> // Position Allocate Rule (No. 256 ~ 511) <br> struct PositionAllocateRule{<br> uint16 seqOfRule;<br> uint8 qtyOfSubRule;<br> uint8 seqOfSubRule;<br> bool removePos;<br> uint16 seqOfPos;<br> uint16 titleOfPos;<br> uint40 nominator;<br> uint16 titleOfNominator;<br> uint16 seqOfVR;<br> uint48 endDate;<br> uint16 para;<br> uint16 argu;<br> uint32 data;<br> }<br>function positionAllocateRuleParser(bytes32 sn) public pure<br> returns(PositionAllocateRule memory rule) {<br> uint _sn = uint(sn);<br> rule = PositionAllocateRule({<br> seqOfRule: uint16(_sn >> 240),<br> qtyOfSubRule: uint8(_sn >> 232),<br> seqOfSubRule: uint8(_sn >> 224),<br> removePos: uint8(_sn >> 216) == 1,<br> seqOfPos: uint16(_sn >> 200),<br> titleOfPos: uint16(_sn >> 184),<br> nominator: uint40(_sn >> 144),<br> titleOfNominator: uint16(_sn >> 128),<br> seqOfVR: uint16(_sn >> 112),<br> endDate: uint48(_sn >> 64),<br> para: uint16(_sn >> 48),<br> argu: uint16(_sn >> 32),<br> data: uint32(_sn)<br> });<br> }<br>|

---

---

| |
|:---|
| 36 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **Position Allocate Rule Attributes** | **Position Allocate Rule Attributes** | **Position Allocate Rule Attributes** |
| **Type** | **Name** | **Meaning** |
| uint16 | seqOfRule | The sequence number of the specific Rule. For a Position Allocate Rule, this sequence number ranges from 256 to 511. |
| uint8 | qtyOfSubRule | The total number of sub-rules contained within a Position Allocate Rule category. |
| uint8 | seqOfSubRule | The sequence number of the specific Rule within the category of Position Allocate Rule. |
| bool | removePos | The Boolean flag indicating whether to remove an existing position (true) or to add a new position (false). |
| uint16 | seqOfPos | The sequence number of the relevant position. |
| uint16 | titleOfPos | The title of the relevant position. |
| uint40 | nominator | The user number of the nominator for the relevant position. |
| uint16 | titleOfNominator | The title of the nominator for the relevant position. |
| uint16 | seqOfVR | The sequence number of the Voting Rule that approves the relevant position. |
| uint16 | endDate | The expiration date of the term of the relevant position. |
| uint16 | para | A reserved parameter for future use. |
| uint16 | argu | A reserved argument for future use. |
| uint32 | data | A reserved data for future use. |

---

---

| |
|:---|
| 37 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp; **(4) First Refusal Rule (No. 512 ~ 767)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The First Refusal Rules govern shareholders' pre-emptive rights to subscribe for newly issued equity or rights of first refusal to purchase equity proposed to be transferred. Such rights may be granted equally to all shareholders or conferred upon specific ones. The allocation of the subject equity may be made pro rata based on voting rights or in accordance with the chronological order in which such rights are exercised. Up to 256 distinct first-refusal rules may be established to apply to different transaction types and different combinations of entitled parties.

---

| |
|:---|
| **Structure of First Refusal Rule** |
| <br> // FirstRefusalRule (No. 512 ~ 767)<br> struct FirstRefusalRule {<br> uint16 seqOfRule;<br> uint8 qtyOfSubRule;<br> uint8 seqOfSubRule;<br> uint8 typeOfDeal;<br> bool membersEqual;<br> bool proRata;<br> bool basedOnPar;<br> uint40[4] rightholders;<br> uint16 para;<br> uint16 argu;<br> }<br>function firstRefusalRuleParser(bytes32 sn) public pure<br> returns(FirstRefusalRule memory rule) {<br> uint _sn = uint(sn);<br>rule = FirstRefusalRule({<br> seqOfRule: uint16(_sn >> 240),<br> qtyOfSubRule: uint8(_sn >> 232),<br> seqOfSubRule: uint8(_sn >> 224),<br> typeOfDeal: uint8(_sn >> 216),<br> membersEqual: uint8(_sn >> 208) == 1,<br> proRata: uint8(_sn >> 200) == 1,<br> basedOnPar: uint8(_sn >> 192) == 1,<br> rightholders: [uint40(_sn >> 152), uint40(_sn >> 112), <br> uint40(_sn >> 72), uint40(_sn >> 32)],<br> para: uint16(_sn >> 16),<br> argu: uint16(_sn)<br> });<br> } |

---

---

| |
|:---|
| 38 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **First Refusal Rule Attributes** | **First Refusal Rule Attributes** | **First Refusal Rule Attributes** |
| **Type** | **Name** | **Meaning** |
| uint16 | seqOfRule | The sequence number of the specific Rule. For a First Refusal Rule, this sequence number ranges from 512 to 767. |
| uint8 | qtyOfSubRule | The total number of sub-rules contained within a First Refusal Rule category. |
| uint8 | seqOfSubRule | The sequence number of the specific Rule within the category of First Refusal Rule. |
| uint8 | typeOfDeal | The type code of the relevant transaction governed by this First Refusal Rule, being: 01-Capital Increase ("CI"); 02-External Share Transfer ("EST"); 03-Internal Share Transfer ("IST"); 04-CI & IST; 05-EST & IST; 06-CI, EST & IST; and 07-CI & EST. |
| bool | membersEqual | The Boolean flag indicating whether all Members are treated equally under this Right of First Refusal Rule. |
| bool | proRata | The Boolean flag indicating whether the target share shall be allocated among the First Refusal claimants on a pro rata basis according to their voting points. |
| bool | basedOnPar | The Boolean flag indicating whether the allocation weights of the Right of First Refusal claimants shall be calculated based on the par value of the shares. |
| uint40[4] | rightholders | The specified holders of the Right of First Refusal, the maximum number of which shall be four. |
| uint16 | para | A reserved parameter for future use. |
| uint16 | argu | A reserved argument for future use. |

---

---

| |
|:---|
| 39 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(5) Group Update Order (No. 768 ~ 1023)** 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Group Update Orders are used to define and update groups of affiliated shareholders (or persons acting in concert). Each group is identified by a representative shareholder's user number. During the activation process of a Shareholders Agreement, the system automatically executes the Group Update Orders contained therein to add specified users into, or remove them from, a particular affiliation group. A proposal for updating Shareholders Agreement with Group Update Orders effectively constitutes a declaration and disclosure by the relevant shareholders of their affiliated relationships. Accordingly, the review and approval of such motion signifies the General Meeting's acknowledgment and approval of such relationships.

---

| |
|:---|
| **Structure of Group Update Order** |
| <br> // GroupUpdateOrder (No. 768 ~ 1023)<br> struct GroupUpdateOrder {<br> uint16 seqOfRule;<br> uint8 qtyOfSubRule;<br> uint8 seqOfSubRule;<br> bool addMember;<br> uint40 groupRep;<br> uint40[4] members;<br> uint16 para;<br> }<br>function groupUpdateOrderParser(bytes32 sn) public pure <br> returns(GroupUpdateOrder memory order) {<br> uint _sn = uint(sn);<br>order = GroupUpdateOrder({<br> seqOfRule: uint16(_sn >> 240),<br> qtyOfSubRule: uint8(_sn >> 232),<br> seqOfSubRule: uint8(_sn >> 224),<br> addMember: uint8(_sn >> 216) == 1,<br> groupRep: uint40(_sn >> 176),<br> members: [<br> uint40(_sn >> 136),<br> uint40(_sn >> 96),<br> uint40(_sn >> 56),<br> uint40(_sn >> 16)<br> ],<br> para: uint16(_sn)<br> });<br> } |

---

---

| |
|:---|
| 40 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **Group Update Order Attributes** | **Group Update Order Attributes** | **Group Update Order Attributes** |
| **Type** | **Name** | **Meaning** |
| uint16 | seqOfRule | The sequence number of the specific Rule. For a Group Update Order, this sequence number ranges from 768 to 1023. |
| uint8 | qtyOfSubRule | The total number of sub-rules contained within a Group Update Order category. |
| uint8 | seqOfSubRule | The sequence number of the specific Rule within the category of Group Update Order. |
| bool | addMember | The Boolean flag indicating whether to add Member(s) into the relevant Group. |
| uint40 | groupRep | The representative user number of the relevant Group. |
| uint40[4] | members | The user numbers of the Members to be added to or removed from the relevant Group, the maximum number of which shall be four. |
| uint16 | para | A reserved parameter for future use. |

---

---

| |
|:---|
| 41 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(6) Listing Rule (No. 1024 ~ 1280)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The Listing Rules set out the rules governing the issuance or trading of shares by listing, including maximum and minimum offering price, minimum trading price, resale lockup days, caps on the number of qualified Investors, the title of Verifiers and issuers, the class of shares to which the rules apply, and the maximum aggregate Par Value of shares that may be issued. Up to 256 Listing Rules may be established to regulate the issuance and trading of different classes of equity.

---

| |
|:---|
| **Structure of Listing Rule** |
| <br> // ListingRule (No. 1024 ~ 1280)<br> struct ListingRule {<br> uint16 seqOfRule;<br> uint16 titleOfIssuer;<br> uint16 classOfShare;<br> uint32 maxTotalPar;<br> uint16 titleOfVerifier;<br> uint16 maxQtyOfInvestors;<br> uint32 ceilingPrice;<br> uint32 floorPrice;<br> uint16 lockupDays;<br> uint16 offPrice;<br> uint16 votingWeight;<br> uint16 distrWeight;<br> uint16 para;<br> }<br>function listingRuleParser(bytes32 sn) public pure <br> returns(ListingRule memory rule) {<br> uint _sn = uint(sn);<br>rule = ListingRule({<br> seqOfRule: uint16(_sn >> 240),<br> titleOfIssuer: uint16(_sn >> 224),<br> classOfShare: uint16(_sn >> 208),<br> maxTotalPar: uint32(_sn >> 176),<br> titleOfVerifier: uint16(_sn >> 160), <br> maxQtyOfInvestors: uint16(_sn >> 144),<br> ceilingPrice: uint32(_sn >> 112),<br> floorPrice: uint32(_sn >> 80),<br> lockupDays: uint16(_sn >> 64),<br> offPrice: uint16(_sn >> 48),<br> votingWeight: uint16(_sn >> 32),<br> distrWeight: uint16(_sn >> 16),<br> para: uint16(_sn)<br> });<br> } |

---

---

| |
|:---|
| 42 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **Listing Rule Attributes** | **Listing Rule Attributes** | **Listing Rule Attributes** |
| **Type** | **Name** | **Meaning** |
| uint16 | seqOfRule | The sequence number of the specific Rule. For a Listing Rule, this sequence number ranges from 1024 to 1280. |
| uint16 | titleOfIssuer | The title number of the issuer authorized, pursuant to this Listing Rule, to invoke the function of issuing new shares by listing. |
| uint16 | classOfShare | The class number of the shares to be issued and traded by listing pursuant to this Listing Rule. |
| uint32 | maxTotalPar | The maximum aggregate par value of the class of shares that may be traded by listing pursuant to this Listing Rule. |
| uint16 | titleOfVerifier | The title number of the Verifier authorized to verify, approve, revoke, or restate the Qualified Investor role for users eligible to purchase or sell the company's shares. |
| uint16 | maxQtyOfInvestors | The maximum total number of investors eligible to purchase or sell the company's shares, which may be set to unlimited by specifying zero. |
| uint32 | ceilingPrice | The maximum price that shall not be exceeded when issuing new shares by listing. |
| uint32 | floorPrice | The minimum price that shall not be lower than when issuing new shares by listing. |
| uint16 | lockupDays | The number of days during which the shares are locked from sale, calculated from the date they are purchased by listing. |
| uint16 | offPrice | The minimum price that shall not be lower than when trading shares by listing. |
| uint16 | votingWeight | The voting weight assigned to the new class of shares to be issued by listing. |
| uint16 | distrWeight | The distribution weight assigned to the new class of shares to be issued by listing. |
| uint16 | para | A reserved parameter for future use. |

---

---

| |
|:---|
| 43 |
| *[**Table of Contents**](#Toc)* |

---

**3.3.2. Terms**

"**Terms**" are defined in form of independent smart contracts, and are relied on structured data objects and their methods to define specific pre-conditions of rights and intermediate parameters algorithm.

Each term has its own sequence number, so it's quite easy to set up a mapping from "title number" to the "address of term".

---

| |
|:---|
| **Term Mapping** |
| <br> // title => body<br> mapping(uint256 => address) terms;<br>|

---

Currently the terms include the following types: **Anti Dilution**, **Lock Up**, **Drag Along**, **Tag Along**, **Put Option** and **Call Option**.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(1) Anti Dilution (No. 1 Term)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Anti-Dilution is a special smart contract designed to protect existing shareholders from dilution caused by the issuance of new shares at a lower price, which would otherwise dilute the effective per-unit acquisition price of their shares (calculated as acquisition cost divided by aggregate par value). The mechanism establishes benchmark prices for different classes of shares and specifies the shareholders' user number of the parties responsible for providing anti-dilution compensation (typically the company's controlling shareholder). If new shares are issued at a price below the applicable benchmark price, the obligated party must compensate the entitled shareholders through a gratuitous transfer of equity, until the weighted-average acquisition price of the entitled shareholders is adjusted to align with the new issuance price.

---

| |
|:---|
| 44 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate the drafting and amendment of the Anti Dilution by users, the following lists the editorial API interfaces that may be invoked by external accounts.

---

| |
|:---|
| **Structure of Benchmark and Ruler** |
| <br> // IAntiDilution.sol (No.1 Term)<br>struct Benchmark{<br> uint16 classOfShare;<br> uint32 floorPrice;<br> EnumerableSet.UintSet obligors; <br> }<br>struct Ruler {<br> // classOfShare => Benchmark<br> mapping(uint256 => Benchmark) marks;<br> EnumerableSet.UintSet classes;<br> } |

---

---

| | |
|:---|:---|
| **Editorial Interfaces of Anti Dilution** | **Editorial Interfaces of Anti Dilution** |
| **API** | **Description of Functions and Parameters** |
| function **addBenchmark**(<br> uint256 <u>*class*</u>, uint <u>*price*</u>) external; | Add an anti-dilution benchmark specifying that the issue price of shares with class sequence number <u>*class*</u> shall not be lower than <u>*price*</u>. |
| function **removeBenchmark**(<br> uint256 <u>*class*</u>) external; | Remove the anti-dilution benchmark applicable to the issue price of shares with class sequence number <u>*class*</u>. |
| function **addObligor**(<br> uint256 <u>*class*</u>, uint256 <u>*obligor*</u>) external; | Add a user with sequence number <u>*obligor*</u> who shall assume the compensation liabilities if the issue price of shares with class sequence number <u>*class*</u> falls below its anti-dilution benchmark. |
| function **removeObligor**(<br> uint256 <u>*class*</u>, uint256 <u>*obligor*</u>) external; | Remove the user with sequence number <u>*obligor*</u> from the group responsible for assuming the compensation liabilities arising from the anti-dilution obligation applicable to shares with class sequence number <u>*class*</u>. |

---

---

| |
|:---|
| 45 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(2) Lock Up (No.2 Term)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Lock Up** is a specialized smart contract designed to define and monitor shares subject to transfer restrictions. For each locked shares, the contract assigns a dedicated "locker" that records the lock-up expiration date and the user numbers of the designated "key holders" whose consent is required for any early release. The subject share may be transferred prior to the expiration of the lock-up period only with the unanimous consent of all key holders; otherwise, the system will automatically reject the proposed transfer. If the lock-up expiration date is set to zero, the share shall remain permanently locked and non-transferable unless all key holders unanimously approve its release.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate the drafting and amendment of the Lock Up by users, the following lists the editorial API interfaces that may be invoked by external accounts.

---

| |
|:---|
| **Structure of Locker** |
| <br> // ILockUp (No.2 Term)<br>struct Locker {<br> uint48 dueDate;<br> EnumerableSet.UintSet keyHolders;<br> } |

---

---

| | |
|:---|:---|
| **Editorial Interfaces of Lock Up** | **Editorial Interfaces of Lock Up** |
| **API** | **Description of Functions and Parameters** |
| function **setLocker**(<br> uint256 <u>*seqOfShare*</u>, uint <u>*dueDate*</u>) external; | Set the locker for the specific share with sequence number <u>*seqOfShare*</u> to be locked from sale until <u>*dueDate*</u>. |
| function **delLocker**(<br> uint256 <u>*seqOfShare*</u>) external; | Delete the locker for the specific share with sequence number <u>*seqOfShare*</u>. |
| function **addKeyholder**(<br> uint256 <u>*seqOfShare*</u>, uint256 <u>*keyholder*</u>) external; | Add the user with number <u>*keyholder*</u>, who is required to vote on the motion to unlock the locker for the share with sequence number <u>*seqOfShare*</u> before the due date. |
| function **removeKeyholder**(<br> uint256 <u>*seqOfShare*</u>, uint256 <u>*keyholder*</u>) external; | Remove the user with number <u>*keyholder*</u>, who is required to vote on the motion to unlock the locker for the share with sequence number <u>*seqOfShare*</u> before the due date. |

---

---

| |
|:---|
| 46 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(3) Drag/Tag Along (No.3 ~ No.4 Term)**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Drag/Tag Along** is a specialized smart contract designed to define and execute coordinated share transfer arrangements. Under a **Drag Along**, when a selling shareholder intends to transfer shares, it may require specified obligors to sell their shares alongside, enabling the buyer to acquire a larger proportion of the company's equity. Under a **Tag Along**, designated right holders may require the seller to allow them to sell their shares on the same price and terms, thereby facilitating a joint exit.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The contract uses a **Link Rule**, encoded in bytes32, to define the exercise start date, exercise period, minimum **Drag Along** price, or minimum annualized ROE, along with other exercise conditions and timelines. It uses the selling shareholder's user number to identify the data object **Link** which is further consists of the **Link Rule** and the followers (i.e. the **Drag Along** obligors or **Tag Along** right-holders participating in the transfer). Exercise conditions may include a change of company control or may be unconditional, depending on the terms.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate the drafting and amendment of the **Drag/Tag Along** by users, the following lists the editorial API interfaces that may be invoked by external accounts.

---

| |
|:---|
| 47 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of LinkRule** |
| <br> // Link Rule<br>struct LinkRule {<br> uint48 triggerDate;<br> uint16 effectiveDays;<br> uint8 triggerType;<br> uint16 shareRatioThreshold;<br> uint32 rate;<br> bool proRata;<br> uint16 seq;<br> uint16 para;<br> uint16 argu;<br> uint16 ref;<br> uint64 data;<br> }<br>function linkRuleParser(bytes32 sn) public pure returns (LinkRule memory rule) {<br> uint _sn = uint(sn);<br>rule = LinkRule({<br> triggerDate: uint48(_sn >> 208),<br> effectiveDays: uint16(_sn >> 192),<br> triggerType: uint8(_sn >> 184),<br> shareRatioThreshold: uint16(_sn >> 168),<br> rate: uint32(_sn >> 136),<br> proRata: uint8(_sn >> 128) == 1,<br> seq: uint16(_sn >> 112),<br> para: uint16(_sn >> 96),<br> argu: uint16(_sn >> 80),<br> ref: uint16(_sn >> 64),<br> data: uint64(_sn)<br> });<br> }<br>// LinksRepo.sol<br>struct Link {<br> RulesParser.LinkRule linkRule;<br> EnumerableSet.UintSet followersList;<br> }<br>struct Repo {<br> // dragger => Link<br> mapping(uint256 => Link) links;<br> EnumerableSet.UintSet draggersList;<br> } |

---

---

| |
|:---|
| 48 |
| *[**Table of Contents**](#Toc)* |

---

---

| | | |
|:---|:---|:---|
| **Link Rule Attributes** | **Link Rule Attributes** | **Link Rule Attributes** |
| **Type** | **Name** | **Meaning** |
| uint48 | triggerDate | The commencement date on which a Drag/Tag-Along right holder may begin to exercise such right. |
| uint16 | effectiveDays | The number of days, commencing from the trigger date, during which a Drag/Tag-Along right holder may exercise such right. |
| uint8 | triggerType | The trigger condition codes applicable to the Drag/Tag-Along right, as follows: 00-Unconditional; 01-Change of Company Control; 02-Change of Company Control with a Transaction Price exceeding the specified threshold; and 03-Change of Company Control with a Return on Equity exceeding the specified threshold. |
| uint16 | shareRatioThreshold | The voting-points ratio threshold above which the relevant shareholder shall be deemed to be the controller of the company. |
| uint32 | rate | The minimum price threshold or minimum ROE threshold above which the Drag-Along rights may be triggered. |
| bool | proRata | A Boolean flag indicating whether claimants shall allocate the quota pro rata to their claimed amounts if the accepted Tag-Along amount is insufficient. |

---

---

| | |
|:---|:---|
| **Editorial Interfaces of Drag/Tag Along** | **Editorial Interfaces of Drag/Tag Along** |
| **API** | **Description of Functions and Parameters** |
| function **addDragger**(<br> bytes32 <u>*rule*</u>, <br> uint256 <u>*dragger*</u>) external; | Add the user with sequence number <u>*dragger*</u> to the link rule codified as <u>*rule*</u> to establish a new Drag/Tag-Along arrangement. |
| function **removeDragger**(<br> uint256 <u>*dragger*</u>) external; | Remove the user with sequence number <u>*dragger*</u> to delete the corresponding Drag/Tag-Along arrangement. |
| function **addFollower**(<br> uint256 <u>*dragger*</u>, <br> uint256 <u>*follower*</u>) external; | Add the user with sequence number <u>*follower*</u> to the Drag/Tag Along arrangement associated with the selling party identified by the user sequence number <u>*dragger*</u>. |
| function **removeFollower**(<br> uint256 <u>*dragger*</u>, <br> uint256 <u>*follower*</u>) external; | Remove the user with sequence number <u>*follower*</u> from the Drag/Tag Along arrangement associated with the selling party identified by the user sequence number <u>*dragger*</u>. |

---

---

| |
|:---|
| 49 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(4) Put/Call Option**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Put/Call Option is a specialized smart contract designed to define and enforce the compulsory purchase or sale of a specified quantity and class of shares at a predetermined price. By flexibly configuring the exercise conditions, it can be used to implement complex equity investment arrangements, such as valuation adjustments and mandatory buybacks.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate the drafting and amendment of the Put/Call Option by users, the following lists the editorial API interfaces that may be invoked by external accounts.

---

| |
|:---|
| **Structure of Linking Rule** |
| <br> // OptionsRepo<br>struct Head {<br> uint32 seqOfOpt;<br> uint8 typeOfOpt;<br> uint16 classOfShare;<br> uint32 rate;<br> uint48 issueDate;<br> uint48 triggerDate;<br> uint16 execDays;<br> uint16 closingDays;<br> uint40 obligor;<br> }<br>function snParser(bytes32 sn) public pure returns (Head memory head) {<br> uint _sn = uint(sn);<br>head = Head({<br> seqOfOpt: uint32(_sn >> 224),<br> typeOfOpt: uint8(_sn >> 216),<br> classOfShare: uint16(_sn >> 200),<br> rate: uint32(_sn >> 168),<br> issueDate: uint48(_sn >> 120),<br> triggerDate: uint48(_sn >> 72),<br> execDays: uint16(_sn >> 56),<br> closingDays: uint16(_sn >> 40),<br> obligor: uint40(_sn)<br> });<br> } |

---

---

| |
|:---|
| 50 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of Cond** |
| <br> // CondsRepo<br>struct Cond {<br> uint32 seqOfCond;<br> uint8 logicOpr;<br> uint8 compOpr1;<br> uint64 para1;<br> uint8 compOpr2;<br> uint64 para2;<br> uint8 compOpr3;<br> uint64 para3;<br> }<br>function snParser(bytes32 sn) public pure returns(Cond memory cond)<br> {<br> uint _sn = uint(sn);<br>cond = Cond({<br> seqOfCond: uint32(_sn >> 224),<br> logicOpr: uint8(_sn >> 216),<br> compOpr1: uint8(_sn >> 208),<br> para1: uint64(_sn >> 144),<br> compOpr2: uint8(_sn >> 136),<br> para2: uint64(_sn >> 72),<br> compOpr3: uint8(_sn >> 64),<br> para3: uint64(_sn)<br> });<br> } |

---

---

| | |
|:---|:---|
| **Editorial Interfaces of Put/Call Option** | **Editorial Interfaces of Put/Call Option** |
| **API** | **Description of Functions and Parameters** |
| function **createCond**(<br> bytes32 <u>*snOfOpt*</u>, bytes32 <u>*snOfCond*</u>, <br> uint <u>*rightholder*</u>, uint <u>*paid*</u>, uint <u>*par*</u>) external returns (OptionsRepo.Head memory head); | Create a new Put/Call Option under which the option terms are codified as <u>*snOfOpt*</u>, the trigger condition is codified as <u>*snOfCond*</u>, the paid value is <u>*paid*</u>, the par value is <u>*par*</u>, and the right holder is the user identified by sequence number <u>*rightholder*</u>. |
| function **delOption**(<br> uint256 <u>*seqOfOpt*</u>) external returns(bool flag); | Remove the Put/Call Option identified by the sequence number <u>*seqOfOpt*</u>. |
| function **addObligorIntoOpt**(<br> uint256 <u>*seqOfOpt*</u>, uint256 <u>*obligor*</u>) external returns (bool flag); | Add the obligor identified by user sequence number <u>*obligor*</u> to the Put/Call Option identified by sequence number <u>*seqOfOpt*</u>. |
| function **removeObligorFromOpt**(<br> uint256 <u>*seqOfOpt*</u>, uint256 <u>*obligor*</u>) external returns (bool flag); | Remove the obligor identified by user sequence number <u>*obligor*</u> from the Put/Call Option identified by sequence number <u>*seqOfOpt*</u>. |

---

---

| |
|:---|
| 51 |
| *[**Table of Contents**](#Toc)* |

---

 **3.3.3. Editorial APIs of Shareholders Agreement** 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Therefore, **Shareholders Agreement** can be deemed as a data base comprises of "rules mapping" and "terms mapping", which is to dynamically define the parameters and attributes of different rules so as to retrieve them in runtime. As for the functions of **Rules Parser** and **Terms**, they are to set up models for the rules and terms in line with legal logic, and to abstractly define their core attributes and methods, thereafter, expose certain APIs so as for users to dynamically define various attributes or parameters of those rules and terms accordingly. So that, during runtime, in accordance with user's commands, specific **Bookkeeper** may search **Shareholders Agreement** as per the predefined logic of specific legal behavior, to get specific attribute or parameter of certain rule, and then, to further determine certain condition or to further control certain process.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The external APIs of the **Shareholders Agreement** are primarily used to add, remove, or query **Terms** and **Rules**. To facilitate the drafting and amendment of the **Shareholders Agreement** by users, the following lists the editorial API interfaces related to contract drafting and inquiry that may be invoked by external accounts.

---

| | |
|:---|:---|
| **Editorial Interfaces of Shareholders Agreement** | **Editorial Interfaces of Shareholders Agreement** |
| **API** | **Description of Functions and Parameters** |
| function **createTerm**(<br> uint <u>*title*</u>, uint <u>*version*</u>) external; | Create a clone smart contract using the term's sequence number <u>*title*</u> and version number <u>*version*</u>, and add the address of the cloned instance into the terms mapping. |
| function **removeTerm**(<br> uint <u>*title*</u>) external; | Remove the clone smart contract identified by the term's sequence number <u>*title*</u>. |
| function **getTerm**(<br> uint <u>*title*</u>) external view returns (address <u>*termAddr*</u>); | Get the address of the clone smart contract identified by the term's sequence number <u>*title*</u>. |
| function **addRule**(<br> uint <u>*seqOfRule*</u>, bytes32 <u>*rule*</u>) external; | Add the Rule encoded in bytes32 as <u>*rule*</u> and identified by the Rule's sequence number <u>*seqOfRule*</u> into the rules' mapping. |
| function **removeRule**(<br> uint256 <u>*seqOfRule*</u>) external; | Remove the rule identified by sequence number <u>*seqOfRule*</u>. |
| function **finalizeSHA**() external; | Transfer the special Roles with write authority over the Terms and this Shareholders Agreement to "Zero" to permanently lock their contents. |

---

---

| |
|:---|
| 52 |
| *[**Table of Contents**](#Toc)* |

---

 **3.3.4. Signature Page** 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Signature Page** is an independent, reusable and inheritable component smart contract that defines several key attributes of contract's execution, including contractual parties, signature fields, signing deadline and closing deadline etc..

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Shareholders Agreement** and **Investment Agreement** both inherit **Signature Page** as a special component to define and record information related to the contract execution.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate the drafting and amendment of the **Signature Page** by users, the following lists the editorial API interfaces that may be invoked by external accounts.

---

| |
|:---|
| **Structure of **Signature Page** |
| <br> // SigsRepo.sol<br>struct Signature {<br> uint40 signer;<br> uint48 sigDate;<br> uint64 blocknumber;<br> bool flag;<br> uint16 para;<br> uint16 arg;<br> uint16 seq;<br> uint16 attr;<br> uint32 data;<br> }<br>struct Blank{<br> EnumerableSet.UintSet seqOfDeals;<br> Signature sig;<br> bytes32 sigHash;<br> }<br>struct Page {<br> // party => Blank<br> mapping(uint256 => Blank) blanks;<br> EnumerableSet.UintSet buyers;<br> EnumerableSet.UintSet sellers;<br> } |

---

---

| |
|:---|
| 53 |
| *[**Table of Contents**](#Toc)* |

---

---

| | |
|:---|:---|
| **Editorial Interfaces of Signature Page** | **Editorial Interfaces of Signature Page** |
| **API** | **Description of Functions and Parameters** |
| function **setTiming**(<br> bool <u>*initPage*</u>, <br> uint <u>*signingDays*</u>, <br> uint <u>*closingDays*</u>) external; | Set the timing parameters for <u>*signingDays*</u> and <u>*closingDays*</u> on the initial page when <u>*initPage*</u> is true, or on the second page when <u>*initPage*</u> is false. This function shall be invoked by the attorney responsible for drafting the relevant contract. |
| function **addBlank**(<br> bool <u>*initPage*</u>, <br> bool <u>*beBuyer*</u>, <br> uint256 <u>*seqOfDeal*</u>, <br> uint256 <u>*acct*</u> ) external; | Add a new blank on the initial page when <u>*initPage*</u> is true, or on the second page when <u>*initPage*</u> is false, for the seller when <u>*beBuyer*</u> is false or for the buyer when <u>*beBuyer*</u> is true, in connection with the deal identified by sequence number <u>*seqOfDeal*</u>, for the intended signer with user number <u>*acct*</u>. This function may be invoked by the attorney responsible for drafting the relevant contract, or by the relevant Sub Keeper when exercising special shareholders' rights. |
| function **removeBlank**(<br> bool <u>*initPage*</u>, <br> uint256 <u>*seqOfDeal*</u>, <br> uint256 <u>*acct*</u> ) external; | Remove the blank from the initial page when <u>*initPage*</u> is true, or from the second page when <u>*initPage*</u> is false, in relation to the deal identified by sequence number <u>*seqOfDeal*</u>, for the intended signer identified by user number <u>*acct*</u>. This function may be invoked by the attorney responsible for drafting the relevant contract, or by the relevant Sub Keeper when exercising special shareholders' rights. |

---

---

| |
|:---|
| 54 |
| *[**Table of Contents**](#Toc)* |

---

 **3.4. Investment Agreement**

**Investment Agreement** dynamically defines all necessary elements of deals for issuing or transferring shares, such as the subject equity shares, price, amounts, buyer's identity, signing deadline, closing deadline, contractual parties and so on.

After an **Investment Agreement** is properly signed on-chain, the parties can call the relevant API of **Bookkeepers** to push forward the rest procedures concerning the deals' execution, like **General Meeting**'s reviewing and approving, paying consideration and closing etc. The relevant **Bookkeepers** will, strictly in line with the rules and terms set out in **Shareholders Agreement**, automatically verify the caller's identy, check the fulfillment of pre-conditions, and control the transaction's procedure, until realizing the final business purpose ---- updates the **Register of Shares**.

The nature of **Investment Agreement** is actually a special script (or, a batch file) consisting of a series of write operation commands to update the book-entry states of the equity shares (i.e. update the **Register of Shares**), which will be automatically executed in an orderly manner, under the control of the relevant **Bookkeepers** in line with predefined conditions and procedures set out in the **Shareholders Agreement**, and will eventually realize the business objectives of updating book-entry states of equity shares, i.e. to realize the legal consequences of issue new shares or transfer existing shares.

If there are any special arrangements stipulated in **Shareholders Agreement**, such as "First Refusal", "Drag-Along", "Tag-Along", or "Anti-Dilution" etc., the right holders can call the relevant API of **Bookkeeper** to exercise their rights during the specific exercising period, then, **Bookkeeper** will automatically change the counter party (for first refusal), add free transaction for gift shares (for anti-dilution), or add new transactions with the same price and conditions (for drag-along or tag-along), in accordance with the algorithm and methods defined in **Shareholders Agreement**, so as to realize the business purpose thereof.

---

| |
|:---|
| 55 |
| *[**Table of Contents**](#Toc)* |

---

Inside **Investment Agreement**, the substantive elements of a share transaction (subject equity, buyer, amount, price, closing deadline, etc.) are defined by a type of structured object, called "**Deal**"; while, the procedural elements (such as contract parties, signing deadline, closing deadline, etc.) are defined by a reusable and inheritable smart contract component, called "**Signature Page**".

3.4.1. Deal

The object of **Deal** defines all necessary factors to issue new shares or transfer existing shares in **Register of Shares**, which also defines a hash lock in form of bytes32 for parties to arrange off-chain or cross-chain payment for equity consideration.

---

| |
|:---|
| 56 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of Object Deal** |
| <br> struct Head{<br> uint8 typeOfDeal;<br> uint16 seqOfDeal;<br> uint16 preSeq;<br> uint16 classOfShare;<br> uint32 seqOfShare;<br> uint40 seller;<br> uint32 priceOfPaid;<br> uint32 priceOfPar;<br> uint48 closingDeadline;<br> uint16 votingWeight;<br> }<br>struct Body{<br> uint40 buyer;<br> uint40 groupOfBuyer;<br> uint64 paid;<br> uint64 par;<br> uint8 state;<br> uint16 para;<br> uint16 distrWeight;<br> bool flag;<br> }<br>struct Deal{<br> Head head;<br> Body body;<br> bytes32 hashLock;<br> }<br>|

---

The share transactions can be categorized into three basic types: "capital increase", "external transfer", and "internal transfer" as per the different types of buyer, and, by combinations of these 3 basic types, it can be further deduced into 7 types of deals in total. In **Shareholders Agreement**, different voting rules can be tailored for each of the said 7 types, so as to satisfy the customized requirements of investors.

---

| |
|:---|
| 57 |
| *[**Table of Contents**](#Toc)* |

---

3.4.2. Editorial APIs of Investment Agreement

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The external APIs of the **Investment Agreement** are primarily used to add, remove, or query **Deal**. In addition, to accommodate transaction requirements such as lock-up and closing of the subject shares, as well as the exercise of special shareholder rights, **Investment Agreement** reserves some other interfaces that may be automatically invoked by the relevant **Sub Keeper** in the course of executing the foregoing processes, so as to automatically update the status of the relevant variables.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To facilitate the drafting and amendment of the **Investment Agreement** by users, the following lists the editorial API interfaces related to contract drafting that may be invoked by external accounts.

---

| | |
|:---|:---|
| **Editorial Interfaces of Investment Agreement** | **Editorial Interfaces of Investment Agreement** |
| **API** | **Description of Functions and Parameters** |
| function addDeal(<br> bytes32 <u>*snOfDeal*</u>,<br> uint <u>*buyer*</u>,<br> uint <u>*groupOfBuyer*</u>,<br> uint <u>*paid*</u>,<br> uint <u>*par*</u>,<br> uint <u>*distrWeight*</u>) external; | Create and add a Deal object to the Investment Agreement with the transaction parameters encoded in bytes32 form as <u>*snOfDeal*</u>, the intended buyer identified by user number <u>*buyer*</u>, the representative of the buyer's affiliated group identified by user number <u>*groupOfBuyer*</u>, the paid value of the transaction as <u>*paid*</u>, the corresponding par value as <u>*par*</u>, and the distribution weight for the new class in a capital increase transaction as <u>*distrWeight*</u>. |
| function delDeal(uint256 <u>*seq*</u>) external; | Remove the Deal identified by sequence number <u>*seq*</u>. |
| function finalizeIA() external; | Finalize the Investment Agreement and lock its contents. |

---

---

| |
|:---|
| 58 |
| *[**Table of Contents**](#Toc)* |

---

3.4.3. Signature Page

**Signature page** is an independent, reusable and inheritable component smart contract that defines several key attributes of contract's execution, including contractual parties, signature fields, signing deadline and closing deadline etc..

**Investment Agreement** defines an initial **Signature Page** and a supplemental **Signature Page**, the former is to be signed by the contracting parties during the contract's formation, while the latter will be automatically filled up by **Bookkeeper** when the relevant right holders exercise their special rights (such as "First Refusal", "Tag-along, "Drag-along", and "Anti-Dilution" etc.)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; When a party calls the API of **Bookkeeper** to sign an **Investment Agreement**, **Bookkeeper** will record the block number and timestamp of the signing action in the signature field, moreover, the signature field also can store a special hash value generated by hashing handwriting signatures or scanned copy of company seal, which can be used to verify digital documents in future.

---

| |
|:---|
| 59 |
| *[**Table of Contents**](#Toc)* |

---

 **4. Identification and Access Control**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The smooth and safe operation of the **system** heavily relies on users' access control and routing control of write commands. In other words, for the calling commands which can change the world states ("**write commands**"), it is vital important to review and verify the identity and authority of the message sender (i.e. the calling account that send out the commands), and at the same time, the smart contract that received the write commands also needs to strictly control their further routing path, i.e. the target contract's address as well as its API to be further called. In brief, by strict controlling the write commands' routing path from two directions of "receiving" and "sending", the information of the whole system can be updated as per the predefined commercial and legal logic.

The write commands in the system can be divided into three categories:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **System Configuration**: refers to the contracts drafting and system configuration actions triggered by external accounts, which will NOT lead to legal consequences;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Legal Acts**: refers to the share transaction and corporate governance activities triggered by external accounts, which WILL directly lead to legal consequences; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Algorithmic Control**: refers to the write commands sent by **Bookkeeper**, upon receiving the previous two types of write commands, in accordance with the predefined algorithms of system, in an orderly manner and be able to change the states of other smart contracts like **Registers, Shareholders Agreement**, or **Investment Agreement**.

For the above write commands, the system adopts three verification methods as per their different nature of behaviors and scopes of influence.

---

| |
|:---|
| 60 |
| *[**Table of Contents**](#Toc)* |

---

 **4.1. Access Control Mechanism on smart contracts' level**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For **System Configuration** and **Algorithmic Control**, these two types of write commands do not dispose any book-entry interests of the system, and usually only take effects within the scope of the company, therefore, belong to the category of technique activities like system configuration, algorithmic control, and operation maintenance. Therefore, **ComBoox** adopts special smart contracts of **Ownable**, **Access Control** and **Draft Control**, which are inheritable and with component attributes, to verify identity of message sender by means of checking their address at the level of each smart contract.

4.1.1. Ownable

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Ownable** is a reusable, inheritable, component-based smart contract, which specialized in defining address accounts of "**Owner**" and "**Reg Center**". Clone contracts and proxy contracts created through **Reg Center** are descendant contracts of the **Ownable** contract. The address of **Reg Center** cannot be changed once it is set, while the **Owner** can transfer its role to other accounts.

---

| |
|:---|
| **Interface of Ownable** |
| <br> struct Admin{<br> address addr;<br> uint8 state;<br> }<br>event SetNewOwner(address indexed owner);<br>function initialize(address owner, address regCenter) external;<br>function setNewOwner(address acct) external;<br>function getOwner() external view returns (address);<br>function getRegCenter() external view returns (address);<br>|

---

---

| |
|:---|
| 61 |
| *[**Table of Contents**](#Toc)* |

---

4.1.2 Access Control

**Access Control** is a reusable, inheritable, component-based smart contract. Each and every smart contracts of the system are all descendant contracts of **Access Control**, so they all can use the methods and attributes inherited from **Access Control** to define roles with different write permissions and to verify them accordingly. **Access Control** defines two special roles "**Direct Keeper**" and "**General Keeper**".

---

| |
|:---|
| **Variables and Interface of Access Control** |
| <br> Admin internal _dk;<br> address internal _gk;<br>event SetDirectKeeper(address indexed keeper);<br>function upgradeDocTo (address newImplementation) external;<br>function initKeepers(address dk, address gk) external;<br>function setDirectKeeper(address keeper) external;<br>function takeBackKeys(address target) external;<br>function getDK() external view returns (address);<br>function getGK() external view returns (address);<br>|

---

**4.1.3. Draft Control**

**Draft Control** is a reusable, inheritable, component-based smart contract designed to define role groupings and their verification logic at the smart contract level. It is a descendant contract of **Access Control** and introduces a specialized role group known as **Attorneys**, whose administrative authority is assigned to a role referred to as the **General Counsel**. Only the EOA having **Attorney** role may edit or configure the terms of **Investment Agreement** or **Shareholders Agreement**.

Therefore, **Investment Agreement**, **Shareholders Agreement**, **Alongs**, **AntiDilution**, **LockUp**, and **Options** are all descendant contracts of **Draft Control**.

---

| |
|:---|
| 62 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Structure of Role and Roles Repo** |
| <br> struct Role{<br> address admin;<br> mapping(address => bool) isMember;<br> }<br>struct Repo{<br> mapping(bytes32 => Role) roles;<br> }<br>|

---

---

| |
|:---|
| **Variables and Interfaces of Draft Control** |
| <br> bytes32 private constant _ATTORNEYS = bytes32("Attorneys");<br>RolesRepo.Repo private _roles;<br>event SetRoleAdmin(bytes32 indexed role, address indexed acct); <br>event LockContents();<br>function setRoleAdmin(bytes32 role, address acct) external;<br>function grantRole(bytes32 role, address acct) external;<br>function revokeRole(bytes32 role, address acct) external;<br>function renounceRole(bytes32 role) external;<br>function abandonRole(bytes32 role) external;<br>function lockContents() external;<br>function isFinalized() external view returns (bool);<br>function getRoleAdmin(bytes32 role) external view returns (address);<br>function hasRole(bytes32 role, address acct) external view returns (bool);<br>|

---

---

| |
|:---|
| 63 |
| *[**Table of Contents**](#Toc)* |

---

**4.1.4. Owner**

**Owner** can be initially set by the account deploying the smart contract, which has the authority to create new group of roles and to appoint admin of the group. From commercial and legal view, **Owner** maps the role of "shareholder" of a company who has the rights to create, propose, review, and voting on approval of the legal documents like contracts, bylaws as well as motions of the General Meeting.

**Owner** can transfer its role to other accounts, and, will lose its role as **Owner** thereafter. **Direct Keeper** is the special role that cannot be influenced by **Owner**, which ensures its relative independence with respect to the roles appointment and control rights assignment, so as to check and balance the power of **Owner** from the perspective of system maintenance or duties independence.

**4.1.5. Direct Keeper**

**Direct Keeper** can be initially set by the account deploying of the smart contract, which has special authority to configure system, mapping the role of "Company Secretary" or "Accountants" from the commercial and legal view, the authority design of which reflects the characteristics of "Company Secretary" who is relatively independent from shareholders and senior executives in system maintenance and assuming independent responsibilities.

---

| |
|:---|
| 64 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Direct Keeper** can transfer its role to other accounts, and will lose the role of **Direct Keeper** thereafter.The General Keeper and all Registers inherit the standard smart contract of "UUPSUpgradeable", thereby possessing the capability to be upgraded without any change to their respective addresses or state variables. Only the Direct Keeper or the General Keeper is authorized to invoke the "upgradeTo()" function. Accordingly, the Company may elect to upgrade its General Keeper or Registers through either of the following methods: (i) by utilizing the General Keeper to transmit a pre-programmed payload to the target smart contract in order to trigger the upgrade function, or (ii) by transferring the Direct Keeper role to an externally owned account (EOA) and causing such EOA to invoke the upgrade function directly. The former method is subject to the Members' voting procedures and is therefore more secure, whereas the latter method is comparatively simpler to execute, as it does not require the programming or encoding of complex payloads.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; All write APIs of the Sub-Keepers are designed to be invoked exclusively through delegate calls initiated by the respective General Keeper; accordingly, all computations are performed within the context of the calling General Keeper. In this manner, any read or write commands sent by the Sub-Keepers may only be directed to the Registers' address retrieved by the calling General Keeper through its "getBook()" function. As a result, external accounts and third-party contracts are effectively precluded from interfering with the Company's governance activities, thereby ensuring that the Company's book-entry records operate securely and automatically, without human intervention.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; In addition, all write APIs of the Registers are restricted to access solely by their respective Direct Keeper or General Keeper. During the creation and initialization of the Company's book-entry system, the Direct Keeper role of each Register is assigned to the relevant General Keeper. Thereafter, access to the write APIs of the Registers shall be restricted exclusively to the General Keeper. This restriction serves as a second layer of security to prevent unauthorized external access.

---

| |
|:---|
| 65 |
| *[**Table of Contents**](#Toc)* |

---

The "**Direct Keeper**" of **General Keeper** has the following special authorities:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Set and update the registration address for each **SubKeeper** and **Register**;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Appoint or remove the "**Direct Keeper**" for each of the **SubKeeper** and **Register**;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Input off-chain "oracle" data (e.g. financial data such as revenue, net profit, etc.) into the system as trigger conditions for exercising certain shareholders rights; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Set up hash lock for pay-in capital, so as for new share subscribers can automatically obtain their **Certificates of Contribution** upon paying their capital contribution.

Therefore, the characters of its authority are quite similar to "**Company Secretary**" or "**Chief Accountant**".

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If **Direct Keeper** of **General Keeper** transfers its role to the General Keeper, then it means the possibility of human interference with the company's book-entry system is completely abandoned, and the system will automatically operate strictly in accordance with the **Shareholders Agreement** by smart contracts.

---

| |
|:---|
| 66 |
| *[**Table of Contents**](#Toc)* |

---

**4.1.6. General Counsel and Attorneys**

**General Counsel** is the admin of the roles group of **Attorneys** and has authorities to grant **Attorney** role to any account addresses.

**Attorneys** can quit their role as **Attorney** by calling the "Renouce Role" API, and **General Counsel** can call the "Abandon Role" API to fire all **Attorneys** at once.

For two types of smart contracts, **Shareholders Agreement** and **Investment Agreement**, only **Attorney** can call their write APIs to "draft" the contents of the contracts (such as rules and terms of **Shareholders Agreement**), or the deal's elements for trading shares (such as the subject share, price, amount), as well as the procedural conditions concerned (such as the contractual parties, signing deadline, and closing deadline etc.).

Therefore, after creating a smart contract of **Shareholders Agreement** or **Investment Agreement**, the creating shareholder as the "**Owner**" needs to appoint a "**General Counsel**" (which can further appoint one or more **Attorneys**) to "draft" the rest terms of the contents. After drafting, **Owner** can review and confirm the contract contents and then calls "**Lock Contents**" API to revoke the appointment for all attorneys at once, and to transfer the role of **Owner** to "zero address", so that, the contents can no longer be altered manually.

It should be emphasized that if **Owner** does not transfer its role to "zero address", it still can modify the contract by reappointing other address as "**General Counsel**" or "**Attorneys**".

---

| |
|:---|
| 67 |
| *[**Table of Contents**](#Toc)* |

---

 **4.2. Commands Routing Mechanism within the company**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The General Keeper serves as the sole entry point for all write commands relating to legal acts and maintains two mappings to record, retrieve and route commands to the addresses of the Sub-Keepers and Registers by reference to their respective sequence numbers. Accordingly, upon receiving any write command, the General Keeper utilizes the Sub-Keeper mapping to route such command to the appropriate address.

---

| |
|:---|
| **Address Mappings in General Keeper** |
| <br> mapping(uint256 => address) private _books;<br> mapping(uint256 => address) private _keepers;<br>|

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **Sub-Keepers** constitute the core computational layer governing identity verification, conditions, procedures, and the legal consequences of relevant actions. They do not store any state variables and operate in a manner analogous to libraries, being invoked exclusively through delegate calls initiated by the General Keeper. Accordingly, any calls routed through the Sub-Keepers are executed within the context of the General Keeper, such that the General Keeper is reflected as the "msg.sender".

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; All write APIs of the Registers are accessible solely by their respective Direct Keeper or the General Keeper. Upon the creation of each Register, the address of the General Keeper is permanently recorded therein, and the Direct Keeper role is transferred to the General Keeper in the initiation process. Consequently, command calls initiated by the General Keeper and routed through the Sub-Keepers via delegate call are duly verified and permitted to access the relevant APIs of the Registers. Conversely, any unauthorized calls originating from accounts other than the General Keeper are effectively excluded and blocked.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Through this mechanism, the General Keeper automatically routes write commands to the appropriate Sub-Keeper, and the specific algorithms defined within each Sub-Keeper are executed within the context of the General Keeper, such that all computations are performed against the General Keeper's state.

---

| |
|:---|
| 68 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As a result, external accounts and third-party contracts are effectively precluded from interfering with the Company's governance activities, thereby ensuring that the Company's book-entry records operate securely and autonomously, without human intervention.

---

| |
|:---|
| 69 |
| *[**Table of Contents**](#Toc)* |

---

 **4.3. Users Identification Mechanism for Entire Platform**

**Legal Acts** directly govern the disposal of book-entry interests, carrying significant commercial and legal implications. They may also give rise to relationships with other companies registered within the **ComBoox** system. Accordingly, the platform incorporates a dedicated smart contract, known as the **Reg Center**, along with a suite of methods designed for user identification. These mechanisms ensure robust identity verification across the entire system.

"**Users**" in the platform of **ComBoox**:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) can be shareholders, directors, managers within the Company, or the creditors, delegates, or agents outside of the Company;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) can establish a contractual relationship with one company, or establish legal relationships with multiple companies simultaneously;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) can be a natural person who controls on-chain behaviors through an external account, or a legal person who exercises its corporate legal rights through a contract account.

Therefore, **ComBoox** adopts a special smart contract **Reg Center** to manage all the digital identities of users of the entire platform.

**ComBoox** only takes the account address as the sole label to identify a user, and does not touch the name, nationality, residence or any other social characters of a natural person or a legal person. Therefore, strictly speaking, it is only the "**digital identity**" that the system actually manages or verifies.

This "**de-identified**" identity management model is shaped, on the one hand, by the inherent technical characteristics of public blockchain, and on the other, by its effectiveness in safeguarding users' personal privacy.

---

| |
|:---|
| 70 |
| *[**Table of Contents**](#Toc)* |

---

 **Nevertheless, almost all countries have real-name requirements like KYC or Anti-Money Laundering for commercial activities such as investment, financing, lending, payment, and foreign exchange etc. So please consult with legal experts of the relevant jurisdictions to seek professional advice on securities laws, anti-money laundering laws and other relevant legal issues so as to ensure all the arrangements and activities can be designed and carried out in a legal way.** 

With the concept of distributed digital identity, **Reg Center** uses a special user number mapping to register and manage users' identities, and at the same time, it also provides a query API for all smart contracts of the system to query and verify the users' identity in runtime.

**4.3.1. User Number Mapping**

User Number Mapping takes a structure as "address => uint256", which can be queried via special APIs for a specific account's user number with the corresponding address.

---

| |
|:---|
| **User Number Mapping** |
| <br> // key => userNo<br> mapping(address => uint) userNo; <br>|

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; When users exercise their rights, the **Sub-Keepers** of the relevant company invoke the query API of the **Reg Center**, through a dedicated library smart contract known as **Royalty Charge**. This **Royalty Charge** enables the **Sub-Keepers** to retrieve the user number of the message sender. The system then verifies the user's identity and access rights based on the records maintained in the corresponding **Register**.

---

| |
|:---|
| 71 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Royalty Charge** |
| event ChargeRoyalty(<br> uint indexed typeOfDoc, uint version, uint indexed rate, <br> uint indexed user, uint author);<br>function msgSender(<br> address target,<br> uint typeOfDoc,<br> uint version,<br> uint rate) external returns(uint40 usr) {<br> address gk = address(this);<br> uint author =<br> gk.getRCByGK().getTemp(<br> typeOfDoc,<br> version).head.author;<br>usr = _rc.getUserNo(<br> msgSender, rate \* (10 \*\* 10), head.author);<br> emit ChargeRoyalty(<br> head.typeOfDoc, head.version, rate, usr, head.author);<br> }<br>|

---

---

| |
|:---|
| **Get UserNo Function in Users Repo** |
| function getUserNo(Repo storage repo, address msgSender) public view returns(uint40) {<br>uint40 user = uint40(repo.userNo[msgSender]);<br>if (user > 0) return user;<br> else revert ("UR.getUserNo: not registered");<br>} |

---

For example, when shareholders exercise voting rights, **GMM Keeper** of the company will firstly call **Reg Center** to query the user number of the message sender, upon receiving the response, **GMM Keeper** will further call **Register of Members** to check whether the user is a member of the company. If the answer is yes, **GMM Keeper** will continue to execute the rest codes accordingly, otherwise, it will terminate the process and return an error message instead.

---

| |
|:---|
| 72 |
| *[**Table of Contents**](#Toc)* |

---

**4.3.2. User Registration** 

Before using any write functions of **ComBoox**, users need to apply for a registration number first (only checking, query or conduct other read operations on the platform of **ComBoox** does not require registration). **Reg Center** will assign a unique user number to the applicant as per its account address automatically.

---

| |
|:---|
| **Object User and Reg-User Function** |
| <br> struct Key {<br> address pubKey;<br> uint16 discount;<br> uint40 gift; <br> uint40 coupon;<br> }<br>struct User {<br> Key primeKey;<br> Key backupKey;<br> }<br>struct Repo {<br> // userNo => User<br> mapping(uint256 => User) users;<br> // key => userNo<br> mapping(address => uint) userNo;<br> LockersRepo.Repo lockers; <br> }<br>function regUser(Repo storage repo, address msgSender) public <br> returns (User memory)<br> {<br> if (msgSender == address(0)) <br> revert USRR_WrongInput(bytes32("USRR_ZeroAddress"));<br>if (usedKey(repo, msgSender))<br> revert USRR_WrongInput(bytes32("USRR_UsedKey"));<br> uint userNo = block.timestamp;<br>do {<br> userNo = uint40(uint(keccak256(abi.encodePacked(<br> userNo, msgSender))));<br> } while (userNo == 0 \|\| !repo.usersList.add(userNo));<br>repo.userNo[msgSender] = userNo;<br>User memory user;<br>user.primeKey.pubKey = msgSender;<br>Rule memory rule = getPlatformRule(repo);<br>if (_isContract(msgSender)) {<br> user.primeKey.discount = 1;<br> user.primeKey.gift = rule.coaRewards;<br> } else user.primeKey.gift = rule.eoaRewards;<br>repo.users[seqOfUser] = user;<br>return user;<br> }<br>|

---

---

| |
|:---|
| 73 |
| *[**Table of Contents**](#Toc)* |

---

After creating new book-entry system for a company, the creator may call "Create Corp Seal" API of **General Keeper** to register a specific user number for the company with **Reg Center. Reg Center** will then assign a user number to the address of the **General Keeper**, which represents the legal person of the company in **ComBoox** and can be used to send write commands to exercise rights on behalf of the company concerned. (If creating a new book-entry system by calling the "Create Comp" API of **Reg Center**, predefined scripts will automatically register a user number for the new company.)

**4.3.3. Backup Key**

To avoid losing control of user account only because losing private key, **ComBoox** allows the registered users to set **ONE** additional account address as "**Backup Key**" (the account address used in registration process is deemed as "**Prime Key**"). However, to prevent the circumvention of some contractual obligations like "Lock-Up" or "First Refusal", the system does **NOT** allow to change the **Backup Key** or add more keys. Therefore, a user can only have maximum two keys, the "**Prime Key**" and "**Backup Key**". The address of "**Backup key**" can also be recognized by **Reg Center** as having the same user number as the "**Prime Key**". Any used account address cannot be used again to register user number or to be set as backup key.

---

| |
|:---|
| 74 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Function of Set Backup Key** |
| <br> function setBackupKey(<br> Repo storage repo, <br> address bKey, <br> address msgSender) public onlyPrimeKey(repo, msgSender) {<br>if (msgSender == address(0)) <br> revert USRR_WrongInput(bytes32("URSBK_ZeroCallerAddress"));<br> if (bKey == address(0)) <br> revert USRR_WrongInput(bytes32("URSBK_ZeroBKeyAddress"));<br> if (usedKey(repo, bKey))<br> revert USRR_WrongInput(bytes32("URSBK_UsedKey"));<br>uint caller = getUserNo(repo, msgSender);<br>User storage user = repo.users[caller];<br>if (user.backupKey.pubKey != address(0))<br> revert USRR_WrongInput(bytes32("URSBK_AlreadySetBackupKey"));<br>user.backupKey.pubKey = bKey;<br> repo.userNo[bKey] = caller;<br>}<br>|

---

**4.3.4. Permission for Query User Number**

The query API of **Reg Center** for retrieving user number is only accessibly for the contract accounts already registered in **ComBoox** and the user's own account. If the query sender is not the relevant user's account, a sum of royalty will be charged from the target user's account to pay to the author account when responding the user's number. To prevent malicious consuming the user's royalty, external smart contracts not registered with **ComBoox** will be blocked in the front end.

---

| |
|:---|
| 75 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Function of Get User Number** |
| <br> function getUserNo(address targetAddr, uint fee, uint author) external returns (uint40) {<br> uint40 target = _getUserNo(targetAddr);<br> if(!docExist(msg.sender))<br> revert RC_WrongAccess(bytes32("RC_DocNotRegistered"));<br> UsersRepo.Key memory rr = getRoyaltyRule(author);<br> address authorAddr = _getUserByNo(author).primeKey.pubKey; <br> _chargeFee(targetAddr, fee, authorAddr, rr);<br> return target;<br> }<br>function _getUserNo(address targetAddr) internal view returns (uint40) {<br> return _users.getUserNo(targetAddr);<br> }<br>function getRoyaltyRule(uint author)public view returns (UsersRepo.Key memory) {<br> return _users.getRoyaltyRule(author);<br> }<br>function _getUserByNo(uint acct) internal view returns (UsersRepo.User memory usr){<br> if (_users.isUserNo(acct)) {<br> usr = _users.users[acct];<br> } else revert BOU_WrongInput(bytes32("BOU_AcctNotRegistered"));<br> }<br>|

---

---

| |
|:---|
| 76 |
| *[**Table of Contents**](#Toc)* |

---

 **5. Templates and Version Control**

 **5.1. Proxying and Cloning Technology**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **ComBoox** extensively adopts proxying and cloning technologies in its smart contract architecture. Specifically, it utilizes the data structures, functions, and algorithms defined in implementation template contracts to operate on the state variables of proxy contracts or clone contracts through the delegatecall mechanism. Proxying technology enables a proxy contract to upgrade its underlying logic without altering its address or stored state variables. In comparison with independently deployed contracts, cloning technology significantly reduces the bytecode size and gas consumption associated with contract deployment. The **General Keeper** and the **Registers** are deployed by proxying their respective implementation templates, whereas **Shareholders' Agreements** and **Investment Agreements** are deployed using cloning techniques.

---

| |
|:---|
| 77 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Function of Proxy Doc** |
| <br> function proxyDoc(<br> Repo storage repo, uint typeOfDoc, uint version, uint creator) public returns (Doc memory doc) {<br> doc = getTemp(repo, typeOfDoc, version);<br> doc.head.creator = uint40(creator);<br> if (doc.head.creator == 0)<br> revert DocsRepo_WrongInput(bytes32("DR_ZeroCreator"));<br> bytes memory data = abi.encodeWithSignature(<br> "initialize(address,address)",<br> msg.sender,<br> address(this));<br> doc.body = address(new ERC1967Proxy(doc.body, data));<br> _regDoc(repo, doc);<br> }<br>function _regDoc(<br> Repo storage repo, Doc memory doc) private {<br> doc.head.seqOfDoc = _increaseCounterOfDocs(repo, doc.head.typeOfDoc, doc.head.version);<br> doc.head.createDate = uint48(block.timestamp);<br> repo.bodies[doc.head.typeOfDoc][doc.head.version][doc.head.seqOfDoc].addr = doc.body;<br> repo.heads[doc.body] = doc.head;<br> }<br>function _increaseCounterOfDocs(<br> Repo storage repo, uint256 typeOfDoc, uint256 version) private returns(uint64) {<br> unchecked {<br> repo.bodies[typeOfDoc][version][0].seq = <br> repo.bodies[typeOfDoc][version][0].seq == type(uint64).max<br> ? 1<br> : repo.bodies[typeOfDoc][version][0].seq + 1;<br> }<br> return repo.bodies[typeOfDoc][version][0].seq;<br> }<br>|

---

---

| |
|:---|
| 78 |
| *[**Table of Contents**](#Toc)* |

---

---

| |
|:---|
| **Function of Create Clone** |
| /\*<br>The MIT License (MIT)<br>Copyright (c) 2018 Murray Software, LLC.<br>Permission is hereby granted, free of charge, to any person obtaining<br>a copy of this software and associated documentation files (the<br>"Software"), to deal in the Software without restriction, including<br>without limitation the rights to use, copy, modify, merge, publish,<br>distribute, sublicense, and/or sell copies of the Software, and to<br>permit persons to whom the Software is furnished to do so, subject to<br>the following conditions:<br>The above copyright notice and this permission notice shall be included<br>in all copies or substantial portions of the Software.<br>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS<br>OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<br>MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.<br>IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY<br>CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,<br>TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE<br>SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br>\*/<br>//solhint-disable max-line-length<br>//solhint-disable no-inline-assembly<br>function _createClone(address temp) private returns (address result) {<br> bytes20 tempBytes = bytes20(temp);<br> assembly {<br> let clone := mload(0x40)<br> mstore(<br> clone,<br> 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)<br> mstore(add(clone, 0x14), tempBytes)<br> mstore(<br> add(clone, 0x28),<br> 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)<br> result := create(0, clone, 0x37)<br> }<br>} |

---

In addition, **contract templates** also adopts a lot of **delegate call mechanism**, i.e.leaving the definitions of data objects, methods and algorithms thereof in public libraries, which further reduced the size of the template contracts, as well as their deploying cost.

---

| |
|:---|
| 79 |
| *[**Table of Contents**](#Toc)* |

---

 **5.2. Documents Mapping of Reg Center**

Another important function of **Reg Center** is to register and manage the template contracts and their clones, for which **Reg Center** adopts two mappings. Users can query a document's type, version, author, creator and creation date by its contract address, or, query a document's address by its sequence number.

---

| |
|:---|
| **Documents Mapping Structure** |
| <br> struct Head {<br> uint32 typeOfDoc;<br> uint32 version;<br> uint64 seqOfDoc;<br> uint40 author;<br> uint40 creator;<br> uint48 createDate;<br> }<br>struct Body {<br> uint32 version;<br> uint64 seq;<br> address addr;<br> }<br>struct Repo {<br> // typeOfDoc => version => seqOfDoc => Body<br> mapping(uint256 => mapping(uint256 => mapping(uint256 => Body))) bodies;<br> // body address => Head <br> mapping(address => Head) heads;<br> // typeOfDoc set<br> EnumerableSet.UintSet typesList;<br> }<br>|

---

---

| |
|:---|
| 80 |
| *[**Table of Contents**](#Toc)* |

---

 **5.3. Types of Template Contracts**

Currently, there are totally 37 template contracts registered in **Reg Center**. When creating a new book-entry system for a company, or creating a new **Shareholders Agreement** or **Investment Agreement**, actually is deploying one or more proxy or clone contracts based on the templates.

---

| | | |
|:---|:---|:---|
| **Template Contracts** | **Template Contracts** | **Template Contracts** |
| **Name** | **Name** | **Name** |
| ROCKeeper | Register of Constitution | FundROCKeeper |
| RODKeeper | Register of Directors |  |
| BMMKeeper | MeetingMinutes |  |
| ROMKeeper | RegisterOfMembers |  |
| GMMKeeper | RegisterOfShares | FundGMMKeeper |
| ROAKeeper | RegisterOfAgreements | Alongs |
| ROOKeeper | RegisterOfOptions | Options |
| ROPKeeper | RegisterOfPledge | LockUp |
| SHAKeeper | InvestmentAgreement |  |
| LOOKeeper | ListOfOrders | FundLOOKeeper |
| ROIKeeper | RegisterOfInvestors | FundROIKeeper |
| Accountant | Cashier | FundAccountant |
| FundRORKeeper | RegisterOfRedemptions | AntiDilution |
| GeneralKeeper | ShareholdersAgreement |  |

---

In **ComBoox**, the design model for setting corporate governance rules is very flexible. Changing the definition of a specific "rule" and its parsing function, the attributes' composition of the rule will be changed; changing an API's algorithm of a **Bookkeeper**, the conditions, procedures and consequences of a legal behavior will be revised. And, all these changing methods on the corporate governing rules and terms, can be implemented by means of developing and incorporating new contract templates into the system.

---

| |
|:---|
| 81 |
| *[**Table of Contents**](#Toc)* |

---

Any developer can develop **contract templates**. These templates can be incorporated into the system upon approval and will become new foundations for proxying or cloning contracts. When users call to proxy or clone contracts, **Reg Center** will deduct a certain amount of CBP from the caller's account and pay to the template author's account as license fees. The rate of such license fee, together with its promotion policies, can be set and adjusted by the template's author at full discretion.

For detailed arrangements concerning the copyright and license fee, as well as **CBP** tokens and the economic model of the system, please see the relevant sections of this paper.

---

| |
|:---|
| 82 |
| *[**Table of Contents**](#Toc)* |

---

 **6. External Write APIs** 

There are totally 84 external write APIs exposed by the system, which collectively encompass nearly all legal acts relating to corporate governance, share transactions, the payment and receipt of USDC. These APIs are routed to various Sub-Keepers for further processing and execution, thereby effectuating the corresponding legal consequences of each act.

 **6.1. APIs Routed To ROC Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 1 | function **createSHA**(<br> uint <u>*version*</u>) external | (Any Member) Create a new shareholders agreement by cloning the Template of the specific <u>*version*</u>. |
| 2 | function **circulateSHA**(<br> address <u>*body*</u>, <br> bytes32 <u>*docUrl*</u>, <br> bytes32 <u>*docHash*</u>) external | (The Owner of the draft) Circulate the finalized draft of shareholders agreement deployed at the address of <u>*body*</u> to the contractual parties for signing, with the URL infomation of <u>*docUrl*</u>, and hash value of <u>*docHash*</u>. |
| 3 | function **signSHA**(<br> address <u>*sha*</u>, <br> bytes32 <u>*sigHash*</u>) external | (Parties to the draft) Sign the finalized draft of shareholders agreement deployed at the address of <u>*sha*</u>, with the hash value of signature as <u>*sigHash*</u>. |
| 4 | function **activateSHA**(<br> address <u>*body*</u>) external | (Any user) Activate the draft of shareholders agreement deployed at the address of <u>*body*</u>. |
| 5 | function **acceptSHA**(<br> bytes32 <u>*sigHash*</u>) external | (Any user) Accept the terms and conditons of SHA in force, with the hash value as <u>*sigHash*</u>. |

---

---

| |
|:---|
| 83 |
| *[**Table of Contents**](#Toc)* |

---

![](rockeeper-01.jpg)

---

| |
|:---|
| 84 |
| *[**Table of Contents**](#Toc)* |

---

![](rockeeper-02.jpg)

---

| |
|:---|
| 85 |
| *[**Table of Contents**](#Toc)* |

---

![](rockeeper-03.jpg)

---

| |
|:---|
| 86 |
| *[**Table of Contents**](#Toc)* |

---

![](rockeeper-04.jpg)

---

| |
|:---|
| 87 |
| *[**Table of Contents**](#Toc)* |

---

![](rockeeper-05.jpg)

---

| |
|:---|
| 88 |
| *[**Table of Contents**](#Toc)* |

---

 **6.2. APIs Routed to ROD Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 6 | function **takeSeat**(<br> uint256 <u>seqOfMotion</u>, <br> uint256 <u>seqOfPos</u>) external | (The elected Director) Assume the director's seat identified by <u>*seqOfPos*</u> pursuant to the authorization granted under the Motion identified by <u>*seqOfMotion*</u>. |
| 7 | function **removeDirector** (<br> uint256 <u>*seqOfMotion*</u>, <br> uint256 <u>*seqOfPos*</u>) external | (The Member having the nomination right) Remove the director on the position numbered as <u>*seqOfPos*</u> as per the removal Motion numbered as <u>*seqOfMotion*</u>. |
| 8 | function **takePosition**(<br> uint256 <u>*seqOfMotion*</u>, <br> uint256 <u>*seqOfPos*</u>) external | (The elected officer) Take the officer position identified as <u>*seqOfPos*</u> pursuant to the authorization granted under the Motion identified as <u>*seqOfMotion*</u>. |
| 9 | function **removeOfficer** (<br> uint256 <u>*seqOfMotion*</u>, <br> uint256 <u>*seqOfPos*</u>) external | (The executor) Remove the executive officer on the position numbered as <u>*seqOfPos*</u> as per the removal Motion numbered as <u>*seqOfMotion*</u>. |
| 10 | function **quitPosition**(<br> uint256 <u>*seqOfPos*</u>) external | (The Director or officer) Quit the position identified as <u>*seqOfPos*</u> voluntarily. |

---

---

| |
|:---|
| 89 |
| *[**Table of Contents**](#Toc)* |

---

![](rodkeeper-06.jpg)

---

| |
|:---|
| 90 |
| *[**Table of Contents**](#Toc)* |

---

![](rodkeeper-07.jpg)

---

| |
|:---|
| 91 |
| *[**Table of Contents**](#Toc)* |

---

![](rodkeeper-08.jpg)

---

| |
|:---|
| 92 |
| *[**Table of Contents**](#Toc)* |

---

![](rodkeeper-09.jpg)

---

| |
|:---|
| 93 |
| *[**Table of Contents**](#Toc)* |

---

![](rodkeeper-10.jpg)

---

| |
|:---|
| 94 |
| *[**Table of Contents**](#Toc)* |

---

 **6.3. APIs Routed To BMM Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 11 | function **nominateOfficer**(<br> uint256 <u>*seqOfPos*</u>, <br> uint256 <u>*candidate*</u>) external | (The Director having the nomination right) Nominate the user identified by its user number as <u>*candidate*</u> for the officer's position numbered as <u>*seqOfPos*</u>. |
| 12 | function **createMotionToRemoveOfficer**(<br> uint256 <u>*seqOfPos*</u>) external | (The Director having the nomination right) Create a draft Motion to remove the officer on the position numbered as <u>*seqOfPos*</u>. |
| 13 | function **createMotionToApproveDoc**(<br> uint256 <u>*doc*</u>, <br> uint256 <u>*seqOfVR*</u>, <br> uint256 <u>*executor*</u>) external | (Any Director) Creates a draft Motion for the Board to approve the document deployed at the address of <u>*doc*</u> as per the voting rule numbered as <u>*seqOfVR*</u> with the user numbered as <u>*executor*</u> to invoke it. |
| 14 | function **proposeToTransferFundWithBoard**(<br> address <u>*to*</u>,<br> bool <u>*isCBP*</u>,<br> uint256 <u>*amt*</u>,<br> uint256 <u>*expireDate*</u>,<br> uint256 <u>*seqOfVR*</u>,<br> uint256 <u>*executor*</u>) external | (Any Director) Propose, to the Board Meeting, to transfer certain amount of CBP (<u>*isCBP*</u> is true) or USDC (<u>*isCBP*</u> is false), to the account address <u>*to*</u>, amount to <u>*amt*</u>, before the timestamp of <u>*expireDate*</u>, as per the **Voting Rule** numbered as <u>*seqOfVR*</u>, with the user numbered as <u>*executor*</u> to execute the **Motion** concerned. |
| 15 | function **createAction**(<br> uint256 <u>*seqOfVR*</u>,<br> address[] memory <u>*targets*</u>,<br> uint256[] memory <u>*values*</u>,<br> bytes[] memory <u>*params*</u>,<br> bytes32 <u>*desHash*</u>,<br> uint256 <u>*executor*</u>) external | Create a draft Motion for the Board to invoke a series of calls, as per the voting rule numbered as <u>*seqOfVR*</u>, to the contracts deployed at their respective addresses of <u>*targets*</u>, with paying ETH amount to <u>*values*</u>, and inputting parameters of <u>*params*</u>, attached with the hash value of the description message as <u>*desHash*</u>, with the user numbered as <u>*executor*</u> to invoke it. |
| 16 | function **entrustDelegaterForBoardMeeting**(<br> uint256 <u>*seqOfMotion*</u>, <br> uint256 <u>*delegate*</u>) external; | (Any Directors) Entrust the user numbered as <u>*delegate*</u> to cast vote in Board meeting for the Motion identified as <u>*seqOfMotion*</u>. |
| 17 | function **proposeMotionToBoard** (<br> uint256 <u>*seqOfMotion*</u>) external | (Any Director) Propose the draft Motion numbered as <u>*seqOfMotion*</u> to the Board meeting. |
| 18 | function **castVote**(<br> uint256 <u>*seqOfMotion*</u>, <br> uint256 <u>*attitude*</u>, <br> bytes32 <u>*sigHash*</u>) external | (Any Director) Casts vote with the attitude for the Motion numbered as <u>*seqOfMotion*</u> with the signature message's hash value as <u>*sigHash*</u>. |
| 19 | function **voteCounting**(<br> uint256 <u>*seqOfMotion*</u>) external | (Any user) Count the vote result for the Motion numbered as <u>*seqOfMotion*</u>. |
| 20 | function **execAction**(<br> uint <u>*typeOfAction*</u>,<br> address[] memory <u>*targets*</u>,<br> uint256[] memory <u>*values*</u>,<br> bytes[] memory <u>*params*</u>,<br> bytes32 <u>*desHash*</u>,<br> uint256 <u>*seqOfMotion*</u>) external | (The designated executor) Executes the Motion numbered as <u>*seqOfMotion*</u>, categorized as <u>*typeOfAction*</u>, to invoke the series of calls to the contracts deployed at addresses of <u>*targets*</u>, with paying the respective ETH amount to <u>*values*</u>, inputting parameters as <u>*params*</u>, attached with description message's hash value as <u>*desHash*</u>. |

---

---

| |
|:---|
| 95 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-11.jpg)

---

| |
|:---|
| 96 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-12.jpg)

---

| |
|:---|
| 97 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-13.jpg)

---

| |
|:---|
| 98 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-14.jpg)

---

| |
|:---|
| 99 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-15.jpg)

---

| |
|:---|
| 100 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-16.jpg)

---

| |
|:---|
| 101 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-17.jpg)

---

| |
|:---|
| 102 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-18.jpg)

---

| |
|:---|
| 103 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-19.jpg)

---

| |
|:---|
| 104 |
| *[**Table of Contents**](#Toc)* |

---

![](bmmkeeper-20.jpg)

---

| |
|:---|
| 105 |
| *[**Table of Contents**](#Toc)* |

---

 **6.4. APIs Routed To ROM Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 21 | function **setMaxQtyOfMembers**(<br> uint256 <u>*max*</u>) external | (The sectary of company, i.e. the Direct Keeper of General Keeper) Set the max quantity of Members as <u>*max*</u>. |
| 22 | function **setPayInAmt**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*amt*</u>, <br> uint256 <u>*expireDate*</u>, <br> bytes32 <u>*hashLock*</u>) external | (The sectary of company, i.e. the Direct Keeper of General Keeper) Set the intended pay in amount of <u>*amt*</u> for the share numbered as <u>*seqOfShare*</u>, before the date of <u>*expireDate*</u>, with the hash lock whose hash value is <u>*hashLock*</u>. |
| 23 | function **requestPaidInCapital**(<br> bytes32 <u>*hashLock*</u>, <br> string memory <u>*hashKey*</u>) external | (The Member, after paying the paid in the relevant price off-chain) Request the specific paid in amount for the target share by inputting the hash key string <u>*hashKey*</u> to unlock the hash lock whose hash value is <u>*hashLock*</u>. |
| 24 | function **withdrawPayInAmt**(<br> bytes32 <u>*hashLock*</u>, <br> uint256 <u>*seqOfShare*</u>) external | (The secrtary of the company, i.e. the Direct Keeper of General Keeper, after the expiration date of the relevant hash lock) Withdraw the setting for granting the pay in amount for the specific share numbered as <u>*seqOfShare*</u>, by inputting the hash lock value <u>*hashLock*</u>. |
| 25 | function **payInCapital**(<br> ICashier.TransferAuth memory <u>*auth*</u>, <br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*paid*</u>) external; | (The shareholder) Pay in capital, for its specific share numbered as <u>*seqOfShare*</u>, to the amount of paid as <u>*paid*</u>, by paying certain amount of USDC through off-chain authorization signed as <u>*auth*</u>. |
| 26 | function **decreaseCapital**(<br> uint <u>*seqOfVR*</u>,<br> uint256 <u>*seqOfShare*</u>,<br> uint <u>*paid*</u>,<br> uint <u>*par*</u>,<br> uint <u>*amt*</u>,<br> uint <u>*seqOfMotion*</u>) external; | (The authorized executor) Decrease the registered capital of the share numbered as <u>*seqOfShare*</u>, as per the voting rule numbered as <u>*seqOfVR*</u>, with the paid value amount to <u>*paid*</u>, par value amount to <u>*par*</u>, and USDC value amount to <u>*amt*</u>, according to the passed resolution numbered as <u>*seqOfMotion*</u>. |

---

---

| |
|:---|
| 106 |
| *[**Table of Contents**](#Toc)* |

---

![](romkeeper-21.jpg)

---

| |
|:---|
| 107 |
| *[**Table of Contents**](#Toc)* |

---

![](romkeeper-22.jpg)

---

| |
|:---|
| 108 |
| *[**Table of Contents**](#Toc)* |

---

![](romkeeper-23.jpg)

---

| |
|:---|
| 109 |
| *[**Table of Contents**](#Toc)* |

---

![](romkeeper-24.jpg)

---

| |
|:---|
| 110 |
| *[**Table of Contents**](#Toc)* |

---

![](romkeeper-25.jpg)

---

| |
|:---|
| 111 |
| *[**Table of Contents**](#Toc)* |

---

![](romkeeper-26.jpg)

---

| |
|:---|
| 112 |
| *[**Table of Contents**](#Toc)* |

---

 **6.5. APIs Routed To GMM Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 27 | function **nominateDirector**(<br> uint256 <u>*seqOfPos*</u>, <br> uint256 <u>*candidate*</u>) external | (The Member who has the nomination right) Nominate the user numbered as <u>*candidate*</u> for the Director's position numbered as <u>*seqOfPos*</u>. |
| 28 | function **createMotionToRemoveDirector**(<br> uint256 <u>*seqOfPos*</u>) external | (The Member who has the nomination right) Create a draft motion to remove the Director on the position numbered as <u>seqOfPos</u>. |
| 29 | function **proposeDocOfGM**(<br> uint256 <u>*doc*</u>, <br> uint256 <u>*seqOfVR*</u>, <br> uint256 <u>*executor*</u>) external | (A Member) Create and propose a draft Motion for the General Meeting to approve the document deployed at the address of <u>*doc*</u> as per the voting rule numbered as <u>*seqOfVR*</u> with the user numbered as <u>*executor*</u> to invoke it. |
| 30 | function **proposeToDistributeUsd**(<br> uint <u>*amt*</u>,<br> uint <u>*expireDate*</u>,<br> uint <u>*seqOfVR*</u>,<br> uint <u>*seqOfDR*</u>,<br> uint <u>*para*</u>,<br> uint <u>*executor*</u>) external; | (A Member) Create and propose a draft Motion for the General Meeting to approve distribution a sum of USDC amount to <u>*amt*</u> before the expiration date <u>*expireDate*</u>, as per the voting rule numbered as <u>*seqOfVR*</u> and the distribution rule numbered as <u>*seqOfDR*</u>, with the parameter of <u>*para*</u> and with the user numbered as <u>*executor*</u> to invoke it. |
| 31 | function **proposeToTransferFundWithGM**(<br> address <u>*to*</u>,<br> bool <u>*isCBP*</u>,<br> uint256 <u>*amt*</u>,<br> uint256 <u>*expireDate*</u>,<br> uint256 <u>*seqOfVR*</u>,<br> uint256 <u>*executor*</u>) external | (A Member or Director) Propose, to the General Meeting, to transfer certain amount of CBP (<u>*isCBP*</u> is true) or USDC (<u>*isCBP*</u> is false), to the account address <u>*to*</u>, amount to <u>*amt*</u>, before the timestamp of <u>*expireDate*</u>, as per the Voting Rule numbered as <u>*seqOfVR*</u>, with the user numbered as <u>*executor*</u> to execute the Motion concerned. |
| 32 | function **createActionOfGM**(<br> uint <u>*seqOfVR*</u>,<br> address[] memory <u>*targets*</u>,<br> uint256[] memory <u>*values*</u>,<br> bytes[] memory <u>*params*</u>,<br> bytes32 <u>*desHash*</u>,<br> uint <u>*executor*</u>) external | (A Member) Create a draft Motion for the General Meeting to execute a series of calls, as per the voting rule numbered as <u>*seqOfVR*</u>, to the contracts deployed at the addresses of <u>*targets*</u>, with paying the respective ETH amount to <u>*values*</u>, and inputting parameters of <u>*params*</u>, attached a description message whose hash value is <u>*desHash*</u>, with the user numbered as <u>*executor*</u> to invoke it. |
| 33 | function **entrustDelegaterForGeneralMeeting**(<br> uint256 <u>*seqOfMotion*</u>, <br> uint256 <u>*delegate*</u>) external | (A Member) Entrust the user numbered as <u>*delegate*</u> to cast vote in General Meeting for the Motion numbered as <u>*seqOfMotion*</u>. |
| 34 | function **proposeMotionToGeneralMeeting**(<br> uint256 <u>*seqOfMotion*</u>) external | (A Member) Proposes the Motion numbered as <u>*seqOfMotion*</u> to the General Meeting. |
| 35 | function **castVoteOfGM**(<br> uint256 <u>*seqOfMotion*</u>,<br> uint256 <u>*attitude*</u>,<br> bytes32 <u>*sigHash*</u>) external | (A Member) Cast vote with the attitude for the Motion numbered as <u>*seqOfMotion*</u> with the signature message's hash value as <u>*sigHash*</u>. |
| 36 | function **voteCountingOfGM**(<br> uint256 <u>*seqOfMotion*</u>) external | (Any user) Count the vote result for the Motion on the General Meeting numbered as <u>*seqOfMotion*</u>. |
| 37 | function **execActionOfGM**(<br> uint <u>*typeOfAction*</u>,<br> address[] memory <u>*targets*</u>,<br> uint256[] memory <u>*values*</u>,<br> bytes[] memory <u>*params*</u>,<br> bytes32 <u>*desHash*</u>,<br> uint256 <u>*seqOfMotion*</u>) external | (The designated executor) Execute the Motion numbered as <u>*seqOfMotion*</u>, categorized as <u>*typeOfAction*</u>, to trigger the series of calls to the contracts deployed at addresses of <u>*targets*</u>, with paying the respective ETH amount to <u>*values*</u>, inputting parameters as <u>*params*</u>, attached with hash value of the description message as <u>*desHash*</u>. |

---

---

| |
|:---|
| 113 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-27.jpg)

---

| |
|:---|
| 114 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-28.jpg)

---

| |
|:---|
| 115 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-29.jpg)

---

| |
|:---|
| 116 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-30.jpg)

---

| |
|:---|
| 117 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-31.jpg)

---

| |
|:---|
| 118 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-32.jpg)

---

| |
|:---|
| 119 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-33.jpg)

---

| |
|:---|
| 120 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-34.jpg)

---

| |
|:---|
| 121 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-35.jpg)

---

| |
|:---|
| 122 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-36.jpg)

---

| |
|:---|
| 123 |
| *[**Table of Contents**](#Toc)* |

---

![](gmmkeeper-37.jpg)

---

| |
|:---|
| 124 |
| *[**Table of Contents**](#Toc)* |

---

 **6.6. APIs Routed To ROA Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 38 | function **createIA**(<br> uint256 <u>*version*</u>) external | (Any Member) Create a draft Investment Agreement on the Register of Agreement, by cloning the Template of the version numbered as <u>*version*</u>. |
| 39 | function **circulateIA**(<br> address <u>*body*</u>, <br> bytes32 <u>*docUrl*</u>, <br> bytes32 <u>*docHash*</u>) external | (The Member who is the Owner of the draft Investment Agreement) Circulate the finalized draft deployed at the address of <u>*body*</u> to the parties for signature, attaching with the URL information of <u>*docUrl*</u> and the hash value of the draft as <u>*docHash*</u>. |
| 40 | function **signIA**(<br> address <u>*ia*</u>, <br> bytes32 <u>*sigHash*</u>) external | (The parties to the Investment Agreement) Sign the Investment Agreement deployed at the address of <u>*ia*</u>, with the signature message's hash value as <u>*sigHash*</u>. |
| 41 | function **pushToCoffer**(<br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>, <br> bytes32 <u>*hashLock*</u>, <br> uint256 <u>*closingDeadline*</u>) external | (The seller) Confirm all conditions precedent have been satisfied and ready for closing, for the specific deal numbered as <u>*seqOfDeal*</u>, under the Investment Agreement deployed at the address of <u>*ia*</u>, by inputting a hash lock value <u>*hashLock*</u> and setting the closing deadline as <u>*closingDeadline*</u>. |
| 42 | function **closeDeal**(<br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>, <br> string memory <u>*hashKey*</u>) external | (The buyer) Close the deal numbered as <u>*seqOfDeal*</u>, under the Investment Agreement deployed at the address of <u>*ia*</u>, after paying the consideration off-chain, by inputting the hash key string <u>*hashKey*</u>. |
| 43 | function **issueNewShare**(<br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>) external | (The issuer) Issue new share directly to the buyer, for the capital increasing Deal numbered as <u>*seqOfDeal*</u> under the Investment Agreement deployed at the address of <u>*ia*</u>. |
| 44 | function **transferTargetShare**(<br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>) external | (The seller) Transfer the subject share directly to the buyer, for the specific share transfer Deal numbered as <u>*seqOfDeal*</u> under the Investment Agreement deployed at the address of <u>*ia*</u>. |
| 45 | function **terminateDeal**(<br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>) external | (The seller, after the expiration date concerned) Terminate the Deal numbered as <u>*seqOfDeal*</u> under the Investment Agreement deployed at the address of <u>*ia*</u>. |
| 46 | function **payOffApprovedDeal**(<br> ICashier.TransferAuth memory <u>*auth*</u>, <br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>, <br> address <u>*to*</u>) external; | (The buyer) Pay off the specific Deal numbered as <u>*seqOfDeal*</u> in the Investment Agreement deployed as the address of <u>*ia*</u>, by paying to the seller/issuer address <u>*to*</u> certain amount of USDC as per the off-chain authorization signed as <u>*auth*</u>, to close the Deal. |

---

---

| |
|:---|
| 125 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-38.jpg)

---

| |
|:---|
| 126 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-39.jpg)

---

| |
|:---|
| 127 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-40.jpg)

---

| |
|:---|
| 128 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-41.jpg)

---

| |
|:---|
| 129 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-42.jpg)

---

| |
|:---|
| 130 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-43.jpg)

---

| |
|:---|
| 131 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-44.jpg)

---

| |
|:---|
| 132 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-45.jpg)

---

| |
|:---|
| 133 |
| *[**Table of Contents**](#Toc)* |

---

![](roakeeper-46.jpg)

---

| |
|:---|
| 134 |
| *[**Table of Contents**](#Toc)* |

---

 **6.7. APIs Routed To ROO Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 47 | function **updateOracle**(<br> uint256 <u>*seqOfOpt*</u>,<br> uint256 <u>*d1*</u>,<br> uint256 <u>*d2*</u>,<br> uint256 <u>*d3*</u>) external | (The sectary of the company, i.e. the Direct Keeper of General Keeper) Update the key performance indicators of <u>*d1*</u>, <u>*d2*</u>, and <u>*d3*</u>, for the specific Option numbered as <u>*seqOfOpt*</u>. |
| 48 | function **execOption**(<br> uint256 <u>*seqOfOpt*</u>) external | (The right holder) Execute the Option numbered as <u>*seqOfOpt*</u>. |
| 49 | function **createSwap**(<br> uint256 <u>*seqOfOpt*</u>,<br> uint256 <u>*seqOfTarget*</u>,<br> uint256 <u>*paidOfTarget*</u>,<br> uint256 <u>*seqOfPledge*</u>) external | (The right holder) Create a Swap on the target share numbered as <u>*seqOfTarget*</u>, for paid value amount to <u>*paidOfTarget*</u>, with the collateral set up on the pledged share numbered as <u>*seqOfPledge*</u>, for executing the Option numbered as <u>*seqOfOpt*</u>. |
| 50 | function **payOffSwap**(<br> ICashier.TransferAuth memory <u>*auth*</u>, <br> uint256 <u>*seqOfOpt*</u>, <br> uint256 <u>*seqOfSwap*</u>, <br> address <u>*to*</u> ) external; | (The pledger) Pay certain amount of USDC as per the off-chain authorization signed as <u>*auth*</u>, to release the pledged share under the Swap numbered <u>*seqOfSwap*</u> of the Option numbered as <u>*seqOfOpt*</u>, to close the Swap. |
| 51 | function **terminateSwap**(<br> uint256 <u>*seqOfOpt*</u>, <br> uint256 <u>*seqOfSwap*</u>) external | (The target share holder) Execute the swap numbered as <u>*seqOfSwap*</u> of the Option numbered as <u>*seqOfOpt*</u>, by transferring the target share and releasing the pledged share. |

---

---

| |
|:---|
| 135 |
| *[**Table of Contents**](#Toc)* |

---

![](rookeeper-47.jpg)

---

| |
|:---|
| 136 |
| *[**Table of Contents**](#Toc)* |

---

![](rookeeper-48.jpg)

---

| |
|:---|
| 137 |
| *[**Table of Contents**](#Toc)* |

---

![](rookeeper-49.jpg)

---

| |
|:---|
| 138 |
| *[**Table of Contents**](#Toc)* |

---

![](rookeeper-50.jpg)

---

| |
|:---|
| 139 |
| *[**Table of Contents**](#Toc)* |

---

![](rookeeper-51.jpg)

---

| |
|:---|
| 140 |
| *[**Table of Contents**](#Toc)* |

---

 **6.8. APIs Routed To ROP Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 52 | function **createPledge**(<br> bytes32 <u>*snOfPld*</u>, <br> uint256 <u>*paid*</u>, <br> uint256 <u>*par*</u>, <br> uint256 <u>*guaranteedAmt*</u>, <br> uint256 <u>*execDays*</u>) external | (Any shareholder) Create a Pledge with the codified serial number <u>*snOfPld*</u> amount to paid value of <u>*paid*</u> and par value of <u>*par*</u> to guarantee the debt amount to <u>*guaranteedAmt*</u> with the guarantee period lasting for number of days of <u>*execDays*</u>. |
| 53 | function **transferPledge**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>, <br> uint256 <u>*buyer*</u>, <br> uint256 <u>*amt*</u>) external | (The creditor) Transfer the Pledge numbered as <u>*seqOfPld*</u> setting up on the pledged share numbered <u>*seqOfShare*</u> to the user numbered as <u>*buyer*</u> with the credit amount to <u>*amt*</u>. |
| 54 | function **refundDebt**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>, <br> uint256 <u>*amt*</u>) external | (The creditor) Confirm refunding of the debt, guaranteed by the Pledge numbered as <u>*seqOfPld*</u> setting on the pledged share numbered as <u>*seqOfShare*</u>, by the amount of <u>*amt*</u>. |
| 55 | function **extendPledge**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>, <br> uint256 <u>*extDays*</u>) external | (The pledger) Extend the guarantee period of the Pledge numbered as <u>*seqOfPld*</u> setting on the pledged share numbered as <u>*seqOfShare*</u> for a such number of days as <u>*extDays*</u>. |
| 56 | function **lockPledge**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>, <br> bytes32 <u>*hashLock*</u>) external | (The creditor) Set up a hash lock with the hash value as <u>*hashLock*</u> on the Pledge numbered as <u>*seqOfPld*</u> setting on the pledged share numbered <u>*seqOfShare*</u>. |
| 57 | function **releasePledge**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>, <br> string memory <u>*hashKey*</u>) external | (The pledger, after paying off-chain and obtaining the hash key) Release the Pledge numbered as <u>seqOfPld</u> setting on the pledged share numbered as <u>*seqOfShare*</u> by inputting the hash key string <u>*hashKey*</u>. |
| 58 | function **execPledge**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>, <br> uint256 <u>*buyer*</u>, <br> uint256 <u>*groupOfBuyer*</u>) external | (The creditor, after off-chain disposal and receipt of the consideration) Execute the Pledge numbered as <u>*seqOfPld*</u> setting on the pledged share numbered as <u>*seqOfShare*</u> to transfer the target share to the user numbered as <u>*buyer*</u> who belongs to the concert group represented by the user numbered as <u>*groupOfBuyer*</u>. |
| 59 | function **revokePledge**(<br> uint256 <u>*seqOfShare*</u>, <br> uint256 <u>*seqOfPld*</u>) external | (The pledger, after the expiration of the guarantee period) Revoke the Pledge numbered as <u>*seqOfPld*</u> setting on the pledged share numbered as <u>*seqOfShare*</u>. |

---

---

| |
|:---|
| 141 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-52.jpg)

---

| |
|:---|
| 142 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-53.jpg)

---

| |
|:---|
| 143 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-54.jpg)

---

| |
|:---|
| 144 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-55.jpg)

---

| |
|:---|
| 145 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-56.jpg)

---

| |
|:---|
| 146 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-57.jpg)

---

| |
|:---|
| 147 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-58.jpg)

---

| |
|:---|
| 148 |
| *[**Table of Contents**](#Toc)* |

---

![](ropkeeper-59.jpg)

---

| |
|:---|
| 149 |
| *[**Table of Contents**](#Toc)* |

---

 **6.9. APIs Routed To SHA Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 60 | function **execAlongRight**(<br> address <u>*ia*</u>,<br> bytes32 <u>*snOfClaim*</u>,<br> bytes32 <u>*sigHash*</u>) external | (The right holder) Execute the Tag-Along right, for the tag along or drag along Claim encoded as snOfClaim in the Investment Agreement deployed at the address of ia, with the signature's hash value as sigHash. |
| 61 | function **acceptAlongDeal**(<br> address <u>*ia*</u>,<br> uint256 <u>*seqOfDeal*</u>,<br> bytes32 <u>*sigHash*</u>) external | (The buyer) Accepts the Tag/Drag Along requests, for the Deal numbered as <u>*seqOfDeal*</u> of the Investment Agreement deployed at the address of <u>*ia*</u>, with the signature's hash value as <u>*sigHash*</u>. |
| 62 | function **execAntiDilution**(<br> address <u>*ia*</u>,<br> uint256 <u>*seqOfDeal*</u>,<br> uint256 <u>*seqOfShare*</u>,<br> bytes32 <u>*sigHash*</u>) external | (The right holder) Execute the Anti-Dilution right, towards the Deal numbered as <u>*seqOfDeal*</u> in the Investment Agreement deployed at the address of <u>*ia*</u>, for its share numbered <u>*seqOfShare*</u>, with the signature hash value as <u>*sigHash*</u>. |
| 63 | function **takeGiftShares**(<br> address <u>*ia*</u>, <br> uint256 <u>*seqOfDeal*</u>) external | (The right holder of Anti-Dilution, after the closing) Take the gift shares, generating as per the Anti-Dilution Term of SHA, for the Deal numbered as <u>*seqOfDeal*</u> in the Investment Agreement deployed at the address of <u>*ia*</u>. |
| 64 | function **execFirstRefusal**(<br> uint256 <u>*seqOfRule*</u>,<br> uint256 <u>*seqOfRightholder*</u>,<br> address <u>*ia*</u>,<br> uint256 <u>*seqOfDeal*</u>,<br> bytes32 <u>*sigHash*</u>) external | (The right holder) Execute its First Refusal right, as per the Rule numbered as <u>*seqOfRule*</u>, with the identified sequence number as <u>*seqOfRightholder*</u>, to request to buy the subject share of the Deal numbered as <u>*seqOfDeal*</u> in the Investment Agreement deployed at the address of <u>*ia*</u>, with the signature hash value as <u>*sigHash*</u>. |
| 65 | function **computeFirstRefusal**(<br> address <u>*ia*</u>,<br> uint256 <u>*seqOfDeal*</u>) external; | (Any Member) Compute the First Refusal claims result for the Deal numbered as <u>*seqOfDeal*</u> of the Investment Agreement deployed at the address of <u>*ia*</u>, so as to obtain the automatically updated Investment Agreement. |

---

---

| |
|:---|
| 150 |
| *[**Table of Contents**](#Toc)* |

---

![](shakeeper-60.jpg)

---

| |
|:---|
| 151 |
| *[**Table of Contents**](#Toc)* |

---

![](shakeeper-61.jpg)

---

| |
|:---|
| 152 |
| *[**Table of Contents**](#Toc)* |

---

![](shakeeper-62.jpg)

---

| |
|:---|
| 153 |
| *[**Table of Contents**](#Toc)* |

---

![](shakeeper-63.jpg)

---

| |
|:---|
| 154 |
| *[**Table of Contents**](#Toc)* |

---

![](shakeeper-64.jpg)

---

| |
|:---|
| 155 |
| *[**Table of Contents**](#Toc)* |

---

![](shakeeper-65.jpg)

---

| |
|:---|
| 156 |
| *[**Table of Contents**](#Toc)* |

---

 **6.10. APIs routed to Accountant**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 66 | function **initClass**(<br> uint <u>*class*</u>) external; | (Secretary of the Company) Initiate a specific <u>*class*</u> of shares to calculate ROE or IRR. |
| 67 | function **distributeProfits**(<br> uint256 <u>*amt*</u>,<br> uint256 <u>*expireDate*</u>,<br> uint256 <u>*seqOfDR*</u>,<br> uint256 <u>*seqOfMotion*</u>) external | (The designated executor) Distribute the profits of the company amount to <u>*amt*</u>, as per the distribution rule numbered as <u>*seqOfDR*</u> and the Motion numbered as <u>*seqOfMotion*</u>, before the expiration date of <u>*expireDate*</u>. |
| 68 | function **distributeIncome**(<br> uint256 <u>*amt*</u>,<br> uint256 <u>*expireDate*</u>,<br> uint256 <u>*seqOfDR*</u>,<br> uint256 <u>*fundManager*</u>,<br> uint256 <u>*seqOfMotion*</u>) external | (The designated executor) Distribute the income of the fund amount to <u>*amt*</u>, as per the Motion numbered as <u>*seqOfMotion*</u>, before the expiration date of <u>*expireDate*</u>, with the user number of the asset manager as <u>*fundManager*</u>. |
| 69 | function **transferFund**(<br> bool <u>*fromBMM*</u>,<br> address <u>*to*</u>,<br> bool <u>*isCBP*</u>,<br> uint256 <u>*amt*</u>,<br> uint256 <u>*expireDate*</u>,<br> uint256 <u>*seqOfMotion*</u>) external | (The designated executor) Transfer, CBP (<u>*isCBP*</u> is true) or ETH (<u>*isCBP*</u> is false), to the account address <u>*to*</u>, amount to <u>*amt*</u>, as per the Motion passed by, the Board (<u>*toBMM*</u> is true) or the General Meeting (<u>*toBMM*</u> is false), before the timestamp of <u>*expireDate*</u>, numbered as <u>*seqOfMotion*</u>. |

---

---

| |
|:---|
| 157 |
| *[**Table of Contents**](#Toc)* |

---

![](accountant-66.jpg)

---

| |
|:---|
| 158 |
| *[**Table of Contents**](#Toc)* |

---

![](accountant-67.jpg)

---

| |
|:---|
| 159 |
| *[**Table of Contents**](#Toc)* |

---

![](accountant-68.jpg)

---

| |
|:---|
| 160 |
| *[**Table of Contents**](#Toc)* |

---

![](accountant-69.jpg)

---

| |
|:---|
| 161 |
| *[**Table of Contents**](#Toc)* |

---

 **6.11. APIs Routed To ROI Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 70 | function **pause**(<br> uint <u>*seqOfLR*</u>) external | (The authorized Enforcer) Pause temporarily the trade of the shares as per the listing rule numbered as <u>*seqOfLR*</u>. |
| 71 | function **unPause**(<br> uint <u>*seqOfLR*</u>) external | (The authorized Enforcer) Restore the trade of the shares as per the listing rule numbered as <u>*seqOfLR*</u>. |
| 72 | function **regInvestor**(<br> address <u>*bKey*</u>, <br> uint256 <u>*groupRep*</u>, <br> bytes32 <u>*idHash*</u>) external | (Any user) Register itself as an investor, by inputting its backup key as <u>*bKey*</u>, the user number of its concert group's representative as <u>*groupRep*</u>, with the hash value of its identity information as <u>*idHash*</u>. |
| 73 | function **approveInvestor**(<br> uint256 <u>*userNo*</u>, <br> uint256 <u>*seqOfLR*</u>) external | (The verifier) Approve the investor's application, pursuant to the Listing Rule numbered as <u>*seqOfLR*</u>, filed by the user numbered as <u>*userNo*</u>. |
| 74 | function **revokeInvestor**(<br> uint256 <u>*userNo*</u>, <br> uint256 <u>*seqOfLR*</u>) external | (The verifier) Revoke the investor's qualification of the user numbered as <u>*userNo*</u>, pursuant to the Listing Rule numbered as <u>*seqOfLR*</u>. |
| 75 | function **freezeShare**(<br> uint <u>*seqOfLR*</u>, <br> uint <u>*seqOfShare*</u>, <br> uint <u>*paid*</u>, <br> bytes32 <u>*hashOrder*</u>) external | (The authorized Enforcer) Freezes the target share identified by sequence number <u>*seqOfShare*</u>, with its paid amount recorded as <u>*paid*</u>, pursuant to the authorization set forth in Listing Rule <u>*seqOfLR*</u>, and in accordance with the execution order identified by the hash value <u>*hashOrder*</u>. |
| 76 | function **unfreezeShare**(<br> uint <u>*seqOfLR*</u>, <br> uint <u>*seqOfShare*</u>, <br> uint <u>*paid*</u>, <br> bytes32 <u>*hashOrder*</u>) external | (The authorized Enforcer) Unfreezes the target share identified by sequence number <u>*seqOfShare*</u>, with its paid amount recorded as <u>*paid*</u>, pursuant to the authorization set forth in Listing Rule <u>*seqOfLR*</u>, and in accordance with the execution order identified by the hash value <u>*hashOrder*</u>. |
| 77 | function **forceTransfer**(<br> uint <u>*seqOfLR*</u>, <br> uint <u>*seqOfShare*</u>, <br> uint <u>*paid*</u>, <br> address <u>*addrTo*</u>, <br> bytes32 <u>*hashOrder*</u>) external | (The authorized Enforcer) Forcibly transfers the target share identified by sequence number <u>*seqOfShare*</u>, with its paid amount recorded as <u>*paid*</u>, to the specified user whose primary key address is <u>*addrTo*</u>, pursuant to the authorization set forth in Listing Rule <u>*seqOfLR*</u>, and in accordance with the execution order identified by the hash value <u>*hashOrder*</u>. |

---

---

| |
|:---|
| 162 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-70.jpg)

---

| |
|:---|
| 163 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-71.jpg)

---

| |
|:---|
| 164 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-72.jpg)

---

| |
|:---|
| 165 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-73.jpg)

---

| |
|:---|
| 166 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-74.jpg)

---

| |
|:---|
| 167 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-75.jpg)

---

| |
|:---|
| 168 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-76.jpg)

---

| |
|:---|
| 169 |
| *[**Table of Contents**](#Toc)* |

---

![](roikeeper-77.jpg)

---

| |
|:---|
| 170 |
| *[**Table of Contents**](#Toc)* |

---

 **6.12. APIs Routed To LOO Keeper**

---

| | | |
|:---|:---|:---|
| **S.N.** | **API** | **Description of Functions and Input Parameters** |
| 78 | function **placeInitialOffer**(<br> uint256 <u>*classOfShare*</u>,<br> uint256 <u>*execHours*</u>,<br> uint256 <u>*paid*</u>,<br> uint256 <u>*price*</u>,<br> uint256 <u>*seqOfLR*</u>) external | (The issuer) Place an initial offer for the class of <u>*classOfShare*</u>, as per the authorization of the Listing Rule numbered as <u>*seqOfLR*</u>, at the price of <u>*price*</u>, to the amount of <u>*paid*</u>, with the available number of hours as <u>*execHours*</u>. |
| 79 | function **withdrawInitialOffer**(<br> uint256 <u>*classOfShare*</u>,<br> uint256 <u>*seqOfOrder*</u>,<br> uint256 <u>*seqOfLR*</u>) external; | (The issuer) Withdraw the initial offer numbered as <u>*seqOfOrder*</u> under the class of <u>*classOfShare*</u>, as per the authorization of the Listing Rule numbered as <u>*seqOfLR*</u>. |
| 80 | function **placeSellOrder**(<br> uint256 <u>*seqOfClass*</u>,<br> uint256 <u>*execHours*</u>,<br> uint256 <u>*paid*</u>,<br> uint256 <u>*price*</u>,<br> uint256 <u>*seqOfLR*</u>) external | (Any qualified investor) Place a sell order under the class numbered as <u>*seqOfClass*</u>, as per the Listing Rule of <u>*seqOfLR*</u>, to the paid value amount to <u>*paid*</u>, at the selling price of <u>*price*</u>, with the available time within the number of hours as <u>*execHours*</u>. |
| 81 | function **withdrawSellOrder**(<br> uint256 <u>*classOfShare*</u>,<br> uint256 <u>*seqOfOrder*</u>) external | (The seller) Withdraw the sell order numbered as <u>*seqOfOrder*</u> for the class of <u>*classOfShare*</u> that it has placed. |
| 82 | function **placeBuyOrder**(<br> ICashier.TransferAuth memory <u>*auth*</u>,<br> uint256 <u>*classOfShare*</u>, <br> uint256 <u>*paid*</u>, <br> uint256 <u>*price*</u>,<br> uint256 <u>*execHours*</u>) external | (Any qualified investor) Place a buy order for the class of <u>*classOfShare*</u>, to the paid value amount to <u>*paid*</u>, at the buy price of <u>*price*</u>, within the available time as number of hours of <u>*execHours*</u>, paying certain amount of USDC as per the off-chain authorization signed as <u>*auth*</u>. |
| 83 | function **placeMarketBuyOrder**(<br> ICashier.TransferAuth memory <u>*auth*</u>,<br> uint256 <u>*classOfShare*</u>, <br> uint256 <u>*paid*</u>, <br> uint256 <u>*execHours*</u> ) external | (Any qualified investor) Place a buy order for the class of <u>*classOfShare*</u>, to the paid value amount to <u>*paid*</u>, at the market price, with the available time within the number of hours as <u>*execHours*</u>, paying certain amount of USDC as per the off-chain authorization signed as <u>*auth*</u>. |
| 84 | function **withdrawBuyOrder**(<br> uint256 <u>*classOfShare*</u>,<br> uint256 <u>*seqOfOrder*</u>) external | (The buyer) Withdraw the buy order numbered as <u>*seqOfOrder*</u> for the class of <u>*classOfShare*</u> that it has placed. |

---

---

| |
|:---|
| 171 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-78.jpg)

---

| |
|:---|
| 172 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-79.jpg)

---

| |
|:---|
| 173 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-80.jpg)

---

| |
|:---|
| 174 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-81.jpg)

---

| |
|:---|
| 175 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-82.jpg)

---

| |
|:---|
| 176 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-83.jpg)

---

| |
|:---|
| 177 |
| *[**Table of Contents**](#Toc)* |

---

![](lookeeper-84.jpg)

---

| |
|:---|
| 178 |
| *[**Table of Contents**](#Toc)* |

---

 **7. Scenarios for Equity Transactions and Corporate Governance** 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; In the course of a company's daily operations and financing activities, all legal actions can generally be categorized into 12 representative scenarios. These scenarios broadly encompass the issuance of new shares, transfer of existing shares, amendment of the shareholders' agreement, equity financing, election of directors and officers, approval of legal documents by resolution, external payments, and the execution of legal agreements, among others. This section presents these scenarios through logical flowcharts (swimlane diagrams), illustrating how the company's stakeholders, acting in their respective capacities as rights holders, may utilize the external APIs provided by the ComBoox system to rigorously and systematically complete the aforementioned legal actions within the ComBoox platform. These scenarios include:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Apply for Qualified Invesotr Status;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Update Shareholders' Agreement;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Trade Equity by Agreement;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Trade Equity trough Listing (in USDC);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Elect or Remove Directors;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Elect or Remove Officers;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Transfer Fund;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) Distribute Profits or Income;

---

| |
|:---|
| 179 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) Call External Smart Contracts;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) Pledge Equity for Debts;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) Execute SHA Rights; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) Execute Options.

---

| |
|:---|
| 180 |
| *[**Table of Contents**](#Toc)* |

---

 **7.1. Apply for Qualified Investor Status**

To invest in a company registered on the ComBoox platform, an individual must first apply for "Qualified Investor" status. This process entails a whitelist review and verification procedure. The "Listing Rules" under the company's Shareholders' Agreement explicitly define which user roles are vested with the authority to approve Qualified Investor applications. These approvers, referred to as "Verifiers," may include the company's shareholders, senior executives, affiliated equity trading venues, or even regulatory authorities.

Only users admitted to the whitelist are permitted to buy and sell the company's shares. Once a user's Qualified Investor status is revoked by a Verifier, all equity holdings of that user are effectively frozen and may not be transferred until the Qualified Investor status is reinstated.

The application and approval process for obtaining Qualified Investor status generally consists of the following steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Applicant calls the regUser() function of RegCenter to sign up with ComBoox Platform;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Applicant calls the setBackupKey() function of RegCenter to set bKey as its backup key;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Applicant calls regInvestor() (the No.72 API) to register itself as an investor, by inputting its backup key as bKey, the user number of its concert group's representative as groupRep, with the hash value of its identity information as idHas.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Verifier calls approveInvestor() (the No.73 API) to approve the investor's application, pursuant to the Listing Rule numbered as seqOfLR, filed by the user numbered as userNo.

---

| |
|:---|
| 181 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-01.jpg)

---

| |
|:---|
| 182 |
| *[**Table of Contents**](#Toc)* |

---

7.2. Update Shareholders' Agreement

The Shareholders' Agreement or the Articles of Association serve as the company's constitutional documents. They set forth the Rules governing corporate governance (Governance Rules), voting procedures (Voting Rules), allocation of executive positions (Position Allocation Rules), pre-emptive rights (First Refusal Rules), listing requirements (Listing Rules), as well as special investor protection provisions (Terms) such as share Lock-Up, Anti-Dilution, Drag-Along and Tag-along rights, Call Options, and Put Options.

Within the ComBoox system, shareholders may, in accordance with prescribed voting rules, submit proposals, cast votes, and activate new versions of the Shareholders' Agreement in order to establish or amend the foregoing Rules and Terms. Once activated, the Shareholders' Agreement will automatically respond in real time to queries from other Sub Keeper contracts and Registry contracts, providing the relevant Rules and Terms. This ensures that all corporate legal actions are executed strictly in accordance with the conditions and procedures stipulated in the Shareholders' Agreement.

The specific process for creating, proposing, voting on, and activating the Shareholders' Agreement includes the following steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Shareholder calls createSHA() (the No.01 API) to create a new shareholders agreement by cloning the Template of the specific version.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Owner of the draft SHA calls circulateSHA() (the No.02 API) to circulate the finalized draft of SHA deployed at the address of body to the contractual parties for signing, with the URL infomation of docUrl, and hash value of docHash.

---

| |
|:---|
| 183 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Shareholders call signSHA() (the No.03 API) to sign the finalized draft of SHA deployed at the address of sha, with the hash value of signature as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Owner of the draft call proposeDocOfGM() (the No.29 API) to create and propose a draft Motion for the General Meeting to approve the document deployed at the address of doc as per the voting rule numbered as seqOfVR with the user numbered as executor to invoke it.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Shareholders call castVoteOfGM() (the No.35 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Any user call voteCountingOfGM() (the No.36 API) to count the vote result for the Motion on the General Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Any Shareholder may call activateSHA() (the No.04 API) to activate the draft of shareholders agreement deployed at the address of body.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) Investor may call acceptSHA() (the No.05 API) to accept the terms and conditons of the SHA in force, with the hash value as sigHash.

---

| |
|:---|
| 184 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-02.jpg)

---

| |
|:---|
| 185 |
| *[**Table of Contents**](#Toc)* |

---

7.3. Trade Equity by Agreement

Equity subscription or transfer by agreement is the share trading mechanism designed by ComBoox for the vast majority of non-listed companies. Under this agreement-based approach, both new share issuances and secondary share transfers may be conducted. Settlements can be executed either through a hash time-lock using off-chain fiat currency as payment consideration, or via atomic delivery-versus-payment (DVP) transactions using USDC.

A General Meeting's resolution is an essential step in agreement-based share transactions, ensuring that special investor rights, such as Lock-Up, First Refusal, Drag Along and Tag Along, can be duly exercised. Where the Shareholders' Agreement specifies that the approval voting ratio for equity-trading-related voting rules (Voting Rules No. 1-7) is set to "0," proposals may bypass the voting stage. In such cases, the relevant share transfer or subscription agreement may be deemed approved by the shareholders' meeting directly upon triggering the calculateVoteResult() API, thereby proceeding immediately to settlement.

The process for conducting equity transactions by agreement includes the following steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Any Shareholder may call createIA() (the No.38 API) to create a draft Investment Agreement on the Register of Agreement, by cloning the Template of the version numbered as version.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Owner of the draft Investment Agreement calls circulateIA() (the No.39 API) to circulate the finalized draft deployed at the address of body to the parties for signature, attaching with the URL information of docUrl and the hash value of the draft as docHash.

---

| |
|:---|
| 186 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Parties to the draft IA call signIA() (the No.40 API) to sign the Investment Agreement deployed at the address of ia, with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Owner of the draft to call proposeDocOfGM() (the No.29 API) to create and propose a draft Motion for the General Meeting to approve the document deployed at the address of doc as per the voting rule numbered as seqOfVR with the user numbered as executor to invoke it.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Shareholders call castVoteOfGM() (the No.35 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Any user may call voteCountingOfGM() (the No.36 API) to count the vote result for the Motion on the General Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Seller may call pushToCoffer() (the No.41 API) to confirm all conditions precedent have been satisfied and ready for closing, for the specific deal numbered as seqOfDeal, under the Investment Agreement deployed at the address of ia, by inputting a hash lock value hashLock and setting the closing deadline as closingDeadline.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) Buyer calls closeDeal() (the No.42 API) to close the deal numbered as seqOfDeal, under the Investment Agreement deployed at the address of ia, after paying the consideration off-chain, by inputting the hash key string hashKey.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) Controller of the company may call issueNewShare() (the No.43 API) to issue new share directly to the buyer, for the capital increasing Deal numbered as seqOfDeal under the Investment Agreement deployed at the address of ia.

---

| |
|:---|
| 187 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) Seller may call transferTargetShare() (the No.44 API) to transfer the subject share directly to the buyer, for the specific share transfer Deal numbered as seqOfDeal under the Investment Agreement deployed at the address of ia.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11) Buyer may call payOffApprovedDeal() (the No.46 API) to pay off the specific Deal numbered as seqOfDeal in the Investment Agreement deployed as the address of ia, by paying to the seller/issuer address to certain amount of USDC as per the off-chain authorization signed as auth, to close the Deal.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12) After the expiration of the Deal, seller may call terminateDeal() (the No.45 API) to terminate the Deal numbered as seqOfDeal under the Investment Agreement deployed at the address of ia.

---

| |
|:---|
| 188 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-03.jpg)

---

| |
|:---|
| 189 |
| *[**Table of Contents**](#Toc)* |

---

7.4. Trade Equity by Listing (in USDC)

The listing-based trading mechanism is designed by ComBoox for companies that are publicly listed. Qualified Investors may subscribe for or transfer company shares through blockchain-based smart contracts using USDC as the settlement currency. This mechanism enables both subscriptions for newly issued shares and secondary trading of existing shares.

The smart contract system, centered on the LOO Keeper and LOO smart contracts, automatically matches and executes orders under a "time priority, price priority" principle, with settlement conducted on a delivery-versus-payment (DVP) model.

A company may stipulate the specific rules governing the listing and issuance of its shares through the "Listing Rules" under its Shareholders' Agreement. Such rules may include, for example, the minimum and maximum issue prices for shares, the minimum interval between share transfers, or the lowest permissible trading price.

Most importantly, the Listing Rules define the role of the Verifier, either as a designated user group or specific individual, who is vested with the authority to approve or revoke "Qualified Investor" status. This whitelist mechanism ensures that all investors participating in the company's share transactions comply with applicable KYC/AML requirements and other regulatory obligations.

A Verifier may be a company director or officer, a designated bookrunner or registrar, an exchange operator, a KYC/AML service provider, or even a competent regulatory authority within a particular jurisdiction.

The company's General Meeting may amend the Listing Rules by updating the Shareholders' Agreement, thereby ensuring that the issuance and trading of its shares remain in compliance with the requirements of specific jurisdictions or trading venues.

---

| |
|:---|
| 190 |
| *[**Table of Contents**](#Toc)* |

---

 **The public offering or trading of company shares is subject to compliance with applicable laws and regulations governing securities registration, securities trading, KYC, AML, and related requirements. Accordingly, prior to engaging in share listing or trading activities, it is strongly recommended to seek professional advice from qualified legal counsel in the relevant jurisdiction.** 

The specific procedures for trading company shares under the listing mechanism are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Controller or director may call placeInitialOffer() (the No.78 API) to place an initial offer for the class of classOfShare, at the price of paid as price, to the amount of paid as paid, with the available number of hours as execHours, pursuant to the Listing Rule numbered as seqOfLR.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) A shareholder may call placeSellOrder() (the No.80 API) to place a sell order under the class numbered as classOfShare, as per the Listing Rule of seqOfLR, to the paid value amount to paid, at the selling price of price, with the available time within the number of hours as execHours.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) A Qualified Investor may call placeBuyOrder() (the No.82 API) to place a buy order for the class of classOfShare, to the paid value amount to paid, at the buy price of price, within the available time as number of hours of execHours, paying certain amount of USDC as per the off-chain authorization signed as auth.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) A Qualified Investor may call placeMarketBuyOrder() (the No.83 API) to place a buy order for the class of classOfShare, to the paid value amount to paid, at the market price, with the available time within the number of hours as execHours, paying certain amount of USDC as per the off-chain authorization signed as auth.

---

| |
|:---|
| 191 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) The Controller or director may call withdrawInitialOffer() (the No.79 API) to withdraw the initial offer numbered as seqOfOrder under the class of classOfShare, pursuant to the Listing Rule numbered as seqOfLR.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) The seller may call withdrawSellOrder() (the No.81 API) to withdraw sell order numbered as seqOfOrder for the class of classOfShare.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) The buyer may call withdrawBuyOrder() (the No.84 API) to withdraw the buy order numbered as seqOfOrder for the class of classOfShare that it has placed.

---

| |
|:---|
| 192 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-04.jpg)

---

| |
|:---|
| 193 |
| *[**Table of Contents**](#Toc)* |

---

7.5. Elect or Remove Directors

The power to appoint and remove directors or officers is a fundamental aspect of corporate governance. Within the ComBoox system, the Position Allocation Rules defined in the Shareholders' Agreement may specify the manner in which company executives and officers are appointed, as well as the duration of their terms of office. For example, such rules may establish shareholders' rights to nominate a certain number of board seats or specific positions such as the Chairperson, or the authority of certain directors or executives to nominate, appoint or remove other company officers.

Users vested with nomination or appointment/removal rights may exercise such powers by triggering designated APIs. The election of company officers may take place at a General Meeting or a Board Meeting. A user holding nomination rights may also initiate a motion to remove (impeach) a director or executive whom they have nominated.

Elected candidates must trigger the Appointment API in order to assume office; similarly, resignation requires activation of the Resignation API.

Shareholders may amend the Shareholders' Agreement to revise the Position Allocation Rules, thereby altering the method of appointment or the term of office for specific positions.

The procedures for the election or appointment of directors are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) The right holder calls nominateDirector() (the No.27 API) to nominate the user numbered as candidate for the Director's position numbered as seqOfPos.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) The right holder calls createMotionToRemoveDirector() (the No.28 API) to create a draft Motion to remove the officer on the position numbered as seqOfPos.

---

| |
|:---|
| 194 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) The right holder calls proposeMotionToGeneralMeeting() (the No.34 API) to proposes the Motion numbered as seqOfMotion to the General Meeting.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Members call castVoteOfGM() (the No.35 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Any user may call voteCountingOfGM() (the No.36 API) to count the vote result for the Motion on the General Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) The elected candidate calls takeSeat() (the No.06 API) to assume the director's seat identified by seqOfPos pursuant to the authorization granted under the Motion identified by seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) The executor calls removeDirector() (the No.07 API) to remove the director on the position numbered as seqOfPos as per the removal Motion numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) The director calls quitPosition() (the No.10 API) to quit the position identified as seqOfPos voluntarily.

---

| |
|:---|
| 195 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-05.jpg)

---

| |
|:---|
| 196 |
| *[**Table of Contents**](#Toc)* |

---

7.6. Elect or Remove Officers

The procedures for the election or appointment of officers are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) The right holder calls nominateOfficer() (the No.11 API) to nominate the user numbered as candidate for the Officer's position numbered as seqOfPos.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) The right holder calls createMotionToRemoveOfficer() (the No.12 API) to create a draft Motion to remove the officer on the position numbered as seqOfPos.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) The right holder calls proposeMotionToBoard() (the No.17 API) to proposes the Motion numbered as seqOfMotion to the Board Meeting.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Directors call castVote () (the No.18 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Any user may call voteCounting() (the No.19 API) to count the vote result for the Motion on the Board Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) The elected candidate calls takePosition() (the No.08 API) to assume the director's seat identified by seqOfPos pursuant to the authorization granted under the Motion identified by seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) The executor calls removeOfficer() (the No.09 API) to remove the director on the position numbered as seqOfPos as per the removal Motion numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) The director calls qutiPosition() (the No.10 API) to quit the position identified as seqOfPos voluntarily.

---

| |
|:---|
| 197 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-06.jpg)

---

| |
|:---|
| 198 |
| *[**Table of Contents**](#Toc)* |

---

7.7. Transfer Fund

External payments constitute one of the most important forms of asset disposition and corporate governance actions for a company. Within the ComBoox system, any external payment made by a company must be approved either at a General Meeting or a Board Meeting. The maximum payment amount that may be authorized by the Board can be expressly stipulated in the Governance Rule set forth in the Shareholders' Agreement. Should any Board Motion on external payments exceed such threshold, the system will automatically return an error and prohibit the Motion from proceeding to a vote.

The ComBoox system permits companies to make external payments in three types of tokens: ETH, USDC, and CBP. The first two represent company assets, while the latter, in the case of the ComBoox DAO, represents a category of long-term liabilities classified as "deferred revenue." For other companies, CBP functions as a special utility token that may be consumed when utilizing the ComBoox system.

The ComBoox system provides dedicated APIs for making payments in CBP or USDC. For ETH, however, payments must be executed by triggering the General Keeper to call the universal interface for external smart contracts, which in turn invokes the General Keeper contract's execActionOfGM() or execAction() function to complete the external payment.

The process for effecting external payments involves the following steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Any Member or Director may call proposeToTransferFundWithBoard() (the No.14 API) to propose to USDCthe Board, or call proposeToTransferFundWithGM() (the No.31 API) to propose to the General Meeting, to transfer certain amount of CBP (isCBP is true) or USDC (isCBP is false), to the account address to, amount to amt, before the timestamp of expireDate, as per the Voting Rule numbered as seqOfVR, with the user numbered as executor to execute the Motion concerned; or

---

| |
|:---|
| 199 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Any Member may call createActio()(the No.15 API) or createActionOfGM() (the No.32 API) to create a draft Motion for the **Board Meeting** or **General Meeting** to execute a series of calls, as per the voting rule numbered as seqOfVR, to the contracts deployed at the addresses of targets, with paying the respective ETH amount to values, and inputting parameters of params, attached a description message whose hash value is desHash, with the user numbered as executor to invoke it.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Directors call castVote () (the No.18 API) to cast vote in the Board Meeting with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Members call castVoteOfGM() (the No.35 API) to cast vote in the **Genal Meeting** with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Any user calls voteCounting() (the No.19 API) to count the vote result for the Motion on the Board Meeting numbered as seqOfMotion; or

---

| |
|:---|
| 200 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Any user may call voteCountingOfGM() (the No.36 API) to count the vote result for the Motion on the General Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) The designated executor calls transferFund() (the No.69 API) to transfer, CBP (isCBP is true) or USDC (isCBP is false), to the account address to, amount to amt, as per the Motion passed by, the Board (toBMM is true) or the General Meeting (toBMM is false), before the timestamp of expireDate, numbered as seqOfMotion; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) The designated executor calls execAction()(the No.20 API) or execActionOfGM() (the No.37 API) to execute the Motion numbered as seqOfMotion, categorized as typeOfAction, to trigger the series of calls to the contracts deployed at addresses of targets, with paying the respective ETH amount to values, inputting parameters as params, attached with hash value of the description message as desHash.

---

| |
|:---|
| 201 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-07.jpg)

---

| |
|:---|
| 202 |
| *[**Table of Contents**](#Toc)* |

---

7.8. Distribute Profits or Income

ComBoox enables companies to distribute profits or income in USDC. Any distribution must be approved by Resolution at the company's General Meeting. Distributions in USDC require triggering the **Cashier** contract's distrProfits() or distrIncome() function to complete the process.

The procedure for distributing company profits includes the following steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Any Member may call proposeToDistributeUsd() (the No.30 API) to propose to distribute profits or income of the company in USDC, to the General Meeting, pursuant to the Voting Rule numbered as seqOfVR, and the Distribution Rule numbered as seqOfDR, amount to amt, before the expiration date of expireDate, with the user numbered as executor to execute.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Members call castVoteOfGM() (the No.35 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Any user may call voteCountingOfGM() (the No.36 API) to count the vote result for the Motion on the General Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) The designated executor call distrProfits() (the No.67 API) or distrIncome() (the No.68 API) to distribute the profits or income of the company in USDC amount to amt, as per the Motion numbered as seqOfMotion, and the distribution rule numbered as seqOfDR, before the expiration date of expireDate.

---

| |
|:---|
| 203 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-08.jpg)

---

| |
|:---|
| 204 |
| *[**Table of Contents**](#Toc)* |

---

7.9. Call External Smart Contracts

As a Turing-complete programming language, Solidity enables the development of smart contracts to implement a wide range of legal actions depending on the application scenario. Within the ComBoox system, the General Keeper contract represents the on-chain legal entity of the company. Accordingly, when the General Keeper invokes an external smart contract, this action is deemed to constitute the company, in its capacity as an independent legal person, undertaking legal acts in external civil or commercial matters.

For this purpose, two universal interfaces-execAction() and execActionOfGM()-have been specifically developed. These functions allow the company to call external smart contracts flexibly, thereby adapting to future contracts designed for various commercial purposes. By invoking such contracts, the company can perform legally binding actions and achieve its intended business objectives. The former interface corresponds to legal actions requiring Board approval, while the latter corresponds to those requiring General Meeting approval.

When invoking external contract interfaces, the target contract addresses and corresponding instructions are structured in arrays. This design allows multiple smart contract functions to be called within a single instruction, enabling the execution of multiple legal actions and the realization of complex business objectives in a single operation.

---

| |
|:---|
| 205 |
| *[**Table of Contents**](#Toc)* |

---

The process for executing external smart contracts through the General Keeper includes the following steps:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Any Member may call createActionOfGM() (the No.32 API) to create a draft Motion for the General Meeting to execute a series of calls, as per the voting rule numbered as seqOfVR, to the contracts deployed at the addresses of targets, with paying the respective ETH amount to values, and inputting parameters of params, attached a description message whose hash value is desHash, with the user numbered as executor to invoke it; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Any director may call createAction() (the No.15 API) to create a draft Motion for the Board Meeting to execute a series of calls, as per the voting rule numbered as seqOfVR, to the contracts deployed at the addresses of targets, with paying the respective ETH amount to values, and inputting parameters of params, attached a description message whose hash value is desHash, with the user numbered as executor to invoke it.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Owner who created the Motion may call proposeMotionToGeneralMeeting() (the No.34 API) to proposes the Motion numbered as seqOfMotion to the General Meeting; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Owner who created the Motion may call proposeMotionToBoard() (the No.17 API) to proposes the Motion numbered as seqOfMotion to the Board Meeting.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Members may call castVoteOfGM() (the No.35 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash; or

---

| |
|:---|
| 206 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Directors may call castVote() (the No.18 API) to cast vote with the attitude for the Motion numbered as seqOfMotion with the signature message's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Any user may call voteCountingOfGM() (the No.36 API) to count the vote result for the Motion on the General Meeting numbered as seqOfMotion; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) Any user may call voteCounting() (the No.19 API) to count the vote result for the Motion on the Boardl Meeting numbered as seqOfMotion.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9) The designated executor may call execActionOfGM() (the No.37 API) to execute the Motion numbered as seqOfMotion, categorized as typeOfAction, to trigger the series of calls to the contracts deployed at addresses of targets, with paying the respective ETH amount to values, inputting parameters as params, attached with hash value of the description message as desHash; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10) The designated executor may call execAction() (the No.20 API) to execute the Motion numbered as seqOfMotion, categorized as typeOfAction, to trigger the series of calls to the contracts deployed at addresses of targets, with paying the respective ETH amount to values, inputting parameters as params, attached with hash value of the description message as desHash.

---

| |
|:---|
| 207 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-09.jpg)

---

| |
|:---|
| 208 |
| *[**Table of Contents**](#Toc)* |

---

7.10. Pledge Shares for Debts

The system maintains a dedicated Register of Pledges smart contract to record all equity pledge arrangements. Shareholders may pledge the equity they hold as collateral for a specified guaranteed amount of debt, subject to a defined guarantee period and up to a pledged value based on the paid value of the shares. The pledgee may transfer its pledge rights together with the underlying debt obligation. The pledgee may also confirm repayment of part of the principal, in which case the system will automatically reduce the pledged equity proportionally.

A pledgee may establish a hash lock mechanism whereby, once the pledgor repays the principal off-chain, the pledge may be released upon submission of the corresponding hash key. Upon maturity of the debt, the pledgee may exercise its rights by transferring the pledged equity to a designated buyer. Conversely, once the guarantee period expires, the pledgor may revoke the pledge to release the pledged shares.

It is important to emphasize that both the pledgee and any buyer designated upon enforcement of the pledge must obtain and maintain Qualified Investor status. Otherwise, the system will return an error message and block both the creation and enforcement of the pledge.

The specific steps for establishing and managing equity pledges are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) A Shareholder may call createPledge() (the No.52 API) to create a Pledge with the codified serial number snOfPld amount to paid value of paid and par value of par to guarantee the debt amount to guarantedAmt with the guarantee period lasting for number of days of execDays.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Pledgee may call transferPledge() (the No.53 API) to transfer the Pledge numbered as seqOfPld setting up on the pledged share numbered seqOfShare to the user numbered as buyer with the credit amount to amt.

---

| |
|:---|
| 209 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Pledgee calls refundDebt() (the No.54 API) to confirm refunding of the debt, guaranteed by the Pledge numbered as seqOfPld setting on the pledged share numbered as seqOfShare, by the amount of amt.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Pledger calls extendPledge() (the No.55 API) to extend the guarantee period of the Pledge numbered as seqOfPld setting on the pledged share numbered as seqOfShare for a such number of days as extDays.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Pledgee calls lockPledge() (the No.56 API) to set up a hash lock with the hash value as hashLock on the Pledge numbered as seqOfPld setting on the pledged share numbered seqOfShare.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) After paying consideration off-chain and obtaining the hash key, Pledger calls releasePledge() (the No. 57 API) to release the Pledge numbered as seqOfPld setting on the pledged share numbered as seqOfShare by inputting the hash key string hashKey.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) After the debt's maturity and before expiration of the guaranteed period, Pledgee calls execPledge() (the No.58 API) to execute the Pledge numbered as seqOfPld setting on the pledged share numbered as seqOfShare to transfer the target share to the user numbered as buyer who belongs to the concert group represented by the user numbered as groupOfBuyer.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8) After the expiration of the guaranteed period, Pledger calls revokePledge() (the No.59 API) to revoke the Pledge numbered as seqOfPld setting on the pledged share numbered as seqOfShare.

---

| |
|:---|
| 210 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-10.jpg)

---

| |
|:---|
| 211 |
| *[**Table of Contents**](#Toc)* |

---

7.11. Execute Special Investor Rights of SHA

First Refusal rights, Drag Along rights, Tag Along rights, and Anti Dilution rights are common features in equity investment transactions. Although it is highly unlikely that all such rights would be exercised simultaneously, the system provides a clear sequence of priority for their exercise.

Once an Investment Agreement has been signed, holders of First Refusal rights may exercise their rights first. In such case, the system will terminate the original Deal contemplated under the Investment Agreement and record the First Refusal exercise claims. Upon expiry of the first-refusal exercise period, the seller may trigger the relevant interface to calculate the outcome of the first-refusal exercise. The system will then, in accordance with the First Refusal Rule set forth in the Shareholders' Agreement, recalculate and generate new transactions reflecting the updated Deals to the agreement.

Subsequently, holders of Drag Along or Tag Along rights may exercise such rights. Upon the expiry of the applicable exercise period, the buyer under the Investment Agreement may trigger the interface to confirm acceptance of the additional transfer transactions arising from the exercise of Drag Along or Tag Along rights.

If the issue price in a capital increase Deal falls below the Anti-Dilution provisions set forth in the SHA, holders of Anti-Dilution rights may exercise their claims. In such case, the system will automatically generate transfer transactions whereby shares representing a specified paid-in value are reallocated, free of charge, from the holdings of the anti-dilution obligors to the rights holders. Upon closing of the underlying transaction, the rights holders may trigger the API concerned to receive the additional shares, thereby adjusting the subscription price of their holdings to align with the capital increase Deal's price.

---

| |
|:---|
| 212 |
| *[**Table of Contents**](#Toc)* |

---

The exercise procedures for the foregoing special investor rights are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Right holder call execFirstRefusal() (the No.64 API) to execute its First Refusal right, as per the Rule numbered as seqOfRule, with the identified sequence number as seqOfRightholder, to request to buy the subject share of the Deal numbered as seqOfDeal in the Investment Agreement deployed at the address of ia, with the signature hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Any Member may call computeFirstRefusal() (the No.65 API) to compute the First Refusal claims result for the Deal numbered as seqOfDeal of the Investment Agreement deployed at the address of ia, so as to obtain the automatically updated Investment Agreement.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Rightholder may call execAlongRight() (the No.60 API) to execute the Drag-Along right codified as snOfClaim in the Investment Agreement deployed at the address of ia, to sell with the same condition of the obligor's share numbered as seqOfShare to the amount of paid value of paid and par value of par, with the signature's hash value as sigHash; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Rightholder may call execAlongRight() (the No.60 API) to execute the Tag-Along right, for the Deal numbered as seqOfDeal in the Investment Agreement deployed at the address of ia, to sell with the same condition of its share numbered as seqOfShare to the amount of paid value of paid and par value of par, with the signature's hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Buyer may call acceptAlongDeal() (the No.61 API) to accept the Tag/Drag Along requests, for the Deal numbered as seqOfDeal of the Investment Agreement deployed at the address of ia, with the signature's hash value as sigHash.

---

| |
|:---|
| 213 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6) Rightholder may call execAntiDilution() (the No.62 API) to execute the Anti-Dilution right, towards the Deal numbered as seqOfDeal in the Investment Agreement deployed at the address of ia, for its share numbered seqOfShare, with the signature hash value as sigHash.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7) Rightholder may call takeGiftShares() (the No.63 API) to take the gift shares, generating as per the Anti-Dilution Term of SHA, for the Deal numbered as seqOfDeal in the Investment Agreement deployed at the address of ia.

---

| |
|:---|
| 214 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-11.jpg)

---

| |
|:---|
| 215 |
| *[**Table of Contents**](#Toc)* |

---

7.12. Execute Options

Options are a common feature in equity financing arrangements and generally take the form of Put Option or Call Option. The triggering conditions may be based simply on the passage of time or the arrival of a specified date, or they may be contingent upon financial metrics such as the company's revenue or net profit falling below or exceeding a specified threshold. For off-chain data such as company revenue, the triggering conditions should be updated either by an independent third-party auditor or through real-time data feeds provided by automated oracle service providers.

Under a Put Option, the option holder may designate shares held by the obligor as the Pledged Share and identify the shares they wish to dispose of as the Target Share, thereby creating a Swap. Conversely, under a Call Option, the option holder may designate the obligor's shares they intend to acquire as the Target Share and select their own shares as the Pledged Share, likewise creating a Swap.

In such a structure:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. The obligor under a Put Option, or the holder of a Call Option, acting as the buyer of the Target Share, may acquire the Target Share by paying USDC or ETH, thereby releasing the Pledged Share under the Swap.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. The holder of a Put Option, or the obligor under a Call Option, acting as the seller of the Target Share, may trigger the interface to execute the Swap, transferring the Target Share while simultaneously releasing the pledge imposed on the Pledged Share.

The transfer price of the Target Share in a Swap is determined in accordance with the Put / Call Option Terms set forth in the SHA. The pledged paid amount of the Pledged Share is automatically calculated by the system as the total transaction value of the Target Share transfer divided by the acquisition price of the Pledged Share.

---

| |
|:---|
| 216 |
| *[**Table of Contents**](#Toc)* |

---

The procedures for exercising options are as follows:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) Direct Keeper of General Keeper calls updateOracle() (the No.47 API) to update the key performance indicators of d1, d2, and d3, for the specific Option numbered as seqOfOpt.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) Option holder calls execOption() (the No.48 API) to execute the Option numbered as seqOfOpt.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) Option holder calls createSwap() (the No.49 API) to create a Swap on the target share numbered as seqOfTarget, for paid value amount to paidOfTarget, with the collateral set up on the pledged share numbered as seqOfPledge, for executing the Option numbered as seqOfOpt.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) Buyer of the Target Share calls payOffSwap() (the No.50 API) to pay certain amount of ETH with the equivalent value, under the Swap numbered seqOfSwap, of the Option numbered as seqOfOpt, to close the Swap.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5) Shareholder of the Target Share calls terminateSwap() (the No.51 API) to execute the swap numbered as seqOfSwap of the Option numbered as seqOfOpt, by transferring the Target Share and releasing the Pledged Share.

---

| |
|:---|
| 217 |
| *[**Table of Contents**](#Toc)* |

---

![](oaprocess-12.jpg)

---

| |
|:---|
| 218 |
| *[**Table of Contents**](#Toc)* |

---

 **8. CBP And Economic Model**

To measure and collect license fees for authors, the system introduced an ERC-20 token ---- "**ComBoox Points**" ("**CBP**").

**The Attributes and Specifications of CBP** Name: ComBooxPoints Symbol: CBP Standard: ERC20 Book-Entry Contract: RegCenter Unit: CBP Minimum unit: Lee Conversion formula: 1 CBP = 10^18 Lee

 **CBP** does **NOT** represent any equity share or ownership share of any entities, and does **NOT** have any beneficiary interests of equity or trust, which is only aimed to collect license fees for smart contracts in **ComBoox**. The value of **CBP** may fluctuate from time to time depending on the number of users and registered companies in **ComBoox**, which may reflect the value change of the smart contracts concerned with respect to their intellectual property rights.

---

| |
|:---|
| 219 |
| *[**Table of Contents**](#Toc)* |

---

In order to reduce the **uncertainty of CBP prices**, especially to avoid the risk of "**price increase**" brought about by the increase in user stickiness, we deliberately adopts a basic pricing model of "**Fixed Maximum Price, Adjustable Promotion Policy**".

**ComBoox's economic model** and **license fee** can be summarized as follows:

 **8.1. Rate of Royalty**

The **author** may set the rate of royalty for any write APIs of the **contract templates**. Each time a user calls the said API to exercise rights, a calculated license fee will be transferred from its account to the **author's account**. Once set, the rate will be fixed on the particular **contract template**, based on which, **clone contracts** will inherit the same **rate of royalty**.

 **8.2. Collection of License Fee**

When a **user** exercise rights by calling a contract's chargeable API, the contract will automatically call **Reg Center** to query the caller's user number. Thereafter, the **Register** will charge a specific amount of **CBP** from the caller's **Prime Key** account based on the rate of royalty set in the template, and pay to the **author**.

 **8.3. Commission of Platform**

For each license fee payment, **ComBoox** charges a commission of up to 20%, which is directly transferred to the **Owner** of **ComBoox**. From time to time, **ComBoox** may revise its promotional policies to reduce the commission rate or establish a minimum royalty rate to ensure coverage of its operational costs. As such, while the platform's maximum commission rate is fixed at 20%, the actual amount payable may vary based on applicable discount policies.

---

| |
|:---|
| 220 |
| *[**Table of Contents**](#Toc)* |

---

 **8.4. Promotion Policy**

**Author** may create or adjust its license fee at any time by providing users a certain amount of **coupon** or a certain rate of **quantity discount.** Therefore, the original royalty rate set by author when deploying template actually is the ceiling rate.

 **License Fee Payable = Royalty Rate - Total Coupon - Number of Calls \* Quantity Discount Rate** 

---

| |
|:---|
| **Function of _chargeFee** |
| function _chargeFee(<br> address targetAddr, <br> uint fee, <br> address authorAddr,<br> UsersRepo.Key memory rr ) private {<br>UsersRepo.User storage t = _getUser(targetAddr);<br> address ownerAddr = getOwner();<br>UsersRepo.Rule memory pr = getPlatformRule();<br> uint floorPrice = uint(pr.floor) \* 10 \*\* 9;<br> if (fee < floorPrice)<br> revert RC_WrongState(bytes32("RC_FeeTooLow"));<br>uint offAmt = uint(t.primeKey.coupon) \* uint(rr.discount) <br> \* fee / 10000 + uint(rr.coupon) \* 10 \*\* 9;<br> fee = (offAmt < (fee - floorPrice)) ? (fee - offAmt) : floorPrice;<br> uint giftAmt = uint(rr.gift) \* 10 \*\* 9;<br>if (ownerAddr == authorAddr \|\| pr.rate == 2000) {<br> if (fee > giftAmt)<br> _transfer(t.primeKey.pubKey, authorAddr, fee - giftAmt);<br> } else {<br> _transfer(t.primeKey.pubKey, ownerAddr, fee \* (2000 - pr.rate) / 10000);<br> uint balaceAmt = fee \* (8000 + pr.rate) / 10000;<br> if (balaceAmt > giftAmt)<br> _transfer(t.primeKey.pubKey, authorAddr, balaceAmt - giftAmt);<br> }<br>_addCouponOnce(targetAddr);<br> } |

---

---

| |
|:---|
| 221 |
| *[**Table of Contents**](#Toc)* |

---

 **8.5. New User's Gift**

**ComBoox** may introduce promotion policy to give a certain amount of CBP as gift to newly registered **external accounts** from time to time. For details of promotion policy, users can call "Get Platform Rule" API of **Reg Center** to check details.

 **8.6. Transfer of Smart Contracts' Copyright**

Smart contracts' **Author** can freely transfer the templates' copyright to other users. After transfer, license fee for these smart contracts will be paid to **prime key** address of the transferee. The transferee will then be entitled to further transfer the copyright to other users.

---

| |
|:---|
| **Function of TransferIPR** |
| function transferIPR(<br> Repo storage repo,<br> uint typeOfDoc,<br> uint version,<br> uint transferee,<br> uint caller ) public {<br>if (caller != getAuthor(repo, typeOfDoc, version))<br> revert DocsRepo_WrongParty(bytes32("DR_NotAuthor"));<br>repo.heads[repo.bodies[typeOfDoc][version][0].addr].author <br> = uint40(transferee);<br> } |

---

---

| |
|:---|
| 222 |
| *[**Table of Contents**](#Toc)* |

---

 **8.7. Transfer of System's ownership**

**ComBoox's Owner** can also transfer its ownership to other accounts, thereby transferring the creditor's right to receivables of platform commission.

---

| |
|:---|
| **Function of TransferOwnership** |
| function transferOwnership(<br> Repo storage repo, address newOwner) public onlyOwner(repo) {<br>if (newOwner == address(0)) <br> revert USRR_WrongInput(bytes32("UR_TO: zero address"));<br>repo.users[0].primeKey.pubKey = newOwner;<br> }<br>|

---

---

| |
|:---|
| 223 |
| *[**Table of Contents**](#Toc)* |

---

 **9. Financial Records**

**ComBoox** adopts USDC as special "general equivalence" to pay for new share subscription or share transfer consideration. It also allows companies booked in the system to transfer USDC respectively, or to pay ETH together with calling external smart contracts to pay for the cost or consideration of legal actions.

To facilitate automatic bookkeeping of the financial records of these activities, the system set up special events in the smart contracts of the **General Keeper**, **Sub-Keepers** and **Cashier**, so that the financial records of these payment activities can be retrieved and summarized in real time automatically.

 **9.1. Exchange Rate**

**9.1.1. USD/CBP** 

The system offers **CBP** to the public through the smart contract of Fuel Tank, at the USD/CBP exchange rate that is determined by the **Owner** of the **Platform**. Currently, the exchange rate is 2,816.15 USD/CBP, which can be retrieved in real time by users.

**9.1.2. USDC**

The price of **USDC** is deemed to be always $1.00 per unit.

---

| |
|:---|
| 224 |
| *[**Table of Contents**](#Toc)* |

---

 **9.2. CBP Flow Records**

As an ERC-20 token, CBP's income and expenditure are booked in the Registration Center, which automatically records the sender, recipient and amount of each transaction Users can further distinguish the CBP payments with respect to their detailed scenarios and reasons according to the identity of the payer and payee. For example, when the payer is "zero" address, it means the Platform minted coins to the payee.

---

| |
|:---|
| **CBP Transfer Event** |
| event Transfer(address indexed from, address indexed to, uint256 value); |

---

---

| |
|:---|
| 225 |
| *[**Table of Contents**](#Toc)* |

---

 **9.3. USDC Flow Records**

**ComBoox** provides API for equity trading transactions in **USDC**, and, **Cashier** holds, receives, forwards, transfers, or distributes the **USDC** paid in connection with these transactions, and is also responsible for recording all such **USDC** payment activities.

**9.3.1. USDC Inflow**

For USDC paid to the company such as paid-in contributions and equity subscriptions, the **Cashier** will only record the reason for the payment through the event log, and will not allocate such USDC to the deposit account or the escrow account.

---

| |
|:---|
| **Collect USD Function** |
| function collectUsd(TransferAuth memory auth, bytes32 remark) external anyKeeper {<br> _transferWithAuthorization(auth);<br> emit ReceiveUsd(auth.from, auth.value, remark);<br> } |

---

**9.3.2. USDC Outflow**

In addition to the **USDC Distribution** scenario described in section (1), any other **USDC** payments of a company shall also be subject to the approval of the **General Meeting of Members** or the **Board of Directors** in accordance with the corporate governance process stipulated in the **Shareholders Agreement**, which are essentially the process of implementing the resolutions of the **General Meeting of Members** or the ones of the **Board of Directors**.

The authorized executor needs to call the function of **ExecAction** or **ExecActionOfGM** of **General Keeper**, so as to further invoke the function of **TransferUSD** of **Cashier** to make the payment.

---

| |
|:---|
| 226 |
| *[**Table of Contents**](#Toc)* |

---

**9.3.3. USDC Deposit Records**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(1) Distribute USD Function**

As the price of USDC is deemed to be $1.00 per unit, no balance or change will be generated for payments made in USDC. Any consideration or refund will be settled directly to the relevant user's account.

However, in the event that any USDC is distributed by a company to its Members, the corresponding amounts will be allocated under each Member's User Number in a private mapping called "_lockers". Thereafter, Members may retrieve their allocated deposits at their discretion at any time.

---

| |
|:---|
| **Mapping _lockers & Distribute Profits Function of Cashier** |
| <br> mapping(uint => uint) private _lockers;<br>function distrProfits(uint amt, uint seqOfDR) external onlyKeeper returns(<br> WaterfallsRepo.Drop[] memory mlist){<br>if (balanceOfComp() < amt)<br> revert Cashier_Overflow(bytes32("Cashier_InsufficientAmt"));<br>RulesParser.DistrRule memory rule =<br> _gk.getSHA().getRule(seqOfDR).DistrRuleParser();<br>IRegisterOfMembers _rom = _gk.getROM();<br> IRegisterOfShares _ros = _gk.getROS();<br> WaterfallsRepo.Drop memory drop;<br>if (rule.typeOfDistr == uint8(RulesParser.TypeOfDistr.ProRata)) {<br> (drop, mlist,) = _rivers.proRataDistr(amt, _rom, _ros, false);<br> } else if (rule.typeOfDistr == uint8(RulesParser.TypeOfDistr.IntFront)) {<br> (drop, mlist,) = _rivers.intFrontDistr(amt, _ros, rule);<br> } else revert Cashier_WrongState(bytes32("Cashier_WrongTypeOfDistr"));<br>emit DistrProfits(amt, seqOfDR, drop.seqOfDistr);<br> _distrUsd(mlist, bytes32("DistrProfits"));<br>}<br>function _distrUsd(WaterfallsRepo.Drop[] memory mlist, bytes32 remark) private {<br>uint len = mlist.length;<br> while (len > 0) {<br> WaterfallsRepo.Drop memory drop = mlist[len-1];<br> _depositUsd(drop.member, drop.income + drop.principal, remark);<br> len--;<br> }<br> }<br>function _depositUsd(uint payee, uint amt, bytes32 remark) private {<br> if (payee == 0) {<br> revert Cashier_WrongParty(bytes32("Cashier_ZeroPayee"));<br> }<br>emit DepositUsd(amt, payee, remark);<br>_lockers[payee] += amt;<br> _lockers[0] += amt;<br> }<br>|

---

---

| |
|:---|
| 227 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(2) Pickup USD Function**

USDC deposited in a user's deposit account can only be exclusively picked up by such user by calling the Pickup USD Function of the Cashier, and cannot be misappropriated or withdrawn by any other account.

---

| |
|:---|
| **Function of pickupUsd (Cashier)** |
| function pickupUsd() external {<br> uint caller = _msgSender(msg.sender, 18000);<br> uint value = _lockers[caller];<br>if (value > 0) {<br> _lockers[caller] = 0;<br> _lockers[0] -= value;<br> emit PickupUsd(msg.sender, caller, value);<br>if (!_gk.getBank().transfer(msg.sender, value))<br> revert Cashier_TransferFailed(bytes32("Cashier_TransferFailed"));<br> } else revert Cashier_Overflow(bytes32("Cashier_NoBalance"));<br>} |

---

---

| |
|:---|
| 228 |
| *[**Table of Contents**](#Toc)* |

---

**9.3.4. USDC Escrow Records**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(1) Escrow USDC**

The system allows verified investors to trade the equity shares of the registered companies in the smart contract of **List of Orders** with six types of orders: limited buy order, market buy order, limited sell order, market sell order, limited issue order, and market issue order. When listing a limited buy order, the system needs to deposit the USDC paid by the buyer into the escrow account as margin.

When depositing margin, the system will call the function of **Custody USD** of **Cashier**, and deposit the relevant amount into a private mapping called "_coffers". This allows different users to be distinguished and prevents the margin from being taken out by the user himself or any other user.

---

| |
|:---|
| **Mapping _coffers & Function of custodyUsd (Cashier)** |
| mapping(address => uint) private _coffers;<br> function _transferWithAuthorization(TransferAuth memory auth) private {<br> _usd().transferWithAuthorization(<br> auth.from, <br> address(this), <br> auth.value,<br> auth.validAfter, <br> auth.validBefore, <br> auth.nonce, <br> auth.v,<br> auth.r,<br> auth.s);<br> }<br> function custodyUsd(TransferAuth memory auth, bytes32 remark) external anyKeeper {<br> _transferWithAuthorization(auth);<br> _coffers[auth.from] += auth.value;<br> _coffers[address(0)] += auth.value;<br> emit CustodyUsd(auth.from, auth.value, remark);<br> } |

---

---

| |
|:---|
| 229 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(2) Release USDC** 

When a sell order or issue order is listed, the system will take the lead in matching the transaction with the existing listed buy orders, and after the transaction is closed, the margin locked up with the buy order will be released to the seller's deposit account as consideration, or to the company as capital contribution.

Upon releasing the margin, the **Release USD** function of **Cashier** will be called, through the events of which the payer, payee, amount, and reason of the payment will automatically be recorded. Similar to **Save To Coffer**, a summary description of the reason of payment will be saved in ASCII code via a Bytes32 fixed-length array.

---

| |
|:---|
| **Function of releaseUsd (Cashier)** |
| function releaseUsd(<br> address from, address to, uint amt, bytes32 remark) external anyKeeper {<br> if(_coffers[from] < amt) <br> revert Cashier_Overflow("Cashier_InsufficientAmt");<br>_coffers[from] -= amt;<br> _coffers[address(0)] -= amt;<br>emit ReleaseUsd(from, to, amt, remark);<br>if (!_gk.getBank().transfer(to, amt)) <br> revert Cashier_TransferFailed(bytes32("Cashier_TransferFailed"));<br> }<br>|

---

---

| |
|:---|
| 230 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **(3) Reason of USDC Escrow**

The table below provides a summary of the reasons for escrow or releasing USDC margin and their ASCII codes.

---

| | | |
|:---|:---|:---|
| **Reason of Escrow** | **Reason of Escrow** | **Reason of Escrow** |
| **Scenario** | **Brief Description** | **ASCII Code (Bytes32 in Hex)** |
| Deposit Buy Order Margin | CustodyValueOfBid | 0x437573746f647956616c75654f66426964000000000000000000000000000000 |
| Release Margin to Company | CloseInitOfferAgainstBid | 0x436c6f7365496e69744f66666572416761696e73744269640000000000000000 |
| Release Margin to Seller | CloseOfferAgainstBid | 0x436c6f73654f66666572416761696e7374426964000000000000000000000000 |
| Refund Buy Order Margin | RefundValueOfBidOrder | 0x526566756e6456616c75654f664269644f726465720000000000000000000000 |

---

---

| |
|:---|
| 231 |
| *[**Table of Contents**](#Toc)* |

---

 **10. Key Legal Issues**

When start using **ComBoox** to book equity shares and corporate governance records, you may consider several key legal issues as follows:

 **10.1. Digital Identification Mechanism VS. Real-Name Requirements**

There is a distance between digital identification mechanism of **ComBoox** and real-name requirements in various countries. **ComBoox** takes the EVM account address as the basis of user identification, and does not verify the user's social identity such as name, nationality, or residence etc., which has a distance to the real-name requirements of various jurisdictions with respect to finance, securities, foreign exchange, tax, investor suitability, and anti-money laundering.

Not directly managing users' social identity information is certainly related to the characteristics of blockchain technology, but more importantly, it is conducive to effectively protecting personal privacy, business secrets and other information in the open public blockchain environment.

Even though there exists a distance between digital identification and real-name requirements, while, distance does not mean impossible. Stakeholders of a company can surely cooperate together to register and maintain their social identities in accordance with the legal requirements of the relevant jurisdictions of registration, operation or transaction, and to effectively connect their on-chain digital identity with their real world social identities, so as to satisfy the mandatory real-name requirements of the relevant laws and regulations.

---

| |
|:---|
| 232 |
| *[**Table of Contents**](#Toc)* |

---

Making full use of the rigid programming logic of blockchain and smart contracts to realize the concept of "**Code is Law**", thereby effectively overcoming or even fundamentally solving the problems caused by human interference, and enhancing equity value by leveraging the great support of the massive liquidity of crypto markets. All Benefits and advantages brought by blockchain technologies can certainly outweigh costs and expenses incurred by satisfying the real-name requirement.

No matter it is to anti-tax avoidance, anti-money laundering, counter-terrorism financing, to protect financial consumers' rights and interests, to maintain foreign exchange order, or to protect monetary sovereignty, real-name requirements always have their specific legislation purpose and specific interests protection objects. As long as these legislative purposes can be effectively achieved through scientific methods, and the rights and interests of the subjects can be effectively protected, on-chain corporate governance and compliance operation goals can be perfectly combined ultimately.

---

| |
|:---|
| 233 |
| *[**Table of Contents**](#Toc)* |

---

 **10.2. Real Time Information Disclosure VS. Trade Secret Protection**

Blockchain's technical features determine that once equity shares and corporate behaviors are booked on chain, such records will become publicly aware and cannot be kept as confidential information in traditional way.

However, equity shares and corporate governance records, by nature, shall be public information and should not be regarded as trade secrets. By means of public registration system to ensure a proper transparency of corporate governance, so as to protect rights of creditors, bona fide third parties and other external stakeholders, to establish the fiduciary duties of managers to shareholders, and to determine the apparent agency relationship between managers and the company, these are the general legal principles that most countries adopted to regulate the external legal relationships of companies as per their prevailing commercial laws. It is also a fundamental reason why the public registration system of company archives has been established in so many countries.

Usually, what are protected as trade secrets are usually confidential information that has monopoly legitimacy and commercial value, such as intellectual property rights, major transactions pricing, etc. Most corporate governance documents and most contents thereof obviously do not belong to this category.

For those parts of corporate governance documents that really need to be kept confidential, other workarounds can be used to deal with them, thereby resolving the conflict between information confidentiality and governance behavior on chain.

---

| |
|:---|
| 234 |
| *[**Table of Contents**](#Toc)* |

---

For example, encrypt the electronic document with natural language first, and then upload the encrypted file to the IPFS, and finally use the CID hash as the content index to be stored on blockchain. In this way, the confidentiality of trade secrets can be satisfied on the one hand, and corporate governance behaviors such as company decisions and shareholder resolutions can be kept on the blockchain on the other, and the original text of confidential information can be retrieved, downloaded, decrypted, and restored from IPFS when necessary, so as to verify the consistency of decision-making results with the subject contents reviewed. With this approach, corporate governance can maintain openness and standardization while achieving effective protection of trade secrets, avoiding the use of "confidentiality" as an excuse to circumvent the voting process on blockchain, or sacrificing the commercial interests of confidential information because of voting on blockchain.

Therefore, the distance between information disclosure on blockchain and the trade secret protection can be solved by smart contracts. While ensuring the information security, the transparency and non-tamperability of blockchain can be well utilized to achieve transparency and standardization of corporate governance.

---

| |
|:---|
| 235 |
| *[**Table of Contents**](#Toc)* |

---

 **10.3. Internal Book-Entry Records VS. Public Registration Information**

Public registration system has been widely adopted in various countries as a basic legal principle to maintain the commercial order. At the same time, company laws usually require companies to properly manage corporate governance documents such as the register of shares, register of members, general meetings minutes, register of directors, etc. to ensure the transparency and legality of company operations.

So, if there are any discrepancies between the internal governance records managed by**ComBoox a**nd the company files in public registration authority, which one should prevail and will it give rise to a conflict of laws?

In international judicial practices, the delivery of equity and the establishment of shareholder identity are often determined on company's internal legal behaviors, such as issuing a capital certificate or recording names of shareholders in the register of members. In other words, when regulating the "internal" equity investment relationship between shareholders and the company, and when judging the delivery time of the "internal" contractual relationship between the buyers and sellers of equity transactions, the company's internal files are often the decisive basis for judgment. Therefore, it can also be generally understood that the company's internal files are the "effective basis" for judging equity establishment and equity delivery, and are the fundamental basis for handling internal investment relationships and internal contract relationships.

On the other hand, when a creditor relies on the public information to claim that shareholders shall implement capital contribution obligation, the stock investors claim that the managers of a listed company shall bear their fiduciary duties, bona fide third party claims that a contract signed by directors shall bind the company, the internal files' records (such as equity shares have been transferred, managers have resigned etc.) cannot be used as a defensive reason then. Judicial practice often determines the attribution of liability and the establishment of an apparent agency relationship based on the public registration information. Therefore, the publicly registered company records are the "confrontational basis" for judging the attribution of responsibilities and adversarial legal claims, and are the fundamental basis for handling the company's external relationship of creditors' rights or apparent agencies.

---

| |
|:---|
| 236 |
| *[**Table of Contents**](#Toc)* |

---

Therefore, the internal files managed by the company do not conflict with the officially registered company records, but play different legal roles at different levels. Moreover, this problem is not a new problem brought by **ComBoox** or blockchain technology, but an inherent legal problem that has existed for a long time. Existing legal principles, legal norms and judicial practices have mature rules and jurisprudence to solve them. The internal company records confirm the shareholder's identity, allocate the ownership of shares, and regulate the internal legal relationship of a company; public registration records deal with credit relationship, insolvency liability and apparent agents, and regulate external legal relationship for a company. The two records system together constitute the legal system of corporate governance, are interconnected and complementary, and jointly ensure the legality and transparency of company operations.

It is worth noting that most countries require companies to update their public registration information in a timely manner in event of changes in shareholdings, managers or major company governance decisions, thus ensuring the consistency of the internal file and the official registry, which proves that both records are well coexisting and complementing with each other.

Therefore, if a company adopts **ComBoox** to manage its internal records on blockchain, it will not create a legal conflict with the information in official public registration system. Moreover, if **ComBoox** solution is widely used, it is likely to promote or even revolutionize existing public registration system, and may lead to the integration of two records system into one.

---

| |
|:---|
| 237 |
| *[**Table of Contents**](#Toc)* |

---

 **10.4. Give Legal Effects to On-Chain Books**

In brief, through constitutional documents like articles of association or bylaws, the company needs to give on-chain books special legal effects from the following aspects:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) **Registers of Interests**: The contents of **Register of Shares**, **Register of Pledges** and **Register of Options** directly reflect property rights and interests. Therefore, it is necessary to clearly stipulate in the constitutional document that these on-chain **Registers** shall be regarded as the fundamental basis for the relevant rights and interests, so that changes in these **Registers** can directly lead to legal consequences of creation, modification, disposal or elimination of the relevant legal rights or legal relationships;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) **Registers of Governance Behaviors**: The core meaning of **Registers** of governance behaviors (like **Board Meeting Minutes**, **General Meeting Minutes**, or **Register of Directors**) is to record the expressions of intention, and the key points of recording the expressions of intention lies in confirming the binding forces of electronic signatures to their specific subjects, therefore, it needs to stipulate in the constitutional documents that:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. calling commands relating to expressions of intention (such as signing documents, proposing motion, voting, taking office, resignation, etc.) signed (or triggered) by the parties through their electronic wallet (or private key) have legal binding forces upon the perpetrators;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. on-chain timestamp recorded by the system shall be regarded as the time when the relevant legal behavior occurred;

---

| |
|:---|
| 238 |
| *[**Table of Contents**](#Toc)* |

---

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c. the hash digest value stored on-chain shall be regarded as the fundamental basis for verifying the integrity of the expression content; and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d. legal documents that lack on-chain evidence (such as general meeting resolution, board meeting resolutions, or director's signature etc.) are not legally binding on the company.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) **Prevailing of Smart Contracts**: **Shareholders Agreements, Investment Agreements** and other smart contracts of the system will automatically control on-chain legal actions, and will directly result in legal consequences like equity changes, inauguration and resignation. Therefore, it's vital important to clearly specify in the company's constitutional document drafted in natural language that, in case any descriptions exist (in meaning or in logical) between the natural language documents and their corresponding on-chain smart contracts, the smart contracts shall prevail.

---

| |
|:---|
| 239 |
| *[**Table of Contents**](#Toc)* |

---

 **11. Software License**

**ComBoox Software License 1.0**

TERMS AND CONDITIONS FOR USE, REPRODUCTION AND DISTRIBUTION.

**1. Definition.**

"**Contributor**" shall mean copyright owner, and the other contribution owner and any individual or Legal Entity who have submitted the Work to the Copyright Owner and subsequently incorporated within the Work.

"**Contribution**" shall mean the original version of the Work and any additions to that Work, that is intentionally submitted to Contributor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner.

"**Legal Entity**" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

"**License**" shall mean the terms and conditions for the permitted use as defined by this document.

"**Licensor**" shall mean the copyright owner and/or Legal Entity authorized by the copyright owner that is granting the License.

"**Permitted Use**" shall mean the acts of calling the smart contracts of **ComBoox** via their specific API to read or write data on the blockchain network where they were originally deployed by Contributor, and the acts of reproduction, distribution or presentation of the Work for purposes of research, verification or testing, on a computer not linking with any blockchain network, or on a local testing blockchain that consists of one or more nodes entirely and exclusively controlled by You.

---

| |
|:---|
| 240 |
| *[**Table of Contents**](#Toc)* |

---

"**Work**" or ("**ComBoox**") shall mean the ComBoox system, a blockchain based statutory books keeping system, consisting of a series of smart contracts, including all Contribution(s).

"**You**" shall mean an individual or Legal Entity exercising permissions granted by this License.

**2. Grant of License**

Subject to the terms and conditions of this License, each Contributor hereby grants to you a worldwide, non-exclusive copyright License for the Permitted Use of Work.

**3. No Trademark License**

No trademark license is granted to use the trade names, trademarks of Contributor, except as required for reasonable and customary use in describing the origin of the Work.

**4. Prohibition**

Unless expressly permitted in this License or other agreements, You are prohibited from:

Deploying the smart contracts of ComBoox, in whole or in part, for whatever purpose, on any blockchain network that has one or more nodes out of your control;

Modifying, translating, or creating derivative works based on the Work; or

Using or disposing of the Work in any illegal manner.

---

| |
|:---|
| 241 |
| *[**Table of Contents**](#Toc)* |

---

**5. Additional Terms**

If you intend to use the Licensed Work in a way that does not fully comply with the requirements stipulated in this License, please contact Contributor in advance to apply for a commercial license.

The Permitted Use and any Contributions to the Work must include a readable copy of this License (refer to the section below on Special Requirements On Reproduction or Distribution).

**6. Termination**

Any use of the Work in violation of this License will automatically terminate your rights under this License for the current and all other Work.

**7. Disclaimer of Warranty**

(1) Contributor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE WORK OR THE CONTRIBUTION, NO MATTER HOW IT'S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

---

| |
|:---|
| 242 |
| *[**Table of Contents**](#Toc)* |

---

(2) Although ComBoox provides some valuable Legal and Compliance solutions, whereas, it cannot ensure absolute compliance for any significant legal issues, please seek professional advice from legal experts of the relevant jurisdictions. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE FOR ANY DAMAGES caused by below issues:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i. AML/KYC Compliance: shall mean the mandatory legal requirements about identity verification and identity archives management, that various countries stipulated in the fields of financing, securities, investment, asset management, currency exchange, payment etc., for the purpose of investor suitability protection, anti-money laundering, anti-terrorist financing, anti-tax avoidance, and other related purposes,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ii. Securities Compliance: shall mean the mandatory legal requirements around securities issuance and/or transaction activities (such as reporting, filing, and disclosure) for the securities-type equity public offerings or specified private placement in terms of stocks, bonds, and other financing instruments in various countries; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iii. Data Compliance: shall mean the mandatory legal requirements for data processing activities in various countries, in order to protecting data security, personal information rights, national security and/or commercial secrets.

(3) As an infrastructure software, ComBoox cannot influence or control any behavior of its users or third parties. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE FOR ANY DAMAGES caused by below third party behavior:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i. Inaccurate, incomplete or untimely data uploaded/provided by users;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ii. A third party malicious attack, hack, tamper, intercept, or controls over the data against its owner's intention; or

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iii. The unavailability of the blockchain due to the failure of any external environment supplier, such as the unavailability of electrical power, internet connection, and/or any other similar public utilities or infrastructures failure caused by third parties' behavior or negligence.

---

| |
|:---|
| 243 |
| *[**Table of Contents**](#Toc)* |

---

**8. Language**

This License is written in English and Chinese; both shall have the same legal effect. In case of any discrepancies between the two versions, the English one shall prevail.

**9. Special Requirements On Reproduction or Distribution**

To reproduce or distribute this WORK, you are required to complete following steps:

Create a file named "LICENSE" which contains the whole context of this License in the first directory of your package;

Attach the statement to the appropriate annotated syntax at the beginning of each source file.

This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which can be obtained at:

[https://github.com/paul-lee-attorney/comboox]

THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.

YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR MORE NODES THAT ARE OUT OF YOUR CONTROL.

---

| |
|:---|
| 244 |
| *[**Table of Contents**](#Toc)* |

---

## Ex-32

# Source Codes of ComBoox

---

| | |
|:---|:---|
| File Name | Path |
| [BookOfDocs.sol](#contracts-center-books-bookofdocs-sol) | contracts/center/books/BookOfDocs.sol |
| [BookOfPoints.sol](#contracts-center-books-bookofpoints-sol) | contracts/center/books/BookOfPoints.sol |
| [BookOfUsers.sol](#contracts-center-books-bookofusers-sol) | contracts/center/books/BookOfUsers.sol |
| [IBookOfDocs.sol](#contracts-center-books-ibookofdocs-sol) | contracts/center/books/IBookOfDocs.sol |
| [IBookOfPoints.sol](#contracts-center-books-ibookofpoints-sol) | contracts/center/books/IBookOfPoints.sol |
| [IBookOfUsers.sol](#contracts-center-books-ibookofusers-sol) | contracts/center/books/IBookOfUsers.sol |
| [IRegCenter.sol](#contracts-center-iregcenter-sol) | contracts/center/IRegCenter.sol |
| [RegCenter.sol](#contracts-center-regcenter-sol) | contracts/center/RegCenter.sol |
| [CashLockers.sol](#contracts-center-utils-cashlockers-sol) | contracts/center/utils/CashLockers.sol |
| [CreateNewComp.sol](#contracts-center-utils-createnewcomp-sol) | contracts/center/utils/CreateNewComp.sol |
| [ICashLockers.sol](#contracts-center-utils-icashlockers-sol) | contracts/center/utils/ICashLockers.sol |
| [ICreateNewComp.sol](#contracts-center-utils-icreatenewcomp-sol) | contracts/center/utils/ICreateNewComp.sol |
| [IUSDC.sol](#contracts-center-utils-mockusdc-iusdc-sol) | contracts/center/utils/MockUSDC/IUSDC.sol |
| [MockUSDC.sol](#contracts-center-utils-mockusdc-mockusdc-sol) | contracts/center/utils/MockUSDC/MockUSDC.sol |
| [UsdFuelTank.sol](#contracts-center-utils-usdfueltank-sol) | contracts/center/utils/UsdFuelTank.sol |
| [Cashier.sol](#contracts-comps-books-cashier-cashier-sol) | contracts/comps/books/cashier/Cashier.sol |
| [ICashier.sol](#contracts-comps-books-cashier-icashier-sol) | contracts/comps/books/cashier/ICashier.sol |
| [IListOfOrders.sol](#contracts-comps-books-loo-ilistoforders-sol) | contracts/comps/books/loo/IListOfOrders.sol |
| [ListOfOrders.sol](#contracts-comps-books-loo-listoforders-sol) | contracts/comps/books/loo/ListOfOrders.sol |
| [IInvestmentAgreement.sol](#contracts-comps-books-roa-iinvestmentagreement-sol) | contracts/comps/books/roa/IInvestmentAgreement.sol |
| [InvestmentAgreement.sol](#contracts-comps-books-roa-investmentagreement-sol) | contracts/comps/books/roa/InvestmentAgreement.sol |
| [IRegisterOfAgreements.sol](#contracts-comps-books-roa-iregisterofagreements-sol) | contracts/comps/books/roa/IRegisterOfAgreements.sol |
| [RegisterOfAgreements.sol](#contracts-comps-books-roa-registerofagreements-sol) | contracts/comps/books/roa/RegisterOfAgreements.sol |
| [IRegisterOfConstitution.sol](#contracts-comps-books-roc-iregisterofconstitution-sol) | contracts/comps/books/roc/IRegisterOfConstitution.sol |
| [IShareholdersAgreement.sol](#contracts-comps-books-roc-ishareholdersagreement-sol) | contracts/comps/books/roc/IShareholdersAgreement.sol |
| [RegisterOfConstitution.sol](#contracts-comps-books-roc-registerofconstitution-sol) | contracts/comps/books/roc/RegisterOfConstitution.sol |
| [ShareholdersAgreement.sol](#contracts-comps-books-roc-shareholdersagreement-sol) | contracts/comps/books/roc/ShareholdersAgreement.sol |
| [Alongs.sol](#contracts-comps-books-roc-terms-alongs-sol) | contracts/comps/books/roc/terms/Alongs.sol |
| [AntiDilution.sol](#contracts-comps-books-roc-terms-antidilution-sol) | contracts/comps/books/roc/terms/AntiDilution.sol |
| [IAlongs.sol](#contracts-comps-books-roc-terms-ialongs-sol) | contracts/comps/books/roc/terms/IAlongs.sol |
| [IAntiDilution.sol](#contracts-comps-books-roc-terms-iantidilution-sol) | contracts/comps/books/roc/terms/IAntiDilution.sol |
| [ILockUp.sol](#contracts-comps-books-roc-terms-ilockup-sol) | contracts/comps/books/roc/terms/ILockUp.sol |
| [IOptions.sol](#contracts-comps-books-roc-terms-ioptions-sol) | contracts/comps/books/roc/terms/IOptions.sol |
| [LockUp.sol](#contracts-comps-books-roc-terms-lockup-sol) | contracts/comps/books/roc/terms/LockUp.sol |
| [Options.sol](#contracts-comps-books-roc-terms-options-sol) | contracts/comps/books/roc/terms/Options.sol |
| [IRegisterOfDirectors.sol](#contracts-comps-books-rod-iregisterofdirectors-sol) | contracts/comps/books/rod/IRegisterOfDirectors.sol |
| [RegisterOfDirectors.sol](#contracts-comps-books-rod-registerofdirectors-sol) | contracts/comps/books/rod/RegisterOfDirectors.sol |
| [IRegisterOfInvestors.sol](#contracts-comps-books-roi-iregisterofinvestors-sol) | contracts/comps/books/roi/IRegisterOfInvestors.sol |
| [RegisterOfInvestors.sol](#contracts-comps-books-roi-registerofinvestors-sol) | contracts/comps/books/roi/RegisterOfInvestors.sol |
| [IRegisterOfMembers.sol](#contracts-comps-books-rom-iregisterofmembers-sol) | contracts/comps/books/rom/IRegisterOfMembers.sol |
| [RegisterOfMembers.sol](#contracts-comps-books-rom-registerofmembers-sol) | contracts/comps/books/rom/RegisterOfMembers.sol |
| [IRegisterOfOptions.sol](#contracts-comps-books-roo-iregisterofoptions-sol) | contracts/comps/books/roo/IRegisterOfOptions.sol |
| [RegisterOfOptions.sol](#contracts-comps-books-roo-registerofoptions-sol) | contracts/comps/books/roo/RegisterOfOptions.sol |
| [IRegisterOfPledges.sol](#contracts-comps-books-rop-iregisterofpledges-sol) | contracts/comps/books/rop/IRegisterOfPledges.sol |
| [RegisterOfPledges.sol](#contracts-comps-books-rop-registerofpledges-sol) | contracts/comps/books/rop/RegisterOfPledges.sol |
| [IRegisterOfRedemptions.sol](#contracts-comps-books-ror-iregisterofredemptions-sol) | contracts/comps/books/ror/IRegisterOfRedemptions.sol |
| [RegisterOfRedemptions.sol](#contracts-comps-books-ror-registerofredemptions-sol) | contracts/comps/books/ror/RegisterOfRedemptions.sol |
| [IRegisterOfShares.sol](#contracts-comps-books-ros-iregisterofshares-sol) | contracts/comps/books/ros/IRegisterOfShares.sol |
| [RegisterOfShares.sol](#contracts-comps-books-ros-registerofshares-sol) | contracts/comps/books/ros/RegisterOfShares.sol |
| [AccessControl.sol](#contracts-comps-common-access-accesscontrol-sol) | contracts/comps/common/access/AccessControl.sol |
| [DraftControl.sol](#contracts-comps-common-access-draftcontrol-sol) | contracts/comps/common/access/DraftControl.sol |
| [IAccessControl.sol](#contracts-comps-common-access-iaccesscontrol-sol) | contracts/comps/common/access/IAccessControl.sol |
| [IDraftControl.sol](#contracts-comps-common-access-idraftcontrol-sol) | contracts/comps/common/access/IDraftControl.sol |
| [IOwnable.sol](#contracts-comps-common-access-iownable-sol) | contracts/comps/common/access/IOwnable.sol |
| [Ownable.sol](#contracts-comps-common-access-ownable-sol) | contracts/comps/common/access/Ownable.sol |
| [FilesFolder.sol](#contracts-comps-common-components-filesfolder-sol) | contracts/comps/common/components/FilesFolder.sol |
| [IFilesFolder.sol](#contracts-comps-common-components-ifilesfolder-sol) | contracts/comps/common/components/IFilesFolder.sol |
| [IMeetingMinutes.sol](#contracts-comps-common-components-imeetingminutes-sol) | contracts/comps/common/components/IMeetingMinutes.sol |
| [ISigPage.sol](#contracts-comps-common-components-isigpage-sol) | contracts/comps/common/components/ISigPage.sol |
| [MeetingMinutes.sol](#contracts-comps-common-components-meetingminutes-sol) | contracts/comps/common/components/MeetingMinutes.sol |
| [SigPage.sol](#contracts-comps-common-components-sigpage-sol) | contracts/comps/common/components/SigPage.sol |
| [GeneralKeeper.sol](#contracts-comps-generalkeeper-sol) | contracts/comps/GeneralKeeper.sol |
| [IGeneralKeeper.sol](#contracts-comps-igeneralkeeper-sol) | contracts/comps/IGeneralKeeper.sol |
| [Accountant.sol](#contracts-comps-keepers-accountant-sol) | contracts/comps/keepers/Accountant.sol |
| [BMMKeeper.sol](#contracts-comps-keepers-bmmkeeper-sol) | contracts/comps/keepers/BMMKeeper.sol |
| [FundAccountant.sol](#contracts-comps-keepers-fundaccountant-sol) | contracts/comps/keepers/FundAccountant.sol |
| [FundGMMKeeper.sol](#contracts-comps-keepers-fundgmmkeeper-sol) | contracts/comps/keepers/FundGMMKeeper.sol |
| [FundLOOKeeper.sol](#contracts-comps-keepers-fundlookeeper-sol) | contracts/comps/keepers/FundLOOKeeper.sol |
| [FundROCKeeper.sol](#contracts-comps-keepers-fundrockeeper-sol) | contracts/comps/keepers/FundROCKeeper.sol |
| [FundROIKeeper.sol](#contracts-comps-keepers-fundroikeeper-sol) | contracts/comps/keepers/FundROIKeeper.sol |
| [FundRORKeeper.sol](#contracts-comps-keepers-fundrorkeeper-sol) | contracts/comps/keepers/FundRORKeeper.sol |
| [GMMKeeper.sol](#contracts-comps-keepers-gmmkeeper-sol) | contracts/comps/keepers/GMMKeeper.sol |
| [IAccountant.sol](#contracts-comps-keepers-iaccountant-sol) | contracts/comps/keepers/IAccountant.sol |
| [IBMMKeeper.sol](#contracts-comps-keepers-ibmmkeeper-sol) | contracts/comps/keepers/IBMMKeeper.sol |
| [IGMMKeeper.sol](#contracts-comps-keepers-igmmkeeper-sol) | contracts/comps/keepers/IGMMKeeper.sol |
| [IKeepersRouter.sol](#contracts-comps-keepers-ikeepersrouter-sol) | contracts/comps/keepers/IKeepersRouter.sol |
| [ILOOKeeper.sol](#contracts-comps-keepers-ilookeeper-sol) | contracts/comps/keepers/ILOOKeeper.sol |
| [IROAKeeper.sol](#contracts-comps-keepers-iroakeeper-sol) | contracts/comps/keepers/IROAKeeper.sol |
| [IROCKeeper.sol](#contracts-comps-keepers-irockeeper-sol) | contracts/comps/keepers/IROCKeeper.sol |
| [IRODKeeper.sol](#contracts-comps-keepers-irodkeeper-sol) | contracts/comps/keepers/IRODKeeper.sol |
| [IROIKeeper.sol](#contracts-comps-keepers-iroikeeper-sol) | contracts/comps/keepers/IROIKeeper.sol |
| [IROMKeeper.sol](#contracts-comps-keepers-iromkeeper-sol) | contracts/comps/keepers/IROMKeeper.sol |
| [IROOKeeper.sol](#contracts-comps-keepers-irookeeper-sol) | contracts/comps/keepers/IROOKeeper.sol |
| [IROPKeeper.sol](#contracts-comps-keepers-iropkeeper-sol) | contracts/comps/keepers/IROPKeeper.sol |
| [IRORKeeper.sol](#contracts-comps-keepers-irorkeeper-sol) | contracts/comps/keepers/IRORKeeper.sol |
| [ISHAKeeper.sol](#contracts-comps-keepers-ishakeeper-sol) | contracts/comps/keepers/ISHAKeeper.sol |
| [KeepersRouter.sol](#contracts-comps-keepers-keepersrouter-sol) | contracts/comps/keepers/KeepersRouter.sol |
| [LOOKeeper.sol](#contracts-comps-keepers-lookeeper-sol) | contracts/comps/keepers/LOOKeeper.sol |
| [ROAKeeper.sol](#contracts-comps-keepers-roakeeper-sol) | contracts/comps/keepers/ROAKeeper.sol |
| [ROCKeeper.sol](#contracts-comps-keepers-rockeeper-sol) | contracts/comps/keepers/ROCKeeper.sol |
| [RODKeeper.sol](#contracts-comps-keepers-rodkeeper-sol) | contracts/comps/keepers/RODKeeper.sol |
| [ROIKeeper.sol](#contracts-comps-keepers-roikeeper-sol) | contracts/comps/keepers/ROIKeeper.sol |
| [ROMKeeper.sol](#contracts-comps-keepers-romkeeper-sol) | contracts/comps/keepers/ROMKeeper.sol |
| [ROOKeeper.sol](#contracts-comps-keepers-rookeeper-sol) | contracts/comps/keepers/ROOKeeper.sol |
| [ROPKeeper.sol](#contracts-comps-keepers-ropkeeper-sol) | contracts/comps/keepers/ROPKeeper.sol |
| [SHAKeeper.sol](#contracts-comps-keepers-shakeeper-sol) | contracts/comps/keepers/SHAKeeper.sol |
| [BallotsBox.sol](#contracts-lib-books-ballotsbox-sol) | contracts/lib/books/BallotsBox.sol |
| [Checkpoints.sol](#contracts-lib-books-checkpoints-sol) | contracts/lib/books/Checkpoints.sol |
| [CondsRepo.sol](#contracts-lib-books-condsrepo-sol) | contracts/lib/books/CondsRepo.sol |
| [DealsRepo.sol](#contracts-lib-books-dealsrepo-sol) | contracts/lib/books/DealsRepo.sol |
| [DelegateMap.sol](#contracts-lib-books-delegatemap-sol) | contracts/lib/books/DelegateMap.sol |
| [DocsRepo.sol](#contracts-lib-books-docsrepo-sol) | contracts/lib/books/DocsRepo.sol |
| [DTClaims.sol](#contracts-lib-books-dtclaims-sol) | contracts/lib/books/DTClaims.sol |
| [FilesRepo.sol](#contracts-lib-books-filesrepo-sol) | contracts/lib/books/FilesRepo.sol |
| [FRClaims.sol](#contracts-lib-books-frclaims-sol) | contracts/lib/books/FRClaims.sol |
| [GoldChain.sol](#contracts-lib-books-goldchain-sol) | contracts/lib/books/GoldChain.sol |
| [InvestorsRepo.sol](#contracts-lib-books-investorsrepo-sol) | contracts/lib/books/InvestorsRepo.sol |
| [LinksRepo.sol](#contracts-lib-books-linksrepo-sol) | contracts/lib/books/LinksRepo.sol |
| [LockersRepo.sol](#contracts-lib-books-lockersrepo-sol) | contracts/lib/books/LockersRepo.sol |
| [MembersRepo.sol](#contracts-lib-books-membersrepo-sol) | contracts/lib/books/MembersRepo.sol |
| [MockFeedRegistry.sol](#contracts-lib-books-mockfeedregistry-sol) | contracts/lib/books/MockFeedRegistry.sol |
| [MotionsRepo.sol](#contracts-lib-books-motionsrepo-sol) | contracts/lib/books/MotionsRepo.sol |
| [OfficersRepo.sol](#contracts-lib-books-officersrepo-sol) | contracts/lib/books/OfficersRepo.sol |
| [OptionsRepo.sol](#contracts-lib-books-optionsrepo-sol) | contracts/lib/books/OptionsRepo.sol |
| [OrdersRepo.sol](#contracts-lib-books-ordersrepo-sol) | contracts/lib/books/OrdersRepo.sol |
| [PledgesRepo.sol](#contracts-lib-books-pledgesrepo-sol) | contracts/lib/books/PledgesRepo.sol |
| [RedemptionsRepo.sol](#contracts-lib-books-redemptionsrepo-sol) | contracts/lib/books/RedemptionsRepo.sol |
| [RulesParser.sol](#contracts-lib-books-rulesparser-sol) | contracts/lib/books/RulesParser.sol |
| [SharesRepo.sol](#contracts-lib-books-sharesrepo-sol) | contracts/lib/books/SharesRepo.sol |
| [SigsRepo.sol](#contracts-lib-books-sigsrepo-sol) | contracts/lib/books/SigsRepo.sol |
| [SwapsRepo.sol](#contracts-lib-books-swapsrepo-sol) | contracts/lib/books/SwapsRepo.sol |
| [TeamsRepo.sol](#contracts-lib-books-teamsrepo-sol) | contracts/lib/books/TeamsRepo.sol |
| [TopChain.sol](#contracts-lib-books-topchain-sol) | contracts/lib/books/TopChain.sol |
| [UsdLockersRepo.sol](#contracts-lib-books-usdlockersrepo-sol) | contracts/lib/books/UsdLockersRepo.sol |
| [UsdOrdersRepo.sol](#contracts-lib-books-usdordersrepo-sol) | contracts/lib/books/UsdOrdersRepo.sol |
| [UsersRepo.sol](#contracts-lib-books-usersrepo-sol) | contracts/lib/books/UsersRepo.sol |
| [WaterfallsRepo.sol](#contracts-lib-books-waterfallsrepo-sol) | contracts/lib/books/WaterfallsRepo.sol |
| [InterfacesHub.sol](#contracts-lib-interfaceshub-sol) | contracts/lib/InterfacesHub.sol |
| [ArrayUtils.sol](#contracts-lib-utils-arrayutils-sol) | contracts/lib/utils/ArrayUtils.sol |
| [RolesRepo.sol](#contracts-lib-utils-rolesrepo-sol) | contracts/lib/utils/RolesRepo.sol |
| [RoyaltyCharge.sol](#contracts-lib-utils-royaltycharge-sol) | contracts/lib/utils/RoyaltyCharge.sol |
| [draft-IERC1822.sol](#contracts-openzeppelin-interfaces-draft-ierc1822-sol) | contracts/openzeppelin/interfaces/draft-IERC1822.sol |
| [draft-IERC6093.sol](#contracts-openzeppelin-interfaces-draft-ierc6093-sol) | contracts/openzeppelin/interfaces/draft-IERC6093.sol |
| [IERC1967.sol](#contracts-openzeppelin-interfaces-ierc1967-sol) | contracts/openzeppelin/interfaces/IERC1967.sol |
| [IBeacon.sol](#contracts-openzeppelin-proxy-beacon-ibeacon-sol) | contracts/openzeppelin/proxy/beacon/IBeacon.sol |
| [ERC1967Proxy.sol](#contracts-openzeppelin-proxy-erc1967-erc1967proxy-sol) | contracts/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol |
| [ERC1967Upgrade.sol](#contracts-openzeppelin-proxy-erc1967-erc1967upgrade-sol) | contracts/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol |
| [Proxy.sol](#contracts-openzeppelin-proxy-proxy-sol) | contracts/openzeppelin/proxy/Proxy.sol |
| [Initializable.sol](#contracts-openzeppelin-proxy-utils-initializable-sol) | contracts/openzeppelin/proxy/utils/Initializable.sol |
| [UUPSUpgradeable.sol](#contracts-openzeppelin-proxy-utils-uupsupgradeable-sol) | contracts/openzeppelin/proxy/utils/UUPSUpgradeable.sol |
| [ERC20.sol](#contracts-openzeppelin-token-erc20-erc20-sol) | contracts/openzeppelin/token/ERC20/ERC20.sol |
| [ERC20Upgradeable.sol](#contracts-openzeppelin-token-erc20-erc20upgradeable-sol) | contracts/openzeppelin/token/ERC20/ERC20Upgradeable.sol |
| [IERC20Metadata.sol](#contracts-openzeppelin-token-erc20-extensions-ierc20metadata-sol) | contracts/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol |
| [IERC20.sol](#contracts-openzeppelin-token-erc20-ierc20-sol) | contracts/openzeppelin/token/ERC20/IERC20.sol |
| [Address.sol](#contracts-openzeppelin-utils-address-sol) | contracts/openzeppelin/utils/Address.sol |
| [Context.sol](#contracts-openzeppelin-utils-context-sol) | contracts/openzeppelin/utils/Context.sol |
| [ContextUpgradeable.sol](#contracts-openzeppelin-utils-contextupgradeable-sol) | contracts/openzeppelin/utils/ContextUpgradeable.sol |
| [StorageSlot.sol](#contracts-openzeppelin-utils-storageslot-sol) | contracts/openzeppelin/utils/StorageSlot.sol |
| [EnumerableSet.sol](#contracts-openzeppelin-utils-structs-enumerableset-sol) | contracts/openzeppelin/utils/structs/EnumerableSet.sol |

---

## BookOfDocs.sol

---

| |
|:---|
| **contracts/center/books/BookOfDocs.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IBookOfDocs.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./BookOfUsers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;

<font style="color:#569cd6;">contract</font> BookOfDocs <font style="color:#569cd6;">is</font> IBookOfDocs, BookOfUsers {
    <font style="color:#569cd6;">using</font> DocsRepo <font style="color:#569cd6;">for</font> DocsRepo.Repo;
    <font style="color:#569cd6;">using</font> DocsRepo <font style="color:#569cd6;">for</font> DocsRepo.Head;
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    DocsRepo.Repo <font style="color:#569cd6;">private</font> _docs;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#569cd6;">function</font> upgradeCenterTo(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">external</font> onlyProxy {
        upgradeTo(newImplementation);
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _docs.upgradeDoc(newImplementation, <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>));
        <font style="color:#569cd6;">emit</font> UpgradeDoc(doc.head.codifyHead(), doc.body);
    }

    <font style="color:#569cd6;">function</font> getImplementation() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _getImplementation();
    }

    <font style="color:#6a9955;">// ########################</font>
    <font style="color:#6a9955;">// ##    Error & Event   ##</font>
    <font style="color:#6a9955;">// ########################</font>

    <font style="color:#569cd6;">error</font> BOD_NotProxyable();

    <font style="color:#569cd6;">error</font> BOD_MsgSenderNotRegistered();

    <font style="color:#569cd6;">modifier</font> proxyable(<font style="color:#4ec9b0;">uint</font> typeOfDoc) {
        <font style="color:#569cd6;">if</font> (
            (typeOfDoc == DocsRepo.getTypeByName(<font style="color:#ce9178;">"RegCenter"</font>) ||
            typeOfDoc == DocsRepo.getTypeByName(<font style="color:#ce9178;">"CreateNewComp"</font>) ||
            typeOfDoc == DocsRepo.getTypeByName(<font style="color:#ce9178;">"UsdFuelTank"</font>) ||
            typeOfDoc == DocsRepo.getTypeByName(<font style="color:#ce9178;">"CashLockers"</font>) ||
            typeOfDoc == DocsRepo.getTypeByName(<font style="color:#ce9178;">"MockUSDC"</font>)) &&
            msg.sender != getBookeeper()
        ) <font style="color:#569cd6;">revert</font> BOD_NotProxyable();
        _;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##    Docs   ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#569cd6;">function</font> setTemplate(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">uint</font> author
     ) <font style="color:#569cd6;">external</font> onlyKeeper {
        DocsRepo.Head <font style="color:#569cd6;">memory</font> head =
            _docs.setTemplate(
                typeOfDoc,
                body,
                author,
                _getUserNo(msg.sender)
            );

        <font style="color:#569cd6;">emit</font> SetTemplate(head.typeOfDoc, head.version, body);
    }

    <font style="color:#569cd6;">function</font> regProxy(
        <font style="color:#4ec9b0;">address</font> temp,
        <font style="color:#4ec9b0;">address</font> proxy
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _docs.regProxy(
                temp,
                proxy,
                _getUserNo(msg.sender)
        );

        <font style="color:#569cd6;">emit</font> RegProxy(doc.head.codifyHead(), proxy);
    }

    <font style="color:#569cd6;">function</font> transferIPR(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version,
        <font style="color:#4ec9b0;">uint</font> transferee
    ) <font style="color:#569cd6;">external</font> {
        _docs.transferIPR(
            typeOfDoc,
            version,
            transferee,
            _getUserNo(msg.sender)
        );
        <font style="color:#569cd6;">emit</font> TransferIPR(typeOfDoc, version, transferee);
    }

    <font style="color:#569cd6;">function</font> _getCreator(<font style="color:#4ec9b0;">address</font> msgSender) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> creator) {
        <font style="color:#569cd6;">if</font> (msgSender.isContract()) {
            <font style="color:#569cd6;">if</font> (!_docs.docExist(msgSender))
                <font style="color:#569cd6;">revert</font> BOD_MsgSenderNotRegistered();
            creator = _docs.getHeadByBody(msgSender).creator;
        } <font style="color:#569cd6;">else</font> {
            creator = _getUserNo(msgSender);
        }
    }

    <font style="color:#569cd6;">function</font> cloneDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">external</font> proxyable(typeOfDoc) <font style="color:#569cd6;">returns</font>(
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc
    ) {
        doc = _docs.cloneDoc(
            typeOfDoc,
            version,
            _getCreator(msg.sender)
        );
        IOwnable(doc.body).initialize(msg.sender, <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>));
        <font style="color:#569cd6;">emit</font> CloneDoc(doc.head.codifyHead(), doc.body);
    }

    <font style="color:#569cd6;">function</font> proxyDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">external</font> proxyable(typeOfDoc) <font style="color:#569cd6;">returns</font>(
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc
    ) {
        doc = _docs.proxyDoc(
            typeOfDoc,
            version,
            _getCreator(msg.sender)
        );
        <font style="color:#569cd6;">emit</font> ProxyDoc(doc.head.codifyHead(), doc.body);
    }

    <font style="color:#569cd6;">function</font> upgradeDoc(<font style="color:#4ec9b0;">address</font> temp) <font style="color:#569cd6;">external</font> {
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _docs.upgradeDoc(temp, msg.sender);
        <font style="color:#569cd6;">emit</font> UpgradeDoc(doc.head.codifyHead(), doc.body);
    }

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##  Read I/O    ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">// ---- Type of Doc ----</font>

    <font style="color:#569cd6;">function</font> counterOfTypes() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _docs.counterOfTypes();
    }

    <font style="color:#569cd6;">function</font> typeExist(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _docs.typeExist(<font style="color:#4ec9b0;">uint32</font>(typeOfDoc));
    }

    <font style="color:#569cd6;">function</font> getTypesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _docs.getTypesList();
    }

    <font style="color:#6a9955;">// ---- Counters ----</font>

    <font style="color:#569cd6;">function</font> counterOfVersions(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _docs.counterOfVersions(<font style="color:#4ec9b0;">uint32</font>(typeOfDoc));
    }

    <font style="color:#569cd6;">function</font> counterOfDocs(<font style="color:#4ec9b0;">uint256</font> typeOfDoc, <font style="color:#4ec9b0;">uint256</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">return</font> _docs.counterOfDocs(<font style="color:#4ec9b0;">uint32</font>(typeOfDoc), <font style="color:#4ec9b0;">uint32</font>(version));
    }

    <font style="color:#6a9955;">// ---- Authors ----</font>

    <font style="color:#569cd6;">function</font> getAuthor(<font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _docs.getAuthor(typeOfDoc, version);
    }

    <font style="color:#569cd6;">function</font> getAuthorByBody(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _docs.getAuthorByBody(body);
    }

    <font style="color:#6a9955;">// ---- Temps ----</font>

    <font style="color:#569cd6;">function</font> tempExist(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _docs.tempExist(body);
    }

    <font style="color:#569cd6;">function</font> getTemp(<font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc) {
        doc = _docs.getTemp(typeOfDoc, version);
    }

    <font style="color:#569cd6;">function</font> getVersionsList(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _docs.getVersionsList(<font style="color:#4ec9b0;">uint32</font>(typeOfDoc));
    }

    <font style="color:#6a9955;">// ---- Docs ----</font>

    <font style="color:#569cd6;">function</font> docExist(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _docs.docExist(body);
    }

    <font style="color:#569cd6;">function</font> getHeadByBody(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DocsRepo.Head <font style="color:#569cd6;">memory</font> ) {
        <font style="color:#569cd6;">return</font> _docs.getHeadByBody(body);
    }

    <font style="color:#569cd6;">function</font> getDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> seqOfDoc
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc) {
        doc = _docs.getDoc(typeOfDoc, version, seqOfDoc);
    }

    <font style="color:#569cd6;">function</font> getDocByUserNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc) {
        <font style="color:#569cd6;">if</font> (isUserNo(acct)) {
            doc.body = _getUserByNo(acct).primeKey.pubKey;
            <font style="color:#569cd6;">if</font> (_docs.docExist(doc.body)) doc.head = _docs.heads[doc.body];
            <font style="color:#569cd6;">else</font> doc.body = <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>);
        }
    }

    <font style="color:#569cd6;">function</font> getDocsList(<font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _docs.getDocsList(typeOfDoc, version);
    }

    <font style="color:#569cd6;">function</font> verifyDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> seqOfDoc
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag) {
        flag = _docs.verifyDoc(typeOfDoc, version, seqOfDoc);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## BookOfPoints.sol

---

| |
|:---|
| **contracts/center/books/BookOfPoints.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IBookOfPoints.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/token/ERC20/ERC20Upgradeable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./BookOfDocs.sol"</font>;

<font style="color:#569cd6;">contract</font> BookOfPoints <font style="color:#569cd6;">is</font> IBookOfPoints, ERC20Upgradeable, BookOfDocs {

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#569cd6;">function</font> initialize(
        <font style="color:#4ec9b0;">address</font> keeper
    ) <font style="color:#569cd6;">external</font> initializer {
        __ERC20_init(<font style="color:#ce9178;">"ComBooxPoints"</font>, <font style="color:#ce9178;">"CBP"</font>);
        _initUsers(keeper);
    }

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##  Mint & Lock ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#569cd6;">function</font> mint(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font> onlyOwner {
        _mint(to, amt);
    }

    <font style="color:#569cd6;">function</font> burn(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font> onlyOwner {
        _burn(msg.sender, amt);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## BookOfUsers.sol

---

| |
|:---|
| **contracts/center/books/BookOfUsers.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IBookOfUsers.sol"</font>;
<font style="color:#6a9955;">// import "../access/Ownable.sol";</font>
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/utils/Initializable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/utils/UUPSUpgradeable.sol"</font>;

<font style="color:#569cd6;">contract</font> BookOfUsers <font style="color:#569cd6;">is</font> IBookOfUsers, Initializable, UUPSUpgradeable {
    <font style="color:#569cd6;">using</font> UsersRepo <font style="color:#569cd6;">for</font> UsersRepo.Repo;
    <font style="color:#569cd6;">using</font> UsersRepo <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint256</font>;

    UsersRepo.Repo <font style="color:#569cd6;">private</font> _users;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#569cd6;">function</font> _initUsers(<font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">if</font> (keeper == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> BOU_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BOU_ZeroKeeper"</font>));
        _users.users[<font style="color:#b5cea8;">0</font>].primeKey.pubKey = msg.sender;
        _users.users[<font style="color:#b5cea8;">0</font>].backupKey.pubKey = keeper;
        _users.regUser(msg.sender);
        _users.regUser(keeper);
    }

    <font style="color:#569cd6;">function</font> _authorizeUpgrade(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">override</font> onlyKeeper {}

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##    Modifiers    ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">modifier</font> onlyOwner() {
        <font style="color:#569cd6;">if</font> (msg.sender != _users.getOwner())
            <font style="color:#569cd6;">revert</font> BOU_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BOU_NotOwner"</font>));
        _;
    }

    <font style="color:#569cd6;">modifier</font> onlyKeeper() {
        <font style="color:#569cd6;">if</font> (msg.sender != _users.getBookeeper())
            <font style="color:#569cd6;">revert</font> BOU_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BOU_NotKeeper"</font>));
        _;
    }

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##    Write I/O    ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#569cd6;">function</font> transferOwnership(<font style="color:#4ec9b0;">address</font> newOwner) <font style="color:#569cd6;">external</font> {
        _users.transferOwnership(newOwner);
        <font style="color:#569cd6;">emit</font> TransferOwnership(newOwner);
    }

    <font style="color:#569cd6;">function</font> handoverCenterKey(<font style="color:#4ec9b0;">address</font> newKeeper) <font style="color:#569cd6;">external</font> {
        _users.handoverCenterKey(newKeeper);
        <font style="color:#569cd6;">emit</font> TurnOverCenterKey(newKeeper);
    }

    <font style="color:#6a9955;">// ==== Users ====</font>

    <font style="color:#569cd6;">function</font> _regUser() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>){
        UsersRepo.User <font style="color:#569cd6;">memory</font> user = _users.regUser(msg.sender);
        <font style="color:#569cd6;">return</font> user.primeKey.gift;
    }

    <font style="color:#569cd6;">function</font> setBackupKey(<font style="color:#4ec9b0;">address</font> bKey) <font style="color:#569cd6;">external</font> {
        _users.setBackupKey(bKey, msg.sender);
    }

    <font style="color:#569cd6;">function</font> upgradeBackupToPrime() <font style="color:#569cd6;">external</font> {
        _users.upgradeBackupToPrime(msg.sender);
    }

    <font style="color:#6a9955;">// ==== Royalty & Coupon ====</font>

    <font style="color:#569cd6;">function</font> setPlatformRule(<font style="color:#4ec9b0;">bytes32</font> snOfRule) <font style="color:#569cd6;">external</font> {
        _users.setPlatformRule(snOfRule);
        <font style="color:#569cd6;">emit</font> SetPlatformRule(snOfRule);
    }

    <font style="color:#569cd6;">function</font> setRoyaltyRule(<font style="color:#4ec9b0;">bytes32</font> snOfRoyalty) <font style="color:#569cd6;">external</font> {
        _users.setRoyaltyRule(snOfRoyalty, msg.sender);
    }

    <font style="color:#569cd6;">function</font> _addCouponOnce(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">internal</font> {
        _users.addCouponOnce(targetAddr);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#569cd6;">function</font> getOwner() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _users.getOwner();
    }

    <font style="color:#569cd6;">function</font> getBookeeper() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _users.getBookeeper();
    }

    <font style="color:#569cd6;">function</font> getPlatformRule() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(UsersRepo.Rule <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _users.getPlatformRule();
    }

    <font style="color:#6a9955;">// ==== Users ====</font>

    <font style="color:#569cd6;">function</font> isUserNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _users.isUserNo(acct);
    }

    <font style="color:#569cd6;">function</font> _getUserNo(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _users.getUserNo(targetAddr);
    }

    <font style="color:#569cd6;">function</font> counterOfUsers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _users.counterOfUsers();
    }

    <font style="color:#569cd6;">function</font> getUserNoList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _users.getUserNoList();
    }

    <font style="color:#569cd6;">function</font> _getUser(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _users.getUser(targetAddr);
    }

    <font style="color:#569cd6;">function</font> _getUserByNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font> usr)
    {
        <font style="color:#569cd6;">if</font> (_users.isUserNo(acct)) {
            usr = _users.users[acct];
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> BOU_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BOU_AcctNotRegistered"</font>));
    }

    <font style="color:#569cd6;">function</font> getRoyaltyRule(<font style="color:#4ec9b0;">uint</font> author) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.Key <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _users.getRoyaltyRule(author);
    }

    <font style="color:#569cd6;">function</font> usedKey(<font style="color:#4ec9b0;">address</font> key) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _users.usedKey(key);
    }

    <font style="color:#569cd6;">function</font> isPrimeKey(<font style="color:#4ec9b0;">address</font> key) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _users.isPrimeKey(key);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IBookOfDocs.sol

---

| |
|:---|
| **contracts/center/books/IBookOfDocs.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IBookOfDocs</font>
<font style="color:#6a9955;">/// @notice Document registry interface for templates, proxies, and clones.</font>
<font style="color:#6a9955;">/// @dev Exposes write operations for registration/upgrade and read operations for queries.</font>

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/DocsRepo.sol"</font>;

<font style="color:#569cd6;">interface</font> IBookOfDocs {

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Event     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">// ==== Docs ====</font>

    <font style="color:#6a9955;">/// @notice Emitted when a template is registered.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param body Template address.</font>
    <font style="color:#569cd6;">event</font> SetTemplate(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> typeOfDoc, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> version, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> body);

    <font style="color:#6a9955;">/// @notice Emitted when a proxy is registered.</font>
    <font style="color:#6a9955;">/// @param snOfDoc Encoded document header.</font>
    <font style="color:#6a9955;">/// @param body Proxy address.</font>
    <font style="color:#569cd6;">event</font> RegProxy(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfDoc, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> body);

    <font style="color:#6a9955;">/// @notice Emitted when IPR is transferred.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param transferee New author userNo.</font>
    <font style="color:#569cd6;">event</font> TransferIPR(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> version, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> transferee);

    <font style="color:#6a9955;">/// @notice Emitted when a clone is created.</font>
    <font style="color:#6a9955;">/// @param snOfDoc Encoded document header.</font>
    <font style="color:#6a9955;">/// @param body Clone address.</font>
    <font style="color:#569cd6;">event</font> CloneDoc(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfDoc, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> body);

    <font style="color:#6a9955;">/// @notice Emitted when a proxy is created.</font>
    <font style="color:#6a9955;">/// @param snOfDoc Encoded document header.</font>
    <font style="color:#6a9955;">/// @param body Proxy address.</font>
    <font style="color:#569cd6;">event</font> ProxyDoc(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfDoc, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> body);

    <font style="color:#6a9955;">/// @notice Emitted when a proxy is upgraded and registered.</font>
    <font style="color:#6a9955;">/// @param snOfDoc Encoded document header.</font>
    <font style="color:#6a9955;">/// @param body Proxy address.</font>
    <font style="color:#569cd6;">event</font> UpgradeDoc(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfDoc, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> body);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Write     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @notice Register a template contract for a document type.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type (must be > 0 in implementation).</font>
    <font style="color:#6a9955;">/// @param body Template contract address (non-zero).</font>
    <font style="color:#6a9955;">/// @param author Author userNo (must be > 0).</font>
    <font style="color:#569cd6;">function</font> setTemplate(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">uint</font> author
     ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Register an externally created proxy.</font>
    <font style="color:#6a9955;">/// @param temp Template implementation address.</font>
    <font style="color:#6a9955;">/// @param proxy Proxy address.</font>
    <font style="color:#569cd6;">function</font> regProxy(
        <font style="color:#4ec9b0;">address</font> temp,
        <font style="color:#4ec9b0;">address</font> proxy
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Transfer IPR to a new author.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param transferee New author userNo.</font>
    <font style="color:#569cd6;">function</font> transferIPR(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version,
        <font style="color:#4ec9b0;">uint</font> transferee
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create and register an EIP-1167 clone from a template.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return doc Registered document instance.</font>
    <font style="color:#569cd6;">function</font> cloneDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc
    );

    <font style="color:#6a9955;">/// @notice Create and register an ERC1967 proxy initialized via `initialize`.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return doc Registered document instance.</font>
    <font style="color:#569cd6;">function</font> proxyDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc
    );

    <font style="color:#6a9955;">/// @notice Register a proxy upgrade to a new template.</font>
    <font style="color:#6a9955;">/// @param temp New template implementation address.</font>
    <font style="color:#569cd6;">function</font> upgradeDoc(<font style="color:#4ec9b0;">address</font> temp) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##  Read I/O    ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">// ---- Type of Doc ----</font>

    <font style="color:#6a9955;">/// @notice Get number of document types.</font>
    <font style="color:#569cd6;">function</font> counterOfTypes() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Check if a document type exists.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#569cd6;">function</font> typeExist(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get all document types.</font>
    <font style="color:#569cd6;">function</font> getTypesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- Counters ----</font>

    <font style="color:#6a9955;">/// @notice Get latest version for a document type.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#569cd6;">function</font> counterOfVersions(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get count of docs for a type/version.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#569cd6;">function</font> counterOfDocs(<font style="color:#4ec9b0;">uint256</font> typeOfDoc, <font style="color:#4ec9b0;">uint256</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">// ---- Authors ----</font>

    <font style="color:#6a9955;">/// @notice Get author userNo for a template.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#569cd6;">function</font> getAuthor(<font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get author userNo by body address.</font>
    <font style="color:#6a9955;">/// @param body Document body address.</font>
    <font style="color:#569cd6;">function</font> getAuthorByBody(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">// ---- Temps ----</font>

    <font style="color:#6a9955;">/// @notice Check if a template exists for a body address.</font>
    <font style="color:#6a9955;">/// @param body Template address.</font>
    <font style="color:#569cd6;">function</font> tempExist(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get template document for a type/version.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return doc Template document.</font>
    <font style="color:#569cd6;">function</font> getTemp(<font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc);

    <font style="color:#6a9955;">/// @notice Get all templates for a document type.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#569cd6;">function</font> getVersionsList(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- Docs ----</font>

    <font style="color:#6a9955;">/// @notice Check if a document instance exists for a body address.</font>
    <font style="color:#6a9955;">/// @param body Document body address.</font>
    <font style="color:#569cd6;">function</font> docExist(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get header by body address.</font>
    <font style="color:#6a9955;">/// @param body Document body address.</font>
    <font style="color:#569cd6;">function</font> getHeadByBody(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DocsRepo.Head <font style="color:#569cd6;">memory</font> );

    <font style="color:#6a9955;">/// @notice Get a specific document instance by type/version/seq.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param seqOfDoc Document sequence number.</font>
    <font style="color:#6a9955;">/// @return doc Document instance.</font>
    <font style="color:#569cd6;">function</font> getDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> seqOfDoc
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc);

    <font style="color:#6a9955;">/// @notice Get a document instance by userNo.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return doc Document instance (zeroed if not found).</font>
    <font style="color:#569cd6;">function</font> getDocByUserNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc);

    <font style="color:#6a9955;">/// @notice Get all documents for a type/version.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#569cd6;">function</font> getDocsList(<font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DocsRepo.Doc[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Verify that a document instance is a valid clone or proxy of its template.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param seqOfDoc Document sequence number.</font>
    <font style="color:#6a9955;">/// @return flag True if valid.</font>
    <font style="color:#569cd6;">function</font> verifyDoc(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> seqOfDoc
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IBookOfPoints.sol

---

| |
|:---|
| **contracts/center/books/IBookOfPoints.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IBookOfPoints</font>
<font style="color:#6a9955;">/// @notice ERC20-like points mint/burn interface used by the registry.</font>
<font style="color:#6a9955;">/// @dev Exposes privileged mint and burn operations for platform points.</font>

<font style="color:#569cd6;">interface</font> IBookOfPoints {

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Write     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @notice Mint points to an address.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param amt Amount to mint (uint256 in implementation).</font>
    <font style="color:#569cd6;">function</font> mint(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Burn points from the caller.</font>
    <font style="color:#6a9955;">/// @param amt Amount to burn (uint256 in implementation).</font>
    <font style="color:#569cd6;">function</font> burn(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IBookOfUsers.sol

---

| |
|:---|
| **contracts/center/books/IBookOfUsers.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IBookOfUsers</font>
<font style="color:#6a9955;">/// @notice User registry interface for platform ownership, keeper control, and user key management.</font>
<font style="color:#6a9955;">/// @dev Exposes read/write operations for user registration, platform rules, and royalty settings.</font>

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/UsersRepo.sol"</font>;

<font style="color:#569cd6;">interface</font> IBookOfUsers {

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Error     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#569cd6;">error</font> BOU_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> BOU_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#6a9955;">/// @notice Emitted when platform rule is updated.</font>
    <font style="color:#6a9955;">/// @param snOfRule Packed rule bytes.</font>
    <font style="color:#569cd6;">event</font> SetPlatformRule(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfRule);

    <font style="color:#6a9955;">/// @notice Emitted when platform ownership changes.</font>
    <font style="color:#6a9955;">/// @param newOwner New owner address.</font>
    <font style="color:#569cd6;">event</font> TransferOwnership(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> newOwner);

    <font style="color:#6a9955;">/// @notice Emitted when platform keeper changes.</font>
    <font style="color:#6a9955;">/// @param newKeeper New keeper address.</font>
    <font style="color:#569cd6;">event</font> TurnOverCenterKey(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> newKeeper);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Write     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">// ==== Opts Setting ====</font>

    <font style="color:#6a9955;">/// @notice Transfer platform ownership.</font>
    <font style="color:#6a9955;">/// @param newOwner New owner address (non-zero in implementation).</font>
    <font style="color:#569cd6;">function</font> transferOwnership(<font style="color:#4ec9b0;">address</font> newOwner) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Handover keeper role for platform control.</font>
    <font style="color:#6a9955;">/// @param newKeeper New keeper address (non-zero in implementation).</font>
    <font style="color:#569cd6;">function</font> handoverCenterKey(<font style="color:#4ec9b0;">address</font> newKeeper) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== User ====</font>

    <font style="color:#6a9955;">/// @notice Set backup key for the caller.</font>
    <font style="color:#6a9955;">/// @param bKey Backup key address (non-zero, unused).</font>
    <font style="color:#569cd6;">function</font> setBackupKey(<font style="color:#4ec9b0;">address</font> bKey) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Promote backup key to prime key for the caller.</font>
    <font style="color:#569cd6;">function</font> upgradeBackupToPrime() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Royalty & Coupon ====</font>

    <font style="color:#6a9955;">/// @notice Set platform rule values.</font>
    <font style="color:#6a9955;">/// @param snOfRule Packed rule bytes.</font>
    <font style="color:#569cd6;">function</font> setPlatformRule(<font style="color:#4ec9b0;">bytes32</font> snOfRule) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Set royalty rule for the caller.</font>
    <font style="color:#6a9955;">/// @param snOfRoyalty Packed royalty rule bytes.</font>
    <font style="color:#569cd6;">function</font> setRoyaltyRule(<font style="color:#4ec9b0;">bytes32</font> snOfRoyalty) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##   Read      ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#6a9955;">/// @notice Get platform owner address.</font>
    <font style="color:#6a9955;">/// @return Owner address.</font>
    <font style="color:#569cd6;">function</font> getOwner() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">/// @notice Get platform keeper address.</font>
    <font style="color:#6a9955;">/// @return Keeper address.</font>
    <font style="color:#569cd6;">function</font> getBookeeper() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">/// @notice Get current platform rule values.</font>
    <font style="color:#6a9955;">/// @return Current rule.</font>
    <font style="color:#569cd6;">function</font> getPlatformRule() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(UsersRepo.Rule <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Users ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a userNo exists.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isUserNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get total number of registered users.</font>
    <font style="color:#6a9955;">/// @return Count of users.</font>
    <font style="color:#569cd6;">function</font> counterOfUsers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get list of all user numbers.</font>
    <font style="color:#6a9955;">/// @return Array of user numbers.</font>
    <font style="color:#569cd6;">function</font> getUserNoList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Royalty & Coupon ====</font>

    <font style="color:#6a9955;">/// @notice Get royalty rule for an author.</font>
    <font style="color:#6a9955;">/// @param author Author userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @return Royalty rule.</font>
    <font style="color:#569cd6;">function</font> getRoyaltyRule(<font style="color:#4ec9b0;">uint</font> author)<font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.Key <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Keys ====</font>

    <font style="color:#6a9955;">/// @notice Check if an address is already registered as a key.</font>
    <font style="color:#6a9955;">/// @param key Address to check.</font>
    <font style="color:#6a9955;">/// @return True if used.</font>
    <font style="color:#569cd6;">function</font> usedKey(<font style="color:#4ec9b0;">address</font> key) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check if an address is a user's prime key.</font>
    <font style="color:#6a9955;">/// @param key Address to check.</font>
    <font style="color:#6a9955;">/// @return True if prime key.</font>
    <font style="color:#569cd6;">function</font> isPrimeKey(<font style="color:#4ec9b0;">address</font> key) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegCenter.sol

---

| |
|:---|
| **contracts/center/IRegCenter.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IRegCenter</font>
<font style="color:#6a9955;">/// @notice Registry center interface combining docs, users, points, and ERC20 operations.</font>
<font style="color:#6a9955;">/// @dev Extends IBookOfPoints, IBookOfDocs, IBookOfUsers, and IERC20.</font>

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../lib/books/UsersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../lib/books/DocsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./books/IBookOfDocs.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./books/IBookOfPoints.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./books/IBookOfUsers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../openzeppelin/token/ERC20/IERC20.sol"</font>;

<font style="color:#569cd6;">interface</font> IRegCenter <font style="color:#569cd6;">is</font> IBookOfPoints, IBookOfDocs, IBookOfUsers, IERC20{

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Error     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#569cd6;">error</font> RC_WrongAccess(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> RC_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Register caller as a user and mint initial gift points if configured.</font>
    <font style="color:#569cd6;">function</font> regUser() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Resolve userNo and charge license fee according to royalty rules.</font>
    <font style="color:#6a9955;">/// @param targetAddr User address to resolve.</font>
    <font style="color:#6a9955;">/// @param fee License fee amount (in points' smallest unit).</font>
    <font style="color:#6a9955;">/// @param author Author userNo.</font>
    <font style="color:#6a9955;">/// @return userNo Resolved user number.</font>
    <font style="color:#569cd6;">function</font> getUserNo(<font style="color:#4ec9b0;">address</font> targetAddr, <font style="color:#4ec9b0;">uint</font> fee, <font style="color:#4ec9b0;">uint</font> author) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">// ==== Self Query ====</font>

    <font style="color:#6a9955;">/// @notice Get caller's user number.</font>
    <font style="color:#569cd6;">function</font> getMyUserNo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get caller's user record.</font>
    <font style="color:#569cd6;">function</font> getMyUser() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Admin Checking ====</font>

    <font style="color:#6a9955;">/// @notice Get user number by address (admin access in implementation).</font>
    <font style="color:#6a9955;">/// @param targetAddr User address.</font>
    <font style="color:#569cd6;">function</font> obtainUserNo(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get user record by address (admin access in implementation).</font>
    <font style="color:#6a9955;">/// @param targetAddr User address.</font>
    <font style="color:#569cd6;">function</font> obtainUser(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get user record by user number (admin access in implementation).</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#569cd6;">function</font> obtainUserByNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegCenter.sol

---

| |
|:---|
| **contracts/center/RegCenter.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegCenter.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./books/BookOfPoints.sol"</font>;

<font style="color:#569cd6;">contract</font> RegCenter <font style="color:#569cd6;">is</font> BookOfPoints, IRegCenter{

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">function</font> regUser() <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">uint</font> gift = _regUser();
        <font style="color:#569cd6;">if</font> (gift > <font style="color:#b5cea8;">0</font>) {
            _mint(msg.sender, gift * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">9</font>);
        }
    }

    <font style="color:#569cd6;">function</font> getUserNo(<font style="color:#4ec9b0;">address</font> targetAddr, <font style="color:#4ec9b0;">uint</font> fee, <font style="color:#4ec9b0;">uint</font> author) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {

        <font style="color:#4ec9b0;">uint40</font> target = _getUserNo(targetAddr);

        <font style="color:#569cd6;">if</font>(!docExist(msg.sender))
            <font style="color:#569cd6;">revert</font> RC_WrongAccess(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RC_DocNotRegistered"</font>));

        UsersRepo.Key <font style="color:#569cd6;">memory</font> rr = getRoyaltyRule(author);
        <font style="color:#4ec9b0;">address</font> authorAddr = _getUserByNo(author).primeKey.pubKey;

        _chargeFee(targetAddr, fee, authorAddr, rr);

        <font style="color:#569cd6;">return</font> target;
    }

    <font style="color:#569cd6;">function</font> _chargeFee(
        <font style="color:#4ec9b0;">address</font> targetAddr,
        <font style="color:#4ec9b0;">uint</font> fee,
        <font style="color:#4ec9b0;">address</font> authorAddr,
        UsersRepo.Key <font style="color:#569cd6;">memory</font> rr
    ) <font style="color:#569cd6;">private</font> {

        UsersRepo.User <font style="color:#569cd6;">memory</font> t = _getUser(targetAddr);
        <font style="color:#4ec9b0;">address</font> ownerAddr = getOwner();

        UsersRepo.Rule <font style="color:#569cd6;">memory</font> pr = getPlatformRule();

        <font style="color:#4ec9b0;">uint</font> floorPrice = <font style="color:#4ec9b0;">uint</font>(pr.floor) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">9</font>;

        <font style="color:#569cd6;">if</font> (fee < floorPrice)
            <font style="color:#569cd6;">revert</font> RC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RC_FeeTooLow"</font>));

        <font style="color:#4ec9b0;">uint</font> offAmt = <font style="color:#4ec9b0;">uint</font>(t.primeKey.coupon) * <font style="color:#4ec9b0;">uint</font>(rr.discount) * fee / <font style="color:#b5cea8;">10000</font> + <font style="color:#4ec9b0;">uint</font>(rr.coupon) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">9</font>;

        fee = (offAmt < (fee - floorPrice))
            ? (fee - offAmt)
            : floorPrice;

        <font style="color:#4ec9b0;">uint</font> giftAmt = <font style="color:#4ec9b0;">uint</font>(rr.gift) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">9</font>;

        <font style="color:#569cd6;">if</font> (ownerAddr == authorAddr || pr.rate == <font style="color:#b5cea8;">2000</font>) {
            <font style="color:#569cd6;">if</font> (fee > giftAmt)
                _transfer(t.primeKey.pubKey, authorAddr, fee - giftAmt);
        } <font style="color:#569cd6;">else</font> {
            _transfer(t.primeKey.pubKey, ownerAddr, fee * (<font style="color:#b5cea8;">2000</font> - pr.rate) / <font style="color:#b5cea8;">10000</font>);

            <font style="color:#4ec9b0;">uint</font> balaceAmt = fee * (<font style="color:#b5cea8;">8000</font> + pr.rate) / <font style="color:#b5cea8;">10000</font>;
            <font style="color:#569cd6;">if</font> ( balaceAmt > giftAmt)
                _transfer(t.primeKey.pubKey, authorAddr, balaceAmt - giftAmt);
        }

        _addCouponOnce(targetAddr);
    }

    <font style="color:#6a9955;">// ==== Self Query ====</font>

    <font style="color:#569cd6;">function</font> getMyUserNo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _getUserNo(msg.sender);
    }

    <font style="color:#569cd6;">function</font> getMyUser() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _getUser(msg.sender);
    }

    <font style="color:#6a9955;">// ==== Admin Checking ====</font>

    <font style="color:#569cd6;">function</font> obtainUserNo(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _getUserNo(targetAddr);
    }

    <font style="color:#569cd6;">function</font> obtainUser(<font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> onlyKeeper <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _getUser(targetAddr);
    }

    <font style="color:#569cd6;">function</font> obtainUserByNo(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> onlyKeeper <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _getUserByNo(acct);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## CashLockers.sol

---

| |
|:---|
| **contracts/center/utils/CashLockers.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ICashLockers.sol"</font>;

<font style="color:#6a9955;">/// @title CashLockers</font>
<font style="color:#6a9955;">/// @notice Escrow contract that locks USDC using EIP-3009 authorizations and releases by hash-lock or expiry.</font>
<font style="color:#6a9955;">/// @dev Tracks per-user custody and total custody for locked balances.</font>
<font style="color:#569cd6;">contract</font> CashLockers <font style="color:#569cd6;">is</font> ICashLockers {

    <font style="color:#569cd6;">using</font> UsdLockersRepo <font style="color:#569cd6;">for</font> UsdLockersRepo.Repo;

    <font style="color:#6a9955;">/// @notice USDC token with transferWithAuthorization support.</font>
    IUSDC <font style="color:#569cd6;">immutable</font> <font style="color:#569cd6;">public</font> usdc;

    <font style="color:#6a9955;">/// @notice Deploy with USDC token address.</font>
    <font style="color:#6a9955;">/// @param _usdc USDC contract address.</font>
    <font style="color:#569cd6;">constructor</font>(<font style="color:#4ec9b0;">address</font> _usdc) {
        usdc = IUSDC(_usdc);
    }

    <font style="color:#6a9955;">/// @notice Custody balances per address.</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint256</font>) <font style="color:#569cd6;">private</font> _coffers;
    UsdLockersRepo.Repo <font style="color:#569cd6;">private</font> _lockers;

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">/// @notice Pull USDC using an EIP-3009 authorization.</font>
    <font style="color:#6a9955;">/// @param auth Authorization data structure.</font>
    <font style="color:#569cd6;">function</font> _transferWithAuthorization(TransferAuth <font style="color:#569cd6;">memory</font> auth) <font style="color:#569cd6;">private</font> {
        usdc.transferWithAuthorization(
            auth.<font style="color:#569cd6;">from</font>,
            <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>),
            auth.value,
            auth.validAfter,
            auth.validBefore,
            auth.nonce,
            auth.v,
            auth.r,
            auth.s
        );
    }

    <font style="color:#6a9955;">/// @notice Lock USDC with a hash-lock until released or expired.</font>
    <font style="color:#6a9955;">/// @param auth USDC authorization (EIP-3009 style).</font>
    <font style="color:#6a9955;">/// @param to Payee address.</font>
    <font style="color:#6a9955;">/// @param expireDate Unix timestamp when withdrawal is allowed.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value (keccak256 of the secret key).</font>
    <font style="color:#569cd6;">function</font> lockUsd(
        TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> lock
    ) <font style="color:#569cd6;">external</font> {

        auth.<font style="color:#569cd6;">from</font> = msg.sender;

        _transferWithAuthorization(auth);

        _coffers[auth.<font style="color:#569cd6;">from</font>] += auth.value;
        _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">1</font>)] += auth.value;

        _lockers.lockUsd(auth.<font style="color:#569cd6;">from</font>, to, expireDate, auth.value, lock);

        <font style="color:#569cd6;">emit</font> LockUsd(auth.<font style="color:#569cd6;">from</font>, to, auth.value, expireDate, lock);
    }

    <font style="color:#6a9955;">/// @notice Lock USDC with an external conditional release hook.</font>
    <font style="color:#6a9955;">/// @param auth USDC authorization (EIP-3009 style).</font>
    <font style="color:#6a9955;">/// @param to Payee address.</font>
    <font style="color:#6a9955;">/// @param expireDate Unix timestamp when withdrawal is allowed.</font>
    <font style="color:#6a9955;">/// @param target Counter-locker contract to call on release.</font>
    <font style="color:#6a9955;">/// @param payload Calldata payload prefix for counter-locker.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock value (keccak256 of the secret key).</font>
    <font style="color:#569cd6;">function</font> lockConsideration(
        TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">calldata</font> payload,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font> {

        auth.<font style="color:#569cd6;">from</font> = msg.sender;

        _transferWithAuthorization(auth);

        _coffers[auth.<font style="color:#569cd6;">from</font>] += auth.value;
        _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">1</font>)] += auth.value;

        _lockers.lockConsideration(
            auth.<font style="color:#569cd6;">from</font>, to, expireDate, auth.value,
            target, payload, hashLock
        );

        <font style="color:#569cd6;">emit</font> LockConsideration(auth.<font style="color:#569cd6;">from</font>, to, auth.value, expireDate, hashLock);
    }

    <font style="color:#6a9955;">/// @notice Release a lock using the preimage string.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#6a9955;">/// @param key Preimage string (must hash to `lock`).</font>
    <font style="color:#569cd6;">function</font> unlockUsd(<font style="color:#4ec9b0;">bytes32</font> lock, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> key) <font style="color:#569cd6;">external</font> {

        UsdLockersRepo.Head <font style="color:#569cd6;">memory</font> head =
            _lockers.releaseUsd(lock, key, msg.sender);

        <font style="color:#569cd6;">if</font> (_coffers[head.<font style="color:#569cd6;">from</font>] < head.amt) {
            <font style="color:#569cd6;">revert</font> CL_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CL_InsufficientBalance"</font>));
        }

        _coffers[head.<font style="color:#569cd6;">from</font>] -= head.amt;
        _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">1</font>)] -= head.amt;

        <font style="color:#569cd6;">emit</font> UnlockUsd(head.<font style="color:#569cd6;">from</font>, head.to, head.amt, lock);

        <font style="color:#569cd6;">if</font> (!usdc.transfer(head.to, head.amt)) {
            <font style="color:#569cd6;">revert</font> CL_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CL_TransferFailed"</font>));
        }
    }

    <font style="color:#6a9955;">/// @notice Withdraw a lock after expiry by the creator.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#569cd6;">function</font> withdrawUsd(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> {

        UsdLockersRepo.Head <font style="color:#569cd6;">memory</font> head =
            _lockers.withdrawUsd(lock, msg.sender);

        <font style="color:#569cd6;">if</font> (_coffers[head.<font style="color:#569cd6;">from</font>] < head.amt) {
            <font style="color:#569cd6;">revert</font> CL_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CL_InsufficientBalance"</font>));
        }

        _coffers[head.<font style="color:#569cd6;">from</font>] -= head.amt;
        _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">1</font>)] -= head.amt;

        <font style="color:#569cd6;">emit</font> WithdrawUsd(head.<font style="color:#569cd6;">from</font>, head.amt, lock);

        <font style="color:#569cd6;">if</font> (!usdc.transfer(head.<font style="color:#569cd6;">from</font>, head.amt)) {
            <font style="color:#569cd6;">revert</font> CL_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CL_TransferFailed"</font>));
        }
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Check if a lock is currently locked.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#569cd6;">function</font> isLocked(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _lockers.isLocked(lock);
    }

    <font style="color:#6a9955;">/// @notice Get total number of lockers.</font>
    <font style="color:#569cd6;">function</font> counterOfLockers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _lockers.counterOfLockers();
    }

    <font style="color:#6a9955;">/// @notice Get locker header by hash.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#569cd6;">function</font> getHeadOfLocker(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(UsdLockersRepo.Head <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _lockers.getHeadOfLocker(lock);
    }

    <font style="color:#6a9955;">/// @notice Get full locker by hash.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#569cd6;">function</font> getLocker(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(UsdLockersRepo.Locker <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _lockers.getLocker(lock);
    }

    <font style="color:#6a9955;">/// @notice Get list of all hash locks.</font>
    <font style="color:#569cd6;">function</font> getLockersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _lockers.getSnList();
    }

    <font style="color:#6a9955;">/// @notice Get custody balance for an address.</font>
    <font style="color:#6a9955;">/// @param acct Address to query.</font>
    <font style="color:#569cd6;">function</font> custodyOf(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _coffers[acct];
    }

    <font style="color:#6a9955;">/// @notice Get total custody balance.</font>
    <font style="color:#569cd6;">function</font> totalCustody() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">1</font>)];
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## CreateNewComp.sol

---

| |
|:---|
| **contracts/center/utils/CreateNewComp.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/utils/Initializable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/utils/UUPSUpgradeable.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ICreateNewComp.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">contract</font> CreateNewComp <font style="color:#569cd6;">is</font> ICreateNewComp, Initializable, UUPSUpgradeable {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#569cd6;">enum</font> GKs {
        ZeroPoint,
        PrivateComp,
        GrowingComp,
        ListedComp,
        GeneralComp, <font style="color:#6a9955;">// 4</font>
        CloseFund,
        ListedCloseFund,
        OpenFund,
        ListedOpenFund,
        GeneralFund
    }

    <font style="color:#569cd6;">enum</font> Keepers {
        ZeroPoint,
        ROCK,
        RODK,
        BMMK,
        ROMK,
        GMMK, <font style="color:#6a9955;">// 5</font>
        ROAK,
        ROOK,
        ROPK,
        SHAK,
        LOOK, <font style="color:#6a9955;">// 10</font>
        ROIK,
        Accountant,
        Blank_1,
        Blank_2,
        GK, <font style="color:#6a9955;">// 15</font>
        RORK
    }

    <font style="color:#569cd6;">enum</font> Books {
        ZeroPoint,
        ROC,
        ROD,
        BMM,
        ROM,
        GMM, <font style="color:#6a9955;">// 5</font>
        ROA,
        ROO,
        ROP,
        ROS,
        LOO, <font style="color:#6a9955;">// 10</font>
        ROI,
        Bank,
        Blank_1,
        Blank_2,
        Cashier, <font style="color:#6a9955;">// 15</font>
        ROR
    }

    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">public</font> rc;
    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">public</font> bank;
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">20</font>] <font style="color:#569cd6;">private</font> _docs4FundKeeper;
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">20</font>] <font style="color:#569cd6;">private</font> _docs4Keeper;
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">20</font>] <font style="color:#569cd6;">private</font> _docs4Book;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#569cd6;">function</font> initialize(
        <font style="color:#4ec9b0;">address</font> _usdc, <font style="color:#4ec9b0;">address</font> _rc
    ) <font style="color:#569cd6;">external</font> initializer {
        <font style="color:#569cd6;">if</font> (_rc == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> CNC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CNC_ZeroRC"</font>));
        <font style="color:#569cd6;">if</font> (_usdc == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> CNC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CNC_ZeroUSDC"</font>));

        rc = _rc;
        bank = _usdc;
        _initDocs4Keeper();
        _initDocs4FundKeeper();
        _initDocs4Book();
    }

    <font style="color:#569cd6;">function</font> _authorizeUpgrade(<font style="color:#4ec9b0;">address</font> newImpl) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">override</font> onlyKeeper{}

    <font style="color:#569cd6;">function</font> upgradeCNCTo(<font style="color:#4ec9b0;">address</font> newImpl) <font style="color:#569cd6;">external</font> onlyKeeper onlyProxy {
        upgradeTo(newImpl);
        rc.getRC().upgradeDoc(newImpl);
    }

    <font style="color:#6a9955;">//######################</font>
    <font style="color:#6a9955;">//##  Error & Event   ##</font>
    <font style="color:#6a9955;">//######################</font>

    <font style="color:#569cd6;">error</font> CNC_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> CNC_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Modifiers   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">modifier</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (rc.getRC().getBookeeper() != msg.sender)
            <font style="color:#569cd6;">revert</font> CNC_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CNC_NotKeeper"</font>));
        _;
    }

    <font style="color:#6a9955;">// ==== Type Setting ====</font>

    <font style="color:#6a9955;">/// @dev Initialize the document type mapping for keepers and books.</font>
    <font style="color:#6a9955;">/// uint32(uint(keccak256("ROCKeeper"))) = 0x4c9c9582</font>
    <font style="color:#569cd6;">function</font> _initDocs4Keeper() <font style="color:#569cd6;">private</font> {
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROCK)]       = 0x4c9c9582;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.RODK)]       = 0x4218a169;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.BMMK)]       = 0xca6e13b7;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROMK)]       = 0xa223ca65;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.GMMK)]       = 0x49148247;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROAK)]       = 0x7eaeb1a4;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROOK)]       = 0x3ac07862;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROPK)]       = 0x4fcfb5a7;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.SHAK)]       = 0x2beb4fa1;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK)]       = 0xf9b45faf;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROIK)]       = 0xd042852b;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.Accountant)] = 0x671969be;
        _docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.GK)]         = 0x25586efd;
    }

    <font style="color:#569cd6;">function</font> _initDocs4FundKeeper() <font style="color:#569cd6;">private</font> {
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROCK)]       = 0x1590b2fb;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.RODK)]       = 0x4218a169;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.BMMK)]       = 0xca6e13b7;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROMK)]       = 0xa223ca65;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.GMMK)]       = 0x6c88e247;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROAK)]       = 0x7eaeb1a4;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROOK)]       = 0x3ac07862;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROPK)]       = 0x4fcfb5a7;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.SHAK)]       = 0x2beb4fa1;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK)]       = 0x6ab7d4a6;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.ROIK)]       = 0x918b186a;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.Accountant)] = 0x797eb8dd;
        _docs4FundKeeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.RORK)]       = 0x7ecb1211;
    }

    <font style="color:#569cd6;">function</font> _initDocs4Book() <font style="color:#569cd6;">private</font> {
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROC)]        = 0xd37755d2;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROD)]        = 0xe46d6d1a;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.BMM)]        = 0x741de5d6;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROM)]        = 0x2d24e68a;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.GMM)]        = 0x741de5d6;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROA)]        = 0xdf54d158;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROO)]        = 0x0329c3b1;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROP)]        = 0xc4a1057a;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROS)]        = 0x021dad98;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.LOO)]        = 0x198962ae;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROI)]        = 0x01716bf1;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.Cashier)]    = 0xa019f9ef;
        _docs4Book[<font style="color:#4ec9b0;">uint8</font>(Books.ROR)]        = 0x8bb6c49c;
    }

    <font style="color:#6a9955;">// ==== configuration ====</font>

    <font style="color:#569cd6;">function</font> updateRC(<font style="color:#4ec9b0;">address</font> _rc) <font style="color:#569cd6;">external</font> onlyKeeper {
        rc = _rc;
        <font style="color:#569cd6;">emit</font> UpdateRC(_rc, msg.sender);
    }

    <font style="color:#569cd6;">function</font> updateBank(<font style="color:#4ec9b0;">address</font> _bank) <font style="color:#569cd6;">external</font> onlyKeeper {
        bank = _bank;
        <font style="color:#569cd6;">emit</font> UpdateBank(_bank, msg.sender);
    }

    <font style="color:#569cd6;">function</font> updateDocs4Keeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">external</font> onlyKeeper {
        _docs4Keeper[titleOfKeeper] = typeOfDoc;
        <font style="color:#569cd6;">emit</font> UpdateDocs4Keeper(titleOfKeeper, typeOfDoc);
    }

    <font style="color:#569cd6;">function</font> getSeqOfDoc4Keeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _docs4Keeper[titleOfKeeper];
    }

    <font style="color:#569cd6;">function</font> updateDocs4FundKeeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">external</font> onlyKeeper {
        _docs4FundKeeper[titleOfKeeper] = typeOfDoc;
        <font style="color:#569cd6;">emit</font> UpdateDocs4FundKeeper(titleOfKeeper, typeOfDoc);
    }

    <font style="color:#569cd6;">function</font> getSeqOfDoc4FundKeeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _docs4FundKeeper[titleOfKeeper];
    }

    <font style="color:#569cd6;">function</font> updateDocs4Book(<font style="color:#4ec9b0;">uint</font> titelOfBook, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">external</font> onlyKeeper {
        _docs4Book[titelOfBook] = typeOfDoc;
        <font style="color:#569cd6;">emit</font> UpdateDocs4Book(titelOfBook, typeOfDoc);
    }

    <font style="color:#569cd6;">function</font> getSeqOfDoc4Book(<font style="color:#4ec9b0;">uint</font> titelOfBook) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _docs4Book[titelOfBook];
    }

    <font style="color:#6a9955;">// ==== Create Comp ====</font>
    <font style="color:#569cd6;">function</font> createComp(<font style="color:#4ec9b0;">uint</font> typeOfEntity, <font style="color:#4ec9b0;">address</font> dk) <font style="color:#569cd6;">external</font> {
        <font style="color:#569cd6;">if</font> (dk == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> CNC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CNC_ZeroDK"</font>));

        <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#b5cea8;">0</font> || typeOfEntity > <font style="color:#b5cea8;">9</font>)
            <font style="color:#569cd6;">revert</font> CNC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CNC_InvalidTypeOfEntity"</font>));

        <font style="color:#4ec9b0;">address</font> gk = _createProxyAtLatestVersion(_docs4Keeper[<font style="color:#4ec9b0;">uint8</font>(Keepers.GK)]);
        IAccessControl(gk).initKeepers(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>), gk);
        gk.getGK().createCorpSeal(<font style="color:#4ec9b0;">uint8</font>(typeOfEntity));

        <font style="color:#4ec9b0;">address</font> router = _getLatestRouter();
        gk.getGK().setRouter(router);

        _deployKeepers(typeOfEntity, gk);

        _deployBooks(typeOfEntity, dk, gk);

        IOwnable(gk).setNewOwner(msg.sender);
        IAccessControl(gk).setDirectKeeper(dk);
    }

    <font style="color:#569cd6;">function</font> _createProxyAtLatestVersion(<font style="color:#4ec9b0;">uint256</font> typeOfDoc) <font style="color:#569cd6;">private</font>
        <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">address</font> body)
    {
        <font style="color:#4ec9b0;">uint256</font> latest = rc.getRC().counterOfVersions(typeOfDoc);
        body = rc.getRC().proxyDoc(typeOfDoc, latest).body;
    }

    <font style="color:#569cd6;">function</font> _getLatestRouter() <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#6a9955;">// uint32(uint(keccak256("KeepersRouter")))</font>
        <font style="color:#4ec9b0;">uint</font> typeOfDoc = 0xf0ff1907;
        <font style="color:#4ec9b0;">uint</font> version = rc.getRC().counterOfVersions(typeOfDoc);
        <font style="color:#569cd6;">return</font> rc.getRC().getTemp(typeOfDoc,version).body;
    }

    <font style="color:#569cd6;">function</font> _deployKeepers(<font style="color:#4ec9b0;">uint</font> typeOfEntity, <font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">1</font>;
        <font style="color:#569cd6;">while</font> (i <= <font style="color:#b5cea8;">16</font>) {

            <font style="color:#569cd6;">if</font> (i == <font style="color:#4ec9b0;">uint8</font>(Keepers.Blank_1) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.Blank_2) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.GK)
            ) { i++; <font style="color:#569cd6;">continue</font>; }

            <font style="color:#569cd6;">if</font> (typeOfEntity < <font style="color:#b5cea8;">5</font> && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.RORK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.PrivateComp) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.ROOK) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.SHAK) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.GrowingComp) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.ListedComp) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.ROOK) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.SHAK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity > <font style="color:#b5cea8;">4</font> && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.ROOK) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.SHAK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.CloseFund) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.RORK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.ListedCloseFund) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.RORK)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.OpenFund) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK)
            )) { i++; <font style="color:#569cd6;">continue</font>; }

            <font style="color:#4ec9b0;">address</font> keeper = typeOfEntity > <font style="color:#b5cea8;">4</font>
                ? _getLatestVersionOfTemp(_docs4FundKeeper[i])
                : _getLatestVersionOfTemp(_docs4Keeper[i]);

            gk.getGK().regKeeper(i, keeper);
            i++;
        }
    }

    <font style="color:#569cd6;">function</font> _getLatestVersionOfTemp(
        <font style="color:#4ec9b0;">uint</font> typeOfDoc
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">address</font> temp) {
        <font style="color:#4ec9b0;">uint256</font> latest = rc.getRC().counterOfVersions(typeOfDoc);
        temp = rc.getRC().getTemp(typeOfDoc, latest).body;
    }

    <font style="color:#569cd6;">function</font> _deployBooks(
        <font style="color:#4ec9b0;">uint</font> typeOfEntity, <font style="color:#4ec9b0;">address</font> dk, <font style="color:#4ec9b0;">address</font> gk
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">1</font>;
        <font style="color:#569cd6;">while</font> (i <= <font style="color:#b5cea8;">16</font>) {

            <font style="color:#569cd6;">if</font> (i == <font style="color:#4ec9b0;">uint8</font>(Books.Blank_1) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Books.Blank_2)
            ) {i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (i == <font style="color:#4ec9b0;">uint8</font>(Books.Bank)) {
                gk.getGK().regBook(i, bank);
                i++; <font style="color:#569cd6;">continue</font>;
            }

            <font style="color:#569cd6;">if</font> (typeOfEntity < <font style="color:#b5cea8;">5</font> && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.ROR)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.PrivateComp) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.ROO) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Books.LOO)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.GrowingComp) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.LOO)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.ListedComp) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.ROO)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity > <font style="color:#b5cea8;">4</font> && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.ROO)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.CloseFund) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.LOO) ||
                i == <font style="color:#4ec9b0;">uint8</font>(Books.ROR)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.ListedCloseFund) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.ROR)
            )) { i++; <font style="color:#569cd6;">continue</font>;}

            <font style="color:#569cd6;">if</font> (typeOfEntity == <font style="color:#4ec9b0;">uint8</font>(GKs.OpenFund) && (
                i == <font style="color:#4ec9b0;">uint8</font>(Books.LOO)
            )) { i++; <font style="color:#569cd6;">continue</font>; }

            <font style="color:#4ec9b0;">address</font> book = _createProxyAtLatestVersion(_docs4Book[i]);
            <font style="color:#569cd6;">if</font> (i == <font style="color:#4ec9b0;">uint8</font>(Books.ROS) || i == <font style="color:#4ec9b0;">uint8</font>(Books.ROM)) {
                IAccessControl(book).initKeepers(dk, gk);
            } <font style="color:#569cd6;">else</font> {
                IAccessControl(book).initKeepers(gk, gk);
            }
            gk.getGK().regBook(i, book);
            IOwnable(book).setNewOwner(msg.sender);
            i++;
        }
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ICashLockers.sol

---

| |
|:---|
| **contracts/center/utils/ICashLockers.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/UsdLockersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../utils/MockUSDC/IUSDC.sol"</font>;

<font style="color:#569cd6;">interface</font> ICashLockers {

    <font style="color:#569cd6;">struct</font> TransferAuth{
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>;
        <font style="color:#4ec9b0;">address</font> to;
        <font style="color:#4ec9b0;">uint256</font> value;
        <font style="color:#4ec9b0;">uint256</font> validAfter;
        <font style="color:#4ec9b0;">uint256</font> validBefore;
        <font style="color:#4ec9b0;">bytes32</font> nonce;
        <font style="color:#4ec9b0;">uint8</font> v;
        <font style="color:#4ec9b0;">bytes32</font> r;
        <font style="color:#4ec9b0;">bytes32</font> s;
    }

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">error</font> CL_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> CL_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">event</font> LockUsd(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> lock
    );

    <font style="color:#569cd6;">event</font> LockConsideration(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> lock
    );

    <font style="color:#569cd6;">event</font> UnlockUsd(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> lock
    );

    <font style="color:#569cd6;">event</font> WithdrawUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> lock);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Write     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#569cd6;">function</font> lockUsd(
        TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> lock
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> lockConsideration(
        TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">address</font> counterLocker, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">calldata</font> payload, <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> unlockUsd(<font style="color:#4ec9b0;">bytes32</font> lock, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> key) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> withdrawUsd(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">// function usdc() external view returns(IUSDC);</font>

    <font style="color:#569cd6;">function</font> isLocked(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#569cd6;">function</font> counterOfLockers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> getHeadOfLocker(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(UsdLockersRepo.Head <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getLocker(<font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(UsdLockersRepo.Locker <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getLockersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> custodyOf(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> totalCustody() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ICreateNewComp.sol

---

| |
|:---|
| **contracts/center/utils/ICreateNewComp.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/common/access/IAccessControl.sol"</font>;

<font style="color:#569cd6;">interface</font> ICreateNewComp {

    <font style="color:#569cd6;">event</font> UpdateRC(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> newRC, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> updater);

    <font style="color:#569cd6;">event</font> UpdateBank(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> bank, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> owner);

    <font style="color:#569cd6;">event</font> UpdateDocs4GK(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfEntity, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfDoc);

    <font style="color:#569cd6;">event</font> UpdateDocs4FundKeeper(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> titleOfKeeper, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfDoc);

    <font style="color:#569cd6;">event</font> UpdateDocs4Keeper(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> titleOfKeeper, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfDoc);

    <font style="color:#569cd6;">event</font> UpdateDocs4Book(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> titleOfBook, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfDoc);

    <font style="color:#569cd6;">function</font> updateRC(<font style="color:#4ec9b0;">address</font> _rc) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> updateBank(<font style="color:#4ec9b0;">address</font> _bank) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> updateDocs4FundKeeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> getSeqOfDoc4FundKeeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> updateDocs4Keeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> getSeqOfDoc4Keeper(<font style="color:#4ec9b0;">uint</font> titleOfKeeper) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> updateDocs4Book(<font style="color:#4ec9b0;">uint</font> titleOfBook, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> getSeqOfDoc4Book(<font style="color:#4ec9b0;">uint</font> titleOfBook) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> createComp(<font style="color:#4ec9b0;">uint</font> typeOfEntity, <font style="color:#4ec9b0;">address</font> dk) <font style="color:#569cd6;">external</font>;
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IUSDC.sol

---

| |
|:---|
| **contracts/center/utils/MockUSDC/IUSDC.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/token/ERC20/IERC20.sol"</font>;

<font style="color:#6a9955;">// Decimal = 6 </font>
<font style="color:#569cd6;">interface</font> IUSDC <font style="color:#569cd6;">is</font> IERC20{

    <font style="color:#569cd6;">event</font> AuthorizationUsed(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> authorizer, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> nonce);

    <font style="color:#569cd6;">function</font> authorizationState(<font style="color:#4ec9b0;">address</font> authorizer, <font style="color:#4ec9b0;">bytes32</font> nonce)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ---- Mint & Burn ----</font>

    <font style="color:#569cd6;">function</font> mint(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> burn(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ---- TransferWithAuthorization ----</font>

    <font style="color:#569cd6;">function</font> transferWithAuthorization(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>,
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">uint256</font> value,
        <font style="color:#4ec9b0;">uint256</font> validAfter,
        <font style="color:#4ec9b0;">uint256</font> validBefore,
        <font style="color:#4ec9b0;">bytes32</font> nonce,
        <font style="color:#4ec9b0;">uint8</font> v,
        <font style="color:#4ec9b0;">bytes32</font> r,
        <font style="color:#4ec9b0;">bytes32</font> s
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## MockUSDC.sol

---

| |
|:---|
| **contracts/center/utils/MockUSDC/MockUSDC.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IUSDC.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/token/ERC20/ERC20.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../comps/common/access/Ownable.sol"</font>;

<font style="color:#569cd6;">contract</font> MockUSDC <font style="color:#569cd6;">is</font> IUSDC, ERC20(<font style="color:#ce9178;">"USD Coin"</font>, <font style="color:#ce9178;">"USDC"</font>), Ownable {

    <font style="color:#6a9955;">// keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")</font>
    <font style="color:#4ec9b0;">bytes32</font>
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;

    <font style="color:#6a9955;">// USDC on ArbitrumOne EIP-712 DomainSeparator (SM Addr: 0xaf88d065e77c8cC2239327C5EDb3A432268e5831)</font>
    <font style="color:#6a9955;">// bytes32 public constant DOMAIN_SEPARATOR = 0x08d11903f8419e68b1b8721bcbe2e9fc68569122a77ef18c216f10b3b5112c78;</font>

    <font style="color:#6a9955;">// keccak256("USD Coin");</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> NAME_HASH = 0x52878b207aaddbfc15ea7bebcda681eb8ccd306e2227b61cef68505c8c056341;

    <font style="color:#6a9955;">// keccak256("2");</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION_HASH = 0xad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5;

    <font style="color:#6a9955;">// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    <font style="color:#569cd6;">function</font> domainSeparator() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>) {
        <font style="color:#569cd6;">return</font> keccak256(
            abi.encode(
                TYPE_HASH,
                NAME_HASH,
                VERSION_HASH,
                block.chainid,
                <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)
            )
        );
    }

    <font style="color:#6a9955;">// ---- Authorization ----</font>

    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">bytes32</font> => <font style="color:#4ec9b0;">bool</font>)) <font style="color:#569cd6;">private</font> _authorizationStates;

    <font style="color:#569cd6;">function</font> authorizationState(<font style="color:#4ec9b0;">address</font> authorizer, <font style="color:#4ec9b0;">bytes32</font> nonce)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _authorizationStates[authorizer][nonce];
    }

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">error</font> MockUSDC_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> MockUSDC_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ---- Mint & Burn ----</font>

    <font style="color:#569cd6;">function</font> mint(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font> onlyOwner {
        _mint(to, amt);
    }

    <font style="color:#569cd6;">function</font> burn(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font> {
        _burn(msg.sender, amt);
    }

    <font style="color:#6a9955;">// ---- TransferWithAuthorization ----</font>

    <font style="color:#569cd6;">function</font> transferWithAuthorization(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>,
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">uint256</font> value,
        <font style="color:#4ec9b0;">uint256</font> validAfter,
        <font style="color:#4ec9b0;">uint256</font> validBefore,
        <font style="color:#4ec9b0;">bytes32</font> nonce,
        <font style="color:#4ec9b0;">uint8</font> v,
        <font style="color:#4ec9b0;">bytes32</font> r,
        <font style="color:#4ec9b0;">bytes32</font> s
    ) <font style="color:#569cd6;">external</font> {

        <font style="color:#569cd6;">if</font>(block.timestamp < validAfter) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_AuthNotValidNow"</font>));
        }

        <font style="color:#569cd6;">if</font>(block.timestamp > validBefore) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_AuthExpired"</font>));
        }

        <font style="color:#569cd6;">if</font>(_authorizationStates[<font style="color:#569cd6;">from</font>][nonce]) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_AuthUsedOrCanceled"</font>));
        }

        _requireValidSignature(
            <font style="color:#569cd6;">from</font>,
            keccak256(
                abi.encode(
                    TRANSFER_WITH_AUTHORIZATION_TYPEHASH,
                    <font style="color:#569cd6;">from</font>,
                    to,
                    value,
                    validAfter,
                    validBefore,
                    nonce
                )
            ),
            v,
            r,
            s
        );

        _authorizationStates[<font style="color:#569cd6;">from</font>][nonce] = <font style="color:#569cd6;">true</font>;
        <font style="color:#569cd6;">emit</font> AuthorizationUsed(<font style="color:#569cd6;">from</font>, nonce);

        _transfer(<font style="color:#569cd6;">from</font>, to, value);
    }

    <font style="color:#569cd6;">function</font> _requireValidSignature(
        <font style="color:#4ec9b0;">address</font> signer,
        <font style="color:#4ec9b0;">bytes32</font> dataHash,
        <font style="color:#4ec9b0;">uint8</font> v,
        <font style="color:#4ec9b0;">bytes32</font> r,
        <font style="color:#4ec9b0;">bytes32</font> s
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        <font style="color:#569cd6;">if</font>(
            !_isValidSignatureNow(
                signer,
                _toTypedDataHash(dataHash),
                v,
                r,
                s
            )
        ) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_InvalidSignature"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> _toTypedDataHash(<font style="color:#4ec9b0;">bytes32</font> structHash)
        <font style="color:#569cd6;">internal</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> digest)
    {
        <font style="color:#4ec9b0;">bytes32</font> separator = domainSeparator();
        <font style="color:#569cd6;">assembly</font> {
            let ptr := mload(0x40)
            mstore(ptr, <font style="color:#ce9178;">"\x19\x01"</font>)
            mstore(add(ptr, 0x02), separator)
            mstore(add(ptr, 0x22), structHash)
            digest := keccak256(ptr, 0x42)
        }
    }

    <font style="color:#569cd6;">function</font> _isValidSignatureNow(
        <font style="color:#4ec9b0;">address</font> signer,
        <font style="color:#4ec9b0;">bytes32</font> digest,
        <font style="color:#4ec9b0;">uint8</font> v,
        <font style="color:#4ec9b0;">bytes32</font> r,
        <font style="color:#4ec9b0;">bytes32</font> s
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font> (!_isContract(signer)) {
            <font style="color:#569cd6;">return</font> _recover(digest, v, r, s) == signer;
        }
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _isContract(<font style="color:#4ec9b0;">address</font> addr) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint256</font> size;
        <font style="color:#569cd6;">assembly</font> {
            size := extcodesize(addr)
        }
        <font style="color:#569cd6;">return</font> size > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#569cd6;">function</font> _recover(
        <font style="color:#4ec9b0;">bytes32</font> digest,
        <font style="color:#4ec9b0;">uint8</font> v,
        <font style="color:#4ec9b0;">bytes32</font> r,
        <font style="color:#4ec9b0;">bytes32</font> s
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">if</font> (
            <font style="color:#4ec9b0;">uint256</font>(s) >
            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
        ) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_InvalidSValue"</font>));
        }

        <font style="color:#569cd6;">if</font> (v != <font style="color:#b5cea8;">27</font> && v != <font style="color:#b5cea8;">28</font>) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_InvalidVValue"</font>));
        }

        <font style="color:#4ec9b0;">address</font> signer = ecrecover(digest, v, r, s);
        <font style="color:#569cd6;">if</font> (signer == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> MockUSDC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MockUSDC_ZeroSig"</font>));
        }

        <font style="color:#569cd6;">return</font> signer;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## UsdFuelTank.sol

---

| |
|:---|
| **contracts/center/utils/UsdFuelTank.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">// import "../access/Ownable.sol";</font>
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/utils/Initializable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/utils/UUPSUpgradeable.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/cashier/ICashier.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;

<font style="color:#6a9955;">/// @title UsdFuelTank</font>
<font style="color:#6a9955;">/// @notice Accepts USDC authorization via Cashier and dispenses CBP at a fixed rate.</font>
<font style="color:#6a9955;">/// @dev `rate` is the USDC smallest-unit amount per 1e18 CBP.</font>
<font style="color:#569cd6;">contract</font> UsdFuelTank <font style="color:#569cd6;">is</font> Initializable, UUPSUpgradeable {
  <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
  <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

  <font style="color:#6a9955;">/// @notice RegCenter address for access control and bookkeeping.</font>
  <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">public</font> rc;
  <font style="color:#6a9955;">/// @notice Cashier contract that pulls USDC using off-chain authorization.</font>
  <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">public</font> cashier;
  <font style="color:#6a9955;">/// @notice USDC-per-1e18-CBP exchange rate (USDC in smallest units).</font>
  <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> rate;
  <font style="color:#6a9955;">/// @notice Total CBP dispensed by this contract.</font>
  <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> sum;

  <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

  <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

  <font style="color:#569cd6;">function</font> initialize(
    <font style="color:#4ec9b0;">address</font> cashier_, <font style="color:#4ec9b0;">address</font> rc_
  ) <font style="color:#569cd6;">external</font> initializer {
    <font style="color:#569cd6;">if</font> (rc_ == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
      <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_ZeroRC"</font>));

    cashier = cashier_;
    rc = rc_;
  }

  <font style="color:#569cd6;">function</font> _authorizeUpgrade(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">override</font> onlyOwner {}

  <font style="color:#569cd6;">function</font> getImplementation() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
      <font style="color:#569cd6;">return</font> _getImplementation();
  }

  <font style="color:#6a9955;">/// @notice Upgrade implementation via UUPS and register the upgrade in RegCenter.</font>
  <font style="color:#6a9955;">/// @param newImplementation New implementation address.</font>
  <font style="color:#569cd6;">function</font> upgradeTankTo(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">external</font> onlyProxy onlyKeeper {
    upgradeTo(newImplementation);
    rc.getRC().upgradeDoc(newImplementation);
  }

  <font style="color:#6a9955;">// #########################</font>
  <font style="color:#6a9955;">// ##  Modifier & Errors  ##</font>
  <font style="color:#6a9955;">// ######################### </font>

  <font style="color:#569cd6;">error</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

  <font style="color:#569cd6;">error</font> UFT_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

  <font style="color:#569cd6;">error</font> UFT_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

  <font style="color:#569cd6;">modifier</font> onlyOwner {
    <font style="color:#569cd6;">if</font> (msg.sender != rc.getRC().getOwner()) {
      <font style="color:#569cd6;">revert</font> UFT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_NotOwner"</font>));
    }
    _;
  }

  <font style="color:#569cd6;">modifier</font> onlyKeeper {
    <font style="color:#569cd6;">if</font> (msg.sender != rc.getRC().getBookeeper()) {
      <font style="color:#569cd6;">revert</font> UFT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_NotKeeper"</font>));
    }
    _;
  }

  <font style="color:#6a9955;">// ##############</font>
  <font style="color:#6a9955;">// ##  Events  ##</font>
  <font style="color:#6a9955;">// ############## </font>

  <font style="color:#6a9955;">/// @notice Emitted when RegCenter address is updated.</font>
  <font style="color:#6a9955;">/// @param newCenter New RegCenter address.</font>
  <font style="color:#569cd6;">event</font> SetRegCenter(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> newCenter);

  <font style="color:#6a9955;">/// @notice Emitted when Cashier address is updated.</font>
  <font style="color:#6a9955;">/// @param newCashier New Cashier address.</font>
  <font style="color:#569cd6;">event</font> SetCashier(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> newCashier);

  <font style="color:#6a9955;">/// @notice Emitted when rate is updated.</font>
  <font style="color:#6a9955;">/// @param newRate New USDC-per-1e18-CBP rate.</font>
  <font style="color:#569cd6;">event</font> SetRate(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> newRate);

  <font style="color:#6a9955;">/// @notice Emitted on successful refuel.</font>
  <font style="color:#6a9955;">/// @param buyer CBP recipient.</font>
  <font style="color:#6a9955;">/// @param amtOfUSDC USDC amount charged (smallest units).</font>
  <font style="color:#6a9955;">/// @param amtOfCbp CBP amount dispensed (18 decimals).</font>
  <font style="color:#569cd6;">event</font> Refuel(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> buyer, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amtOfUSDC, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amtOfCbp);

  <font style="color:#6a9955;">/// @notice Emitted when owner withdraws CBP reserve.</font>
  <font style="color:#6a9955;">/// @param owner Owner address.</font>
  <font style="color:#6a9955;">/// @param amt CBP amount withdrawn.</font>
  <font style="color:#569cd6;">event</font> WithdrawFuel(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> owner, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt);

  <font style="color:#6a9955;">// ##################</font>
  <font style="color:#6a9955;">// ##  Write I/O   ##</font>
  <font style="color:#6a9955;">// ##################</font>

  <font style="color:#6a9955;">/// @notice Set RegCenter contract.</font>
  <font style="color:#6a9955;">/// @param newCenter RegCenter address (non-zero, must be a contract).</font>
  <font style="color:#569cd6;">function</font> setRegCenter(<font style="color:#4ec9b0;">address</font> newCenter) <font style="color:#569cd6;">external</font> onlyKeeper {
    <font style="color:#569cd6;">if</font> (newCenter == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
       <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_ZeroRC"</font>));
    <font style="color:#569cd6;">if</font> (!newCenter.isContract())
        <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_RCNotContract"</font>));

    rc = newCenter;

    <font style="color:#569cd6;">emit</font> SetRegCenter(newCenter);
  }

  <font style="color:#6a9955;">/// @notice Set Cashier contract.</font>
  <font style="color:#6a9955;">/// @param newCashier Cashier address (non-zero, must be a contract).</font>
  <font style="color:#569cd6;">function</font> setCashier(<font style="color:#4ec9b0;">address</font> newCashier) <font style="color:#569cd6;">external</font> onlyKeeper {
    <font style="color:#569cd6;">if</font> (newCashier == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
        <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_ZeroCashier"</font>));
    <font style="color:#569cd6;">if</font> (!newCashier.isContract())
        <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_CashierNotContract"</font>));
    cashier = newCashier;
    <font style="color:#569cd6;">emit</font> SetCashier(newCashier);
  }

  <font style="color:#6a9955;">/// @notice Set USDC-per-1e18-CBP rate.</font>
  <font style="color:#6a9955;">/// @param newRate New rate (must be > 0).</font>
  <font style="color:#569cd6;">function</font> setRate(<font style="color:#4ec9b0;">uint</font> newRate) <font style="color:#569cd6;">external</font> onlyKeeper {
    <font style="color:#569cd6;">if</font> (newRate == <font style="color:#b5cea8;">0</font>)
        <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_ZeroRate"</font>));
    rate = newRate;
    <font style="color:#569cd6;">emit</font> SetRate(newRate);
  }

  <font style="color:#569cd6;">function</font> takeBackKeys (<font style="color:#4ec9b0;">address</font> target) <font style="color:#569cd6;">external</font> onlyKeeper {
      IAccessControl(target).setDirectKeeper(msg.sender);
  }

  <font style="color:#6a9955;">/// @notice Pull USDC via Cashier authorization and transfer CBP to caller.</font>
  <font style="color:#6a9955;">/// @param auth USDC authorization (EIP-3009 style) for Cashier to collect.</font>
  <font style="color:#6a9955;">/// @param amt CBP amount requested (18 decimals). If zero, it is derived from auth.value.</font>
  <font style="color:#569cd6;">function</font> refuel(ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font> {
    <font style="color:#4ec9b0;">uint</font> balance = <font style="color:#b5cea8;">0</font>;
    <font style="color:#569cd6;">if</font> (amt == <font style="color:#b5cea8;">0</font>) {
      amt = auth.value * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">18</font> / rate ;
    } <font style="color:#569cd6;">else</font> {
      <font style="color:#569cd6;">if</font> (auth.value < (rate * amt / <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">18</font>)) {
        <font style="color:#569cd6;">revert</font> UFT_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_InsufficientUSDC"</font>));
      }
      balance = auth.value - (rate * amt / <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">18</font>);
    }

    <font style="color:#569cd6;">if</font> (amt > <font style="color:#b5cea8;">0</font> && rc.getRC().balanceOf(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)) >= amt) {
      sum += amt;
      <font style="color:#569cd6;">emit</font> Refuel (msg.sender, auth.value - balance, amt);
      <font style="color:#6a9955;">//remark: bytes("CollectUSDCForRefuelCBP")</font>
      ICashier(cashier).collectUsd(auth,
        <font style="color:#4ec9b0;">bytes32</font>(0x436f6c6c65637455534443466f7252656675656c434250000000000000000000));
      <font style="color:#569cd6;">if</font> (!rc.getRC().transfer(msg.sender, amt)) {
        <font style="color:#569cd6;">revert</font> UFT_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_CBPTransferFailed"</font>));
      } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (balance > <font style="color:#b5cea8;">0</font>) {
        <font style="color:#4ec9b0;">uint</font> temp = balance;
        balance = <font style="color:#b5cea8;">0</font>;
        <font style="color:#6a9955;">//remark: bytes("RefundBalanceUSDCForRefuelCBP")</font>
        ICashier(cashier).transferUsd(auth.<font style="color:#569cd6;">from</font>, temp,
          <font style="color:#4ec9b0;">bytes32</font>(0x526566756e6442616c616e636555534443466f7252656675656c434250000000));
      }
    } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> UFT_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_ShortOfCBPReserve"</font>));

  }

  <font style="color:#6a9955;">/// @notice Withdraw CBP reserve to owner.</font>
  <font style="color:#6a9955;">/// @param amt CBP amount to withdraw.</font>
  <font style="color:#569cd6;">function</font> withdrawFuel(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font> onlyOwner {
    <font style="color:#569cd6;">if</font> (rc.getRC().balanceOf(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)) >= amt) {
        <font style="color:#569cd6;">emit</font> WithdrawFuel(msg.sender, amt);
        <font style="color:#569cd6;">if</font> (!rc.getRC().transfer(msg.sender, amt)) {
          <font style="color:#569cd6;">revert</font> UFT_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_CBPTransferFailed"</font>));
        }
    } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> UFT_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UFT_ShortOfCBPReserve"</font>));
  }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## Cashier.sol

---

| |
|:---|
| **contracts/comps/books/cashier/Cashier.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ICashier.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> Cashier <font style="color:#569cd6;">is</font> ICashier, AccessControl {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> WaterfallsRepo <font style="color:#569cd6;">for</font> WaterfallsRepo.Repo;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Custody balances by external account address (escrowed USD).</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint</font>) <font style="color:#569cd6;">private</font> _coffers;
    <font style="color:#6a9955;">// Deposit balances by internal user number (pending pickups).</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => <font style="color:#4ec9b0;">uint</font>) <font style="color:#569cd6;">private</font> _lockers;

    <font style="color:#6a9955;">// Waterfall distribution repository and accounting state.</font>
    WaterfallsRepo.Repo <font style="color:#569cd6;">private</font> _rivers;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">// Pull USD from `auth.from` into this contract using authorization data.</font>
    <font style="color:#6a9955;">// `auth` carries the EIP-3009 style authorization parameters.</font>
    <font style="color:#569cd6;">function</font> _transferWithAuthorization(TransferAuth <font style="color:#569cd6;">memory</font> auth) <font style="color:#569cd6;">private</font> {
        _gk.getBank().transferWithAuthorization(
            auth.<font style="color:#569cd6;">from</font>,
            <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>),
            auth.value,
            auth.validAfter,
            auth.validBefore,
            auth.nonce,
            auth.v,
            auth.r,
            auth.s
        );
    }

    <font style="color:#569cd6;">function</font> initClass(
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> principal
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info =
            _rivers.initClass(class, principal * <font style="color:#b5cea8;">100</font>);
        <font style="color:#569cd6;">emit</font> InitClass(class, principal, info.distrDate);
    }

    <font style="color:#569cd6;">function</font> redeemClass(
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> principal
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _rivers.redeemClass(class, principal * <font style="color:#b5cea8;">100</font>);
        <font style="color:#569cd6;">emit</font> RedeemClass(class, principal);
    }

    <font style="color:#569cd6;">function</font> collectUsd(
        TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">bytes32</font> remark
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _transferWithAuthorization(auth);
        <font style="color:#569cd6;">emit</font> ReceiveUsd(auth.<font style="color:#569cd6;">from</font>, auth.value, remark);
    }

    <font style="color:#569cd6;">function</font> forwardUsd(
        TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">bytes32</font> remark
    ) <font style="color:#569cd6;">external</font> onlyKeeper{
        _transferWithAuthorization(auth);
        <font style="color:#569cd6;">emit</font> ForwardUsd(auth.<font style="color:#569cd6;">from</font>, to, auth.value, remark);

        <font style="color:#569cd6;">if</font> (!_gk.getBank().transfer(to, auth.value)) {
            <font style="color:#569cd6;">revert</font> Cashier_TransferFailed(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_TransferFailed"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> custodyUsd(
        TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">bytes32</font> remark
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _transferWithAuthorization(auth);
        _coffers[auth.<font style="color:#569cd6;">from</font>] += auth.value;
        _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)] += auth.value;

        <font style="color:#569cd6;">emit</font> CustodyUsd(auth.<font style="color:#569cd6;">from</font>, auth.value, remark);
    }

    <font style="color:#569cd6;">function</font> releaseUsd(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font>(_coffers[<font style="color:#569cd6;">from</font>] < amt) {
            <font style="color:#569cd6;">revert</font> Cashier_Overflow(<font style="color:#ce9178;">"Cashier_InsufficientAmt"</font>);
        }

        _coffers[<font style="color:#569cd6;">from</font>] -= amt;
        _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)] -= amt;

        <font style="color:#569cd6;">emit</font> ReleaseUsd(<font style="color:#569cd6;">from</font>, to, amt, remark);

        <font style="color:#569cd6;">if</font> (!_gk.getBank().transfer(to, amt)) {
            <font style="color:#569cd6;">revert</font> Cashier_TransferFailed(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_TransferFailed"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> transferUsd(
        <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        <font style="color:#569cd6;">if</font> (balanceOfComp() < amt) {
            <font style="color:#569cd6;">revert</font> Cashier_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_InsufficientAmt"</font>));
        }

        <font style="color:#569cd6;">emit</font> TransferUsd(to, amt, remark);

        <font style="color:#569cd6;">if</font> (!_gk.getBank().transfer(to, amt)) {
            <font style="color:#569cd6;">revert</font> Cashier_TransferFailed(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_TransferFailed"</font>));
        }
    }

    <font style="color:#6a9955;">// ==== Distribution ====</font>

    <font style="color:#569cd6;">function</font> distrProfits(<font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> seqOfDR) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> mlist
    ){

        <font style="color:#569cd6;">if</font> (balanceOfComp() < amt) {
            <font style="color:#569cd6;">revert</font> Cashier_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_InsufficientAmt"</font>));
        }

        RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule =
            _gk.getSHA().getRule(seqOfDR).DistrRuleParser();

        IRegisterOfMembers _rom = _gk.getROM();

        IRegisterOfShares _ros = _gk.getROS();
        WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop;

        <font style="color:#569cd6;">if</font> ( rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.ProRata)) {
            (drop, mlist, ) = _rivers.proRataDistr(amt, _rom, _ros, <font style="color:#569cd6;">false</font>);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.IntFront)) {
            (drop, mlist, ) = _rivers.intFrontDistr(amt, _ros, rule);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> Cashier_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_WrongTypeOfDistr"</font>));

        <font style="color:#569cd6;">emit</font> DistrProfits(amt, seqOfDR, drop.seqOfDistr);
        _distrUsd(mlist, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DistrProfits"</font>));
    }

    <font style="color:#6a9955;">// Book each distribution drop as a deposit for the member.</font>
    <font style="color:#6a9955;">// `mlist` is the list of drops to deposit; `remark` tags the ledger entry.</font>
    <font style="color:#569cd6;">function</font> _distrUsd(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> mlist, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">uint</font> len = mlist.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop = mlist[len-<font style="color:#b5cea8;">1</font>];
            _depositUsd(drop.member, drop.income + drop.principal, remark);
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> distrIncome(<font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> seqOfDR, <font style="color:#4ec9b0;">uint</font> fundManager) <font style="color:#569cd6;">external</font> onlyKeeper
        <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> mlist, WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> slist){

        <font style="color:#569cd6;">if</font> (balanceOfComp() < amt) {
            <font style="color:#569cd6;">revert</font> Cashier_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_ShortOfAmt"</font>));
        }

        RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule =
            _gk.getSHA().getRule(seqOfDR).DistrRuleParser();

        IRegisterOfMembers _rom = _gk.getROM();
        IRegisterOfShares _ros = _gk.getROS();
        WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop;

        <font style="color:#569cd6;">if</font> ( rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.ProRata)) {
            (drop, mlist, slist) = _rivers.proRataDistr(amt, _rom, _ros, <font style="color:#569cd6;">true</font>);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.IntFront)) {
            (drop, mlist, slist) = _rivers.intFrontDistr(amt, _ros, rule);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.PrinFront)) {
            (drop, mlist, slist) = _rivers.prinFrontDistr(amt, _ros, rule);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.HuddleCarry)) {
            (drop, mlist, slist) = _rivers.hurdleCarryDistr(amt, _ros, rule, fundManager);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> Cashier_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_WrongTypeOfDistr"</font>));

        <font style="color:#569cd6;">emit</font> DistrIncome(amt, seqOfDR, fundManager, drop.seqOfDistr);

        _distrUsd(mlist, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DistrIncome"</font>));
    }

    <font style="color:#569cd6;">function</font> depositUsd(<font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> user, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font> onlyKeeper{
        <font style="color:#569cd6;">if</font> (balanceOfComp() < amt) {
            <font style="color:#569cd6;">revert</font> Cashier_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_ShortOfAmt"</font>));
        }

        _depositUsd(user, amt, remark);
    }

    <font style="color:#6a9955;">// Credit `amt` USD to the internal deposit locker of `payee`.</font>
    <font style="color:#6a9955;">// `remark` is an accounting tag for the deposit event.</font>
    <font style="color:#569cd6;">function</font> _depositUsd(<font style="color:#4ec9b0;">uint</font> payee, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (payee == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> Cashier_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_ZeroPayee"</font>));
        }

        <font style="color:#569cd6;">emit</font> DepositUsd(amt, payee, remark);

        _lockers[payee] += amt;
        _lockers[<font style="color:#b5cea8;">0</font>] += amt;
    }

    <font style="color:#6a9955;">// ==== Pickup Deposit ====</font>

    <font style="color:#569cd6;">function</font> pickupUsd() <font style="color:#569cd6;">external</font> {

        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(0xa019f9ef, <font style="color:#b5cea8;">1</font>, <font style="color:#b5cea8;">18000</font>);
        <font style="color:#4ec9b0;">uint</font> value = _lockers[caller];

        <font style="color:#569cd6;">if</font> (value > <font style="color:#b5cea8;">0</font>) {

            _lockers[caller] = <font style="color:#b5cea8;">0</font>;
            _lockers[<font style="color:#b5cea8;">0</font>] -= value;

            <font style="color:#569cd6;">emit</font> PickupUsd(msg.sender, caller, value);

            <font style="color:#569cd6;">if</font> (!_gk.getBank().transfer(msg.sender, value)) {
                <font style="color:#569cd6;">revert</font> Cashier_TransferFailed(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_TransferFailed"</font>));
            }

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> Cashier_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Cashier_NoBalance"</font>));
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> custodyOf(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _coffers[acct];
    }

    <font style="color:#569cd6;">function</font> totalEscrow() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)];
    }

    <font style="color:#569cd6;">function</font> totalDeposits() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _lockers[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#569cd6;">function</font> depositOfMine(<font style="color:#4ec9b0;">uint</font> user) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _lockers[user];
    }

    <font style="color:#569cd6;">function</font> balanceOfComp() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#4ec9b0;">uint</font> amt = _gk.getBank().balanceOf(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>));
        <font style="color:#569cd6;">return</font> amt - _coffers[<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)] - _lockers[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">// ==== Waterfalls Distribution ====</font>

    <font style="color:#6a9955;">// ---- Drop ----</font>

    <font style="color:#569cd6;">function</font> getDrop(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop) {
        drop = _rivers.getDrop(seqOfDistr, member, class, seqOfShare);
    }

    <font style="color:#6a9955;">// ---- Flow ----</font>

    <font style="color:#569cd6;">function</font> getFlowInfo(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getFlowInfo(seqOfDistr, member, class);
    }

    <font style="color:#569cd6;">function</font> getDropsOfFlow(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list) {
        list = _rivers.getDropsOfFlow(seqOfDistr, member, class);
    }

    <font style="color:#6a9955;">// ---- Creek ----</font>

    <font style="color:#569cd6;">function</font> getCreekInfo(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getCreekInfo(seqOfDistr, member);
    }

    <font style="color:#569cd6;">function</font> getDropsOfCreek(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list) {
        list = _rivers.getDropsOfCreek(seqOfDistr, member);
    }

    <font style="color:#6a9955;">// ---- Stream ----</font>

    <font style="color:#569cd6;">function</font> getStreamInfo(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getStreamInfo(seqOfDistr);
    }

    <font style="color:#569cd6;">function</font> getCreeksOfStream(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list) {
        list = _rivers.getCreeksOfStream(seqOfDistr);
    }

    <font style="color:#569cd6;">function</font> getDropsOfStream(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list) {
        list = _rivers.getDropsOfStream(seqOfDistr);
    }

    <font style="color:#6a9955;">// ---- Member ----</font>

    <font style="color:#569cd6;">function</font> getPoolInfo(
        <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop) {
        drop =
            _rivers.getPoolInfo(member, class);
    }

    <font style="color:#569cd6;">function</font> getLakeInfo(
        <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop) {
        drop =
            _rivers.getLakeInfo(member);
    }

    <font style="color:#6a9955;">// ==== Waterfalls Class ====</font>

    <font style="color:#569cd6;">function</font> getInitSeaInfo(
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getInitSeaInfo(class);
    }

    <font style="color:#569cd6;">function</font> getSeaInfo(
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getSeaInfo(class);
    }

    <font style="color:#569cd6;">function</font> getGulfInfo(
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getGulfInfo(class);
    }

    <font style="color:#569cd6;">function</font> getIslandInfo(
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info) {
        info = _rivers.getIslandInfo(class, seqOfDistr);
    }

    <font style="color:#569cd6;">function</font> getListOfClasses() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list
    ) {
        list = _rivers.getListOfClasses();
    }

    <font style="color:#569cd6;">function</font> getAllSeasInfo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list
    ) {
        list = _rivers.getAllSeasInfo();
    }

    <font style="color:#6a9955;">// ==== Waterfalls Sum ====</font>

    <font style="color:#569cd6;">function</font> getOceanInfo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info
    ) {
        info = _rivers.getOceanInfo();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ICashier.sol

---

| |
|:---|
| **contracts/comps/books/cashier/ICashier.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../center/utils/MockUSDC/IUSDC.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/WaterfallsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#6a9955;">/// @title ICashier</font>
<font style="color:#6a9955;">/// @notice Cashier interface for USDC custody, transfers, and waterfall distributions.</font>
<font style="color:#569cd6;">interface</font> ICashier {

    <font style="color:#569cd6;">struct</font> TransferAuth{
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>;
        <font style="color:#4ec9b0;">address</font> to;
        <font style="color:#4ec9b0;">uint256</font> value;
        <font style="color:#4ec9b0;">uint256</font> validAfter;
        <font style="color:#4ec9b0;">uint256</font> validBefore;
        <font style="color:#4ec9b0;">bytes32</font> nonce;
        <font style="color:#4ec9b0;">uint8</font> v;
        <font style="color:#4ec9b0;">bytes32</font> r;
        <font style="color:#4ec9b0;">bytes32</font> s;
    }

    <font style="color:#6a9955;">//######################</font>
    <font style="color:#6a9955;">//##   Error & Event  ##</font>
    <font style="color:#6a9955;">//######################</font>

    <font style="color:#569cd6;">error</font> Cashier_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> Cashier_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> Cashier_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> Cashier_TransferFailed(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when USDC is received into the contract.</font>
    <font style="color:#6a9955;">/// @param from Sender address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">event</font> ReceiveUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> remark);

    <font style="color:#6a9955;">/// @notice Emitted when USDC is forwarded from one address to another.</font>
    <font style="color:#6a9955;">/// @param from Sender address.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">event</font> ForwardUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark);

    <font style="color:#6a9955;">/// @notice Emitted when USDC is moved into custody ledger.</font>
    <font style="color:#6a9955;">/// @param from Sender address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">event</font> CustodyUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> remark);

    <font style="color:#6a9955;">/// @notice Emitted when USDC is released from custody to a recipient.</font>
    <font style="color:#6a9955;">/// @param from Custody owner.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">event</font> ReleaseUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark);

    <font style="color:#6a9955;">/// @notice Emitted when USDC is transferred from contract balance.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">event</font> TransferUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> remark);

    <font style="color:#6a9955;">/// @notice Emitted when a waterfall class is initialized.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param principal Principal amount.</font>
    <font style="color:#6a9955;">/// @param initDate Initialization date (timestamp).</font>
    <font style="color:#569cd6;">event</font> InitClass(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> principal, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> initDate);

    <font style="color:#6a9955;">/// @notice Emitted when principal is redeemed for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param principal Principal amount.</font>
    <font style="color:#569cd6;">event</font> RedeemClass(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> principal);

    <font style="color:#6a9955;">/// @notice Emitted when profits are distributed.</font>
    <font style="color:#6a9955;">/// @param amt Distribution amount.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#569cd6;">event</font> DistrProfits(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfDR, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfDistr);

    <font style="color:#6a9955;">/// @notice Emitted when income is distributed.</font>
    <font style="color:#6a9955;">/// @param amt Distribution amount.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @param fundManager Fund manager user number.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#569cd6;">event</font> DistrIncome(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfDR, <font style="color:#4ec9b0;">uint</font> fundManager, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfDistr);

    <font style="color:#6a9955;">/// @notice Emitted when a user deposit is recorded.</font>
    <font style="color:#6a9955;">/// @param amt Amount in smallest unit.</font>
    <font style="color:#6a9955;">/// @param user User number.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">event</font> DepositUsd(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> user, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> remark);

    <font style="color:#6a9955;">/// @notice Emitted when a user picks up USDC.</font>
    <font style="color:#6a9955;">/// @param msgSender Message sender.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#6a9955;">/// @param value Amount in smallest unit.</font>
    <font style="color:#569cd6;">event</font> PickupUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> msgSender, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> caller, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> value);

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">/// @notice Collect USDC from `auth.from` into custody.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization (EIP-3009 style).</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">function</font> collectUsd(TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Forward USDC from `auth.from` to `to`.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">function</font> forwardUsd(TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add USDC into custody ledger using authorization.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">function</font> custodyUsd(TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Release USDC from custody to a recipient.</font>
    <font style="color:#6a9955;">/// @param from Custody owner.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in USDC smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">function</font> releaseUsd(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Transfer USDC from contract balance to recipient.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param amt Amount in USDC smallest unit.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">function</font> transferUsd(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Initialize waterfall class with principal.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param principal Principal amount.</font>
    <font style="color:#569cd6;">function</font> initClass(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> principal) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Redeem principal for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param principal Principal amount.</font>
    <font style="color:#569cd6;">function</font> redeemClass(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> principal) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Distribute profits by waterfall rule.</font>
    <font style="color:#6a9955;">/// @param amt Amount in USDC smallest unit.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @return mlist Member drops list.</font>
    <font style="color:#569cd6;">function</font> distrProfits(<font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> seqOfDR) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> mlist
    );

    <font style="color:#6a9955;">/// @notice Distribute income with manager carry.</font>
    <font style="color:#6a9955;">/// @param amt Amount in USDC smallest unit.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @param para Extra parameter (e.g., fundManager id).</font>
    <font style="color:#6a9955;">/// @return mlist Member drops list.</font>
    <font style="color:#6a9955;">/// @return slist Share drops list.</font>
    <font style="color:#569cd6;">function</font> distrIncome(<font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> seqOfDR, <font style="color:#4ec9b0;">uint</font> para) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> mlist, WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> slist
    );

    <font style="color:#6a9955;">/// @notice Deposit USDC into user escrow.</font>
    <font style="color:#6a9955;">/// @param amt Amount in USDC smallest unit.</font>
    <font style="color:#6a9955;">/// @param user User number.</font>
    <font style="color:#6a9955;">/// @param remark Business remark.</font>
    <font style="color:#569cd6;">function</font> depositUsd(<font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> user, <font style="color:#4ec9b0;">bytes32</font> remark) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Withdraw caller's escrow balance.</font>
    <font style="color:#569cd6;">function</font> pickupUsd() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Get custody balance of an address.</font>
    <font style="color:#6a9955;">/// @param acct Account address.</font>
    <font style="color:#6a9955;">/// @return Balance in USDC smallest unit.</font>
    <font style="color:#569cd6;">function</font> custodyOf(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get total escrowed amount.</font>
    <font style="color:#6a9955;">/// @return Total escrow in USDC smallest unit.</font>
    <font style="color:#569cd6;">function</font> totalEscrow() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get total deposits amount.</font>
    <font style="color:#6a9955;">/// @return Total deposits in USDC smallest unit.</font>
    <font style="color:#569cd6;">function</font> totalDeposits() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get deposit of a user.</font>
    <font style="color:#6a9955;">/// @param user User number.</font>
    <font style="color:#6a9955;">/// @return Deposit in USDC smallest unit.</font>
    <font style="color:#569cd6;">function</font> depositOfMine(<font style="color:#4ec9b0;">uint</font> user) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get contract USDC balance.</font>
    <font style="color:#6a9955;">/// @return Balance in USDC smallest unit.</font>
    <font style="color:#569cd6;">function</font> balanceOfComp() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">// ==== Waterfalls Distribution ====</font>

    <font style="color:#6a9955;">// ---- Drop ----</font>

    <font style="color:#6a9955;">/// @notice Get a specific drop by path.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return drop Drop record.</font>
    <font style="color:#569cd6;">function</font> getDrop(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop);

    <font style="color:#6a9955;">// ---- Flow ----</font>

    <font style="color:#6a9955;">/// @notice Get flow summary info.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return info Flow summary drop.</font>
    <font style="color:#569cd6;">function</font> getFlowInfo(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get drops in a flow.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return list Drop list.</font>
    <font style="color:#569cd6;">function</font> getDropsOfFlow(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">// ---- Creek ----</font>

    <font style="color:#6a9955;">/// @notice Get creek summary info.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @return info Creek summary drop.</font>
    <font style="color:#569cd6;">function</font> getCreekInfo(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get drops in a creek.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @return list Drop list.</font>
    <font style="color:#569cd6;">function</font> getDropsOfCreek(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">// ---- Stream ----</font>

    <font style="color:#6a9955;">/// @notice Get stream summary info.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @return info Stream summary drop.</font>
    <font style="color:#569cd6;">function</font> getStreamInfo(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get creeks in a stream.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @return list Creek drops list.</font>
    <font style="color:#569cd6;">function</font> getCreeksOfStream(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">/// @notice Get all drops in a stream.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @return list Drop list.</font>
    <font style="color:#569cd6;">function</font> getDropsOfStream(
        <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">// ==== Waterfalls Member ====</font>

    <font style="color:#6a9955;">/// @notice Get pool info for member/class.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return drop Pool info.</font>
    <font style="color:#569cd6;">function</font> getPoolInfo(
        <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop);

    <font style="color:#6a9955;">/// @notice Get lake info for member.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @return drop Lake info.</font>
    <font style="color:#569cd6;">function</font> getLakeInfo(
        <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop);

    <font style="color:#6a9955;">// ==== Waterfalls Class ====</font>

    <font style="color:#6a9955;">/// @notice Get initial sea info for class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return info Sea info.</font>
    <font style="color:#569cd6;">function</font> getInitSeaInfo(
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get sea info for class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return info Sea info.</font>
    <font style="color:#569cd6;">function</font> getSeaInfo(
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get gulf info for class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return info Gulf info.</font>
    <font style="color:#569cd6;">function</font> getGulfInfo(
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get island info for class and distribution.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @return info Island info.</font>
    <font style="color:#569cd6;">function</font> getIslandInfo(
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info);

    <font style="color:#6a9955;">/// @notice Get list of classes in waterfall.</font>
    <font style="color:#6a9955;">/// @return list Class ids.</font>
    <font style="color:#569cd6;">function</font> getListOfClasses() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">/// @notice Get sea info list for all classes.</font>
    <font style="color:#6a9955;">/// @return list Sea info list.</font>
    <font style="color:#569cd6;">function</font> getAllSeasInfo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list
    );

    <font style="color:#6a9955;">// ==== Waterfalls Sum ====</font>

    <font style="color:#6a9955;">/// @notice Get ocean summary info.</font>
    <font style="color:#6a9955;">/// @return info Ocean info.</font>
    <font style="color:#569cd6;">function</font> getOceanInfo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> info
    );

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IListOfOrders.sol

---

| |
|:---|
| **contracts/comps/books/loo/IListOfOrders.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/UsdOrdersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/GoldChain.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/InvestorsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title IListOfOrders</font>
<font style="color:#6a9955;">/// @notice Order book interface for USD orders and matching results.</font>
<font style="color:#569cd6;">interface</font> IListOfOrders {

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##   Events   ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a new order is placed.</font>
    <font style="color:#6a9955;">/// @param fromSn From-order serial number.</font>
    <font style="color:#6a9955;">/// @param toSn To-order serial number.</font>
    <font style="color:#6a9955;">/// @param qtySn Quantity serial number.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer, false for bid.</font>
    <font style="color:#569cd6;">event</font> OrderPlaced(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> toSn, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> qtySn, <font style="color:#4ec9b0;">bool</font> isOffer);

    <font style="color:#6a9955;">/// @notice Emitted when an order is withdrawn.</font>
    <font style="color:#6a9955;">/// @param head Order head serial number.</font>
    <font style="color:#6a9955;">/// @param body Order body serial number.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer, false for bid.</font>
    <font style="color:#569cd6;">event</font> OrderWithdrawn(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> head, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> body, <font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">indexed</font> isOffer);

    <font style="color:#6a9955;">/// @notice Emitted when a deal is closed from matching orders.</font>
    <font style="color:#6a9955;">/// @param fromSn From-order serial number.</font>
    <font style="color:#6a9955;">/// @param toSn To-order serial number.</font>
    <font style="color:#6a9955;">/// @param qtySn Quantity serial number.</font>
    <font style="color:#6a9955;">/// @param consideration Deal consideration.</font>
    <font style="color:#569cd6;">event</font> DealClosed(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> consideration);

    <font style="color:#6a9955;">/// @notice Emitted when an order expires.</font>
    <font style="color:#6a9955;">/// @param head Order head serial number.</font>
    <font style="color:#6a9955;">/// @param body Order body serial number.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer, false for bid.</font>
    <font style="color:#569cd6;">event</font> OrderExpired(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> head, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> body, <font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">indexed</font> isOffer);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Match and/or place a sell offer.</font>
    <font style="color:#6a9955;">/// @param input Offer data.</font>
    <font style="color:#6a9955;">/// @param execHours Expiration in hours.</font>
    <font style="color:#6a9955;">/// @return deals Matched deals.</font>
    <font style="color:#6a9955;">/// @return lenOfDeals Number of valid deals.</font>
    <font style="color:#6a9955;">/// @return expired Expired orders.</font>
    <font style="color:#6a9955;">/// @return lenOfExpired Number of expired orders.</font>
    <font style="color:#6a9955;">/// @return offer Remaining offer.</font>
    <font style="color:#569cd6;">function</font> placeSellOrder(
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> offer
    );

    <font style="color:#6a9955;">/// @notice Match and/or place a buy bid.</font>
    <font style="color:#6a9955;">/// @param input Bid data.</font>
    <font style="color:#6a9955;">/// @param execHours Expiration in hours.</font>
    <font style="color:#6a9955;">/// @return deals Matched deals.</font>
    <font style="color:#6a9955;">/// @return lenOfDeals Number of valid deals.</font>
    <font style="color:#6a9955;">/// @return expired Expired orders.</font>
    <font style="color:#6a9955;">/// @return lenOfExpired Number of expired orders.</font>
    <font style="color:#6a9955;">/// @return bid Remaining bid.</font>
    <font style="color:#569cd6;">function</font> placeBuyOrder(
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (
        UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> bid
    );

    <font style="color:#6a9955;">/// @notice Withdraw an order.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return order Removed order.</font>
    <font style="color:#569cd6;">function</font> withdrawOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(GoldChain.Order <font style="color:#569cd6;">memory</font> order);

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Deals ====</font>

    <font style="color:#6a9955;">/// @notice Get order counter.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Counter value.</font>
    <font style="color:#569cd6;">function</font> counterOfOrders(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get head order id.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Order id.</font>
    <font style="color:#569cd6;">function</font> headOfList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get tail order id.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Order id.</font>
    <font style="color:#569cd6;">function</font> tailOfList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get order list length.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Length.</font>
    <font style="color:#569cd6;">function</font> lengthOfList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get order sequence list.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Order ids.</font>
    <font style="color:#569cd6;">function</font> getSeqList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an order exists.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> seqOfOrder, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get order by sequence.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Order record.</font>
    <font style="color:#569cd6;">function</font> getOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> seqOfOrder, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get all orders in a book.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book.</font>
    <font style="color:#6a9955;">/// @return Order list.</font>
    <font style="color:#569cd6;">function</font> getOrders(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Class ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a class exists in LOO.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @return True if listed.</font>
    <font style="color:#569cd6;">function</font> isClass(<font style="color:#4ec9b0;">uint</font> classOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get list of listed classes.</font>
    <font style="color:#6a9955;">/// @return Class ids.</font>
    <font style="color:#569cd6;">function</font> getClassesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ListOfOrders.sol

---

| |
|:---|
| **contracts/comps/books/loo/ListOfOrders.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IListOfOrders.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> ListOfOrders <font style="color:#569cd6;">is</font> IListOfOrders, AccessControl {
    <font style="color:#569cd6;">using</font> UsdOrdersRepo <font style="color:#569cd6;">for</font> UsdOrdersRepo.Repo;
    <font style="color:#569cd6;">using</font> UsdOrdersRepo <font style="color:#569cd6;">for</font> UsdOrdersRepo.Deal;
    <font style="color:#569cd6;">using</font> GoldChain <font style="color:#569cd6;">for</font> GoldChain.Chain;
    <font style="color:#569cd6;">using</font> GoldChain <font style="color:#569cd6;">for</font> GoldChain.Node;
    <font style="color:#569cd6;">using</font> GoldChain <font style="color:#569cd6;">for</font> GoldChain.Data;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">// class of share => order book for the class</font>
    <font style="color:#569cd6;">mapping</font> (<font style="color:#4ec9b0;">uint</font> => UsdOrdersRepo.Repo) <font style="color:#569cd6;">private</font> _ordersOfClass;
    <font style="color:#6a9955;">// List of classes traded in this order book.</font>
    EnumerableSet.UintSet <font style="color:#569cd6;">private</font> _classesList;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#569cd6;">function</font> placeSellOrder(
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(
        UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> offer
    ) {
        _classesList.add(input.classOfShare);

        (deals, lenOfDeals, expired, lenOfExpired, offer) =
            _ordersOfClass[input.classOfShare].placeSellOrder(
                input,
                execHours
            );

        <font style="color:#569cd6;">if</font> (lenOfDeals > <font style="color:#b5cea8;">0</font>) _logDeals(deals, lenOfDeals);
        <font style="color:#569cd6;">if</font> (lenOfExpired > <font style="color:#b5cea8;">0</font>) _logExpired(expired, <font style="color:#569cd6;">false</font>, lenOfExpired);
        <font style="color:#569cd6;">if</font> (offer.price > <font style="color:#b5cea8;">0</font>) _logOrder(offer, <font style="color:#569cd6;">true</font>);
    }

    <font style="color:#569cd6;">function</font> _bpToDt(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> amt * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">10</font>;
    }

    <font style="color:#569cd6;">function</font> _logOrder(UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> order, <font style="color:#4ec9b0;">bool</font> isOffer) <font style="color:#569cd6;">private</font> {
        (<font style="color:#4ec9b0;">bytes32</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn) = order.codifyDeal();
        <font style="color:#569cd6;">emit</font> OrderPlaced(fromSn, toSn, qtySn, isOffer);
    }

    <font style="color:#569cd6;">function</font> _logDeals(UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals, <font style="color:#4ec9b0;">uint</font> len) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            (<font style="color:#4ec9b0;">bytes32</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn) =
                deals[len - <font style="color:#b5cea8;">1</font>].codifyDeal();
            <font style="color:#569cd6;">emit</font> DealClosed(fromSn, toSn, qtySn, _bpToDt(deals[len - <font style="color:#b5cea8;">1</font>].consideration));
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> _logExpired(GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired, <font style="color:#4ec9b0;">bool</font> isOffer, <font style="color:#4ec9b0;">uint</font> len) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">emit</font> OrderExpired(expired[len - <font style="color:#b5cea8;">1</font>].node.codifyNode(),
                expired[len - <font style="color:#b5cea8;">1</font>].data.codifyData(), isOffer);
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> placeBuyOrder(
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (
        UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> bid
    ) {

        _classesList.add(input.classOfShare);

        (deals, lenOfDeals, expired, lenOfExpired, bid) =
            _ordersOfClass[input.classOfShare].placeBuyOrder(
                input,
                execHours
            );

        <font style="color:#569cd6;">if</font> (lenOfDeals > <font style="color:#b5cea8;">0</font>) _logDeals(deals, lenOfDeals);
        <font style="color:#569cd6;">if</font> (lenOfExpired > <font style="color:#b5cea8;">0</font>) _logExpired(expired, <font style="color:#569cd6;">true</font>, lenOfExpired);
        <font style="color:#569cd6;">if</font> (bid.price > <font style="color:#b5cea8;">0</font>) _logOrder(bid, <font style="color:#569cd6;">false</font>);
    }

    <font style="color:#569cd6;">function</font> withdrawOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> seqOfOrder, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(GoldChain.Order <font style="color:#569cd6;">memory</font> order) {

        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> order;

        order = _ordersOfClass[classOfShare].withdrawOrder(
            seqOfOrder, isOffer
        );

        <font style="color:#569cd6;">emit</font> OrderWithdrawn(
            order.node.codifyNode(), order.data.codifyData(), isOffer
        );
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Chain ====</font>

    <font style="color:#569cd6;">function</font> counterOfOrders(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">return</font> _ordersOfClass[classOfShare].counterOfOrders(isOffer);
    }

    <font style="color:#569cd6;">function</font> headOfList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">return</font> _ordersOfClass[classOfShare].headOfList(isOffer);
    }

    <font style="color:#569cd6;">function</font> tailOfList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">return</font> _ordersOfClass[classOfShare].tailOfList(isOffer);
    }

    <font style="color:#569cd6;">function</font> lengthOfList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">return</font> _ordersOfClass[classOfShare].lengthOfList(isOffer);
    }

    <font style="color:#569cd6;">function</font> getSeqList(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> list;
        list = _ordersOfClass[classOfShare].getSeqList(isOffer);
    }

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#569cd6;">function</font> isOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> seqOfOrder, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        <font style="color:#569cd6;">return</font> _ordersOfClass[classOfShare].isOrder(isOffer, seqOfOrder);
    }

    <font style="color:#569cd6;">function</font> getOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> seqOfOrder, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order <font style="color:#569cd6;">memory</font> order) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> order;
        order = _ordersOfClass[classOfShare].getOrder(isOffer, seqOfOrder);
    }

    <font style="color:#569cd6;">function</font> getOrders(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order[] <font style="color:#569cd6;">memory</font> list) {
        <font style="color:#569cd6;">if</font> (!_classesList.contains(classOfShare)) <font style="color:#569cd6;">return</font> list;
        list = _ordersOfClass[classOfShare].getOrders(isOffer);
    }

    <font style="color:#6a9955;">// ==== Class ====</font>
    <font style="color:#569cd6;">function</font> isClass(<font style="color:#4ec9b0;">uint</font> classOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _classesList.contains(classOfShare);
    }

    <font style="color:#569cd6;">function</font> getClassesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _classesList.values();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IInvestmentAgreement.sol

---

| |
|:---|
| **contracts/comps/books/roa/IInvestmentAgreement.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/DealsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/ISigPage.sol"</font>;

<font style="color:#6a9955;">/// @title IInvestmentAgreement</font>
<font style="color:#6a9955;">/// @notice Investment agreement interface for deal lifecycle and swaps.</font>
<font style="color:#569cd6;">interface</font> IInvestmentAgreement <font style="color:#569cd6;">is</font> ISigPage {

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Event     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a deal is registered.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">event</font> RegDeal(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfDeal);

    <font style="color:#6a9955;">/// @notice Emitted when deal conditions precedent are cleared.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock for closing.</font>
    <font style="color:#6a9955;">/// @param closingDeadline Closing deadline timestamp.</font>
    <font style="color:#569cd6;">event</font> ClearDealCP(
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seq,
        <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> closingDeadline
    );

    <font style="color:#6a9955;">/// @notice Emitted when a deal is closed.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Hash key for closing.</font>
    <font style="color:#569cd6;">event</font> CloseDeal(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seq, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">indexed</font> hashKey);

    <font style="color:#6a9955;">/// @notice Emitted when a deal is terminated.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#569cd6;">event</font> TerminateDeal(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seq);

    <font style="color:#6a9955;">/// @notice Emitted when an approved deal is paid off.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param msgValue Payment value.</font>
    <font style="color:#569cd6;">event</font> PayOffApprovedDeal(<font style="color:#4ec9b0;">uint</font> seqOfDeal, <font style="color:#4ec9b0;">uint</font> msgValue);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">// ======== InvestmentAgreement ========</font>

    <font style="color:#6a9955;">/// @notice Add a deal from packed head and params.</font>
    <font style="color:#6a9955;">/// @param sn Packed deal head.</font>
    <font style="color:#6a9955;">/// @param buyer Buyer user number.</font>
    <font style="color:#6a9955;">/// @param groupOfBuyer Buyer group number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight.</font>
    <font style="color:#569cd6;">function</font> addDeal(
        <font style="color:#4ec9b0;">bytes32</font> sn,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> groupOfBuyer,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> distrWeight
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Register a deal record.</font>
    <font style="color:#6a9955;">/// @param deal Deal record.</font>
    <font style="color:#6a9955;">/// @return seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> regDeal(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font> seqOfDeal);

    <font style="color:#6a9955;">/// @notice Delete a deal by sequence.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#569cd6;">function</font> delDeal(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Lock a deal subject.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @return flag True if locked.</font>
    <font style="color:#569cd6;">function</font> lockDealSubject(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Release a deal subject.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @return flag True if released.</font>
    <font style="color:#569cd6;">function</font> releaseDealSubject(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Clear a deal with hash lock and deadline.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#6a9955;">/// @param closingDeadline Closing deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> clearDealCP( <font style="color:#4ec9b0;">uint256</font> seq, <font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">uint</font> closingDeadline) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Close a deal using hash preimage.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Preimage string.</font>
    <font style="color:#6a9955;">/// @return flag True if closed.</font>
    <font style="color:#569cd6;">function</font> closeDeal(<font style="color:#4ec9b0;">uint256</font> seq, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Close a locked deal directly.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @return flag True if closed.</font>
    <font style="color:#569cd6;">function</font> directCloseDeal(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Terminate a deal.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return True if terminated.</font>
    <font style="color:#569cd6;">function</font> terminateDeal(<font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Accept a free-gift deal.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @return True if accepted.</font>
    <font style="color:#569cd6;">function</font> takeGift(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Finalize the investment agreement.</font>
    <font style="color:#569cd6;">function</font> finalizeIA() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Pay off an approved deal.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param msgValue Paid value.</font>
    <font style="color:#6a9955;">/// @param caller Buyer user number.</font>
    <font style="color:#6a9955;">/// @return flag True if closed.</font>
    <font style="color:#569cd6;">function</font> payOffApprovedDeal(
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> msgValue,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Request price difference for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> requestPriceDiff(
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//  #####################</font>
    <font style="color:#6a9955;">//  ##     Read I/O    ##</font>
    <font style="color:#6a9955;">//  #####################</font>

    <font style="color:#6a9955;">// ======== InvestmentAgreement ========</font>
    <font style="color:#6a9955;">/// @notice Get composite IA type.</font>
    <font style="color:#6a9955;">/// @return Type code.</font>
    <font style="color:#569cd6;">function</font> getTypeOfIA() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>);

    <font style="color:#6a9955;">/// @notice Get deal by sequence.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#6a9955;">/// @return Deal record.</font>
    <font style="color:#569cd6;">function</font> getDeal(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DealsRepo.Deal <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get deal sequence list.</font>
    <font style="color:#6a9955;">/// @return Deal ids.</font>
    <font style="color:#569cd6;">function</font> getSeqList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## InvestmentAgreement.sol

---

| |
|:---|
| **contracts/comps/books/roa/InvestmentAgreement.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/SigPage.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IInvestmentAgreement.sol"</font>;

<font style="color:#569cd6;">contract</font> InvestmentAgreement <font style="color:#569cd6;">is</font> IInvestmentAgreement, SigPage {
    <font style="color:#569cd6;">using</font> DealsRepo <font style="color:#569cd6;">for</font> DealsRepo.Repo;
    <font style="color:#569cd6;">using</font> SigsRepo <font style="color:#569cd6;">for</font> SigsRepo.Page;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    DealsRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#569cd6;">function</font> addDeal(
        <font style="color:#4ec9b0;">bytes32</font> sn,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> groupOfBuyer,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> distrWeight
    ) <font style="color:#569cd6;">external</font> onlyAttorney {
        _repo.addDeal(sn, buyer, groupOfBuyer, paid, par, distrWeight);
    }

    <font style="color:#569cd6;">function</font> regDeal(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal)
        <font style="color:#569cd6;">external</font> attorneyOrGK <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font> seqOfDeal)
    {
        seqOfDeal = _repo.regDeal(deal);

        <font style="color:#569cd6;">if</font> (!isFinalized()) {
            <font style="color:#569cd6;">if</font> (deal.head.seller != <font style="color:#b5cea8;">0</font>) _sigPages[<font style="color:#b5cea8;">0</font>].addBlank(<font style="color:#569cd6;">false</font>, seqOfDeal, deal.head.seller);
            _sigPages[<font style="color:#b5cea8;">0</font>].addBlank(<font style="color:#569cd6;">true</font>, seqOfDeal, deal.body.buyer);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (deal.head.seller != <font style="color:#b5cea8;">0</font>) _sigPages[<font style="color:#b5cea8;">1</font>].addBlank(<font style="color:#569cd6;">false</font>, seqOfDeal, deal.head.seller);
            _sigPages[<font style="color:#b5cea8;">1</font>].addBlank(<font style="color:#569cd6;">true</font>, seqOfDeal, deal.body.buyer);
        }

        <font style="color:#569cd6;">emit</font> RegDeal(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> delDeal(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> onlyAttorney {

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _repo.deals[seq];

        <font style="color:#569cd6;">if</font> (_repo.delDeal(seq)) {
            <font style="color:#569cd6;">if</font> (deal.head.seller != <font style="color:#b5cea8;">0</font>) {
                _sigPages[<font style="color:#b5cea8;">0</font>].removeBlank(deal.head.seqOfDeal, deal.head.seller);
            }
            _sigPages[<font style="color:#b5cea8;">0</font>].removeBlank(deal.head.seqOfDeal, deal.body.buyer);
        }
    }

    <font style="color:#569cd6;">function</font> lockDealSubject(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = _repo.lockDealSubject(seq);
    }

    <font style="color:#569cd6;">function</font> releaseDealSubject(<font style="color:#4ec9b0;">uint256</font> seq)
        <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _repo.releaseDealSubject(seq);
    }

    <font style="color:#569cd6;">function</font> clearDealCP(
        <font style="color:#4ec9b0;">uint256</font> seq,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> closingDeadline
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.clearDealCP(seq, hashLock, closingDeadline);
        <font style="color:#569cd6;">emit</font> ClearDealCP(seq, hashLock, closingDeadline);
    }

    <font style="color:#569cd6;">function</font> closeDeal(<font style="color:#4ec9b0;">uint256</font> seq, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey)
        <font style="color:#569cd6;">external</font>
        onlyKeeper
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _repo.closeDeal(seq, hashKey);
        <font style="color:#569cd6;">emit</font> CloseDeal(seq, hashKey);
    }

    <font style="color:#569cd6;">function</font> directCloseDeal(<font style="color:#4ec9b0;">uint256</font> seq)
        <font style="color:#569cd6;">external</font>
        onlyKeeper
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _repo.directCloseDeal(seq);
        <font style="color:#569cd6;">emit</font> CloseDeal(seq, <font style="color:#ce9178;">''</font>);
    }

    <font style="color:#569cd6;">function</font> terminateDeal(<font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _repo.terminateDeal(seqOfDeal);
        <font style="color:#569cd6;">emit</font> TerminateDeal(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> takeGift(<font style="color:#4ec9b0;">uint256</font> seq)
        <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _repo.takeGift(seq);
        <font style="color:#569cd6;">emit</font> CloseDeal(seq, <font style="color:#ce9178;">"0"</font>);
    }

    <font style="color:#569cd6;">function</font> finalizeIA() <font style="color:#569cd6;">external</font> {
        _repo.calTypeOfIA();
        lockContents();
    }

    <font style="color:#569cd6;">function</font> payOffApprovedDeal(
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> msgValue,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag){
        flag = _repo.payOffApprovedDeal(seqOfDeal, caller);
        <font style="color:#569cd6;">emit</font> PayOffApprovedDeal(seqOfDeal, msgValue);
    }

    <font style="color:#569cd6;">function</font> requestPriceDiff(
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.requestPriceDiff(seqOfDeal, seqOfShare);
    }

    <font style="color:#6a9955;">//  #################################</font>
    <font style="color:#6a9955;">//  ##       Read I/O              ##</font>
    <font style="color:#6a9955;">//  #################################</font>

    <font style="color:#569cd6;">function</font> getTypeOfIA() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {
        <font style="color:#569cd6;">return</font> _repo.getTypeOfIA();
    }

    <font style="color:#569cd6;">function</font> getDeal(<font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DealsRepo.Deal <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getDeal(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> getSeqList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSeqList();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfAgreements.sol

---

| |
|:---|
| **contracts/comps/books/roa/IRegisterOfAgreements.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/IFilesFolder.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IInvestmentAgreement.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/DTClaims.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/FRClaims.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/TopChain.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfAgreements</font>
<font style="color:#6a9955;">/// @notice Interface for claims handling and IA result mocking.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfAgreements <font style="color:#569cd6;">is</font> IFilesFolder {

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Error    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#569cd6;">error</font> ROA_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Event    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a first-refusal claim is submitted.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param caller Claimer user number.</font>
    <font style="color:#569cd6;">event</font> ClaimFirstRefusal(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> ia, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> caller);

    <font style="color:#6a9955;">/// @notice Emitted when along claims are accepted for a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">event</font> AcceptAlongClaims(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> ia, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfDeal);

    <font style="color:#6a9955;">/// @notice Emitted when an along right is executed.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param snOfDTClaim Drag/tag claim serial number.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">event</font> ExecAlongRight(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> ia, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfDTClaim, <font style="color:#4ec9b0;">bytes32</font> sigHash);

    <font style="color:#6a9955;">/// @notice Emitted when first-refusal result is computed.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">event</font> ComputeFirstRefusal(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> ia, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfDeal);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ======== RegisterOfAgreements ========</font>

    <font style="color:#6a9955;">/// @notice Submit a first-refusal claim for an IA deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param caller Claimer user number.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> claimFirstRefusal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint256</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Compute first-refusal allocation ratios.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return output Claims list with weights/ratios.</font>
    <font style="color:#569cd6;">function</font> computeFirstRefusal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (FRClaims.Claim[] <font style="color:#569cd6;">memory</font> output);

    <font style="color:#6a9955;">/// @notice Execute drag/tag along right claim.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param snOfClaim Encoded claim head.</font>
    <font style="color:#6a9955;">// / @param dragAlong True for drag-along.</font>
    <font style="color:#6a9955;">// / @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">// / @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">// / @param paid Paid amount.</font>
    <font style="color:#6a9955;">// / @param par Par amount.</font>
    <font style="color:#6a9955;">// / @param caller Claimer user number.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> execAlongRight(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> snOfClaim,
        <font style="color:#6a9955;">// bool dragAlong,</font>
        <font style="color:#6a9955;">// uint256 seqOfDeal,</font>
        <font style="color:#6a9955;">// uint256 seqOfShare,</font>
        <font style="color:#6a9955;">// uint paid,</font>
        <font style="color:#6a9955;">// uint par,</font>
        <font style="color:#6a9955;">// uint256 caller,</font>
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Accept all along claims for a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return Claims list.</font>
    <font style="color:#569cd6;">function</font> acceptAlongClaims(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(DTClaims.Claim[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Create mock results for an IA.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#569cd6;">function</font> createMockOfIA(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== FR Claims ====</font>

    <font style="color:#6a9955;">/// @notice Check if FR claims exist for a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> hasFRClaims(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint</font> seqOfDeal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check if account has any FR claim.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return True if claimed.</font>
    <font style="color:#569cd6;">function</font> isFRClaimer(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get deal list with FR claims.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @return Deal list.</font>
    <font style="color:#569cd6;">function</font> getSubjectDealsOfFR(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get FR claims of a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return Claims list.</font>
    <font style="color:#569cd6;">function</font> getFRClaimsOfDeal(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(FRClaims.Claim[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether all FR claims are accepted.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @return True if all accepted.</font>
    <font style="color:#569cd6;">function</font> allFRClaimsAccepted(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== DT Claims ====</font>

    <font style="color:#6a9955;">/// @notice Check if DT claims exist for a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> hasDTClaims(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get deal list with DT claims.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @return Deal list.</font>
    <font style="color:#569cd6;">function</font> getSubjectDealsOfDT(<font style="color:#4ec9b0;">address</font> ia)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get DT claims of a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @return Claims list.</font>
    <font style="color:#569cd6;">function</font> getDTClaimsOfDeal(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DTClaims.Claim[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get DT claim for a share.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return Claim record.</font>
    <font style="color:#569cd6;">function</font> getDTClaimForShare(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DTClaims.Claim <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether all DT claims are accepted.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @return True if all accepted.</font>
    <font style="color:#569cd6;">function</font> allDTClaimsAccepted(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== Mock Results ====</font>

    <font style="color:#6a9955;">/// @notice Get mock results for IA.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @return controllor Controller user number.</font>
    <font style="color:#6a9955;">/// @return ratio Ratio (0-10000).</font>
    <font style="color:#569cd6;">function</font> mockResultsOfIA(<font style="color:#4ec9b0;">address</font> ia)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font> controllor, <font style="color:#4ec9b0;">uint16</font> ratio);

    <font style="color:#6a9955;">/// @notice Get mock results for account.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return groupRep Group representative.</font>
    <font style="color:#6a9955;">/// @return ratio Ratio (0-10000).</font>
    <font style="color:#569cd6;">function</font> mockResultsOfAcct(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font> groupRep, <font style="color:#4ec9b0;">uint16</font> ratio);

    <font style="color:#6a9955;">// ==== AllClaimsAccepted ====</font>

    <font style="color:#6a9955;">/// @notice Check whether all claims are accepted.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @return True if all accepted.</font>
    <font style="color:#569cd6;">function</font> allClaimsAccepted(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfAgreements.sol

---

| |
|:---|
| **contracts/comps/books/roa/RegisterOfAgreements.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfAgreements.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/FilesFolder.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfAgreements <font style="color:#569cd6;">is</font> IRegisterOfAgreements, FilesFolder {
    <font style="color:#569cd6;">using</font> DTClaims <font style="color:#569cd6;">for</font> DTClaims.Claims;
    <font style="color:#569cd6;">using</font> DTClaims <font style="color:#569cd6;">for</font> DTClaims.Head;
    <font style="color:#569cd6;">using</font> FRClaims <font style="color:#569cd6;">for</font> FRClaims.Claims;
    <font style="color:#569cd6;">using</font> FilesRepo <font style="color:#569cd6;">for</font> FilesRepo.Repo;
    <font style="color:#569cd6;">using</font> TopChain <font style="color:#569cd6;">for</font> TopChain.Chain;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// ia => frClaims</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => FRClaims.Claims) <font style="color:#569cd6;">private</font> _frClaims;
    <font style="color:#6a9955;">// ia => dtClaims</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => DTClaims.Claims) <font style="color:#569cd6;">private</font> _dtClaims;
    <font style="color:#6a9955;">// ia => mockResults</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => TopChain.Chain) <font style="color:#569cd6;">private</font> _mockOfIA;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== FirstRefusal ====</font>

    <font style="color:#569cd6;">function</font> claimFirstRefusal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint256</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (block.timestamp >= _repo.frExecDeadline(ia)) {
            <font style="color:#569cd6;">revert</font> ROA_WrongState(<font style="color:#ce9178;">"ROA_MissedDeadline"</font>);
        }
        _frClaims[ia].claimFirstRefusal(seqOfDeal, caller, sigHash);
        <font style="color:#569cd6;">emit</font> ClaimFirstRefusal(ia, seqOfDeal, caller);
    }

    <font style="color:#569cd6;">function</font> computeFirstRefusal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (FRClaims.Claim[] <font style="color:#569cd6;">memory</font> output) {
        <font style="color:#569cd6;">if</font> (block.timestamp < _repo.frExecDeadline(ia)) {
            <font style="color:#569cd6;">revert</font> ROA_WrongState(<font style="color:#ce9178;">"ROA_NotReachedFRDeadline"</font>);
        }
        output = _frClaims[ia].computeFirstRefusal(seqOfDeal, _gk.getROM());
        <font style="color:#569cd6;">emit</font> ComputeFirstRefusal(ia, seqOfDeal);
    }

    <font style="color:#6a9955;">// ==== DragAlong & TagAlong ====</font>

    <font style="color:#569cd6;">function</font> execAlongRight(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> snOfClaim,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (block.timestamp < _repo.frExecDeadline(ia)) {
            <font style="color:#569cd6;">revert</font> ROA_WrongState(<font style="color:#ce9178;">"ROA_NotReachedFRDeadline"</font>);
        }
        <font style="color:#569cd6;">if</font> (block.timestamp >= _repo.dtExecDeadline(ia)) {
            <font style="color:#569cd6;">revert</font> ROA_WrongState(<font style="color:#ce9178;">"ROA_MissedDTDeadline"</font>);
        }

        _dtClaims[ia].execAlongRight(snOfClaim, sigHash);

        <font style="color:#569cd6;">emit</font> ExecAlongRight(ia, snOfClaim, sigHash);
    }

    <font style="color:#569cd6;">function</font> acceptAlongClaims(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(DTClaims.Claim[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (block.timestamp < _repo.dtExecDeadline(ia)) {
            <font style="color:#569cd6;">revert</font> ROA_WrongState(<font style="color:#ce9178;">"ROA_NotReachedDTDeadline"</font>);
        }

        <font style="color:#569cd6;">emit</font> AcceptAlongClaims(ia, seqOfDeal);
        <font style="color:#569cd6;">return</font> _dtClaims[ia].acceptAlongClaims(seqOfDeal);
    }

    <font style="color:#6a9955;">// ==== Mock ====</font>

    <font style="color:#569cd6;">function</font> createMockOfIA(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_mockOfIA[ia].qtyOfMembers() == <font style="color:#b5cea8;">0</font>) {
            (TopChain.Node[] <font style="color:#569cd6;">memory</font> list, TopChain.Para <font style="color:#569cd6;">memory</font> para) =
                _gk.getROM().getSnapshot();
            _mockOfIA[ia].restoreChain(list, para);
            _mockOfIA[ia].mockDealsOfIA(IInvestmentAgreement(ia), _gk.getROS());
        }
    }

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##  Read I/O ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">// ==== FR Claims ====</font>

    <font style="color:#569cd6;">function</font> hasFRClaims(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint</font> seqOfDeal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _frClaims[ia].isDeal(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> isFRClaimer(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _frClaims[ia].isClaimer(acct);
    }

    <font style="color:#569cd6;">function</font> getSubjectDealsOfFR(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _frClaims[ia].getDeals();
    }

    <font style="color:#569cd6;">function</font> getFRClaimsOfDeal(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(FRClaims.Claim[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _frClaims[ia].getClaimsOfDeal(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> allFRClaimsAccepted(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _frClaims[ia].allAccepted();
    }

    <font style="color:#6a9955;">// ==== DT Claims ====</font>

    <font style="color:#569cd6;">function</font> hasDTClaims(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _dtClaims[ia].hasClaim(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> getSubjectDealsOfDT(<font style="color:#4ec9b0;">address</font> ia)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _dtClaims[ia].getDeals();
    }

    <font style="color:#569cd6;">function</font> getDTClaimsOfDeal(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DTClaims.Claim[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _dtClaims[ia].getClaimsOfDeal(seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> getDTClaimForShare(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DTClaims.Claim <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _dtClaims[ia].getClaimForShare(seqOfDeal, seqOfShare);
    }

    <font style="color:#569cd6;">function</font> allDTClaimsAccepted(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _dtClaims[ia].allAccepted();
    }

    <font style="color:#6a9955;">// ==== Mock Results ====</font>

    <font style="color:#569cd6;">function</font> mockResultsOfIA(<font style="color:#4ec9b0;">address</font> ia)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font> controllor, <font style="color:#4ec9b0;">uint16</font> ratio)
    {
        TopChain.Chain <font style="color:#569cd6;">storage</font> mock = _mockOfIA[ia];

        controllor = mock.head();
        ratio = <font style="color:#4ec9b0;">uint16</font> (mock.votesOfGroup(controllor) / mock.totalVotes());
    }

    <font style="color:#569cd6;">function</font> mockResultsOfAcct(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font> groupRep, <font style="color:#4ec9b0;">uint16</font> ratio)
    {
        TopChain.Chain <font style="color:#569cd6;">storage</font> mock = _mockOfIA[ia];

        groupRep = mock.rootOf(acct);
        ratio = <font style="color:#4ec9b0;">uint16</font> (mock.votesOfGroup(groupRep) / mock.totalVotes());
    }

    <font style="color:#6a9955;">// ==== allClaimsAccepted ====</font>

    <font style="color:#569cd6;">function</font> allClaimsAccepted(<font style="color:#4ec9b0;">address</font> ia) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> (_dtClaims[ia].allAccepted() && _frClaims[ia].allAccepted());
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfConstitution.sol

---

| |
|:---|
| **contracts/comps/books/roc/IRegisterOfConstitution.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/IFilesFolder.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfConstitution</font>
<font style="color:#6a9955;">/// @notice Interface for managing the constitution document register.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfConstitution <font style="color:#569cd6;">is</font> IFilesFolder{

    <font style="color:#6a9955;">//##############</font>
    <font style="color:#6a9955;">//##  Event   ##</font>
    <font style="color:#6a9955;">//##############</font>

    <font style="color:#6a9955;">/// @notice Emitted when the active pointer is updated.</font>
    <font style="color:#6a9955;">/// @param pointer New pointer address.</font>
    <font style="color:#569cd6;">event</font> ChangePointer(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> pointer);

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Write  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#6a9955;">/// @notice Update the active pointer to a registered document.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> changePointer(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Get the current pointer address.</font>
    <font style="color:#6a9955;">/// @return Current document pointer address.</font>
    <font style="color:#569cd6;">function</font> pointer() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IShareholdersAgreement.sol

---

| |
|:---|
| **contracts/comps/books/roc/IShareholdersAgreement.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/ISigPage.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/DocsRepo.sol"</font>;

<font style="color:#6a9955;">/// @notice Design notes:</font>
<font style="color:#6a9955;">/// - The implementation is created via BookOfDocs/DocsRepo `cloneDoc()` and is not upgradeable.</font>
<font style="color:#6a9955;">/// - `typeOfDoc` and `version` are validated in RegCenter/BookOfDocs/DocsRepo `cloneDoc()`.</font>
<font style="color:#6a9955;">/// - Overwrites during drafting are allowed by design; before finalization, contents are mutable.</font>
<font style="color:#6a9955;">/// - Finalization calls `lockContents()` (onlyOwner) and revokes the Attorneys role and Owner, so no further edits are possible.</font>
<font style="color:#6a9955;">/// - Drafting changes do not require on-chain state tracking; only finalized Terms/Rules are used by other registers.</font>
<font style="color:#6a9955;">/// - `finalizeSHA()` is intended to be triggered by the Owner after validation, then submitted to shareholder approval;</font>
<font style="color:#6a9955;">///   once effective, Terms/Rules serve as the ledger source for other contracts.</font>
<font style="color:#6a9955;">/// @title IShareholdersAgreement</font>
<font style="color:#6a9955;">/// @notice Interface for terms/rules registry in the Shareholders Agreement.</font>
<font style="color:#569cd6;">interface</font> IShareholdersAgreement <font style="color:#569cd6;">is</font> ISigPage {

    <font style="color:#569cd6;">enum</font> TitleOfTerm {
        ZeroPoint,
        AntiDilution,   <font style="color:#6a9955;">// 1</font>
        LockUp,         <font style="color:#6a9955;">// 2</font>
        DragAlong,      <font style="color:#6a9955;">// 3</font>
        TagAlong,       <font style="color:#6a9955;">// 4</font>
        Options         <font style="color:#6a9955;">// 5</font>
    }

    <font style="color:#6a9955;">// ==== Rules ========</font>

<font style="color:#6a9955;">/*
    |  Seq  |        Type       |    Abb       |            Description                     |  |    0  |  GovernanceRule   |     GR       | Board Constitution and General Rules of GM |  |    1  |  VotingRuleOfGM   |     CI       | VR for Capital Increase                    |  |    2  |  |   SText      | VR for External Share Transfer             |  |    3  |  |   STint      | VR for Internal Share Transfer             |  |    4  |  |    1+3       | VR for CI & STint                          |  |    5  |  |    2+3       | VR for SText & STint                       |  |    6  |  |   1+2+3      | VR for CI & SText & STint                  |  |    7  |  |    1+2       | VR for CI & SText                          |  |    8  |  |   SHA        | VR for Update SHA                          |  |    9  |  |  O-Issue-GM  | VR for Ordinary Issues of GeneralMeeting   |  |   10  |  |  S-Issue-GM  | VR for Special Issues Of GeneralMeeting    |  |   11  | VotingRuleOfBoard |     CI       | VR for Capital Increase                    |  |   12  |  |   SText      | VR for External Share Transfer             |  |   13  |  |   STint      | VR for Internal Share Transfer             |  |   14  |  |    1+3       | VR for CI & STint                          |  |   15  |  |    2+3       | VR for SText & STint                       |  |   16  |  |   1+2+3      | VR for CI & SText & STint                  |  |   17  |  |    1+2       | VR for CI & SText                          |  |   18  |  |   SHA        | VR for Update SHA                          |  |   19  |  |  O-Issue-B   | VR for Ordinary Issues Of Board            |  |   20  |  |  S-Issue-B   | VR for Special Issues Of Board             |  |   21  | UnilateralDecision| UniDecPower  | UnilateralDicisionPowerWithoutVoting       |
    ...

    |  256  | PositionAllocateRule |   PA Rule   | Management Positions' Allocation Rules    |
    ...

    |  512  | FirstRefusalRule  |  FR for CI...| FR rule for Investment Deal                |
    ...

    |  768  | GroupUpdateOrder  |  GroupUpdate | Grouping Members as per their relationship |
    ...

    |  1024 | ListingRule       |  ListingRule | Listing Rule for Share Issue & Transfer    |
    ...

*/</font>

    <font style="color:#569cd6;">struct</font> TermsRepo {
        <font style="color:#6a9955;">// titleOfTerm => body</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#4ec9b0;">address</font>) terms;
        <font style="color:#6a9955;">// Tracking existing term titles for enumeration.</font>
        EnumerableSet.UintSet seqList;
    }

    <font style="color:#569cd6;">struct</font> RulesRepo {
        <font style="color:#6a9955;">// seq => rule</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#4ec9b0;">bytes32</font>) rules;
        <font style="color:#6a9955;">// Tracking existing rule sequences for enumeration.</font>
        EnumerableSet.UintSet seqList;
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##    Error   ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">error</font> SHA_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##     Write    ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/**
     * @dev Create a clone contract as per the template type number (`titleOfTerm`)
     * and its version number (`version`).
     * Note `titleOfTerm` and `version` shall be bigger than zero.
     */</font>
    <font style="color:#6a9955;">/// @notice Create a term clone by type and version.</font>
    <font style="color:#6a9955;">/// @param titleOfTerm Term type identifier (> 0).</font>
    <font style="color:#6a9955;">/// @param version Template version (> 0).</font>
    <font style="color:#569cd6;">function</font> createTerm(<font style="color:#4ec9b0;">uint</font> titleOfTerm, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/**
     * @dev Remove tracking of a clone contract from mapping as per its template
     * type number (`titleOfTerm`).
     */</font>
    <font style="color:#6a9955;">/// @notice Remove a term by type.</font>
    <font style="color:#6a9955;">/// @param titleOfTerm Term type identifier.</font>
    <font style="color:#569cd6;">function</font> removeTerm(<font style="color:#4ec9b0;">uint</font> titleOfTerm) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/**
     * @dev Add a pre-defined `rule` into the Rules Mapping (seqNumber => rule)
     * Note a sequence number (`seqNumber`) of the `rule` SHALL be able to be parsed by
     * RuleParser library, and such `seqNumber` shall be used as the search key to
     * retrieve the rule from the Rules Mapping.
     */</font>
    <font style="color:#6a9955;">/// @notice Add a rule by sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfRule Rule sequence.</font>
    <font style="color:#6a9955;">/// @param rule Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> addRule(<font style="color:#4ec9b0;">uint</font> seqOfRule, <font style="color:#4ec9b0;">bytes32</font> rule) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/**
     * @dev Remove tracking of a rule from the Rules Mapping as per its sequence
     * number (`seq`).
     */</font>
    <font style="color:#6a9955;">/// @notice Remove a rule by sequence.</font>
    <font style="color:#6a9955;">/// @param seq Rule sequence.</font>
    <font style="color:#569cd6;">function</font> removeRule(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/**
     * @dev Initiate the Shareholders Agreement with predefined default rules.
     */</font>
    <font style="color:#6a9955;">/// @notice Initialize default rules.</font>
    <font style="color:#569cd6;">function</font> initDefaultRules() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/**
     * @dev Transfer special Roles having write authorities to address "Zero",
     * so as to fix the contents of the Shareholders Agreement avoiding any further
     * revision by any EOA.
     */</font>
    <font style="color:#6a9955;">/// @notice Finalize SHA and lock contents.</font>
    <font style="color:#569cd6;">function</font> finalizeSHA() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Terms ====</font>

    <font style="color:#6a9955;">/**
     * @dev Returns whether a specific Term numbered as `titleOfTerm` exist
     * in the current Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Check if a term exists.</font>
    <font style="color:#6a9955;">/// @param titleOfTerm Term type identifier.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> hasTitle(<font style="color:#4ec9b0;">uint256</font> titleOfTerm) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns total quantities of Terms in the current
     * Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Get number of terms.</font>
    <font style="color:#6a9955;">/// @return Term count.</font>
    <font style="color:#569cd6;">function</font> qtyOfTerms() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns total quantities of Terms stiputed in the current
     * Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Get term type list.</font>
    <font style="color:#6a9955;">/// @return Term type ids.</font>
    <font style="color:#569cd6;">function</font> getTitles() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns the contract address of the specific Term
     * numbered as `titleOfTerm` from the Terms Mapping of the Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Get term contract address.</font>
    <font style="color:#6a9955;">/// @param titleOfTerm Term type identifier.</font>
    <font style="color:#6a9955;">/// @return Term contract address.</font>
    <font style="color:#569cd6;">function</font> getTerm(<font style="color:#4ec9b0;">uint256</font> titleOfTerm) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">// ==== Rules ====</font>

    <font style="color:#6a9955;">/**
     * @dev Returns whether a specific Rule numbered as `seq` exist
     * in the current Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Check if a rule exists.</font>
    <font style="color:#6a9955;">/// @param seq Rule sequence.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> hasRule(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns total quantities of Rules in the current
     * Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Get number of rules.</font>
    <font style="color:#6a9955;">/// @return Rule count.</font>
    <font style="color:#569cd6;">function</font> qtyOfRules() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns total quantities of Rules stiputed in the current
     * Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Get rule sequence list.</font>
    <font style="color:#6a9955;">/// @return Rule ids.</font>
    <font style="color:#569cd6;">function</font> getRules() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns the specific Rule numbered as `seq` from the Rules Mapping
     * of the Shareholders Agreemnt.
     */</font>
    <font style="color:#6a9955;">/// @notice Get a rule by sequence.</font>
    <font style="color:#6a9955;">/// @param seq Rule sequence.</font>
    <font style="color:#6a9955;">/// @return Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> getRule(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfConstitution.sol

---

| |
|:---|
| **contracts/comps/books/roc/RegisterOfConstitution.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfConstitution.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/FilesFolder.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfConstitution <font style="color:#569cd6;">is</font> IRegisterOfConstitution, FilesFolder {

    <font style="color:#6a9955;">/// @notice Current active constitution document address.</font>
    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">private</font> _pointer;

    <font style="color:#6a9955;">// ==== UUPSUpgradeable ====</font>

    <font style="color:#6a9955;">/// @dev Storage gap for upgrade safety.</font>
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> changePointer(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_pointer != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            setStateOfFile(_pointer, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Revoked));
        _pointer = body;
        <font style="color:#569cd6;">emit</font> ChangePointer(body);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#569cd6;">function</font> pointer() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _pointer;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ShareholdersAgreement.sol

---

| |
|:---|
| **contracts/comps/books/roc/ShareholdersAgreement.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IShareholdersAgreement.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/SigPage.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">contract</font> ShareholdersAgreement <font style="color:#569cd6;">is</font> IShareholdersAgreement, SigPage {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">/// @notice Mapping of term document types to term addresses.</font>
    TermsRepo <font style="color:#569cd6;">private</font> _terms;
    <font style="color:#6a9955;">/// @notice Repository of voting and governance rules.</font>
    RulesRepo <font style="color:#569cd6;">private</font> _rules;

    <font style="color:#569cd6;">function</font> docTypeOfTerm(<font style="color:#4ec9b0;">uint256</font> i) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">if</font> (i == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;               <font style="color:#6a9955;">// ZeroPoint</font>
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (i == <font style="color:#b5cea8;">1</font>) <font style="color:#569cd6;">return</font> 0xe5707158; <font style="color:#6a9955;">// uint32(uint(keccak256("AntiDilution")))</font>
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (i == <font style="color:#b5cea8;">2</font>) <font style="color:#569cd6;">return</font> 0x19f096ac; <font style="color:#6a9955;">// uint32(uint(keccak256("LockUp")))</font>
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (i == <font style="color:#b5cea8;">3</font>) <font style="color:#569cd6;">return</font> 0x4511939f; <font style="color:#6a9955;">// uint32(uint(keccak256("Alongs")))</font>
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (i == <font style="color:#b5cea8;">4</font>) <font style="color:#569cd6;">return</font> 0x4511939f; <font style="color:#6a9955;">// uint32(uint(keccak256("Alongs")))</font>
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (i == <font style="color:#b5cea8;">5</font>) <font style="color:#569cd6;">return</font> 0x755d04a0; <font style="color:#6a9955;">// uint32(uint(keccak256("Options")))</font>
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> SHA_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHA_InvalidTitle"</font>));
    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##    modifier    ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">/// @dev Reverts if the term title does not exist.</font>
    <font style="color:#569cd6;">modifier</font> titleExist(<font style="color:#4ec9b0;">uint256</font> title) {
        <font style="color:#569cd6;">if</font> (!hasTitle(title))
            <font style="color:#569cd6;">revert</font> SHA_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHA_TitleNotExist"</font>));
        _;
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> createTerm(<font style="color:#4ec9b0;">uint</font> titleOfTerm, <font style="color:#4ec9b0;">uint</font> version)
        <font style="color:#569cd6;">external</font>
        onlyGC
    {
        <font style="color:#4ec9b0;">address</font> gc = msg.sender;

        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _rc.getRC().cloneDoc(
            docTypeOfTerm(titleOfTerm),
            version
        );

        IAccessControl(doc.body).initKeepers(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>), _gk);

        IDraftControl(doc.body).setRoleAdmin(
            keccak256(<font style="color:#4ec9b0;">bytes</font>(<font style="color:#ce9178;">"Attorneys"</font>)),
            gc
        );

        _terms.terms[titleOfTerm] = doc.body;
        _terms.seqList.add(titleOfTerm);
    }

    <font style="color:#569cd6;">function</font> removeTerm(<font style="color:#4ec9b0;">uint</font> titleOfTerm) <font style="color:#569cd6;">external</font> onlyAttorney {
        <font style="color:#569cd6;">if</font> (_terms.seqList.remove(titleOfTerm)) {
            <font style="color:#569cd6;">delete</font> _terms.terms[titleOfTerm];
        }
    }

    <font style="color:#6a9955;">// ==== Rules ====</font>

    <font style="color:#569cd6;">function</font> addRule(<font style="color:#4ec9b0;">uint</font> seqOfRule, <font style="color:#4ec9b0;">bytes32</font> rule) <font style="color:#569cd6;">external</font> onlyAttorney {
        _addRule(seqOfRule, rule);
    }

    <font style="color:#6a9955;">/// @dev Insert or overwrite a rule and track its sequence number.</font>
    <font style="color:#569cd6;">function</font> _addRule(<font style="color:#4ec9b0;">uint</font> seqOfRule, <font style="color:#4ec9b0;">bytes32</font> rule) <font style="color:#569cd6;">private</font> {
        _rules.rules[seqOfRule] = rule;
        _rules.seqList.add(seqOfRule);
    }

    <font style="color:#569cd6;">function</font> removeRule(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> onlyAttorney {
        <font style="color:#569cd6;">if</font> (_rules.seqList.remove(seq)) {
            <font style="color:#569cd6;">delete</font> _rules.rules[seq];
        }
    }

    <font style="color:#569cd6;">function</font> initDefaultRules() <font style="color:#569cd6;">external</font> onlyKeeper {

        <font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> rules = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">bytes32</font>[](<font style="color:#b5cea8;">15</font>);
        <font style="color:#4ec9b0;">uint16</font>[<font style="color:#b5cea8;">15</font>] <font style="color:#569cd6;">memory</font> seqs = [<font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">1</font>, <font style="color:#b5cea8;">2</font>, <font style="color:#b5cea8;">3</font>, <font style="color:#b5cea8;">4</font>, <font style="color:#b5cea8;">5</font>, <font style="color:#b5cea8;">6</font>, <font style="color:#b5cea8;">7</font>, <font style="color:#b5cea8;">8</font>, <font style="color:#b5cea8;">9</font>, <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">12</font>, <font style="color:#b5cea8;">512</font>, <font style="color:#b5cea8;">513</font>];

        <font style="color:#6a9955;">// DefualtGovernanceRule</font>
        rules[<font style="color:#b5cea8;">0</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x000000000003e800000d0503e8003213880500241388000000000000140101f4));

        <font style="color:#6a9955;">// DefaultVotingRules</font>
        rules[<font style="color:#b5cea8;">1</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00010c010100001a0b000001000f08070e010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">2</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00020c020100001388000100010f08070e010107000000000000000000000000));
        rules[<font style="color:#b5cea8;">3</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00030c030100000000000101000008070e010107000000000000000000000000));
        rules[<font style="color:#b5cea8;">4</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00040c040100001a0b000001000f08070e010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">5</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00050c050100001388000100010f08070e010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">6</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00060c060100001a0b000001000f08070e010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">7</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00070c070100001a0b000001000f08070e010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">8</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00080c080100001a0b000001000000001d010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">9</font>]  = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x00090c090100001388010000000000001d010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">10</font>] = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x000a0c0a0100001a0b010000000000001d010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">11</font>] = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x000b0c0b02138800000100000000000009010100000000000000000000000000));
        rules[<font style="color:#b5cea8;">12</font>] = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x000c0c0c021a0b00000100000000000009010100000000000000000000000000));

        <font style="color:#6a9955;">// DefaultFirstRefusalRules</font>
        rules[<font style="color:#b5cea8;">13</font>] = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x0200020101010100000000000000000000000000000000000000000000000000));
        rules[<font style="color:#b5cea8;">14</font>] = <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(0x0201020202010100000000000000000000000000000000000000000000000000));

        <font style="color:#4ec9b0;">uint</font> len = <font style="color:#b5cea8;">15</font>;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            _addRule(seqs[len - <font style="color:#b5cea8;">1</font>], rules[len - <font style="color:#b5cea8;">1</font>]);
            len--;
        }

    }

    <font style="color:#6a9955;">// ==== Finalize SHA ====</font>

    <font style="color:#569cd6;">function</font> finalizeSHA() <font style="color:#569cd6;">external</font> {

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> titles = getTitles();
        <font style="color:#4ec9b0;">uint</font> len = titles.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            IDraftControl(_terms.terms[titles[len-<font style="color:#b5cea8;">1</font>]]).lockContents();
            len --;
        }

        lockContents();
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Terms ====</font>

    <font style="color:#569cd6;">function</font> hasTitle(<font style="color:#4ec9b0;">uint256</font> titleOfTerm) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _terms.seqList.contains(titleOfTerm);
    }

    <font style="color:#569cd6;">function</font> qtyOfTerms() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _terms.seqList.length();
    }

    <font style="color:#569cd6;">function</font> getTitles() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _terms.seqList.values();
    }

    <font style="color:#569cd6;">function</font> getTerm(<font style="color:#4ec9b0;">uint256</font> titleOfTerm) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> titleExist(titleOfTerm) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _terms.terms[titleOfTerm];
    }

    <font style="color:#6a9955;">// ==== Rules ====</font>

    <font style="color:#569cd6;">function</font> hasRule(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _rules.seqList.contains(seq);
    }

    <font style="color:#569cd6;">function</font> qtyOfRules() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _rules.seqList.length();
    }

    <font style="color:#569cd6;">function</font> getRules() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _rules.seqList.values();
    }

    <font style="color:#569cd6;">function</font> getRule(<font style="color:#4ec9b0;">uint256</font> seq) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>) {
        <font style="color:#569cd6;">return</font> _rules.rules[seq];
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Alongs.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/Alongs.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../common/access/DraftControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IAlongs.sol"</font>;

<font style="color:#569cd6;">contract</font> Alongs <font style="color:#569cd6;">is</font> IAlongs, DraftControl {
    <font style="color:#569cd6;">using</font> LinksRepo <font style="color:#569cd6;">for</font> LinksRepo.Repo;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    LinksRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#569cd6;">function</font> addDragger(<font style="color:#4ec9b0;">bytes32</font> rule, <font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> onlyAttorney {
        _repo.addDragger(rule, dragger, _gk.getROM());
    }

    <font style="color:#569cd6;">function</font> removeDragger(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> onlyAttorney {
        _repo.removeDragger(dragger);
    }

    <font style="color:#569cd6;">function</font> addFollower(<font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower) <font style="color:#569cd6;">external</font> onlyAttorney {
        _repo.addFollower(dragger, follower);
    }

    <font style="color:#569cd6;">function</font> removeFollower(<font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower) <font style="color:#569cd6;">external</font> onlyAttorney {
        _repo.removeFollower(dragger, follower);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> isDragger(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isDragger(dragger, _gk.getROM());
    }

    <font style="color:#569cd6;">function</font> getLinkRule(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (RulesParser.LinkRule <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getLinkRule(dragger, _gk.getROM());
    }

    <font style="color:#569cd6;">function</font> isFollower(<font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isFollower(dragger, follower, _gk.getROM());
    }

    <font style="color:#569cd6;">function</font> getDraggers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getDraggers();
    }

    <font style="color:#569cd6;">function</font> getFollowers(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getFollowers(dragger, _gk.getROM());
    }

    <font style="color:#569cd6;">function</font> priceCheck(
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.priceCheck(deal, _gk.getROS(), _gk.getROM());
    }

    <font style="color:#6a9955;">// #############</font>
    <font style="color:#6a9955;">// ##  Term   ##</font>
    <font style="color:#6a9955;">// #############</font>

    <font style="color:#569cd6;">function</font> isTriggered(<font style="color:#4ec9b0;">address</font> ia, DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {

        IRegisterOfMembers _rom = _gk.getROM();
        IRegisterOfAgreements _roa = _gk.getROA();

        <font style="color:#569cd6;">if</font> (_roa.getHeadOfFile(ia).state != <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Circulated))
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">if</font> (deal.head.typeOfDeal ==
            <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.CapitalIncrease) ||
            deal.head.typeOfDeal == <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.PreEmptive)
        ) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">if</font> (!_repo.isDragger(deal.head.seller, _rom)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        RulesParser.LinkRule <font style="color:#569cd6;">memory</font> rule =
            _repo.getLinkRule(deal.head.seller, _rom);

        <font style="color:#569cd6;">if</font> (rule.triggerDate > <font style="color:#b5cea8;">0</font> &&
            (block.timestamp < rule.triggerDate ||
                block.timestamp >= rule.triggerDate + <font style="color:#4ec9b0;">uint</font>(rule.effectiveDays)*<font style="color:#b5cea8;">86400</font> ))
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">if</font> (rule.triggerType == <font style="color:#4ec9b0;">uint8</font>(LinksRepo.TriggerTypeOfAlongs.NoConditions))
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#4ec9b0;">uint40</font> controllor = _rom.controllor();
        <font style="color:#569cd6;">if</font> (controllor != _rom.groupRep(deal.head.seller))
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        (<font style="color:#4ec9b0;">uint40</font> newControllor, <font style="color:#4ec9b0;">uint16</font> shareRatio) = _roa.mockResultsOfIA(ia);
        <font style="color:#569cd6;">if</font> (controllor == newControllor && shareRatio > rule.shareRatioThreshold)
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">return</font> priceCheck(deal);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## AntiDilution.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/AntiDilution.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../common/access/DraftControl.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IAntiDilution.sol"</font>;

<font style="color:#569cd6;">contract</font> AntiDilution <font style="color:#569cd6;">is</font> IAntiDilution, DraftControl {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    Ruler <font style="color:#569cd6;">private</font> _ruler;

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##   Modifier  ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">modifier</font> onlyMarked(<font style="color:#4ec9b0;">uint256</font> class) {
        <font style="color:#569cd6;">if</font>(!isMarked(class))
            <font style="color:#569cd6;">revert</font> AD_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AD_ClassNotMarked"</font>));
        _;
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> addBenchmark(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint</font> price) <font style="color:#569cd6;">external</font> onlyAttorney {

        <font style="color:#569cd6;">if</font> (class == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> AD_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AD_ZeroClass"</font>));
        <font style="color:#569cd6;">if</font> (price == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> AD_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AD_ZeroPrice"</font>));

        _ruler.marks[class].classOfShare = <font style="color:#4ec9b0;">uint16</font>(class);
        _ruler.marks[class].floorPrice = <font style="color:#4ec9b0;">uint32</font>(price);

        _ruler.classes.add(class);
    }

    <font style="color:#569cd6;">function</font> removeBenchmark(<font style="color:#4ec9b0;">uint256</font> class) <font style="color:#569cd6;">external</font> onlyAttorney {
        <font style="color:#569cd6;">if</font> (_ruler.classes.remove(class))
            <font style="color:#569cd6;">delete</font> _ruler.marks[class];
    }

    <font style="color:#569cd6;">function</font> addObligor(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font> onlyMarked(class) onlyAttorney {
        <font style="color:#569cd6;">if</font> (obligor == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> AD_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AD_ZeroObligor"</font>));
        _ruler.marks[class].obligors.add(obligor);
    }

    <font style="color:#569cd6;">function</font> removeObligor(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font> onlyMarked(class) onlyAttorney {
        _ruler.marks[class].obligors.remove(obligor);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> isMarked(<font style="color:#4ec9b0;">uint256</font> class) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = _ruler.classes.contains(class);
    }

    <font style="color:#569cd6;">function</font> getClasses() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _ruler.classes.values();
    }

    <font style="color:#569cd6;">function</font> getFloorPriceOfClass(<font style="color:#4ec9b0;">uint256</font> class)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font> price)
    {
        price = _ruler.marks[class].floorPrice;
    }

    <font style="color:#569cd6;">function</font> isObligor(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _ruler.marks[class].obligors.contains(acct);
    }

    <font style="color:#569cd6;">function</font> getObligorsOfAD(<font style="color:#4ec9b0;">uint256</font> class)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _ruler.marks[class].obligors.values();
    }

    <font style="color:#569cd6;">function</font> getGiftPaid(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>)
    {
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal =
            IInvestmentAgreement(ia).getDeal(seqOfDeal);

        SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
            _gk.getROS().getShare(seqOfShare);

        <font style="color:#569cd6;">if</font> (!isTriggered(deal, share.head.class))
            <font style="color:#569cd6;">revert</font> AD_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AD_NotTriggered"</font>));

        <font style="color:#4ec9b0;">uint32</font> floorPrice = getFloorPriceOfClass(share.head.class);

        <font style="color:#569cd6;">if</font> (share.head.priceOfPaid < floorPrice)
            <font style="color:#569cd6;">revert</font> AD_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AD_PriceBelowFloor"</font>));

        <font style="color:#569cd6;">return</font> (share.body.paid * floorPrice / deal.head.priceOfPaid - share.body.paid);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Term      ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> isTriggered(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal, <font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {

        <font style="color:#569cd6;">if</font> (deal.head.typeOfDeal != <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.CapitalIncrease))
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">if</font> (deal.head.priceOfPaid < getFloorPriceOfClass(class)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IAlongs.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/IAlongs.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/books/LinksRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../roa/IRegisterOfAgreements.sol"</font>;

<font style="color:#6a9955;">/// @title IAlongs</font>
<font style="color:#6a9955;">/// @notice Interface for managing drag-along/tag-along relationships and rules.</font>
<font style="color:#569cd6;">interface</font> IAlongs {

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Write    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Add a dragger with an encoded link rule.</font>
    <font style="color:#6a9955;">/// @param rule Encoded link rule.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#569cd6;">function</font> addDragger(<font style="color:#4ec9b0;">bytes32</font> rule, <font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a dragger and its followers.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#569cd6;">function</font> removeDragger(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add a follower to a dragger.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param follower Follower account.</font>
    <font style="color:#569cd6;">function</font> addFollower(<font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a follower from a dragger.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param follower Follower account.</font>
    <font style="color:#569cd6;">function</font> removeFollower(<font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##  Read I/O ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is a dragger.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @return True if dragger.</font>
    <font style="color:#569cd6;">function</font> isDragger(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get link rule for a dragger.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @return Link rule.</font>
    <font style="color:#569cd6;">function</font> getLinkRule(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (RulesParser.LinkRule <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether a follower is linked to a dragger.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param follower Follower account.</font>
    <font style="color:#6a9955;">/// @return True if linked.</font>
    <font style="color:#569cd6;">function</font> isFollower(<font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get list of draggers.</font>
    <font style="color:#6a9955;">/// @return Dragger accounts.</font>
    <font style="color:#569cd6;">function</font> getDraggers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get followers linked to a dragger.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @return Follower accounts.</font>
    <font style="color:#569cd6;">function</font> getFollowers(<font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check price/ROE constraints based on link rule.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#6a9955;">/// @return True if constraints satisfied.</font>
    <font style="color:#569cd6;">function</font> priceCheck(
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether a deal triggers along rights.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#6a9955;">/// @return True if triggered.</font>
    <font style="color:#569cd6;">function</font> isTriggered(<font style="color:#4ec9b0;">address</font> ia, DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IAntiDilution.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/IAntiDilution.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/books/SharesRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/books/DealsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../roa/IInvestmentAgreement.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title IAntiDilution</font>
<font style="color:#6a9955;">/// @notice Interface for anti-dilution term management and checks.</font>
<font style="color:#569cd6;">interface</font> IAntiDilution {

    <font style="color:#6a9955;">/// @notice Floor price benchmark and obligors for a share class.</font>
    <font style="color:#569cd6;">struct</font> Benchmark{
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> floorPrice;
        EnumerableSet.UintSet obligors;
    }

    <font style="color:#6a9955;">/// @notice Repository of benchmarks keyed by share class.</font>
    <font style="color:#569cd6;">struct</font> Ruler {
        <font style="color:#6a9955;">// classOfShare => Benchmark</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Benchmark) marks;
        <font style="color:#6a9955;">// Set of benchmarked classes</font>
        EnumerableSet.UintSet classes;
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Error    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">error</font> AD_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> AD_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> AD_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> AD_ZeroValue(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Write    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Add or update a floor price benchmark for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param price Floor price.</font>
    <font style="color:#569cd6;">function</font> addBenchmark(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint</font> price) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a benchmark for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">function</font> removeBenchmark(<font style="color:#4ec9b0;">uint256</font> class) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add an obligor to a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param obligor Account id.</font>
    <font style="color:#569cd6;">function</font> addObligor(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove an obligor from a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param obligor Account id.</font>
    <font style="color:#569cd6;">function</font> removeObligor(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ############</font>
    <font style="color:#6a9955;">// ##  read  ##</font>
    <font style="color:#6a9955;">// ############</font>

    <font style="color:#6a9955;">/// @notice Check whether a class has a benchmark.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return flag True if marked.</font>
    <font style="color:#569cd6;">function</font> isMarked(<font style="color:#4ec9b0;">uint256</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Get all benchmarked classes.</font>
    <font style="color:#6a9955;">/// @return Class ids.</font>
    <font style="color:#569cd6;">function</font> getClasses() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get floor price for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return price Floor price.</font>
    <font style="color:#569cd6;">function</font> getFloorPriceOfClass(<font style="color:#4ec9b0;">uint256</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font> price);

    <font style="color:#6a9955;">/// @notice Get obligors for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return Obligor accounts.</font>
    <font style="color:#569cd6;">function</font> getObligorsOfAD(<font style="color:#4ec9b0;">uint256</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether an account is an obligor of a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param acct Account id.</font>
    <font style="color:#6a9955;">/// @return flag True if obligor.</font>
    <font style="color:#569cd6;">function</font> isObligor(<font style="color:#4ec9b0;">uint256</font> class, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Calculate anti-dilution gift paid for a deal and share.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#6a9955;">/// @return gift Gift paid amount.</font>
    <font style="color:#569cd6;">function</font> getGiftPaid(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font> gift);

    <font style="color:#6a9955;">/// @notice Check whether a deal triggers anti-dilution for a class.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @return True if triggered.</font>
    <font style="color:#569cd6;">function</font> isTriggered(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal, <font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ILockUp.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/ILockUp.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/books/BallotsBox.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/books/DealsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../common/components/ISigPage.sol"</font>;

<font style="color:#6a9955;">/// @title ILockUp</font>
<font style="color:#6a9955;">/// @notice Interface for share lock-up rules and exemptions.</font>
<font style="color:#569cd6;">interface</font> ILockUp {

    <font style="color:#6a9955;">/// @notice Lock-up configuration for a share.</font>
    <font style="color:#569cd6;">struct</font> Locker {
        <font style="color:#4ec9b0;">uint48</font> dueDate;
        EnumerableSet.UintSet keyHolders;
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Error    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">error</font> LU_ZeroValue(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Write    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Set lock-up due date for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#6a9955;">/// @param dueDate Lock-up due date (timestamp).</font>
    <font style="color:#569cd6;">function</font> setLocker(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> dueDate) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove lock-up for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#569cd6;">function</font> delLocker(<font style="color:#4ec9b0;">uint256</font> seqOfShare) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add a keyholder who can exempt a lock-up.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#6a9955;">/// @param keyholder Account id.</font>
    <font style="color:#569cd6;">function</font> addKeyholder(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> keyholder) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a keyholder.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#6a9955;">/// @param keyholder Account id.</font>
    <font style="color:#569cd6;">function</font> removeKeyholder(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> keyholder) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Check whether a share is locked.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#6a9955;">/// @return True if locked.</font>
    <font style="color:#569cd6;">function</font> isLocked(<font style="color:#4ec9b0;">uint256</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get lock-up info for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number.</font>
    <font style="color:#6a9955;">/// @return dueDate Lock-up due date.</font>
    <font style="color:#6a9955;">/// @return keyHolders Exemption keyholders.</font>
    <font style="color:#569cd6;">function</font> getLocker(<font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font> dueDate, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> keyHolders);

    <font style="color:#6a9955;">/// @notice Get all locked shares.</font>
    <font style="color:#6a9955;">/// @return Share sequences.</font>
    <font style="color:#569cd6;">function</font> lockedShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether a deal is blocked by lock-up.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#6a9955;">/// @return True if blocked.</font>
    <font style="color:#569cd6;">function</font> isTriggered(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether a deal is exempted from lock-up.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#6a9955;">/// @return True if exempted.</font>
    <font style="color:#569cd6;">function</font> isExempted(<font style="color:#4ec9b0;">address</font> ia, DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IOptions.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/IOptions.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../lib/books/OptionsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title IOptions</font>
<font style="color:#6a9955;">/// @notice Interface for option term management and queries.</font>
<font style="color:#569cd6;">interface</font> IOptions {

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Create an option from encoded inputs.</font>
    <font style="color:#6a9955;">/// @param snOfOpt Option serial number.</font>
    <font style="color:#6a9955;">/// @param snOfCond Condition serial number.</font>
    <font style="color:#6a9955;">/// @param rightholder Rightholder account.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @return head Option head.</font>
    <font style="color:#569cd6;">function</font> createOption(
        <font style="color:#4ec9b0;">bytes32</font> snOfOpt,
        <font style="color:#4ec9b0;">bytes32</font> snOfCond,
        <font style="color:#4ec9b0;">uint</font> rightholder,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (OptionsRepo.Head <font style="color:#569cd6;">memory</font> head);

    <font style="color:#6a9955;">/// @notice Remove a pending option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @return flag True if removed.</font>
    <font style="color:#569cd6;">function</font> delOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Add an obligor to an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @param obligor Account id.</font>
    <font style="color:#6a9955;">/// @return flag True if added.</font>
    <font style="color:#569cd6;">function</font> addObligorIntoOpt(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> obligor
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Remove an obligor from an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @param obligor Account id.</font>
    <font style="color:#6a9955;">/// @return flag True if removed.</font>
    <font style="color:#569cd6;">function</font> removeObligorFromOpt(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> obligor
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">// ==== Option ====</font>

    <font style="color:#6a9955;">/// @notice Get the option counter.</font>
    <font style="color:#6a9955;">/// @return Counter value.</font>
    <font style="color:#569cd6;">function</font> counterOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get number of options.</font>
    <font style="color:#6a9955;">/// @return Count.</font>
    <font style="color:#569cd6;">function</font> qtyOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Check whether an option exists.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get an option by sequence number.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @return option Option record.</font>
    <font style="color:#569cd6;">function</font> getOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OptionsRepo.Option <font style="color:#569cd6;">memory</font> option);

    <font style="color:#6a9955;">/// @notice Get all options.</font>
    <font style="color:#6a9955;">/// @return Option list.</font>
    <font style="color:#569cd6;">function</font> getAllOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (OptionsRepo.Option[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Obligor ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is an obligor.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @param acct Account id.</font>
    <font style="color:#6a9955;">/// @return True if obligor.</font>
    <font style="color:#569cd6;">function</font> isObligor(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get obligors of an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence number.</font>
    <font style="color:#6a9955;">/// @return Obligor accounts.</font>
    <font style="color:#569cd6;">function</font> getObligorsOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== snOfOpt ====</font>
    <font style="color:#6a9955;">/// @notice Get list of option sequence numbers.</font>
    <font style="color:#6a9955;">/// @return Option ids.</font>
    <font style="color:#569cd6;">function</font> getSeqList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## LockUp.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/LockUp.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../common/access/DraftControl.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ILockUp.sol"</font>;

<font style="color:#569cd6;">contract</font> LockUp <font style="color:#569cd6;">is</font> ILockUp, DraftControl {
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint256</font>[];
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// default expire date as "2105-09-19"</font>
    <font style="color:#4ec9b0;">uint48</font> <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">constant</font> _REMOTE_FUTURE = <font style="color:#b5cea8;">4282732800</font>;

    <font style="color:#6a9955;">// lockers[0].keyHolders: ssnList;</font>
    <font style="color:#6a9955;">// seqOfShare => Locker</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Locker) <font style="color:#569cd6;">private</font> _lockers;

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ## Write I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> setLocker(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> dueDate) <font style="color:#569cd6;">external</font> onlyAttorney {
        _lockers[seqOfShare].dueDate = <font style="color:#4ec9b0;">uint48</font>(dueDate) == <font style="color:#b5cea8;">0</font> ? _REMOTE_FUTURE : <font style="color:#4ec9b0;">uint48</font>(dueDate);
        _lockers[<font style="color:#b5cea8;">0</font>].keyHolders.add(seqOfShare);
    }

    <font style="color:#569cd6;">function</font> delLocker(<font style="color:#4ec9b0;">uint256</font> seqOfShare) <font style="color:#569cd6;">external</font> onlyAttorney {
        <font style="color:#569cd6;">if</font> (_lockers[<font style="color:#b5cea8;">0</font>].keyHolders.remove(seqOfShare)) {
            <font style="color:#569cd6;">delete</font> _lockers[seqOfShare];
        }
    }

    <font style="color:#569cd6;">function</font> addKeyholder(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> keyholder) <font style="color:#569cd6;">external</font> onlyAttorney {
        <font style="color:#569cd6;">if</font>(seqOfShare == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> LU_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LU_ZeroSeqOfShare"</font>));
        _lockers[seqOfShare].keyHolders.add(keyholder);
    }

    <font style="color:#569cd6;">function</font> removeKeyholder(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> keyholder) <font style="color:#569cd6;">external</font> onlyAttorney {
        <font style="color:#569cd6;">if</font>(seqOfShare == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> LU_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LU_ZeroSeqOfShare"</font>));
        _lockers[seqOfShare].keyHolders.remove(keyholder);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> isLocked(<font style="color:#4ec9b0;">uint256</font> seqOfShare) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font>(seqOfShare == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> LU_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LU_ZeroSeqOfShare"</font>));
        <font style="color:#569cd6;">return</font> _lockers[seqOfShare].dueDate > block.timestamp;
    }

    <font style="color:#569cd6;">function</font> getLocker(<font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font> dueDate, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> keyHolders)
    {
        dueDate = _lockers[seqOfShare].dueDate;
        keyHolders = _lockers[seqOfShare].keyHolders.values();
    }

    <font style="color:#569cd6;">function</font> lockedShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _lockers[<font style="color:#b5cea8;">0</font>].keyHolders.values();
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Term      ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> isTriggered(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {

        <font style="color:#569cd6;">if</font> (
            deal.head.typeOfDeal > <font style="color:#b5cea8;">1</font> &&
            isLocked(deal.head.seqOfShare) &&
            _lockers[deal.head.seqOfShare].dueDate >= deal.head.closingDeadline
        ) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _isExempted(DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> agreedParties)
        <font style="color:#569cd6;">private</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">if</font> (!isTriggered(deal)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        Locker <font style="color:#569cd6;">storage</font> locker = _lockers[deal.head.seqOfShare];

        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> holders = locker.keyHolders.values();
        <font style="color:#4ec9b0;">uint256</font> len = holders.length;

        <font style="color:#569cd6;">if</font> (len == <font style="color:#b5cea8;">0</font> || len > agreedParties.length) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">return</font> holders.fullyCoveredBy(agreedParties);
        }
    }

    <font style="color:#569cd6;">function</font> isExempted(<font style="color:#4ec9b0;">address</font> ia, DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {

        <font style="color:#4ec9b0;">uint</font> seqOfMotion = _gk.getROA().getHeadOfFile(ia).seqOfMotion;

        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties = ISigPage(ia).getParties();

        BallotsBox.Case <font style="color:#569cd6;">memory</font> consentCase = _gk.getGMM().getCaseOfAttitude(seqOfMotion, <font style="color:#b5cea8;">1</font>);

        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> supporters =
            consentCase.voters.combine(consentCase.principals).merge(parties);

        <font style="color:#569cd6;">return</font> _isExempted(deal, supporters);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## Options.sol

---

| |
|:---|
| **contracts/comps/books/roc/terms/Options.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../common/access/DraftControl.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IOptions.sol"</font>;

<font style="color:#569cd6;">contract</font> Options <font style="color:#569cd6;">is</font> IOptions, DraftControl {
    <font style="color:#569cd6;">using</font> OptionsRepo <font style="color:#569cd6;">for</font> OptionsRepo.Repo;
    <font style="color:#569cd6;">using</font> OptionsRepo <font style="color:#569cd6;">for</font> OptionsRepo.Option;
    <font style="color:#569cd6;">using</font> OptionsRepo <font style="color:#569cd6;">for</font> OptionsRepo.Head;
    <font style="color:#569cd6;">using</font> OptionsRepo <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.Bytes32Set;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    OptionsRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ## Write I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> createOption(
        <font style="color:#4ec9b0;">bytes32</font> snOfOpt,
        <font style="color:#4ec9b0;">bytes32</font> snOfCond,
        <font style="color:#4ec9b0;">uint</font> rightholder,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">external</font> onlyAttorney <font style="color:#569cd6;">returns</font> (OptionsRepo.Head <font style="color:#569cd6;">memory</font> head) {
        head = _repo.createOption(snOfOpt, snOfCond, rightholder, paid, par);
    }

    <font style="color:#569cd6;">function</font> delOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> onlyAttorney <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag){
        flag = _repo.removeOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> addObligorIntoOpt(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> obligor
    ) <font style="color:#569cd6;">external</font> onlyAttorney <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (isOption(seqOfOpt))
            flag = _repo.records[seqOfOpt].obligors.add(obligor);
    }

    <font style="color:#569cd6;">function</font> removeObligorFromOpt(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> obligor
    ) <font style="color:#569cd6;">external</font> onlyAttorney <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (isOption(seqOfOpt))
            flag = _repo.records[seqOfOpt].obligors.remove(obligor);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">// ==== Option ====</font>

    <font style="color:#569cd6;">function</font> counterOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _repo.counterOfOptions();
    }

    <font style="color:#569cd6;">function</font> qtyOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.qtyOfOptions();
    }

    <font style="color:#569cd6;">function</font> isOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OptionsRepo.Option <font style="color:#569cd6;">memory</font> option)
    {
        <font style="color:#569cd6;">return</font> _repo.getOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getAllOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (OptionsRepo.Option[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getAllOptions();
    }

    <font style="color:#6a9955;">// ==== Obligor ====</font>

    <font style="color:#569cd6;">function</font> isObligor(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isObligor(seqOfOpt, acct);
    }

    <font style="color:#569cd6;">function</font> getObligorsOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getObligorsOfOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getSeqList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSeqList();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfDirectors.sol

---

| |
|:---|
| **contracts/comps/books/rod/IRegisterOfDirectors.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/components/IMeetingMinutes.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/OfficersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfDirectors</font>
<font style="color:#6a9955;">/// @notice Interface for managing director/officer positions and appointments.</font>
<font style="color:#6a9955;">/// @dev Provides write functions for position lifecycle and read queries for roles.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfDirectors {

    <font style="color:#6a9955;">//###################</font>
    <font style="color:#6a9955;">//##    Events     ##</font>
    <font style="color:#6a9955;">//###################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a position is created or updated.</font>
    <font style="color:#6a9955;">/// @param snOfPos Encoded position head (title/seq/nomination/term fields).</font>
    <font style="color:#569cd6;">event</font> AddPosition(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfPos);

    <font style="color:#6a9955;">/// @notice Emitted when a position is removed.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number.</font>
    <font style="color:#569cd6;">event</font> RemovePosition(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPos);

    <font style="color:#6a9955;">/// @notice Emitted when a position is taken by an officer.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number.</font>
    <font style="color:#6a9955;">/// @param caller Officer account id.</font>
    <font style="color:#569cd6;">event</font> TakePosition(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPos, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> caller);

    <font style="color:#6a9955;">/// @notice Emitted when an officer quits a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number.</font>
    <font style="color:#6a9955;">/// @param caller Officer account id.</font>
    <font style="color:#569cd6;">event</font> QuitPosition(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPos, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> caller);

    <font style="color:#6a9955;">/// @notice Emitted when a position is vacated by removal.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number.</font>
    <font style="color:#569cd6;">event</font> RemoveOfficer(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPos);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Create a position using an encoded serial number.</font>
    <font style="color:#6a9955;">/// @param snOfPos Encoded position head (non-zero, valid fields).</font>
    <font style="color:#569cd6;">function</font> createPosition(<font style="color:#4ec9b0;">bytes32</font> snOfPos) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Update a position with explicit fields.</font>
    <font style="color:#6a9955;">/// @param pos Position struct (seqOfPos > 0, title > Shareholder, endDate > startDate).</font>
    <font style="color:#569cd6;">function</font> updatePosition(OfficersRepo.Position <font style="color:#569cd6;">memory</font> pos) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a vacant position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> removePosition(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Take an available position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Officer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> takePosition (<font style="color:#4ec9b0;">uint256</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Quit a position held by the caller.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Officer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> quitPosition (<font style="color:#4ec9b0;">uint256</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Vacate a position by removal.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> removeOfficer (<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Positions ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a position exists and is active.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> posExist(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether a position is occupied.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @return True if occupied.</font>
    <font style="color:#569cd6;">function</font> isOccupied(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get position details.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @return Position record.</font>
    <font style="color:#569cd6;">function</font> getPosition(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OfficersRepo.Position <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Managers ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is a manager.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @return True if manager.</font>
    <font style="color:#569cd6;">function</font> isManager(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get number of managers.</font>
    <font style="color:#6a9955;">/// @return Count of managers.</font>
    <font style="color:#569cd6;">function</font> getNumOfManagers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/// @notice Get manager account list.</font>
    <font style="color:#6a9955;">/// @return Manager user list.</font>
    <font style="color:#569cd6;">function</font> getManagersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get manager position list.</font>
    <font style="color:#6a9955;">/// @return Position id list.</font>
    <font style="color:#569cd6;">function</font> getManagersPosList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Directors ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is a director.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @return True if director.</font>
    <font style="color:#569cd6;">function</font> isDirector(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get number of directors.</font>
    <font style="color:#6a9955;">/// @return Count of directors.</font>
    <font style="color:#569cd6;">function</font> getNumOfDirectors() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/// @notice Get director account list.</font>
    <font style="color:#6a9955;">/// @return Director user list.</font>
    <font style="color:#569cd6;">function</font> getDirectorsList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get director position list.</font>
    <font style="color:#6a9955;">/// @return Position id list.</font>
    <font style="color:#569cd6;">function</font> getDirectorsPosList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Executives ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account holds a position.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @return True if holds.</font>
    <font style="color:#569cd6;">function</font> hasPosition(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint256</font> seqOfPos)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get positions held by an account.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @return Position id list.</font>
    <font style="color:#569cd6;">function</font> getPosInHand(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get full position info held by an account.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @return Position list.</font>
    <font style="color:#569cd6;">function</font> getFullPosInfoInHand(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (OfficersRepo.Position[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether an account holds a title.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param title Title id (see OfficersRepo.TitleOfOfficers).</font>
    <font style="color:#6a9955;">/// @return flag True if holds.</font>
    <font style="color:#569cd6;">function</font> hasTitle(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> title)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Check whether an account has nomination rights for a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @return True if has rights.</font>
    <font style="color:#569cd6;">function</font> hasNominationRight(<font style="color:#4ec9b0;">uint</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== seatsCalculator ====</font>

    <font style="color:#6a9955;">/// @notice Get number of board seats occupied under an account's nomination.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @return Number of occupied seats.</font>
    <font style="color:#569cd6;">function</font> getBoardSeatsOccupied(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfDirectors.sol

---

| |
|:---|
| **contracts/comps/books/rod/RegisterOfDirectors.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfDirectors.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfDirectors <font style="color:#569cd6;">is</font> IRegisterOfDirectors, AccessControl {
    <font style="color:#569cd6;">using</font> OfficersRepo <font style="color:#569cd6;">for</font> OfficersRepo.Repo;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Repository for directors, officers, their positions, and their titles.</font>
    OfficersRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ==== UUPS Upgradeable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== PositionSetting ====</font>
    <font style="color:#569cd6;">function</font> createPosition(<font style="color:#4ec9b0;">bytes32</font> snOfPos) <font style="color:#569cd6;">external</font> onlyKeeper {
            _repo.createPosition(snOfPos);
        <font style="color:#569cd6;">emit</font> AddPosition(snOfPos);
    }

    <font style="color:#569cd6;">function</font> updatePosition(OfficersRepo.Position <font style="color:#569cd6;">memory</font> pos) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.addPosition(pos);
        <font style="color:#569cd6;">emit</font> AddPosition(OfficersRepo.codifyPosition(pos));
    }

    <font style="color:#569cd6;">function</font> removePosition(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.removePosition(seqOfPos))
            <font style="color:#569cd6;">emit</font> RemovePosition(seqOfPos);
    }

    <font style="color:#6a9955;">// ---- Officers ----</font>

    <font style="color:#569cd6;">function</font> takePosition (<font style="color:#4ec9b0;">uint256</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.takePosition(seqOfPos, caller))
            <font style="color:#569cd6;">emit</font> TakePosition(seqOfPos, caller);
    }

    <font style="color:#569cd6;">function</font> quitPosition (<font style="color:#4ec9b0;">uint256</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.quitPosition(seqOfPos, caller))
            <font style="color:#569cd6;">emit</font> QuitPosition(seqOfPos, caller);
    }

    <font style="color:#569cd6;">function</font> removeOfficer (<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.vacatePosition(seqOfPos))
            <font style="color:#569cd6;">emit</font> RemoveOfficer(seqOfPos);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Positions ====</font>

    <font style="color:#569cd6;">function</font> posExist(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.posExist(seqOfPos);
    }

    <font style="color:#569cd6;">function</font> isOccupied(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isOccupied(seqOfPos);
    }

    <font style="color:#569cd6;">function</font> getPosition(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OfficersRepo.Position <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getPosition(seqOfPos);
    }

    <font style="color:#6a9955;">// ==== Managers ====</font>

    <font style="color:#569cd6;">function</font> isManager(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isManager(acct);
    }

    <font style="color:#569cd6;">function</font> getNumOfManagers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _repo.getNumOfManagers();
    }

    <font style="color:#569cd6;">function</font> getManagersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getManagersList();
    }

    <font style="color:#569cd6;">function</font> getManagersPosList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getManagersPosList();
    }

    <font style="color:#6a9955;">// ==== Directors ====</font>

    <font style="color:#569cd6;">function</font> isDirector(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isDirector(acct);
    }

    <font style="color:#569cd6;">function</font> getNumOfDirectors() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _repo.getNumOfDirectors();
    }

    <font style="color:#569cd6;">function</font> getDirectorsList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getDirectorsList();
    }

    <font style="color:#569cd6;">function</font> getDirectorsPosList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> )
    {
        <font style="color:#569cd6;">return</font> _repo.getDirectorsPosList();
    }

    <font style="color:#6a9955;">// ==== Executives ====</font>

    <font style="color:#569cd6;">function</font> hasPosition(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint256</font> seqOfPos)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.hasPosition(acct, seqOfPos);
    }

    <font style="color:#569cd6;">function</font> getPosInHand(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getPosInHand(acct);
    }

    <font style="color:#569cd6;">function</font> getFullPosInfoInHand(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (OfficersRepo.Position[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getFullPosInfoInHand(acct);
    }

    <font style="color:#569cd6;">function</font> hasTitle(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> title) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _repo.hasTitle(acct, title, _gk.getROM());
    }

    <font style="color:#569cd6;">function</font> hasNominationRight(<font style="color:#4ec9b0;">uint</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.hasNominationRight(seqOfPos, acct, _gk.getROM());
    }

    <font style="color:#6a9955;">// ==== seatsCalculator ====</font>

    <font style="color:#569cd6;">function</font> getBoardSeatsOccupied(<font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> )
    {
        <font style="color:#569cd6;">return</font> _repo.getBoardSeatsOccupied(acct);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfInvestors.sol

---

| |
|:---|
| **contracts/comps/books/roi/IRegisterOfInvestors.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/InvestorsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfInvestors</font>
<font style="color:#6a9955;">/// @notice Interface for investor registry and compliance controls.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfInvestors {

     <font style="color:#6a9955;">// ################</font>
     <font style="color:#6a9955;">// ##    Error   ##</font>
     <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">error</font> ROI_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROI_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

     <font style="color:#6a9955;">// ################</font>
     <font style="color:#6a9955;">// ##  Event(s)  ##</font>
     <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Emitted when LOO operations are paused.</font>
    <font style="color:#6a9955;">/// @param agent Operator user number.</font>
    <font style="color:#569cd6;">event</font> Paused(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> agent);

    <font style="color:#6a9955;">/// @notice Emitted when LOO operations are unpaused.</font>
    <font style="color:#6a9955;">/// @param agent Operator user number.</font>
    <font style="color:#569cd6;">event</font> UnPaused(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> agent);

    <font style="color:#6a9955;">/// @notice Emitted when a share is frozen for compliance.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount frozen.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#6a9955;">/// @param hashOrder Related order hash.</font>
    <font style="color:#569cd6;">event</font> FreezeShare(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> caller, <font style="color:#4ec9b0;">bytes32</font> hashOrder);

    <font style="color:#6a9955;">/// @notice Emitted when a frozen share is unfrozen.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount unfrozen.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#6a9955;">/// @param hashOrder Related order hash.</font>
    <font style="color:#569cd6;">event</font> UnfreezeShare(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> caller, <font style="color:#4ec9b0;">bytes32</font> hashOrder);

    <font style="color:#6a9955;">/// @notice Emitted when a forced transfer is executed for a frozen share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount transferred.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#6a9955;">/// @param hashOrder Related order hash.</font>
    <font style="color:#569cd6;">event</font> ForceTransfer(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> caller, <font style="color:#4ec9b0;">bytes32</font> hashOrder);

    <font style="color:#6a9955;">/// @notice Emitted when an investor is registered.</font>
    <font style="color:#6a9955;">/// @param investor Investor user number.</font>
    <font style="color:#6a9955;">/// @param groupRep Group representative user number.</font>
    <font style="color:#6a9955;">/// @param idHash Investor id hash.</font>
    <font style="color:#569cd6;">event</font> RegInvestor(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> investor, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> groupRep, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> idHash);

    <font style="color:#6a9955;">/// @notice Emitted when an investor is approved.</font>
    <font style="color:#6a9955;">/// @param investor Investor user number.</font>
    <font style="color:#6a9955;">/// @param verifier Verifier user number.</font>
    <font style="color:#569cd6;">event</font> ApproveInvestor(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> investor, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> verifier);

    <font style="color:#6a9955;">/// @notice Emitted when an investor approval is revoked.</font>
    <font style="color:#6a9955;">/// @param investor Investor user number.</font>
    <font style="color:#6a9955;">/// @param verifier Verifier user number.</font>
    <font style="color:#569cd6;">event</font> RevokeInvestor(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> investor, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> verifier);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Pause LOO ====</font>

    <font style="color:#6a9955;">/// @notice Pause LOO operations.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#569cd6;">function</font> pause(<font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Unpause LOO operations.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#569cd6;">function</font> unPause(<font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Freeze Share ====</font>

    <font style="color:#6a9955;">/// @notice Freeze a share for an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#6a9955;">/// @param hashOrder Order hash.</font>
    <font style="color:#569cd6;">function</font> freezeShare(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Unfreeze a share for an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#6a9955;">/// @param hashOrder Order hash.</font>
    <font style="color:#569cd6;">function</font> unfreezeShare(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Force transfer a frozen share.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param caller Operator user number.</font>
    <font style="color:#6a9955;">/// @param hashOrder Order hash.</font>
    <font style="color:#569cd6;">function</font> forceTransfer(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#6a9955;">/// @notice Register or update an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param groupRep Group representative.</font>
    <font style="color:#6a9955;">/// @param idHash ID hash.</font>
    <font style="color:#569cd6;">function</font> regInvestor(<font style="color:#4ec9b0;">uint</font> userNo,<font style="color:#4ec9b0;">uint</font> groupRep,<font style="color:#4ec9b0;">bytes32</font> idHash) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Approve an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param verifier Verifier user number.</font>
    <font style="color:#569cd6;">function</font> approveInvestor(<font style="color:#4ec9b0;">uint</font> userNo,<font style="color:#4ec9b0;">uint</font> verifier) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Revoke an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param verifier Verifier user number.</font>
    <font style="color:#569cd6;">function</font> revokeInvestor(<font style="color:#4ec9b0;">uint</font> userNo,<font style="color:#4ec9b0;">uint</font> verifier) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Restore investors repo from snapshots.</font>
    <font style="color:#6a9955;">/// @param list Investor list.</font>
    <font style="color:#6a9955;">/// @param qtyOfInvestors Approved investor count.</font>
    <font style="color:#569cd6;">function</font> restoreInvestorsRepo(InvestorsRepo.Investor[] <font style="color:#569cd6;">memory</font> list, <font style="color:#4ec9b0;">uint</font> qtyOfInvestors) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Paused ====</font>

    <font style="color:#6a9955;">/// @notice Check if paused.</font>
    <font style="color:#6a9955;">/// @return True if paused.</font>
    <font style="color:#569cd6;">function</font> isPaused() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== Freeze ====</font>

    <font style="color:#6a9955;">/// @notice Check if investor is frozen.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @return True if frozen.</font>
    <font style="color:#569cd6;">function</font> isFrozen(<font style="color:#4ec9b0;">uint</font> userNo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check if share is frozen.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return True if frozen.</font>
    <font style="color:#569cd6;">function</font> isFrozenShare(<font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get frozen shares of an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @return Share list.</font>
    <font style="color:#569cd6;">function</font> frozenShares(<font style="color:#4ec9b0;">uint</font> userNo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get frozen paid amount for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return Paid amount.</font>
    <font style="color:#569cd6;">function</font> frozenPaid(<font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#6a9955;">/// @notice Check if investor exists.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isInvestor(<font style="color:#4ec9b0;">uint</font> userNo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get investor record.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @return Investor record.</font>
    <font style="color:#569cd6;">function</font> getInvestor(<font style="color:#4ec9b0;">uint</font> userNo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(InvestorsRepo.Investor <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get approved investor count.</font>
    <font style="color:#6a9955;">/// @return Count.</font>
    <font style="color:#569cd6;">function</font> getQtyOfInvestors() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get investor list.</font>
    <font style="color:#6a9955;">/// @return Investor user numbers.</font>
    <font style="color:#569cd6;">function</font> investorList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get investor info list.</font>
    <font style="color:#6a9955;">/// @return Investor records.</font>
    <font style="color:#569cd6;">function</font> investorInfoList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(InvestorsRepo.Investor[] <font style="color:#569cd6;">memory</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfInvestors.sol

---

| |
|:---|
| **contracts/comps/books/roi/RegisterOfInvestors.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfInvestors.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfInvestors <font style="color:#569cd6;">is</font> IRegisterOfInvestors, AccessControl {
    <font style="color:#569cd6;">using</font> InvestorsRepo <font style="color:#569cd6;">for</font> InvestorsRepo.Repo;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">// Repository for investors and their groupings.</font>
    InvestorsRepo.Repo <font style="color:#569cd6;">private</font> _investors;

    <font style="color:#6a9955;">/// @dev mapping from seqOfShare to paid amount under frozen;</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => <font style="color:#4ec9b0;">uint</font>) <font style="color:#569cd6;">private</font> _frozenPaid;

    <font style="color:#6a9955;">/// @dev mapping from userNo to seqOfShare under frozen;</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => EnumerableSet.UintSet) <font style="color:#569cd6;">private</font> _frozenShares;

    <font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">private</font> _paused;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Pause LOO ====</font>

    <font style="color:#569cd6;">function</font> pause(<font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_paused == <font style="color:#569cd6;">true</font>) {
            <font style="color:#569cd6;">revert</font> ROI_WrongState(<font style="color:#ce9178;">"ROI_AlreadyPaused"</font>);
        }
        _paused = <font style="color:#569cd6;">true</font>;
        <font style="color:#569cd6;">emit</font> Paused(caller);
    }

    <font style="color:#569cd6;">function</font> unPause(<font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_paused == <font style="color:#569cd6;">false</font>) {
            <font style="color:#569cd6;">revert</font> ROI_WrongState(<font style="color:#ce9178;">"ROI_AlreadyUnpaused"</font>);
        }
        _paused = <font style="color:#569cd6;">false</font>;
        <font style="color:#569cd6;">emit</font> UnPaused(caller);
    }

    <font style="color:#6a9955;">// ==== Freeze Share ====</font>

    <font style="color:#569cd6;">function</font> freezeShare(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _frozenShares[userNo].add(seqOfShare);
        _frozenPaid[seqOfShare] += paid;
        <font style="color:#569cd6;">emit</font> FreezeShare(seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#569cd6;">function</font> unfreezeShare(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _unfreezeShare(userNo, seqOfShare, paid);
        <font style="color:#569cd6;">emit</font> UnfreezeShare(seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#569cd6;">function</font> _unfreezeShare(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (_frozenPaid[seqOfShare] < paid) {
            <font style="color:#569cd6;">revert</font> ROI_Overflow(<font style="color:#ce9178;">"ROI_ShotOfFrozenPaid"</font>);
        }
        _frozenPaid[seqOfShare] -= paid;
        <font style="color:#569cd6;">if</font> (_frozenPaid[seqOfShare] == <font style="color:#b5cea8;">0</font> )
            _frozenShares[userNo].remove(seqOfShare);
    }

    <font style="color:#569cd6;">function</font> forceTransfer(
        <font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _unfreezeShare(userNo, seqOfShare, paid);
        <font style="color:#569cd6;">emit</font> ForceTransfer(seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#569cd6;">function</font> regInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> groupRep,
        <font style="color:#4ec9b0;">bytes32</font> idHash
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _investors.regInvestor(userNo, groupRep, idHash);
        <font style="color:#569cd6;">emit</font> RegInvestor(userNo, groupRep, idHash);
    }

    <font style="color:#569cd6;">function</font> approveInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> verifier
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _investors.approveInvestor(userNo, verifier);
        <font style="color:#569cd6;">emit</font> ApproveInvestor(userNo, verifier);
    }

    <font style="color:#569cd6;">function</font> revokeInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> verifier
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _investors.revokeInvestor(userNo, verifier);
        <font style="color:#569cd6;">emit</font> RevokeInvestor(userNo, verifier);
    }

    <font style="color:#569cd6;">function</font> restoreInvestorsRepo(
        InvestorsRepo.Investor[] <font style="color:#569cd6;">memory</font> list, <font style="color:#4ec9b0;">uint</font> qtyOfInvestors
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _investors.restoreRepo(list, qtyOfInvestors);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Paused ====</font>

    <font style="color:#569cd6;">function</font> isPaused() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _paused;
    }

    <font style="color:#6a9955;">// ==== Frozen ====</font>

    <font style="color:#569cd6;">function</font> isFrozen(<font style="color:#4ec9b0;">uint</font> userNo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _frozenShares[userNo].length() > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#569cd6;">function</font> isFrozenShare(<font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _frozenPaid[seqOfShare] > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#569cd6;">function</font> frozenShares(<font style="color:#4ec9b0;">uint</font> userNo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _frozenShares[userNo].values();
    }

    <font style="color:#569cd6;">function</font> frozenPaid(<font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> _frozenPaid[seqOfShare];
    }

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#569cd6;">function</font> isInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _investors.isInvestor(userNo);
    }

    <font style="color:#569cd6;">function</font> getInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(InvestorsRepo.Investor <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _investors.getInvestor(userNo);
    }

    <font style="color:#569cd6;">function</font> getQtyOfInvestors()
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> _investors.getQtyOfInvestors();
    }

    <font style="color:#569cd6;">function</font> investorList()
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _investors.investorList();
    }

    <font style="color:#569cd6;">function</font> investorInfoList()
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(InvestorsRepo.Investor[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _investors.investorInfoList();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfMembers.sol

---

| |
|:---|
| **contracts/comps/books/rom/IRegisterOfMembers.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/Checkpoints.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/MembersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/SharesRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/TopChain.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfMembers</font>
<font style="color:#6a9955;">/// @notice Interface for member registry, votes, and grouping.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfMembers {

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Error     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">error</font> ROM_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROM_WrongAccess(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Event     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Emitted when vote base is updated.</font>
    <font style="color:#6a9955;">/// @param basedOnPar True if vote base is par amount.</font>
    <font style="color:#569cd6;">event</font> SetVoteBase(<font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">indexed</font> basedOnPar);

    <font style="color:#6a9955;">/// @notice Emitted when capital base is increased.</font>
    <font style="color:#6a9955;">/// @param votingWeight Voting weight delta.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount delta.</font>
    <font style="color:#6a9955;">/// @param par Par amount delta.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight delta.</font>
    <font style="color:#569cd6;">event</font> CapIncrease(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> votingWeight, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> par, <font style="color:#4ec9b0;">uint</font> distrWeight);

    <font style="color:#6a9955;">/// @notice Emitted when capital base is decreased.</font>
    <font style="color:#6a9955;">/// @param votingWeight Voting weight delta.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount delta.</font>
    <font style="color:#6a9955;">/// @param par Par amount delta.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight delta.</font>
    <font style="color:#569cd6;">event</font> CapDecrease(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> votingWeight, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> par, <font style="color:#4ec9b0;">uint</font> distrWeight);

    <font style="color:#6a9955;">/// @notice Emitted when maximum member count is updated.</font>
    <font style="color:#6a9955;">/// @param max Maximum count.</font>
    <font style="color:#569cd6;">event</font> SetMaxQtyOfMembers(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> max);

    <font style="color:#6a9955;">/// @notice Emitted when minimum on-chain vote ratio is updated.</font>
    <font style="color:#6a9955;">/// @param min Minimum ratio.</font>
    <font style="color:#569cd6;">event</font> SetMinVoteRatioOnChain(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> min);

    <font style="color:#6a9955;">/// @notice Emitted when amount base is updated.</font>
    <font style="color:#6a9955;">/// @param basedOnPar True if amount base is par amount.</font>
    <font style="color:#569cd6;">event</font> SetAmtBase(<font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">indexed</font> basedOnPar);

    <font style="color:#6a9955;">/// @notice Emitted when a member is added.</font>
    <font style="color:#6a9955;">/// @param acct Member account.</font>
    <font style="color:#6a9955;">/// @param qtyOfMembers New member count.</font>
    <font style="color:#569cd6;">event</font> AddMember(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> acct, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> qtyOfMembers);

    <font style="color:#6a9955;">/// @notice Emitted when a share is linked to a member.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param acct Member account.</font>
    <font style="color:#569cd6;">event</font> AddShareToMember(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> acct);

    <font style="color:#6a9955;">/// @notice Emitted when a share is removed from a member.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param acct Member account.</font>
    <font style="color:#569cd6;">event</font> RemoveShareFromMember(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> acct);

    <font style="color:#6a9955;">/// @notice Emitted when member amounts are changed.</font>
    <font style="color:#6a9955;">/// @param acct Member account.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount delta.</font>
    <font style="color:#6a9955;">/// @param par Par amount delta.</font>
    <font style="color:#6a9955;">/// @param increase True if increased, false if decreased.</font>
    <font style="color:#569cd6;">event</font> ChangeAmtOfMember(
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> acct,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> par,
        <font style="color:#4ec9b0;">bool</font> increase
    );

    <font style="color:#6a9955;">/// @notice Emitted when a member is added to a group.</font>
    <font style="color:#6a9955;">/// @param acct Member account.</font>
    <font style="color:#6a9955;">/// @param root Group root account.</font>
    <font style="color:#569cd6;">event</font> AddMemberToGroup(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> acct, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> root);

    <font style="color:#6a9955;">/// @notice Emitted when a member is removed from a group.</font>
    <font style="color:#6a9955;">/// @param acct Member account.</font>
    <font style="color:#6a9955;">/// @param root Group root account.</font>
    <font style="color:#569cd6;">event</font> RemoveMemberFromGroup(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> acct, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> root);

    <font style="color:#6a9955;">/// @notice Emitted when group representative changes.</font>
    <font style="color:#6a9955;">/// @param orgRep Original representative account.</font>
    <font style="color:#6a9955;">/// @param newRep New representative account.</font>
    <font style="color:#569cd6;">event</font> ChangeGroupRep(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> orgRep, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> newRep);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Set maximum number of members.</font>
    <font style="color:#6a9955;">/// @param max Max member count.</font>
    <font style="color:#569cd6;">function</font> setMaxQtyOfMembers(<font style="color:#4ec9b0;">uint</font> max) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Set minimum vote ratio required on chain.</font>
    <font style="color:#6a9955;">/// @param min Ratio (0-4999).</font>
    <font style="color:#569cd6;">function</font> setMinVoteRatioOnChain(<font style="color:#4ec9b0;">uint</font> min) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Set vote base to par or paid.</font>
    <font style="color:#6a9955;">/// @param _basedOnPar True for par-based votes.</font>
    <font style="color:#569cd6;">function</font> setVoteBase(<font style="color:#4ec9b0;">bool</font> _basedOnPar) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Increase/decrease capital base.</font>
    <font style="color:#6a9955;">/// @param votingWeight Voting weight (%).</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight (%).</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#569cd6;">function</font> capIncrease(
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add a member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> addMember(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Link a share to its member owner.</font>
    <font style="color:#6a9955;">/// @param share Share record.</font>
    <font style="color:#569cd6;">function</font> addShareToMember(
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Unlink a share from its member owner.</font>
    <font style="color:#6a9955;">/// @param share Share record.</font>
    <font style="color:#569cd6;">function</font> removeShareFromMember(
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Update member votes and points.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param votingWeight Voting weight (%).</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight (%).</font>
    <font style="color:#6a9955;">/// @param deltaPaid Paid delta.</font>
    <font style="color:#6a9955;">/// @param deltaPar Par delta.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#569cd6;">function</font> increaseAmtOfMember(
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">external</font> ;

    <font style="color:#6a9955;">/// @notice Group a member under a root.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param root Root member user number.</font>
    <font style="color:#569cd6;">function</font> addMemberToGroup(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> root) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a member from group.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> removeMemberFromGroup(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Restore shares in ROM.</font>
    <font style="color:#6a9955;">/// @param shares Share list.</font>
    <font style="color:#569cd6;">function</font> restoreSharesInRom(SharesRepo.Share[] <font style="color:#569cd6;">memory</font> shares) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Restore top chain state.</font>
    <font style="color:#6a9955;">/// @param list Node list.</font>
    <font style="color:#6a9955;">/// @param para Chain parameters.</font>
    <font style="color:#569cd6;">function</font> restoreTopChainInRom(TopChain.Node[] <font style="color:#569cd6;">memory</font> list, TopChain.Para <font style="color:#569cd6;">memory</font> para) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Restore vote history for a member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param list Checkpoint list.</font>
    <font style="color:#6a9955;">/// @param distrPts Distribution points checkpoint.</font>
    <font style="color:#569cd6;">function</font> restoreVotesHistoryInRom(
        <font style="color:#4ec9b0;">uint</font> acct, Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font> list,
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> distrPts
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ##############</font>
    <font style="color:#6a9955;">// ##   Read   ##</font>
    <font style="color:#6a9955;">// ##############</font>

    <font style="color:#6a9955;">/// @notice Check whether a user is member.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return True if member.</font>
    <font style="color:#569cd6;">function</font> isMember(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get total member count.</font>
    <font style="color:#6a9955;">/// @return Member count.</font>
    <font style="color:#569cd6;">function</font> qtyOfMembers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get member list.</font>
    <font style="color:#6a9955;">/// @return Member user numbers.</font>
    <font style="color:#569cd6;">function</font> membersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get sorted member list.</font>
    <font style="color:#6a9955;">/// @return Sorted member user numbers.</font>
    <font style="color:#569cd6;">function</font> sortedMembersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get top-level member count.</font>
    <font style="color:#6a9955;">/// @return Count.</font>
    <font style="color:#569cd6;">function</font> qtyOfTopMembers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get top-level member list.</font>
    <font style="color:#6a9955;">/// @return Member user numbers.</font>
    <font style="color:#569cd6;">function</font> topMembersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- Cap & Equity ----</font>

    <font style="color:#6a9955;">/// @notice Get owners' equity checkpoint.</font>
    <font style="color:#6a9955;">/// @return Equity checkpoint.</font>
    <font style="color:#569cd6;">function</font> ownersEquity() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get owners' distribution points.</font>
    <font style="color:#6a9955;">/// @return Points checkpoint.</font>
    <font style="color:#569cd6;">function</font> ownersPoints() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get capital at date.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#6a9955;">/// @return Checkpoint at date.</font>
    <font style="color:#569cd6;">function</font> capAtDate(<font style="color:#4ec9b0;">uint</font> date) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get owners' equity history.</font>
    <font style="color:#6a9955;">/// @return Checkpoint history.</font>
    <font style="color:#569cd6;">function</font> ownersEquityHistory() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>);

   <font style="color:#6a9955;">/// @notice Get member equity.</font>
   <font style="color:#6a9955;">/// @param acct Member user number.</font>
   <font style="color:#6a9955;">/// @return Equity checkpoint.</font>
   <font style="color:#569cd6;">function</font> equityOfMember(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
       <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

   <font style="color:#6a9955;">/// @notice Get member distribution points.</font>
   <font style="color:#6a9955;">/// @param acct Member user number.</font>
   <font style="color:#6a9955;">/// @return Points checkpoint.</font>
   <font style="color:#569cd6;">function</font> pointsOfMember(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
       <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get member equity at date.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#6a9955;">/// @return Equity checkpoint.</font>
    <font style="color:#569cd6;">function</font> equityAtDate(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get member current votes.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @return Votes.</font>
    <font style="color:#569cd6;">function</font> votesInHand(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Get member votes at date.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#6a9955;">/// @return Votes.</font>
    <font style="color:#569cd6;">function</font> votesAtDate(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Get vote history of member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @return Checkpoint history.</font>
    <font style="color:#569cd6;">function</font> votesHistory(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- ShareNum ----</font>

    <font style="color:#6a9955;">/// @notice Get number of shares held by member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @return Share count.</font>
    <font style="color:#569cd6;">function</font> qtyOfSharesInHand(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get shares held by member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @return Share list.</font>
    <font style="color:#569cd6;">function</font> sharesInHand(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- Class ---- </font>

    <font style="color:#6a9955;">/// @notice Get number of shares in class held by member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return Share count.</font>
    <font style="color:#569cd6;">function</font> qtyOfSharesInClass(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get shares in class held by member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return Share list.</font>
    <font style="color:#569cd6;">function</font> sharesInClass(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check if member belongs to class.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return True if belongs.</font>
    <font style="color:#569cd6;">function</font> isClassMember(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get classes a member belongs to.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @return Class ids.</font>
    <font style="color:#569cd6;">function</font> classesBelonged(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get member count in a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return Member count.</font>
    <font style="color:#569cd6;">function</font> qtyOfClassMember(<font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Get members of a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return Member list.</font>
    <font style="color:#569cd6;">function</font> getMembersOfClass(<font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- TopChain ----</font>

    <font style="color:#6a9955;">/// @notice Check whether votes are based on par.</font>
    <font style="color:#6a9955;">/// @return True if based on par.</font>
    <font style="color:#569cd6;">function</font> basedOnPar() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get max member count.</font>
    <font style="color:#6a9955;">/// @return Max count.</font>
    <font style="color:#569cd6;">function</font> maxQtyOfMembers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get min vote ratio on chain.</font>
    <font style="color:#6a9955;">/// @return Ratio value.</font>
    <font style="color:#569cd6;">function</font> minVoteRatioOnChain() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get total votes.</font>
    <font style="color:#6a9955;">/// @return Vote sum.</font>
    <font style="color:#569cd6;">function</font> totalVotes() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Get controller user number.</font>
    <font style="color:#6a9955;">/// @return Controller user number.</font>
    <font style="color:#569cd6;">function</font> controllor() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get tail of chain.</font>
    <font style="color:#6a9955;">/// @return Tail node id.</font>
    <font style="color:#569cd6;">function</font> tailOfChain() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get head of queue.</font>
    <font style="color:#6a9955;">/// @return Head node id.</font>
    <font style="color:#569cd6;">function</font> headOfQueue() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get tail of queue.</font>
    <font style="color:#6a9955;">/// @return Tail node id.</font>
    <font style="color:#569cd6;">function</font> tailOfQueue() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">// ==== group ====</font>

    <font style="color:#6a9955;">/// @notice Get group representative for member.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @return Representative user number.</font>
    <font style="color:#569cd6;">function</font> groupRep(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>);

    <font style="color:#6a9955;">/// @notice Get total votes of a group.</font>
    <font style="color:#6a9955;">/// @param acct Group root user number.</font>
    <font style="color:#6a9955;">/// @return Vote sum.</font>
    <font style="color:#569cd6;">function</font> votesOfGroup(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Get group depth.</font>
    <font style="color:#6a9955;">/// @param acct Group root user number.</font>
    <font style="color:#6a9955;">/// @return Depth value.</font>
    <font style="color:#569cd6;">function</font> deepOfGroup(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/// @notice Get members of a group.</font>
    <font style="color:#6a9955;">/// @param acct Group root user number.</font>
    <font style="color:#6a9955;">/// @return Member list.</font>
    <font style="color:#569cd6;">function</font> membersOfGroup(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get number of groups on chain.</font>
    <font style="color:#6a9955;">/// @return Group count.</font>
    <font style="color:#569cd6;">function</font> qtyOfGroupsOnChain() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get total number of groups.</font>
    <font style="color:#6a9955;">/// @return Group count.</font>
    <font style="color:#569cd6;">function</font> qtyOfGroups() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/// @notice Check if two accounts are affiliated.</font>
    <font style="color:#6a9955;">/// @param acct1 First user number.</font>
    <font style="color:#6a9955;">/// @param acct2 Second user number.</font>
    <font style="color:#6a9955;">/// @return True if affiliated.</font>
    <font style="color:#569cd6;">function</font> affiliated(<font style="color:#4ec9b0;">uint256</font> acct1, <font style="color:#4ec9b0;">uint256</font> acct2)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== snapshot ====</font>

    <font style="color:#6a9955;">/// @notice Get top chain snapshot.</font>
    <font style="color:#6a9955;">/// @return Node list.</font>
    <font style="color:#6a9955;">/// @return Chain parameters.</font>
    <font style="color:#569cd6;">function</font> getSnapshot() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (TopChain.Node[] <font style="color:#569cd6;">memory</font>, TopChain.Para <font style="color:#569cd6;">memory</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfMembers.sol

---

| |
|:---|
| **contracts/comps/books/rom/RegisterOfMembers.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfMembers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfMembers <font style="color:#569cd6;">is</font> IRegisterOfMembers, AccessControl {
    <font style="color:#569cd6;">using</font> MembersRepo <font style="color:#569cd6;">for</font> MembersRepo.Repo;
    <font style="color:#569cd6;">using</font> TopChain <font style="color:#569cd6;">for</font> TopChain.Chain;
    <font style="color:#569cd6;">using</font> Checkpoints <font style="color:#569cd6;">for</font> Checkpoints.History;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Repository for members and their shares, votes, equity, points, and groupings.</font>
    MembersRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Modifier   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">modifier</font> onlyROS() {
        <font style="color:#569cd6;">if</font> (msg.sender != <font style="color:#4ec9b0;">address</font>(_gk.getROS())) {
            <font style="color:#569cd6;">revert</font> ROM_WrongAccess(<font style="color:#ce9178;">"ROM_NotROS"</font>);
        }
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ---- Options Setting ----</font>

    <font style="color:#569cd6;">function</font> setMaxQtyOfMembers(<font style="color:#4ec9b0;">uint</font> max) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.chain.setMaxQtyOfMembers(max);
        <font style="color:#569cd6;">emit</font> SetMaxQtyOfMembers(max);
    }

    <font style="color:#569cd6;">function</font> setMinVoteRatioOnChain(<font style="color:#4ec9b0;">uint</font> min) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.chain.setMinVoteRatioOnChain(min);
        <font style="color:#569cd6;">emit</font> SetMinVoteRatioOnChain(min);
    }

    <font style="color:#569cd6;">function</font> setVoteBase(<font style="color:#4ec9b0;">bool</font> _basedOnPar) <font style="color:#569cd6;">external</font> onlyKeeper {
        IRegisterOfShares _ros = _gk.getROS();
        <font style="color:#569cd6;">if</font> (_repo.setVoteBase(_ros, _basedOnPar))
            <font style="color:#569cd6;">emit</font> SetVoteBase(_basedOnPar);
    }

    <font style="color:#569cd6;">function</font> capIncrease(
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">external</font> onlyROS {

        _repo.increaseAmtOfCap(votingWeight, distrWeight, paid, par, isIncrease);

        <font style="color:#569cd6;">if</font> (isIncrease) <font style="color:#569cd6;">emit</font> CapIncrease(votingWeight, paid, par, distrWeight);
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">emit</font> CapDecrease(votingWeight, paid, par, distrWeight);
    }

    <font style="color:#569cd6;">function</font> addMember(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> onlyROS {
        <font style="color:#569cd6;">if</font> (_repo.addMember(acct))
            <font style="color:#569cd6;">emit</font> AddMember(acct, _repo.chain.qtyOfMembers());
    }

    <font style="color:#569cd6;">function</font> addShareToMember(
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">external</font> onlyROS {

        _repo.addShareToMember(share.head);

        _repo.increaseAmtOfMember(
            share.head.shareholder,
            share.head.votingWeight,
            share.body.distrWeight,
            share.body.paid,
            share.body.par,
            <font style="color:#569cd6;">true</font>
        );

        <font style="color:#569cd6;">emit</font> AddShareToMember(share.head.seqOfShare, share.head.shareholder);
    }

    <font style="color:#569cd6;">function</font> removeShareFromMember(
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">external</font> onlyROS {

        _repo.increaseAmtOfMember(
            share.head.shareholder,
            share.head.votingWeight,
            share.body.distrWeight,
            share.body.paid,
            share.body.par,
            <font style="color:#569cd6;">false</font>
        );

        _repo.removeShareFromMember(share.head);

        <font style="color:#569cd6;">if</font> (_repo.qtyOfSharesInHand(share.head.shareholder) == <font style="color:#b5cea8;">0</font>)
            _repo.delMember(share.head.shareholder);

        <font style="color:#569cd6;">emit</font> RemoveShareFromMember(share.head.seqOfShare, share.head.shareholder);
    }

    <font style="color:#569cd6;">function</font> increaseAmtOfMember(
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">public</font> onlyROS {

        _repo.increaseAmtOfMember(
            acct,
            votingWeight,
            distrWeight,
            deltaPaid,
            deltaPar,
            isIncrease
        );

        <font style="color:#569cd6;">emit</font> ChangeAmtOfMember(
            acct,
            deltaPaid,
            deltaPar,
            isIncrease
        );
    }

    <font style="color:#569cd6;">function</font> addMemberToGroup(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> root) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.chain.top2Sub(acct, root);
        <font style="color:#569cd6;">emit</font> AddMemberToGroup(acct, root);
    }

    <font style="color:#569cd6;">function</font> removeMemberFromGroup(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#4ec9b0;">uint</font> root = _repo.chain.rootOf(acct);
        <font style="color:#4ec9b0;">uint256</font> next = _repo.chain.nextNode(acct);

        _repo.chain.sub2Top(acct);
        <font style="color:#569cd6;">emit</font> RemoveMemberFromGroup(acct, root);
        <font style="color:#569cd6;">if</font> (acct == root) <font style="color:#569cd6;">emit</font> ChangeGroupRep(root, next);
    }

    <font style="color:#6a9955;">// ==== Restore ====</font>

    <font style="color:#569cd6;">function</font> restoreSharesInRom(SharesRepo.Share[] <font style="color:#569cd6;">memory</font> shares) <font style="color:#569cd6;">external</font> onlyKeeper{
        _repo.restoreSharesInRepo(shares);
    }

    <font style="color:#569cd6;">function</font> restoreTopChainInRom(
        TopChain.Node[] <font style="color:#569cd6;">memory</font> list, TopChain.Para <font style="color:#569cd6;">memory</font> para
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.chain.restoreChain(list, para);
    }

    <font style="color:#569cd6;">function</font> restoreVotesHistoryInRom(
        <font style="color:#4ec9b0;">uint</font> acct, Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font> list,
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> distrPts
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        MembersRepo.Member <font style="color:#569cd6;">storage</font> member = _repo.members[acct];
        member.votesInHand.restoreHistory(list);
        member.votesInHand.updateDistrPoints(distrPts.rate, distrPts.paid, distrPts.par, distrPts.points);
    }

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##   Read I/O   ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">// ---- membersList ----</font>

    <font style="color:#569cd6;">function</font> isMember(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isMember(acct);
    }

    <font style="color:#569cd6;">function</font> qtyOfMembers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.qtyOfMembers();
    }

    <font style="color:#569cd6;">function</font> membersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.membersList();
    }

    <font style="color:#569cd6;">function</font> sortedMembersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.sortedMembersList();
    }

    <font style="color:#569cd6;">function</font> qtyOfTopMembers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.qtyOfTopMembers();
    }

    <font style="color:#569cd6;">function</font> topMembersList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.topMembersList();
    }

    <font style="color:#6a9955;">// ---- Cap & Equity ----</font>

    <font style="color:#569cd6;">function</font> ownersEquity()
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.ownersEquity();
    }

    <font style="color:#569cd6;">function</font> ownersPoints()
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.ownersPoints();
    }

    <font style="color:#569cd6;">function</font> capAtDate(<font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.capAtDate(date);
    }

    <font style="color:#569cd6;">function</font> ownersEquityHistory() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.ownersEquityHistory();
    }

   <font style="color:#569cd6;">function</font> equityOfMember(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.equityOfMember(acct);
    }

   <font style="color:#569cd6;">function</font> pointsOfMember(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.pointsOfMember(acct);
    }

   <font style="color:#569cd6;">function</font> equityAtDate(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.equityAtDate(acct, date);
    }

    <font style="color:#569cd6;">function</font> votesInHand(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>)
    {
        <font style="color:#569cd6;">if</font> (!_repo.isMember(acct)) {
            <font style="color:#569cd6;">revert</font> ROM_WrongInput(<font style="color:#ce9178;">"ROM_NotMember"</font>);
        }
        <font style="color:#569cd6;">return</font> _repo.chain.nodes[acct].amt;
    }

    <font style="color:#569cd6;">function</font> votesAtDate(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.votesAtDate(acct, date);
    }

    <font style="color:#569cd6;">function</font> votesHistory(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.votesHistory(acct);
    }

    <font style="color:#6a9955;">// ---- ShareNum ----</font>

    <font style="color:#569cd6;">function</font> qtyOfSharesInHand(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.qtyOfSharesInHand(acct);
    }

    <font style="color:#569cd6;">function</font> sharesInHand(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.sharesInHand(acct);
    }

    <font style="color:#6a9955;">// ---- Class ---- </font>

    <font style="color:#569cd6;">function</font> qtyOfSharesInClass(<font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.qtyOfSharesInClass(acct, class);
    }

    <font style="color:#569cd6;">function</font> sharesInClass(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.sharesInClass(acct, class);
    }

    <font style="color:#569cd6;">function</font> isClassMember(<font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isClassMember(acct, class);
    }

    <font style="color:#569cd6;">function</font> classesBelonged(<font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.classesBelonged(acct);
    }

    <font style="color:#569cd6;">function</font> qtyOfClassMember(<font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.qtyOfClassMember(class);
    }

    <font style="color:#569cd6;">function</font> getMembersOfClass(<font style="color:#4ec9b0;">uint</font> class)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getMembersOfClass(class);
    }

    <font style="color:#6a9955;">// ---- TopChain ----</font>

    <font style="color:#569cd6;">function</font> basedOnPar() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.basedOnPar();
    }

    <font style="color:#569cd6;">function</font> maxQtyOfMembers() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.maxQtyOfMembers();
    }

    <font style="color:#569cd6;">function</font> minVoteRatioOnChain() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.minVoteRatioOnChain();
    }

    <font style="color:#569cd6;">function</font> totalVotes() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.totalVotes();
    }

    <font style="color:#569cd6;">function</font> controllor() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.head();
    }

    <font style="color:#569cd6;">function</font> tailOfChain() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.tail();
    }

    <font style="color:#569cd6;">function</font> headOfQueue() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.headOfQueue();
    }

    <font style="color:#569cd6;">function</font> tailOfQueue() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.tailOfQueue();
    }

    <font style="color:#6a9955;">// ==== group ====</font>

    <font style="color:#569cd6;">function</font> groupRep(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.rootOf(acct);
    }

    <font style="color:#569cd6;">function</font> votesOfGroup(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.votesOfGroup(acct);
    }

    <font style="color:#569cd6;">function</font> deepOfGroup(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.deepOfBranch(acct);
    }

    <font style="color:#569cd6;">function</font> membersOfGroup(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.chain.membersOfGroup(acct);
    }

    <font style="color:#569cd6;">function</font> qtyOfGroupsOnChain() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.qtyOfBranches();
    }

    <font style="color:#569cd6;">function</font> qtyOfGroups() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.qtyOfGroups();
    }

    <font style="color:#569cd6;">function</font> affiliated(<font style="color:#4ec9b0;">uint256</font> acct1, <font style="color:#4ec9b0;">uint256</font> acct2)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.chain.affiliated(acct1, acct2);
    }

    <font style="color:#6a9955;">// ==== snapshot ====</font>

    <font style="color:#569cd6;">function</font> getSnapshot() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (TopChain.Node[] <font style="color:#569cd6;">memory</font>, TopChain.Para <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.chain.getSnapshot();
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfOptions.sol

---

| |
|:---|
| **contracts/comps/books/roo/IRegisterOfOptions.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../roc/terms/IOptions.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/OptionsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/SwapsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IRegisterOfOptions</font>
<font style="color:#6a9955;">/// @notice Interface for options registry, execution, and swaps.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfOptions {

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Event    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Emitted when an option is created.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param codeOfOpt Option code.</font>
    <font style="color:#569cd6;">event</font> CreateOpt(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> codeOfOpt);

    <font style="color:#6a9955;">/// @notice Emitted when an option is issued.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param issueDate Issue date (timestamp).</font>
    <font style="color:#569cd6;">event</font> IssueOpt(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> issueDate);

    <font style="color:#6a9955;">/// @notice Emitted when an obligor is added to an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param obligor Obligor account.</font>
    <font style="color:#569cd6;">event</font> AddObligorIntoOpt(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> obligor);

    <font style="color:#6a9955;">/// @notice Emitted when an obligor is removed from an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param obligor Obligor account.</font>
    <font style="color:#569cd6;">event</font> RemoveObligorFromOpt(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> obligor);

    <font style="color:#6a9955;">/// @notice Emitted when oracle data is updated for an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param data1 Data slot 1.</font>
    <font style="color:#6a9955;">/// @param data2 Data slot 2.</font>
    <font style="color:#6a9955;">/// @param data3 Data slot 3.</font>
    <font style="color:#569cd6;">event</font> UpdateOracle(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> data1, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> data2, <font style="color:#4ec9b0;">uint</font> data3);

    <font style="color:#6a9955;">/// @notice Emitted when an option is executed.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#569cd6;">event</font> ExecOpt(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt);

    <font style="color:#6a9955;">/// @notice Emitted when a swap is registered for an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param snOfSwap Swap serial number.</font>
    <font style="color:#569cd6;">event</font> RegSwap(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfSwap);

    <font style="color:#6a9955;">/// @notice Emitted when a swap is paid off.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param snOfSwap Swap serial number.</font>
    <font style="color:#569cd6;">event</font> PayOffSwap(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfSwap);

    <font style="color:#6a9955;">/// @notice Emitted when a swap is terminated.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">event</font> TerminateSwap(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfSwap);

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Write    ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Create an option from encoded inputs.</font>
    <font style="color:#6a9955;">/// @param sn Packed option head.</font>
    <font style="color:#6a9955;">/// @param snOfCond Packed condition head.</font>
    <font style="color:#6a9955;">/// @param rightholder Rightholder user number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @return head Option head.</font>
    <font style="color:#569cd6;">function</font> createOption(
        <font style="color:#4ec9b0;">bytes32</font> sn,
        <font style="color:#4ec9b0;">bytes32</font> snOfCond,
        <font style="color:#4ec9b0;">uint</font> rightholder,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(OptionsRepo.Head <font style="color:#569cd6;">memory</font> head);

    <font style="color:#6a9955;">/// @notice Issue a prepared option.</font>
    <font style="color:#6a9955;">/// @param opt Option record.</font>
    <font style="color:#569cd6;">function</font> issueOption(OptionsRepo.Option <font style="color:#569cd6;">memory</font> opt) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Register option terms contract.</font>
    <font style="color:#6a9955;">/// @param opts Options terms address.</font>
    <font style="color:#569cd6;">function</font> regOptionTerms(<font style="color:#4ec9b0;">address</font> opts) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add obligor to option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param obligor Obligor user number.</font>
    <font style="color:#569cd6;">function</font> addObligorIntoOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove obligor from option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param obligor Obligor user number.</font>
    <font style="color:#569cd6;">function</font> removeObligorFromOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Update oracle data for option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param d1 Data slot 1.</font>
    <font style="color:#6a9955;">/// @param d2 Data slot 2.</font>
    <font style="color:#6a9955;">/// @param d3 Data slot 3.</font>
    <font style="color:#569cd6;">function</font> updateOracle(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> d1,
        <font style="color:#4ec9b0;">uint</font> d2,
        <font style="color:#4ec9b0;">uint</font> d3
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> execOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create a swap for an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfTarget Target share sequence.</font>
    <font style="color:#6a9955;">/// @param paidOfTarget Paid target amount.</font>
    <font style="color:#6a9955;">/// @param seqOfPledge Pledge share sequence.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#6a9955;">/// @return swap Swap record.</font>
    <font style="color:#569cd6;">function</font> createSwap(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfTarget,
        <font style="color:#4ec9b0;">uint</font> paidOfTarget,
        <font style="color:#4ec9b0;">uint</font> seqOfPledge,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap);

    <font style="color:#6a9955;">/// @notice Pay off a swap.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @return swap Swap record.</font>
    <font style="color:#569cd6;">function</font> payOffSwap(
        <font style="color:#4ec9b0;">uint</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap);

    <font style="color:#6a9955;">/// @notice Terminate a swap.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @return swap Swap record.</font>
    <font style="color:#569cd6;">function</font> terminateSwap(
        <font style="color:#4ec9b0;">uint</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap);

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Get option counter.</font>
    <font style="color:#6a9955;">/// @return Counter value.</font>
    <font style="color:#569cd6;">function</font> counterOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#6a9955;">/// @notice Get number of options.</font>
    <font style="color:#6a9955;">/// @return Count.</font>
    <font style="color:#569cd6;">function</font> qtyOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">/// @notice Check whether an option exists.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get option by sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return opt Option record.</font>
    <font style="color:#569cd6;">function</font> getOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OptionsRepo.Option <font style="color:#569cd6;">memory</font> opt);

    <font style="color:#6a9955;">/// @notice Get all options.</font>
    <font style="color:#6a9955;">/// @return Option list.</font>
    <font style="color:#569cd6;">function</font> getAllOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (OptionsRepo.Option[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check if account is rightholder.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return True if rightholder.</font>
    <font style="color:#569cd6;">function</font> isRightholder(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check if account is obligor.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return True if obligor.</font>
    <font style="color:#569cd6;">function</font> isObligor(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get obligors of an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return Obligor list.</font>
    <font style="color:#569cd6;">function</font> getObligorsOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get option sequence list.</font>
    <font style="color:#6a9955;">/// @return Option ids.</font>
    <font style="color:#569cd6;">function</font> getSeqListOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== Swap ====</font>
    <font style="color:#6a9955;">/// @notice Get swap counter for option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return Counter value.</font>
    <font style="color:#569cd6;">function</font> counterOfSwaps(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>);

    <font style="color:#6a9955;">/// @notice Get total paid target amount.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return Paid sum.</font>
    <font style="color:#569cd6;">function</font> sumPaidOfTarget(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Check if swap exists.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isSwap(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get swap by sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @return swap Swap record.</font>
    <font style="color:#569cd6;">function</font> getSwap(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap);

    <font style="color:#6a9955;">/// @notice Get all swaps of an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return Swap list.</font>
    <font style="color:#569cd6;">function</font> getAllSwapsOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether all swaps are closed.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return True if all closed.</font>
    <font style="color:#569cd6;">function</font> allSwapsClosed(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== oracles ====</font>

    <font style="color:#6a9955;">/// @notice Get oracle value at date.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#6a9955;">/// @return Oracle checkpoint.</font>
    <font style="color:#569cd6;">function</font> getOracleAtDate(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get latest oracle value.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return Oracle checkpoint.</font>
    <font style="color:#569cd6;">function</font> getLatestOracle(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get all oracle checkpoints of an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @return Checkpoint list.</font>
    <font style="color:#569cd6;">function</font> getAllOraclesOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfOptions.sol

---

| |
|:---|
| **contracts/comps/books/roo/RegisterOfOptions.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfOptions.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfOptions <font style="color:#569cd6;">is</font> IRegisterOfOptions, AccessControl {
    <font style="color:#569cd6;">using</font> OptionsRepo <font style="color:#569cd6;">for</font> OptionsRepo.Repo;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Repository for options and swaps.</font>
    OptionsRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">function</font> createOption(
        <font style="color:#4ec9b0;">bytes32</font> sn,
        <font style="color:#4ec9b0;">bytes32</font> snOfCond,
        <font style="color:#4ec9b0;">uint</font> rightholder,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(OptionsRepo.Head <font style="color:#569cd6;">memory</font> head) {
        head = _repo.createOption(sn, snOfCond, rightholder, paid, par);
        <font style="color:#569cd6;">emit</font> CreateOpt(head.seqOfOpt, OptionsRepo.codifyHead(head));
    }

    <font style="color:#569cd6;">function</font> issueOption(OptionsRepo.Option <font style="color:#569cd6;">memory</font> opt) <font style="color:#569cd6;">external</font> onlyKeeper
    {
        <font style="color:#4ec9b0;">uint</font> issueDate = _repo.issueOption(opt);
        <font style="color:#569cd6;">emit</font> IssueOpt(opt.head.seqOfOpt, issueDate);
    }

    <font style="color:#569cd6;">function</font> regOptionTerms(<font style="color:#4ec9b0;">address</font> opts) <font style="color:#569cd6;">external</font> onlyKeeper {

        OptionsRepo.Option[] <font style="color:#569cd6;">memory</font> optsList = IOptions(opts).getAllOptions();

        <font style="color:#4ec9b0;">uint</font> len = optsList.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            OptionsRepo.Option <font style="color:#569cd6;">memory</font> opt = optsList[len - <font style="color:#b5cea8;">1</font>];

            opt.head.issueDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
            opt.body.state = <font style="color:#4ec9b0;">uint8</font>(OptionsRepo.StateOfOpt.Issued);

            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> obligors =
                IOptions(opts).getObligorsOfOption(opt.head.seqOfOpt);

            opt.head = _repo.regOption(opt);

            _repo.addObligorsIntoOption(opt.head.seqOfOpt, obligors);

            <font style="color:#569cd6;">emit</font> CreateOpt(opt.head.seqOfOpt, OptionsRepo.codifyHead(opt.head));

            len--;
        }
    }

    <font style="color:#569cd6;">function</font> addObligorIntoOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.addObligorIntoOption(seqOfOpt, obligor))
            <font style="color:#569cd6;">emit</font> AddObligorIntoOpt(seqOfOpt, obligor);
    }

    <font style="color:#569cd6;">function</font> removeObligorFromOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> obligor) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.removeObligorFromOption(seqOfOpt, obligor))
            <font style="color:#569cd6;">emit</font> RemoveObligorFromOpt(seqOfOpt, obligor);
    }

    <font style="color:#6a9955;">// ==== Exec Option ====</font>

    <font style="color:#569cd6;">function</font> updateOracle(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> d1,
        <font style="color:#4ec9b0;">uint</font> d2,
        <font style="color:#4ec9b0;">uint</font> d3
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.updateOracle(seqOfOpt, d1, d2, d3);
        <font style="color:#569cd6;">emit</font> UpdateOracle(seqOfOpt, d1, d2, d3);
    }

    <font style="color:#569cd6;">function</font> execOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.execOption(seqOfOpt, caller);
        <font style="color:#569cd6;">emit</font> ExecOpt(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> createSwap(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfTarget,
        <font style="color:#4ec9b0;">uint</font> paidOfTarget,
        <font style="color:#4ec9b0;">uint</font> seqOfPledge,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap) {
        swap = _repo.createSwap(seqOfOpt, seqOfTarget, paidOfTarget, seqOfPledge, caller, _gk.getROS());
        <font style="color:#569cd6;">emit</font> RegSwap(seqOfOpt, SwapsRepo.codifySwap(swap));
    }

    <font style="color:#569cd6;">function</font> payOffSwap(
        <font style="color:#4ec9b0;">uint</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap) {
        swap = _repo.payOffSwap(seqOfOpt, seqOfSwap);
        <font style="color:#569cd6;">emit</font> PayOffSwap(seqOfOpt, SwapsRepo.codifySwap(swap));
    }

    <font style="color:#569cd6;">function</font> terminateSwap(
        <font style="color:#4ec9b0;">uint</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap){
        swap = _repo.terminateSwap(seqOfOpt, seqOfSwap);
        <font style="color:#569cd6;">emit</font> TerminateSwap(seqOfOpt, seqOfSwap);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">// ==== Option ====</font>

    <font style="color:#569cd6;">function</font> counterOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _repo.counterOfOptions();
    }

    <font style="color:#569cd6;">function</font> qtyOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.qtyOfOptions();
    }

    <font style="color:#569cd6;">function</font> isOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OptionsRepo.Option <font style="color:#569cd6;">memory</font> opt)
    {
        opt = _repo.getOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getAllOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (OptionsRepo.Option[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getAllOptions();
    }

    <font style="color:#569cd6;">function</font> isRightholder(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isRightholder(seqOfOpt, acct);
    }

    <font style="color:#569cd6;">function</font> isObligor(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isObligor(seqOfOpt, acct);
    }

    <font style="color:#569cd6;">function</font> getObligorsOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getObligorsOfOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getSeqListOfOptions() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSeqList();
    }

    <font style="color:#6a9955;">// ==== Swap ====</font>
    <font style="color:#569cd6;">function</font> counterOfSwaps(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.counterOfSwaps(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> sumPaidOfTarget(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.sumPaidOfTarget(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> isSwap(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isSwap(seqOfOpt, seqOfSwap);
    }

    <font style="color:#569cd6;">function</font> getSwap(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getSwap(seqOfOpt, seqOfSwap);
    }

    <font style="color:#569cd6;">function</font> getAllSwapsOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getAllSwapsOfOption(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> allSwapsClosed(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.allSwapsClosed(seqOfOpt);
    }

    <font style="color:#6a9955;">// ==== Oracles ====</font>

    <font style="color:#569cd6;">function</font> getOracleAtDate(<font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> date)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getOracleAtDate(seqOfOpt, date);
    }

    <font style="color:#569cd6;">function</font> getLatestOracle(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getLatestOracle(seqOfOpt);
    }

    <font style="color:#569cd6;">function</font> getAllOraclesOfOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getAllOraclesOfOption(seqOfOpt);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfPledges.sol

---

| |
|:---|
| **contracts/comps/books/rop/IRegisterOfPledges.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/PledgesRepo.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfPledges</font>
<font style="color:#6a9955;">/// @notice Interface for creating, transferring, and enforcing share pledges.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfPledges {

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Error     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">error</font> ROP_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Event     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a pledge is created.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param creditor Creditor account.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount pledged.</font>
    <font style="color:#6a9955;">/// @param par Par amount pledged.</font>
    <font style="color:#569cd6;">event</font> CreatePledge(
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld,
        <font style="color:#4ec9b0;">uint256</font> creditor,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> paid,
        <font style="color:#4ec9b0;">uint256</font> par
    );

    <font style="color:#6a9955;">/// @notice Emitted when a pledge is transferred.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Original pledge sequence.</font>
    <font style="color:#6a9955;">/// @param newSeqOfPld New pledge sequence.</font>
    <font style="color:#6a9955;">/// @param buyer New creditor account.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount transferred.</font>
    <font style="color:#6a9955;">/// @param par Par amount transferred.</font>
    <font style="color:#569cd6;">event</font> TransferPledge(
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> newSeqOfPld,
        <font style="color:#4ec9b0;">uint256</font> buyer,
        <font style="color:#4ec9b0;">uint256</font> paid,
        <font style="color:#4ec9b0;">uint256</font> par
    );

    <font style="color:#6a9955;">/// @notice Emitted when debt is refunded against a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param refundAmt Refunded amount.</font>
    <font style="color:#569cd6;">event</font> RefundDebt(
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> refundAmt
    );

    <font style="color:#6a9955;">/// @notice Emitted when a pledge execution is extended.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param extDays Extension days.</font>
    <font style="color:#569cd6;">event</font> ExtendPledge(
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld,
        <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> extDays
    );

    <font style="color:#6a9955;">/// @notice Emitted when a pledge is locked by hash.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#569cd6;">event</font> LockPledge(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> hashLock);

    <font style="color:#6a9955;">/// @notice Emitted when a pledge is released by hash key.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Hash key.</font>
    <font style="color:#569cd6;">event</font> ReleasePledge(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">indexed</font> hashKey);

    <font style="color:#6a9955;">/// @notice Emitted when a pledge is executed.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#569cd6;">event</font> ExecPledge(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld);

    <font style="color:#6a9955;">/// @notice Emitted when a pledge is revoked.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#569cd6;">event</font> RevokePledge(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfPld);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Create a pledge from encoded inputs.</font>
    <font style="color:#6a9955;">/// @param snOfPld Pledge serial number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount pledged.</font>
    <font style="color:#6a9955;">/// @param par Par amount pledged.</font>
    <font style="color:#6a9955;">/// @param guaranteedAmt Guaranteed amount.</font>
    <font style="color:#6a9955;">/// @param execDays Execution days after default.</font>
    <font style="color:#6a9955;">/// @return head Pledge head.</font>
    <font style="color:#569cd6;">function</font> createPledge(
        <font style="color:#4ec9b0;">bytes32</font> snOfPld,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(PledgesRepo.Head <font style="color:#569cd6;">memory</font> head);

    <font style="color:#6a9955;">/// @notice Issue a pledge by head parameters.</font>
    <font style="color:#6a9955;">/// @param head Pledge head.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount pledged.</font>
    <font style="color:#6a9955;">/// @param par Par amount pledged.</font>
    <font style="color:#6a9955;">/// @param guaranteedAmt Guaranteed amount.</font>
    <font style="color:#6a9955;">/// @param execDays Execution days after default.</font>
    <font style="color:#6a9955;">/// @return regHead Registered head.</font>
    <font style="color:#569cd6;">function</font> issuePledge(
        PledgesRepo.Head <font style="color:#569cd6;">memory</font> head,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(PledgesRepo.Head <font style="color:#569cd6;">memory</font> regHead);

    <font style="color:#6a9955;">/// @notice Register a pledge record.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#6a9955;">/// @return head Registered head.</font>
    <font style="color:#569cd6;">function</font> regPledge(
        PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> pld
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(PledgesRepo.Head <font style="color:#569cd6;">memory</font> head);

    <font style="color:#6a9955;">/// @notice Transfer pledge to a new creditor.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param buyer New creditor account.</font>
    <font style="color:#6a9955;">/// @param amt Transfer amount.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#6a9955;">/// @return newPld New pledge record.</font>
    <font style="color:#569cd6;">function</font> transferPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> newPld);

    <font style="color:#6a9955;">/// @notice Refund debt against a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param amt Refunded amount.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#6a9955;">/// @return newPld Updated pledge record.</font>
    <font style="color:#569cd6;">function</font> refundDebt(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> newPld);

    <font style="color:#6a9955;">/// @notice Extend pledge execution days.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param extDays Extension days.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> extendPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> extDays,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Lock/Release/Exec/Revoke ====</font>

    <font style="color:#6a9955;">/// @notice Lock a pledge with hash lock.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> lockPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Release a locked pledge with hash key.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Hash key.</font>
    <font style="color:#6a9955;">/// @return releaseDate Release date.</font>
    <font style="color:#569cd6;">function</font> releasePledge(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font> releaseDate);

    <font style="color:#6a9955;">/// @notice Execute a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> execPledge(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Revoke a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> revokePledge(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld, <font style="color:#4ec9b0;">uint</font> caller)
        <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Get pledge counter for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return Counter value.</font>
    <font style="color:#569cd6;">function</font> counterOfPledges(<font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>);

    <font style="color:#6a9955;">/// @notice Check whether a pledge exists.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isPledge(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get pledge serial number list.</font>
    <font style="color:#6a9955;">/// @return Serial numbers.</font>
    <font style="color:#569cd6;">function</font> getSNList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get pledge by sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @return Pledge record.</font>
    <font style="color:#569cd6;">function</font> getPledge(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get pledges of a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return Pledge list.</font>
    <font style="color:#569cd6;">function</font> getPledgesOfShare(<font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get all pledges.</font>
    <font style="color:#6a9955;">/// @return Pledge list.</font>
    <font style="color:#569cd6;">function</font> getAllPledges() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge[] <font style="color:#569cd6;">memory</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfPledges.sol

---

| |
|:---|
| **contracts/comps/books/rop/RegisterOfPledges.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfPledges.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfPledges <font style="color:#569cd6;">is</font> IRegisterOfPledges, AccessControl {
    <font style="color:#569cd6;">using</font> PledgesRepo <font style="color:#569cd6;">for</font> PledgesRepo.Repo;
    <font style="color:#569cd6;">using</font> PledgesRepo <font style="color:#569cd6;">for</font> PledgesRepo.Pledge;

    <font style="color:#6a9955;">// Repository for pledges and their states.</font>
    PledgesRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> createPledge(
        <font style="color:#4ec9b0;">bytes32</font> snOfPld,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(PledgesRepo.Head <font style="color:#569cd6;">memory</font> head){
        head = _repo.createPledge(
            snOfPld,
            paid,
            par,
            guaranteedAmt,
            execDays
        );

        <font style="color:#569cd6;">emit</font> CreatePledge(
            head.seqOfShare,
            head.seqOfPld,
            head.creditor,
            paid,
            par
        );
    }

    <font style="color:#569cd6;">function</font> issuePledge(
        PledgesRepo.Head <font style="color:#569cd6;">memory</font> head,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(PledgesRepo.Head <font style="color:#569cd6;">memory</font> regHead)
    {
        regHead = _repo.issuePledge(
            head,
            paid,
            par,
            guaranteedAmt,
            execDays
        );

        <font style="color:#569cd6;">emit</font> CreatePledge(
            head.seqOfShare,
            head.seqOfPld,
            head.creditor,
            paid,
            par
        );
    }

    <font style="color:#569cd6;">function</font> regPledge(
        PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> pld
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(PledgesRepo.Head <font style="color:#569cd6;">memory</font> head){
        head = _repo.regPledge(pld);

        <font style="color:#569cd6;">emit</font> CreatePledge(
            pld.head.seqOfShare,
            head.seqOfPld,
            pld.head.creditor,
            pld.body.paid,
            pld.body.par
        );
    }

    <font style="color:#6a9955;">// ==== Transfer Pledge ====</font>

    <font style="color:#569cd6;">function</font> transferPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> newPld)
    {
        <font style="color:#569cd6;">if</font> (buyer == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> ROP_WrongInput(<font style="color:#ce9178;">"ROP_ZeroBuyer"</font>);
        }

        newPld = _repo.splitPledge(seqOfShare, seqOfPld, buyer, amt, caller);

        <font style="color:#569cd6;">emit</font> TransferPledge(
            newPld.head.seqOfShare,
            seqOfPld,
            newPld.head.seqOfPld,
            newPld.head.creditor,
            newPld.body.paid,
            newPld.body.par
        );
    }

    <font style="color:#6a9955;">// ==== Update Pledge ====</font>

    <font style="color:#569cd6;">function</font> refundDebt(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> newPld)
    {
        newPld = _repo.splitPledge(seqOfShare, seqOfPld, <font style="color:#b5cea8;">0</font>, amt, caller);

        <font style="color:#569cd6;">emit</font> RefundDebt(seqOfShare, seqOfPld, amt);
    }

    <font style="color:#569cd6;">function</font> extendPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> extDays,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.pledges[seqOfShare][seqOfPld].extendPledge(extDays, caller);
        <font style="color:#569cd6;">emit</font> ExtendPledge(seqOfShare, seqOfPld, extDays);
    }

    <font style="color:#6a9955;">// ==== Lock/Release/Exec/Revoke ====</font>

    <font style="color:#569cd6;">function</font> lockPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.pledges[seqOfShare][seqOfPld].lockPledge(hashLock, caller);
        <font style="color:#569cd6;">emit</font> LockPledge(seqOfShare, seqOfPld, hashLock);
    }

    <font style="color:#569cd6;">function</font> releasePledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        PledgesRepo.Pledge <font style="color:#569cd6;">storage</font> pld =
            _repo.pledges[seqOfShare][seqOfPld];
        pld.releasePledge(hashKey);
        <font style="color:#569cd6;">emit</font> ReleasePledge(seqOfShare, seqOfPld, hashKey);
        <font style="color:#569cd6;">return</font> pld.body.paid;
    }

    <font style="color:#569cd6;">function</font> execPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld, <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.pledges[seqOfShare][seqOfPld].execPledge(caller);
        <font style="color:#569cd6;">emit</font> ExecPledge(seqOfShare, seqOfPld);
    }

    <font style="color:#569cd6;">function</font> revokePledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld, <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.pledges[seqOfShare][seqOfPld].revokePledge(caller);
        <font style="color:#569cd6;">emit</font> RevokePledge(seqOfShare, seqOfPld);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#569cd6;">function</font> counterOfPledges(<font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.counterOfPld(seqOfShare);
    }

    <font style="color:#569cd6;">function</font> isPledge(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPledge)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isPledge(seqOfShare, seqOfPledge);
    }

    <font style="color:#569cd6;">function</font> getSNList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getSNList();
    }

    <font style="color:#569cd6;">function</font> getPledge(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint256</font> seqOfPld)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getPledge(seqOfShare, seqOfPld);
    }

    <font style="color:#569cd6;">function</font> getPledgesOfShare(<font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getPledgesOfShare(seqOfShare);
    }

    <font style="color:#569cd6;">function</font> getAllPledges() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (PledgesRepo.Pledge[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getAllPledges();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfRedemptions.sol

---

| |
|:---|
| **contracts/comps/books/ror/IRegisterOfRedemptions.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/RedemptionsRepo.sol"</font>;

<font style="color:#6a9955;">/// @title IRegisterOfRedemptions</font>
<font style="color:#6a9955;">/// @notice Interface for redemption requests, NAV price, and class packs.</font>
<font style="color:#569cd6;">interface</font> IRegisterOfRedemptions {

    <font style="color:#6a9955;">/// @notice Emitted when a redeemable class is added.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">event</font> AddRedeemableClass(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class);

    <font style="color:#6a9955;">/// @notice Emitted when a redeemable class is removed.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">event</font> RemoveRedeemableClass(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class);

    <font style="color:#6a9955;">/// @notice Emitted when NAV price is updated.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param price NAV price.</font>
    <font style="color:#569cd6;">event</font> UpdateNavPrice(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> price);

    <font style="color:#6a9955;">/// @notice Emitted when a redemption request is submitted.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount requested.</font>
    <font style="color:#6a9955;">/// @param value Redemption value.</font>
    <font style="color:#569cd6;">event</font> RequestForRedemption(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> value);

    <font style="color:#6a9955;">/// @notice Emitted when a class pack is redeemed.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param sumOfPaid Total paid amount redeemed.</font>
    <font style="color:#6a9955;">/// @param totalValue Total redemption value.</font>
    <font style="color:#569cd6;">event</font> RedeemClass(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> sumOfPaid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> totalValue);

    <font style="color:#6a9955;">/// @notice Emitted when a share is redeemed.</font>
    <font style="color:#6a9955;">/// @param shareholder Shareholder user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount redeemed.</font>
    <font style="color:#6a9955;">/// @param value Redemption value.</font>
    <font style="color:#569cd6;">event</font> RedeemShare(<font style="color:#4ec9b0;">uint</font> shareholder, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> value);

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#6a9955;">/// @notice Add a redeemable share class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">function</font> addRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a redeemable share class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">function</font> removeRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Update NAV price for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param price NAV price.</font>
    <font style="color:#569cd6;">function</font> updateNavPrice(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> price) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create a redemption request for a share.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount to redeem.</font>
    <font style="color:#6a9955;">/// @return request Request record.</font>
    <font style="color:#569cd6;">function</font> requestForRedemption(
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> class,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> request
    );

    <font style="color:#6a9955;">/// @notice Redeem a pack for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#6a9955;">/// @return list Requests in pack.</font>
    <font style="color:#6a9955;">/// @return info Pack info.</font>
    <font style="color:#569cd6;">function</font> redeem(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request[] <font style="color:#569cd6;">memory</font> list, RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info
    );

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Check whether a class is redeemable.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return True if redeemable.</font>
    <font style="color:#569cd6;">function</font> isRedeemable(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get list of redeemable classes.</font>
    <font style="color:#6a9955;">/// @return list Class ids.</font>
    <font style="color:#569cd6;">function</font> getClassesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">// ==== Class ====</font>

    <font style="color:#6a9955;">/// @notice Get redemption info for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return info Class info.</font>
    <font style="color:#569cd6;">function</font> getInfoOfClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info
    );

    <font style="color:#6a9955;">/// @notice Get packs list for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @return list Pack ids.</font>
    <font style="color:#569cd6;">function</font> getPacksList(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">// ==== Pack ====</font>

    <font style="color:#6a9955;">/// @notice Get pack info.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#6a9955;">/// @return info Pack info.</font>
    <font style="color:#569cd6;">function</font> getInfoOfPack(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info
    );

    <font style="color:#6a9955;">/// @notice Get shares list in a pack.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#6a9955;">/// @return list Share sequences.</font>
    <font style="color:#569cd6;">function</font> getSharesList(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list);

    <font style="color:#6a9955;">/// @notice Get redemption request for a share in a pack.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @return request Request record.</font>
    <font style="color:#569cd6;">function</font> getRequest(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack, <font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> request
    );

    <font style="color:#6a9955;">/// @notice Get all requests in a pack.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#6a9955;">/// @return requests Request list.</font>
    <font style="color:#569cd6;">function</font> getRequests(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request[] <font style="color:#569cd6;">memory</font> requests
    );
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfRedemptions.sol

---

| |
|:---|
| **contracts/comps/books/ror/RegisterOfRedemptions.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfRedemptions.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/RedemptionsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfRedemptions <font style="color:#569cd6;">is</font> IRegisterOfRedemptions, AccessControl {
    <font style="color:#569cd6;">using</font> RedemptionsRepo <font style="color:#569cd6;">for</font> RedemptionsRepo.Repo;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Repository for redemption classes, packs, and requests.</font>
    RedemptionsRepo.Repo <font style="color:#569cd6;">private</font> _list;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#569cd6;">function</font> addRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> onlyKeeper {
        _list.addRedeemableClass(class);
        <font style="color:#569cd6;">emit</font> AddRedeemableClass(class);
    }

    <font style="color:#569cd6;">function</font> removeRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> onlyKeeper {
        _list.removeRedeemableClass(class);
        <font style="color:#569cd6;">emit</font> RemoveRedeemableClass(class);
    }

    <font style="color:#569cd6;">function</font> updateNavPrice(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> price) <font style="color:#569cd6;">external</font> onlyKeeper{
        _list.updateNavPrice(class, price);
        <font style="color:#569cd6;">emit</font> UpdateNavPrice(class, price);
    }

    <font style="color:#6a9955;">// ==== Redeem ====</font>

    <font style="color:#569cd6;">function</font> requestForRedemption(
        <font style="color:#4ec9b0;">uint</font> caller, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> request
    ) {
        request = _list.requestForRedemption(caller, class, seqOfShare, paid);

        <font style="color:#569cd6;">emit</font> RequestForRedemption(request.class, request.seqOfShare, request.paid, request.value);
    }

    <font style="color:#569cd6;">function</font> redeem(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request[] <font style="color:#569cd6;">memory</font> list, RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info
    ) {
        (list, info) = _list.redeem(class, seqOfPack);

        <font style="color:#569cd6;">emit</font> RedeemClass(class, info.paid, info.value);

        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> request = list[len-<font style="color:#b5cea8;">1</font>];
            <font style="color:#569cd6;">emit</font> RedeemShare(
                request.shareholder,
                request.class,
                request.seqOfShare,
                request.paid,
                request.value
            );
            len--;
        }

    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> isRedeemable(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _list.isRedeemable(class);
    }

    <font style="color:#569cd6;">function</font> getClassesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        list = _list.getClassesList();
    }

    <font style="color:#6a9955;">// ==== Class ====</font>

    <font style="color:#569cd6;">function</font> getInfoOfClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info
    ) {
        info = _list.getInfoOfClass(class);
    }

    <font style="color:#569cd6;">function</font> getPacksList(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        list = _list.getPacksList(class);
    }

    <font style="color:#6a9955;">// ==== Pack ====</font>

    <font style="color:#569cd6;">function</font> getInfoOfPack(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info
    ) {
        info = _list.getInfoOfPack(class, seqOfPack);
    }

    <font style="color:#569cd6;">function</font> getSharesList(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        list = _list.getSharesList(class, seqOfPack);
    }

    <font style="color:#569cd6;">function</font> getRequest(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack, <font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> request
    ) {
        request = _list.getRequest(class, seqOfPack, seqOfShare);
    }

    <font style="color:#569cd6;">function</font> getRequests(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        RedemptionsRepo.Request[] <font style="color:#569cd6;">memory</font> requests
    ) {
        requests = _list.getRequests(class, seqOfPack);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRegisterOfShares.sol

---

| |
|:---|
| **contracts/comps/books/ros/IRegisterOfShares.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/SharesRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/LockersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/DealsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../rom/IRegisterOfMembers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../roc/IShareholdersAgreement.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../roc/terms/ILockUp.sol"</font>;

<font style="color:#569cd6;">interface</font> IRegisterOfShares {

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Error     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">error</font> ROS_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROS_WrongAccess(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Event     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a share is issued.</font>
    <font style="color:#6a9955;">/// @param shareNumber Share serial number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#569cd6;">event</font> IssueShare(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> shareNumber, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> par);

    <font style="color:#6a9955;">/// @notice Emitted when a share is transferred.</font>
    <font style="color:#6a9955;">/// @param shareNumber Original share serial number.</font>
    <font style="color:#6a9955;">/// @param newShareNumber New share serial number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount transferred.</font>
    <font style="color:#6a9955;">/// @param par Par amount transferred.</font>
    <font style="color:#569cd6;">event</font> TransferShare(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> shareNumber, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> newShareNumber, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> par);

    <font style="color:#6a9955;">/// @notice Emitted when capital is paid in for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param amount Paid-in amount.</font>
    <font style="color:#569cd6;">event</font> PayInCapital(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amount);

    <font style="color:#6a9955;">/// @notice Emitted when paid/par amounts are reduced for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount reduced.</font>
    <font style="color:#6a9955;">/// @param par Par amount reduced.</font>
    <font style="color:#569cd6;">event</font> SubAmountFromShare(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> par);

    <font style="color:#6a9955;">/// @notice Emitted when a share is deregistered.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">event</font> DeregisterShare(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare);

    <font style="color:#6a9955;">/// @notice Emitted when price of paid amount is updated.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param newPrice New price.</font>
    <font style="color:#569cd6;">event</font> UpdatePriceOfPaid(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> newPrice);

    <font style="color:#6a9955;">/// @notice Emitted when paid-in deadline is updated.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paidInDeadline New deadline timestamp.</font>
    <font style="color:#569cd6;">event</font> UpdatePaidInDeadline(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paidInDeadline);

    <font style="color:#6a9955;">/// @notice Emitted when clean paid amount is decreased.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Amount decreased.</font>
    <font style="color:#569cd6;">event</font> DecreaseCleanPaid(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid);

    <font style="color:#6a9955;">/// @notice Emitted when clean paid amount is increased.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Amount increased.</font>
    <font style="color:#569cd6;">event</font> IncreaseCleanPaid(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> paid);

    <font style="color:#6a9955;">/// @notice Emitted when a pay-in amount is set with hash lock.</font>
    <font style="color:#6a9955;">/// @param headSn Share head serial number.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#569cd6;">event</font> SetPayInAmt(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> headSn, <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> hashLock);

    <font style="color:#6a9955;">/// @notice Emitted when a pay-in amount is withdrawn.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param amount Amount withdrawn.</font>
    <font style="color:#569cd6;">event</font> WithdrawPayInAmt(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amount);

    <font style="color:#6a9955;">/// @notice Emitted when equity of a class is adjusted.</font>
    <font style="color:#6a9955;">/// @param isIncrease True if increase, false if decrease.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param amt Amount changed.</font>
    <font style="color:#569cd6;">event</font> IncreaseEquityOfClass(<font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">indexed</font> isIncrease, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> class, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> issueShare(
        <font style="color:#4ec9b0;">bytes32</font> shareNumber,
        <font style="color:#4ec9b0;">uint</font> payInDeadline,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> distrWeight
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> addShare(SharesRepo.Share <font style="color:#569cd6;">memory</font> share) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> setPayInAmt(<font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> hashLock) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> requestPaidInCapital(<font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> withdrawPayInAmt(<font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> payInCapital(<font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> transferShare(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> to,
        <font style="color:#4ec9b0;">uint</font> priceOfPaid,
        <font style="color:#4ec9b0;">uint</font> priceOfPar
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> decreaseCapital(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== CleanPaid ====</font>

    <font style="color:#569cd6;">function</font> decreaseCleanPaid(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> increaseCleanPaid(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== State & PaidInDeadline ====</font>

    <font style="color:#569cd6;">function</font> updatePriceOfPaid(<font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> newPrice) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> updatePaidInDeadline(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paidInDeadline) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== EquityOfClass ====</font>

    <font style="color:#569cd6;">function</font> increaseEquityOfClass(
        <font style="color:#4ec9b0;">bool</font> isIncrease,
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">uint</font> deltaCleanPaid
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> restoreShares(SharesRepo.Share[] <font style="color:#569cd6;">memory</font> shares, SharesRepo.Share[] <font style="color:#569cd6;">memory</font> classes) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##   Read I/O   ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#569cd6;">function</font> counterOfShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>);

    <font style="color:#569cd6;">function</font> counterOfClasses() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>);

    <font style="color:#6a9955;">// ==== SharesRepo ====</font>

    <font style="color:#569cd6;">function</font> isShare(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#569cd6;">function</font> getShare(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (
        SharesRepo.Share <font style="color:#569cd6;">memory</font>
    );

    <font style="color:#569cd6;">function</font> getQtyOfShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> getSeqListOfShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getSharesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getShareZero() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- Class ----    </font>

    <font style="color:#569cd6;">function</font> getQtyOfSharesInClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#569cd6;">function</font> getSeqListOfClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getInfoOfClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getSharesOfClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getPremium() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">// ==== PayInCapital ====</font>

    <font style="color:#569cd6;">function</font> getLocker(
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (LockersRepo.Locker <font style="color:#569cd6;">memory</font>);

    <font style="color:#569cd6;">function</font> getLocksList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ==== NotLocked ====</font>

    <font style="color:#569cd6;">function</font> notLocked(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> closingDate
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

 }</code></pre>
```
 |
| [Contents](#toc) |

---

## RegisterOfShares.sol

---

| |
|:---|
| **contracts/comps/books/ros/RegisterOfShares.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRegisterOfShares.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../common/access/AccessControl.sol"</font>;

<font style="color:#569cd6;">contract</font> RegisterOfShares <font style="color:#569cd6;">is</font> IRegisterOfShares, AccessControl {
    <font style="color:#569cd6;">using</font> LockersRepo <font style="color:#569cd6;">for</font> LockersRepo.Repo;
    <font style="color:#569cd6;">using</font> LockersRepo <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> SharesRepo <font style="color:#569cd6;">for</font> SharesRepo.Repo;
    <font style="color:#569cd6;">using</font> SharesRepo <font style="color:#569cd6;">for</font> SharesRepo.Share;
    <font style="color:#569cd6;">using</font> SharesRepo <font style="color:#569cd6;">for</font> SharesRepo.Head;
    <font style="color:#569cd6;">using</font> SharesRepo <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint256</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Repository for shares and their classes, amounts, paid and par values, </font>
    <font style="color:#6a9955;">// distribution weights, and payment deadlines.</font>
    SharesRepo.Repo <font style="color:#569cd6;">private</font> _repo;
    <font style="color:#6a9955;">// Repository for lockers of pay-in capital, which are used to secure the </font>
    <font style="color:#6a9955;">// payment of shares.</font>
    LockersRepo.Repo <font style="color:#569cd6;">private</font> _lockers;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">// ==== IssueShare ====</font>

    <font style="color:#569cd6;">function</font> issueShare(
        <font style="color:#4ec9b0;">bytes32</font> shareNumber,
        <font style="color:#4ec9b0;">uint</font> payInDeadline,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> distrWeight
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
            SharesRepo.createShare(shareNumber, payInDeadline, paid, par, distrWeight);

        addShare(share);
    }

    <font style="color:#569cd6;">function</font> addShare(
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">public</font> onlyKeeper {

        IRegisterOfMembers _rom = _gk.getROM();

        share = _repo.addShare(share);

        _rom.addMember(share.head.shareholder);
        _rom.capIncrease(
            share.head.votingWeight,
            share.body.distrWeight,
            share.body.paid,
            share.body.par,
            <font style="color:#569cd6;">true</font>
        );
        _rom.addShareToMember(share);

        <font style="color:#569cd6;">emit</font> IssueShare(
            share.head.codifyHead(),
            share.body.paid,
            share.body.par
        );
    }

    <font style="color:#6a9955;">// ==== PayInCapital ====</font>

    <font style="color:#569cd6;">function</font> setPayInAmt(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        SharesRepo.Share <font style="color:#569cd6;">storage</font> share =
            _repo.shares[seqOfShare];

        LockersRepo.Head <font style="color:#569cd6;">memory</font> head =
            LockersRepo.Head({
                <font style="color:#569cd6;">from</font>: share.head.seqOfShare,
                to: share.head.shareholder,
                expireDate: <font style="color:#4ec9b0;">uint48</font>(expireDate),
                value: <font style="color:#4ec9b0;">uint128</font>(amt)
            });

        _lockers.lockPoints(head, hashLock);

        <font style="color:#569cd6;">emit</font> SetPayInAmt(LockersRepo.codifyHead(head), hashLock);
    }

    <font style="color:#569cd6;">function</font> requestPaidInCapital(
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        LockersRepo.Head <font style="color:#569cd6;">memory</font> head =
            _lockers.pickupPoints(hashLock, hashKey, <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">if</font> (head.value > <font style="color:#b5cea8;">0</font>) {

            SharesRepo.Share <font style="color:#569cd6;">storage</font> share =
                _repo.shares[head.<font style="color:#569cd6;">from</font>];

            _payInCapital(share, head.value);
        }
    }

    <font style="color:#569cd6;">function</font> withdrawPayInAmt(
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        LockersRepo.Head <font style="color:#569cd6;">memory</font> head =
            _lockers.withdrawDeposit(hashLock, seqOfShare);

        <font style="color:#569cd6;">emit</font> WithdrawPayInAmt(head.<font style="color:#569cd6;">from</font>, head.value);
    }

    <font style="color:#569cd6;">function</font> payInCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        SharesRepo.Share <font style="color:#569cd6;">storage</font> share =
            _repo.shares[seqOfShare];

        _payInCapital(share, amt);
    }

    <font style="color:#6a9955;">// ==== TransferShare ====</font>

    <font style="color:#569cd6;">function</font> transferShare(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> to,
        <font style="color:#4ec9b0;">uint</font> priceOfPaid,
        <font style="color:#4ec9b0;">uint</font> priceOfPar
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        IRegisterOfMembers _rom = _gk.getROM();

        SharesRepo.Share <font style="color:#569cd6;">storage</font> share = _repo.shares[seqOfShare];

        <font style="color:#569cd6;">if</font> (share.head.shareholder == to) {
            <font style="color:#569cd6;">revert</font> ROS_WrongInput(<font style="color:#ce9178;">"ROS_SelfDeal"</font>);
        }

        SharesRepo.Share <font style="color:#569cd6;">memory</font> newShare;

        newShare.head = SharesRepo.Head({
            seqOfShare: <font style="color:#b5cea8;">0</font>,
            preSeq: share.head.seqOfShare,
            class: share.head.class,
            issueDate: <font style="color:#b5cea8;">0</font>,
            shareholder: <font style="color:#4ec9b0;">uint40</font>(to),
            priceOfPaid: <font style="color:#4ec9b0;">uint32</font>(priceOfPaid),
            priceOfPar: <font style="color:#4ec9b0;">uint32</font>(priceOfPar),
            votingWeight: share.head.votingWeight,
            argu: <font style="color:#b5cea8;">0</font>
        });

        newShare.body = SharesRepo.Body({
            payInDeadline: share.body.payInDeadline,
            paid: <font style="color:#4ec9b0;">uint64</font>(paid),
            par: <font style="color:#4ec9b0;">uint64</font>(par),
            cleanPaid: <font style="color:#4ec9b0;">uint64</font>(paid),
            distrWeight: share.body.distrWeight
        });

        _decreaseShareAmt(share, paid, par);

        _rom.addMember(to);

        newShare = _repo.regShare(newShare);

        _rom.addShareToMember(newShare);

        <font style="color:#569cd6;">emit</font> TransferShare(
            share.head.codifyHead(),
            newShare.head.codifyHead(),
            paid,
            par
        );
    }

    <font style="color:#6a9955;">// ==== DecreaseCapital ====</font>

    <font style="color:#569cd6;">function</font> decreaseCapital(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        SharesRepo.Share <font style="color:#569cd6;">storage</font> share =
            _repo.shares[seqOfShare];

        _repo.increaseEquityOfClass(
            <font style="color:#569cd6;">false</font>,
            share.head.class,
            paid,
            par,
            <font style="color:#b5cea8;">0</font>
        );

        _gk.getROM().capIncrease(
            share.head.votingWeight,
            share.body.distrWeight,
            paid,
            par,
            <font style="color:#569cd6;">false</font>
        );

        _decreaseShareAmt(share, paid, par);
    }

    <font style="color:#6a9955;">// ==== cleanAmt ====</font>

    <font style="color:#569cd6;">function</font> decreaseCleanPaid(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.increaseCleanPaid(
            <font style="color:#569cd6;">false</font>,
            seqOfShare,
            paid
        );

        <font style="color:#569cd6;">emit</font> DecreaseCleanPaid(seqOfShare, paid);
    }

    <font style="color:#569cd6;">function</font> increaseCleanPaid(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.increaseCleanPaid(
            <font style="color:#569cd6;">true</font>,
            seqOfShare,
            paid
        );

        <font style="color:#569cd6;">emit</font> IncreaseCleanPaid(seqOfShare, paid);
    }

    <font style="color:#6a9955;">// ==== State & PaidInDeadline ====</font>

    <font style="color:#569cd6;">function</font> updatePriceOfPaid(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> newPrice
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.updatePriceOfPaid(seqOfShare, newPrice);
        <font style="color:#569cd6;">emit</font> UpdatePriceOfPaid(seqOfShare, newPrice);
    }

    <font style="color:#569cd6;">function</font> updatePaidInDeadline(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> deadline
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.updatePayInDeadline(seqOfShare, deadline);
        <font style="color:#569cd6;">emit</font> UpdatePaidInDeadline(seqOfShare, deadline);
    }

    <font style="color:#6a9955;">// ==== EquityOfClass ====</font>

    <font style="color:#569cd6;">function</font> increaseEquityOfClass(
        <font style="color:#4ec9b0;">bool</font> isIncrease,
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">uint</font> deltaCleanPaid
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.increaseEquityOfClass(
            isIncrease,
            classOfShare,
            deltaPaid,
            deltaPar,
            deltaCleanPaid
        );

        <font style="color:#4ec9b0;">uint</font> amt = (deltaPaid << <font style="color:#b5cea8;">128</font>) + <font style="color:#4ec9b0;">uint128</font>(deltaPar << <font style="color:#b5cea8;">64</font>) + <font style="color:#4ec9b0;">uint64</font>(deltaCleanPaid);

        <font style="color:#569cd6;">emit</font> IncreaseEquityOfClass(isIncrease, classOfShare, amt);
    }

    <font style="color:#6a9955;">// ==== private funcs ====</font>

    <font style="color:#569cd6;">function</font> _payInCapital(
        SharesRepo.Share <font style="color:#569cd6;">storage</font> share,
        <font style="color:#4ec9b0;">uint</font> amount
    ) <font style="color:#569cd6;">private</font> {

        IRegisterOfMembers _rom = _gk.getROM();

        _repo.payInCapital(share.head.seqOfShare, amount);

        _rom.capIncrease(
            share.head.votingWeight,
            share.body.distrWeight,
            amount,
            <font style="color:#b5cea8;">0</font>,
            <font style="color:#569cd6;">true</font>
        );

        _rom.increaseAmtOfMember(
            share.head.shareholder,
            share.head.votingWeight,
            share.body.distrWeight,
            amount,
            <font style="color:#b5cea8;">0</font>,
            <font style="color:#569cd6;">true</font>
        );

        <font style="color:#569cd6;">emit</font> PayInCapital(share.head.seqOfShare, amount);
    }

    <font style="color:#569cd6;">function</font> _decreaseShareAmt(
        SharesRepo.Share <font style="color:#569cd6;">storage</font> share,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">private</font> {

        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#569cd6;">if</font> (par == share.body.par) {

            _rom.removeShareFromMember(share);

            <font style="color:#569cd6;">emit</font> DeregisterShare(share.head.seqOfShare);

        } <font style="color:#569cd6;">else</font> {

            _rom.increaseAmtOfMember(
                share.head.shareholder,
                share.head.votingWeight,
                share.body.distrWeight,
                paid,
                par,
                <font style="color:#569cd6;">false</font>
            );

            <font style="color:#569cd6;">emit</font> SubAmountFromShare(share.head.seqOfShare, paid, par);
        }

        _repo.subAmtFromShare(share.head.seqOfShare, paid, par);
    }

    <font style="color:#569cd6;">function</font> restoreShares(
        SharesRepo.Share[] <font style="color:#569cd6;">memory</font> shares,
        SharesRepo.Share[] <font style="color:#569cd6;">memory</font> classes
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.restoreRepo(shares, classes);
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##   Read I/O  ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">function</font> counterOfShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> _repo.counterOfShares();
    }

    <font style="color:#569cd6;">function</font> counterOfClasses() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> _repo.counterOfClasses();
    }

    <font style="color:#6a9955;">// ==== SharesRepo ====</font>

    <font style="color:#569cd6;">function</font> isShare(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isShare(seqOfShare);
    }

    <font style="color:#569cd6;">function</font> getShare(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (
        SharesRepo.Share <font style="color:#569cd6;">memory</font>
    ) {
        <font style="color:#569cd6;">return</font> _repo.getShare(seqOfShare);
    }

    <font style="color:#569cd6;">function</font> getQtyOfShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.getQtyOfShares();
    }

    <font style="color:#569cd6;">function</font> getSeqListOfShares() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSeqListOfShares();
    }

    <font style="color:#569cd6;">function</font> getSharesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSharesList();
    }

    <font style="color:#569cd6;">function</font> getShareZero() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getShareZero();
    }

    <font style="color:#6a9955;">// ---- Class ----    </font>

    <font style="color:#569cd6;">function</font> getQtyOfSharesInClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.getQtyOfSharesInClass(classOfShare);
    }

    <font style="color:#569cd6;">function</font> getSeqListOfClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSeqListOfClass(classOfShare);
    }

    <font style="color:#569cd6;">function</font> getInfoOfClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getInfoOfClass(classOfShare);
    }

    <font style="color:#569cd6;">function</font> getSharesOfClass(
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SharesRepo.Share[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSharesOfClass(classOfShare);
    }

    <font style="color:#569cd6;">function</font> getPremium() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> _repo.getPremium();
    }

    <font style="color:#6a9955;">// ==== PayInCapital ====</font>

    <font style="color:#569cd6;">function</font> getLocker(
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (LockersRepo.Locker <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _lockers.getLocker(hashLock);
    }

    <font style="color:#569cd6;">function</font> getLocksList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _lockers.getSnList();
    }

    <font style="color:#6a9955;">// ==== NotLocked ====</font>
    <font style="color:#569cd6;">function</font> notLocked(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> closingDate
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        IShareholdersAgreement _sha = _gk.getSHA();

        <font style="color:#569cd6;">if</font> (!_sha.hasTitle(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.LockUp))){
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#4ec9b0;">address</font> lu = _sha.getTerm(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.LockUp));

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal;

        deal.head.typeOfDeal = <font style="color:#b5cea8;">2</font>;
        deal.head.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(seqOfShare);
        deal.head.closingDeadline = <font style="color:#4ec9b0;">uint48</font>(closingDate);

        <font style="color:#569cd6;">if</font> (!ILockUp(lu).isTriggered(deal)) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## AccessControl.sol

---

| |
|:---|
| **contracts/comps/common/access/AccessControl.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IAccessControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./Ownable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">contract</font> AccessControl <font style="color:#569cd6;">is</font> IAccessControl, Ownable {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#569cd6;">enum</font> Books {
        ZeroPoint,
        ROC,        <font style="color:#6a9955;">//1</font>
        ROD,
        BMM,
        ROM,
        GMM,        <font style="color:#6a9955;">//5</font>
        ROA,
        ROO,
        ROP,
        ROS,
        LOO,        <font style="color:#6a9955;">//10</font>
        ROI,
        Bank,
        Blank_1,
        Blank_2,
        Cashier,    <font style="color:#6a9955;">//15</font>
        ROR
    }

    <font style="color:#569cd6;">enum</font> Keepers {
        ZeroPoint,
        ROCK,       <font style="color:#6a9955;">//1</font>
        RODK,
        BMMK,
        ROMK,
        GMMK,       <font style="color:#6a9955;">//5</font>
        ROAK,
        ROOK,
        ROPK,
        SHAK,
        LOOK,       <font style="color:#6a9955;">//10</font>
        ROIK,
        Accountant,
        Blank_1,
        Blank_2,
        Blank_3,    <font style="color:#6a9955;">//15</font>
        RORK
    }

    <font style="color:#6a9955;">/// @notice Direct keeper admin record.</font>
    Admin <font style="color:#569cd6;">internal</font> _dk;
    <font style="color:#6a9955;">/// @notice General keeper address.</font>
    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">internal</font> _gk;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#6a9955;">/// @dev Storage gap for upgrade safety.</font>
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#569cd6;">function</font> initKeepers(
        <font style="color:#4ec9b0;">address</font> directKeeper,
        <font style="color:#4ec9b0;">address</font> generalKeeper
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">virtual</font> reinitializer(<font style="color:#b5cea8;">2</font>) {
        _initKeepers(directKeeper, generalKeeper);
    }

    <font style="color:#6a9955;">/// @dev Authorize UUPS upgrades. Caller must be GK or DK.</font>
    <font style="color:#569cd6;">function</font> _authorizeUpgrade(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> {
        <font style="color:#569cd6;">if</font> (msg.sender != _gk && msg.sender != _dk.addr) {
            <font style="color:#569cd6;">revert</font> AC_WrongAccess(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AC_NotGKorDK"</font>));
        }
        <font style="color:#569cd6;">if</font> (!_rc.getRC().tempExist(newImplementation)) {
            <font style="color:#569cd6;">revert</font> AC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AC_TempNotExist"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> upgradeDocTo(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">virtual</font> {
        upgradeTo(newImplementation);
        _rc.getRC().upgradeDoc(newImplementation);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Modifier  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Restrict to direct keeper.</font>
    <font style="color:#569cd6;">modifier</font> onlyDK {
        <font style="color:#569cd6;">if</font> (_dk.addr != msg.sender) {
            <font style="color:#569cd6;">revert</font> AC_WrongAccess(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AC_NotDK"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// /// @notice Restrict to general keeper.</font>
    <font style="color:#6a9955;">// modifier onlyGK {</font>
    <font style="color:#6a9955;">//     if (_gk != msg.sender) {</font>
    <font style="color:#6a9955;">//         revert AC_WrongAccess(bytes32("AC_NotGK"));</font>
    <font style="color:#6a9955;">//     }</font>
    <font style="color:#6a9955;">//     _;</font>
    <font style="color:#6a9955;">// }</font>

    <font style="color:#6a9955;">/// @notice Restrict to general keeper or direct keeper.</font>
    <font style="color:#569cd6;">modifier</font> onlyKeeper <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">if</font> (_gk != msg.sender && _dk.addr != msg.sender) {
            <font style="color:#569cd6;">revert</font> AC_WrongAccess(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AC_NotKeeper"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Initialize keeper addresses (one-time).</font>
    <font style="color:#6a9955;">/// @param directKeeper Direct keeper address.</font>
    <font style="color:#6a9955;">/// @param generalKeeper General keeper address.</font>
    <font style="color:#569cd6;">function</font> _initKeepers(<font style="color:#4ec9b0;">address</font> directKeeper,<font style="color:#4ec9b0;">address</font> generalKeeper) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">if</font> (_dk.state != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> AC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"AC_AlreadyInited"</font>));
        }
        _dk.addr = directKeeper;
        _gk = generalKeeper;
        _dk.state = <font style="color:#b5cea8;">1</font>;
    }

    <font style="color:#569cd6;">function</font> setDirectKeeper(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> onlyDK {
        _dk.addr = acct;
        <font style="color:#569cd6;">emit</font> SetDirectKeeper(acct);
    }

    <font style="color:#569cd6;">function</font> takeBackKeys (<font style="color:#4ec9b0;">address</font> target) <font style="color:#569cd6;">external</font> onlyDK {
        IAccessControl(target).setDirectKeeper(msg.sender);
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Read     ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">function</font> getDK() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _dk.addr;
    }

    <font style="color:#569cd6;">function</font> getGK() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _gk;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## DraftControl.sol

---

| |
|:---|
| **contracts/comps/common/access/DraftControl.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IDraftControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./AccessControl.sol"</font>;
<font style="color:#6a9955;">// import "../../../lib/InterfacesHub.sol";</font>

<font style="color:#569cd6;">contract</font> DraftControl <font style="color:#569cd6;">is</font> IDraftControl, AccessControl {
    <font style="color:#569cd6;">using</font> RolesRepo <font style="color:#569cd6;">for</font> RolesRepo.Repo;

    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">constant</font> _ATTORNEYS = keccak256(<font style="color:#4ec9b0;">bytes</font>(<font style="color:#ce9178;">"Attorneys"</font>));
    RolesRepo.Repo <font style="color:#569cd6;">private</font> _roles;

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Modifier  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">modifier</font> onlyGC {
        <font style="color:#569cd6;">if</font> (_roles.getRoleAdmin(_ATTORNEYS) != msg.sender)
            <font style="color:#569cd6;">revert</font> DC_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DC_NotGC"</font>));
        _;
    }

    <font style="color:#569cd6;">modifier</font> onlyAttorney {
        <font style="color:#569cd6;">if</font> (!_roles.hasRole(_ATTORNEYS, msg.sender))
            <font style="color:#569cd6;">revert</font> DC_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DC_NotAttorney"</font>));
        _;
    }

    <font style="color:#569cd6;">modifier</font> attorneyOrGK {
        <font style="color:#569cd6;">if</font> (!_roles.hasRole(_ATTORNEYS, msg.sender) &&
            msg.sender != _gk
        ) <font style="color:#569cd6;">revert</font> DC_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DC_NotAttorneyOrGK"</font>));
        _;
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">function</font> setRoleAdmin(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> onlyOwner {
        _roles.setRoleAdmin(role, acct);
        <font style="color:#569cd6;">emit</font> SetRoleAdmin(role, acct);
    }

    <font style="color:#569cd6;">function</font> grantRole(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> {
        _roles.grantRole(role, acct, msg.sender);
    }

    <font style="color:#569cd6;">function</font> revokeRole(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> {
        _roles.revokeRole(role, acct, msg.sender);
    }

    <font style="color:#569cd6;">function</font> renounceRole(<font style="color:#4ec9b0;">bytes32</font> role) <font style="color:#569cd6;">external</font> {
        _roles.renounceRole(role, msg.sender);
    }

    <font style="color:#569cd6;">function</font> abandonRole(<font style="color:#4ec9b0;">bytes32</font> role) <font style="color:#569cd6;">external</font> onlyOwner {
        _roles.abandonRole(role);
    }

    <font style="color:#569cd6;">function</font> lockContents() <font style="color:#569cd6;">public</font> onlyOwner {
        <font style="color:#569cd6;">if</font>(_dk.state != <font style="color:#b5cea8;">1</font>)
            <font style="color:#569cd6;">revert</font> DC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DC_NotInDraft"</font>));

        _roles.abandonRole(_ATTORNEYS);
        setNewOwner(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        _dk.state = <font style="color:#b5cea8;">2</font>;

        <font style="color:#569cd6;">emit</font> LockContents();
    }

    <font style="color:#6a9955;">// ##############</font>
    <font style="color:#6a9955;">// ##   Read   ##</font>
    <font style="color:#6a9955;">// ##############</font>

    <font style="color:#569cd6;">function</font> isFinalized() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _dk.state == <font style="color:#b5cea8;">2</font>;
    }

    <font style="color:#569cd6;">function</font> getRoleAdmin(<font style="color:#4ec9b0;">bytes32</font> role) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _roles.getRoleAdmin(role);
    }

    <font style="color:#569cd6;">function</font> hasRole(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _roles.hasRole(role, acct);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IAccessControl.sol

---

| |
|:---|
| **contracts/comps/common/access/IAccessControl.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IAccessControl</font>
<font style="color:#6a9955;">/// @notice Access control interface for keeper-based upgrade and key management.</font>
<font style="color:#6a9955;">/// @dev Used by router/keeper contracts to regain control over subordinate contracts.</font>
<font style="color:#569cd6;">interface</font> IAccessControl {

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##   Error      ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#569cd6;">error</font> AC_WrongAccess(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> AC_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##   Event      ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @notice Emitted when direct keeper is updated.</font>
    <font style="color:#6a9955;">/// @param keeper New direct keeper address.</font>
    <font style="color:#569cd6;">event</font> SetDirectKeeper(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> keeper);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Write     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">// ==== UUPS Upgradeability ====</font>

    <font style="color:#6a9955;">// /// @notice Initialize owner, registry center, and keeper addresses.</font>
    <font style="color:#6a9955;">// /// @param owner Owner address.</font>
    <font style="color:#6a9955;">// /// @param regCenter Registry center address.</font>
    <font style="color:#6a9955;">// /// @param directKeeper Direct keeper address.</font>
    <font style="color:#6a9955;">// /// @param generalKeeper General keeper address.</font>
    <font style="color:#6a9955;">// function initialize(</font>
    <font style="color:#6a9955;">//     address owner, </font>
    <font style="color:#6a9955;">//     address regCenter, </font>
    <font style="color:#6a9955;">//     address directKeeper, </font>
    <font style="color:#6a9955;">//     address generalKeeper</font>
    <font style="color:#6a9955;">// ) external;</font>

    <font style="color:#569cd6;">function</font> initKeepers(
        <font style="color:#4ec9b0;">address</font> directKeeper,
        <font style="color:#4ec9b0;">address</font> generalKeeper
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Upgrade implementation and register the upgrade in RegCenter.</font>
    <font style="color:#6a9955;">/// @param newImplementation New implementation address.</font>
    <font style="color:#569cd6;">function</font> upgradeDocTo(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Keeper Control ====</font>

    <font style="color:#6a9955;">/// @notice Set direct keeper address.</font>
    <font style="color:#6a9955;">/// @param keeper New direct keeper address.</font>
    <font style="color:#569cd6;">function</font> setDirectKeeper(<font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Reclaim keeper control from a subordinate contract.</font>
    <font style="color:#6a9955;">/// @param target Target contract address.</font>
    <font style="color:#569cd6;">function</font> takeBackKeys(<font style="color:#4ec9b0;">address</font> target) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Get current direct keeper address.</font>
    <font style="color:#6a9955;">/// @return Direct keeper address.</font>
    <font style="color:#569cd6;">function</font> getDK() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">/// @notice Get current general keeper address.</font>
    <font style="color:#6a9955;">/// @return General keeper address.</font>
    <font style="color:#569cd6;">function</font> getGK() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IDraftControl.sol

---

| |
|:---|
| **contracts/comps/common/access/IDraftControl.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/utils/RolesRepo.sol"</font>;

<font style="color:#6a9955;">/// @title IDraftControl</font>
<font style="color:#6a9955;">/// @notice Draft-stage access control and finalization interface.</font>
<font style="color:#6a9955;">/// @dev Manages role administration and irreversible content locking.</font>
<font style="color:#569cd6;">interface</font> IDraftControl {

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a wrong party attempts a limited action.</font>
    <font style="color:#569cd6;">error</font> DC_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when an action is attempted in an invalid state.</font>
    <font style="color:#569cd6;">error</font> DC_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when a role admin is updated.</font>
    <font style="color:#6a9955;">/// @param role Role identifier.</font>
    <font style="color:#6a9955;">/// @param acct New admin address.</font>
    <font style="color:#569cd6;">event</font> SetRoleAdmin(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> role, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> acct);

    <font style="color:#6a9955;">/// @notice Emitted when contents are finalized and roles are locked.</font>
    <font style="color:#569cd6;">event</font> LockContents();

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Write     ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @notice Set the admin for a role.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Admin address (must be a non-zero address).</font>
    <font style="color:#569cd6;">function</font> setRoleAdmin(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Grant a role to an account.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Account address (non-zero).</font>
    <font style="color:#569cd6;">function</font> grantRole(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Revoke a role from an account.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Account address (non-zero).</font>
    <font style="color:#569cd6;">function</font> revokeRole(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Renounce a role held by the caller.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#569cd6;">function</font> renounceRole(<font style="color:#4ec9b0;">bytes32</font> role) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Abandon a role by clearing its members.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#569cd6;">function</font> abandonRole(<font style="color:#4ec9b0;">bytes32</font> role) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Irreversibly lock contents by removing write authorities.</font>
    <font style="color:#6a9955;">/// @dev Typically sets owner to zero and abandons privileged roles.</font>
    <font style="color:#569cd6;">function</font> lockContents() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##   Read I/O   ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @notice Check whether contents are finalized.</font>
    <font style="color:#6a9955;">/// @return True if the contract is finalized and immutable.</font>
    <font style="color:#569cd6;">function</font> isFinalized() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get the admin address for a role.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#569cd6;">function</font> getRoleAdmin(<font style="color:#4ec9b0;">bytes32</font> role) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">/// @notice Check whether an account has a role.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Account address (non-zero).</font>
    <font style="color:#569cd6;">function</font> hasRole(<font style="color:#4ec9b0;">bytes32</font> role, <font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IOwnable.sol

---

| |
|:---|
| **contracts/comps/common/access/IOwnable.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IOwnable</font>
<font style="color:#6a9955;">/// @notice Minimal ownership interface used by upgradeable components.</font>
<font style="color:#6a9955;">/// @dev Exposes implementation address for UUPS checks and an owner update hook.</font>

<font style="color:#569cd6;">interface</font> IOwnable {

    <font style="color:#6a9955;">/// @notice Admin state container.</font>
    <font style="color:#6a9955;">/// @dev `state` is a small flag used to guard initialization.</font>
    <font style="color:#569cd6;">struct</font> Admin{
        <font style="color:#4ec9b0;">address</font> addr;
        <font style="color:#4ec9b0;">uint8</font> state;
    }

    <font style="color:#6a9955;">// ########################</font>
    <font style="color:#6a9955;">// ##   Error & Event    ##</font>
    <font style="color:#6a9955;">// ########################</font>

    <font style="color:#569cd6;">error</font> Ownable_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> Ownable_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> Ownable_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when the owner address is updated.</font>
    <font style="color:#6a9955;">/// @param owner New owner address.</font>
    <font style="color:#569cd6;">event</font> SetNewOwner(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> owner);

    <font style="color:#6a9955;">// ==== UUPS Upgradeability ====</font>

    <font style="color:#6a9955;">/// @notice Initialize ownership and registry center for an upgradeable proxy.</font>
    <font style="color:#6a9955;">/// @param owner_ Initial owner/admin address (non-zero expected).</font>
    <font style="color:#6a9955;">/// @param regCenter_ Registry center contract address (non-zero expected).</font>
    <font style="color:#569cd6;">function</font> initialize(<font style="color:#4ec9b0;">address</font> owner_,<font style="color:#4ec9b0;">address</font> regCenter_) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Return current implementation address (UUPS compatibility check).</font>
    <font style="color:#6a9955;">/// @return Implementation address.</font>
    <font style="color:#569cd6;">function</font> getImplementation() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Update owner address.</font>
    <font style="color:#6a9955;">/// @param acct New owner address (non-zero in implementations).</font>
    <font style="color:#569cd6;">function</font> setNewOwner(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">external</font>;

    <font style="color:#569cd6;">function</font> getOwner() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#569cd6;">function</font> getRegCenter() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Ownable.sol

---

| |
|:---|
| **contracts/comps/common/access/Ownable.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IOwnable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/proxy/utils/UUPSUpgradeable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/proxy/utils/Initializable.sol"</font>;

<font style="color:#569cd6;">contract</font> Ownable <font style="color:#569cd6;">is</font> IOwnable, Initializable, UUPSUpgradeable {

    Admin <font style="color:#569cd6;">internal</font> _owner;
    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">internal</font> _rc;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#569cd6;">constructor</font>(){
        _disableInitializers();
    }

    <font style="color:#569cd6;">function</font> initialize(
        <font style="color:#4ec9b0;">address</font> owner_,
        <font style="color:#4ec9b0;">address</font> regCenter_
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">virtual</font> initializer {
        _init(owner_, regCenter_);
    }

    <font style="color:#569cd6;">function</font> _init(
        <font style="color:#4ec9b0;">address</font> owner_,
        <font style="color:#4ec9b0;">address</font> regCenter_
    ) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">if</font> (_owner.state != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> Ownable_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Ownable_AlreadyInited"</font>));
        }
        <font style="color:#569cd6;">if</font> (regCenter_ == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> Ownable_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Ownable_ZeroRegCenter"</font>));
        }

        _owner.addr = owner_;
        _owner.state = <font style="color:#b5cea8;">1</font>;
        _rc = regCenter_;
    }

    <font style="color:#569cd6;">function</font> _authorizeUpgrade(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> onlyOwner {}

    <font style="color:#569cd6;">function</font> getImplementation() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _getImplementation();
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Modifier  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#569cd6;">modifier</font> onlyOwner <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">if</font> (_owner.addr != msg.sender) {
            <font style="color:#569cd6;">revert</font> Ownable_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"Ownable_NotOwner"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##  Write I/O  ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">function</font> setNewOwner(<font style="color:#4ec9b0;">address</font> acct) onlyOwner <font style="color:#569cd6;">public</font> {
        _owner.addr = acct;
        <font style="color:#569cd6;">emit</font> SetNewOwner(acct);
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##   Read I/O  ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">function</font> getOwner() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _owner.addr;
    }

    <font style="color:#569cd6;">function</font> getRegCenter() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> _rc;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## FilesFolder.sol

---

| |
|:---|
| **contracts/comps/common/components/FilesFolder.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IFilesFolder.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../access/AccessControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/FilesRepo.sol"</font>;

<font style="color:#569cd6;">contract</font> FilesFolder <font style="color:#569cd6;">is</font> IFilesFolder, AccessControl {
    <font style="color:#569cd6;">using</font> FilesRepo <font style="color:#569cd6;">for</font> FilesRepo.Repo;

    <font style="color:#6a9955;">/// @notice Internal repository of files managed by this folder.</font>
    FilesRepo.Repo <font style="color:#569cd6;">internal</font> _repo;

    <font style="color:#6a9955;">// ==== UUPSUpgradeable ====</font>

    <font style="color:#6a9955;">/// @dev Storage gap for upgrade safety.</font>
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> regFile(<font style="color:#4ec9b0;">bytes32</font> snOfDoc, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">external</font> onlyKeeper
    {
        <font style="color:#569cd6;">if</font> (_repo.regFile(snOfDoc, body))
            <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Created));
    }

    <font style="color:#569cd6;">function</font> circulateFile(
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">uint16</font> signingDays,
        <font style="color:#4ec9b0;">uint16</font> closingDays,
        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.circulateFile(body, signingDays, closingDays, vr, docUrl, docHash);
        <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Circulated));
    }

    <font style="color:#569cd6;">function</font> proposeFile(
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">uint64</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.proposeFile(body, seqOfMotion);
        <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Proposed));
    }

    <font style="color:#569cd6;">function</font> voteCountingForFile(
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">bool</font> approved
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        _repo.voteCountingForFile(body, approved);
        <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, approved ?
                <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Approved) :
                <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Rejected));
    }

    <font style="color:#569cd6;">function</font> execFile(
        <font style="color:#4ec9b0;">address</font> body
    ) <font style="color:#569cd6;">public</font> onlyDK {
        _repo.execFile(body);
        <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Closed));
    }

    <font style="color:#569cd6;">function</font> terminateFile(
        <font style="color:#4ec9b0;">address</font> body
    ) <font style="color:#569cd6;">public</font> onlyDK {
        _repo.terminateFile(body);
        <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Revoked));
    }

    <font style="color:#569cd6;">function</font> setStateOfFile(<font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">uint</font> state) <font style="color:#569cd6;">public</font> onlyKeeper {
        _repo.setStateOfFile(body, state);
        <font style="color:#569cd6;">emit</font> UpdateStateOfFile(body, state);
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> signingDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _repo.signingDeadline(body);
    }

    <font style="color:#569cd6;">function</font> closingDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _repo.closingDeadline(body);
    }

    <font style="color:#569cd6;">function</font> frExecDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _repo.frExecDeadline(body);
    }

    <font style="color:#569cd6;">function</font> dtExecDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _repo.dtExecDeadline(body);
    }

    <font style="color:#569cd6;">function</font> terminateStartpoint(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _repo.terminateStartpoint(body);
    }

    <font style="color:#569cd6;">function</font> votingDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _repo.votingDeadline(body);
    }

    <font style="color:#569cd6;">function</font> isRegistered(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isRegistered(body);
    }

    <font style="color:#569cd6;">function</font> qtyOfFiles() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _repo.qtyOfFiles();
    }

    <font style="color:#569cd6;">function</font> getFilesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getFilesList();
    }

    <font style="color:#569cd6;">function</font> getFile(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (FilesRepo.File <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getFile(body);
    }

    <font style="color:#569cd6;">function</font> getHeadOfFile(<font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (FilesRepo.Head <font style="color:#569cd6;">memory</font> head)
    {
        head = _repo.getHeadOfFile(body);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IFilesFolder.sol

---

| |
|:---|
| **contracts/comps/common/components/IFilesFolder.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/FilesRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/RulesParser.sol"</font>;

<font style="color:#6a9955;">/// @title FilesFolder</font>
<font style="color:#6a9955;">/// @notice Base contract for managing document file lifecycle and metadata.</font>
<font style="color:#6a9955;">/// @dev Provides keeper-controlled state transitions and read access to file records.</font>
<font style="color:#569cd6;">interface</font> IFilesFolder {

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Event  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#6a9955;">/// @notice Emitted when a file state is updated.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param state New state value.</font>
    <font style="color:#569cd6;">event</font> UpdateStateOfFile(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> body, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> state);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Register a document file.</font>
    <font style="color:#6a9955;">/// @param snOfDoc Encoded document identifier.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> regFile(<font style="color:#4ec9b0;">bytes32</font> snOfDoc, <font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Circulate a file for signing and voting.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param signingDays Signing window in days.</font>
    <font style="color:#6a9955;">/// @param closingDays Total closing window in days.</font>
    <font style="color:#6a9955;">/// @param vr Voting rule parameters.</font>
    <font style="color:#6a9955;">/// @param docUrl Document URL hash.</font>
    <font style="color:#6a9955;">/// @param docHash Document content hash.</font>
    <font style="color:#569cd6;">function</font> circulateFile(
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">uint16</font> signingDays,
        <font style="color:#4ec9b0;">uint16</font> closingDays,
        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a circulated file for voting.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#569cd6;">function</font> proposeFile(<font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">uint64</font> seqOfMotion) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Record vote counting result for a proposed file.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param approved True if approved.</font>
    <font style="color:#569cd6;">function</font> voteCountingForFile(<font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">bool</font> approved) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute an approved file.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> execFile(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Revoke a file.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> terminateFile(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Force set file state.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param state New state value.</font>
    <font style="color:#569cd6;">function</font> setStateOfFile(<font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">uint</font> state) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Get signing deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> signingDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get closing deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> closingDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get first execution deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> frExecDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get second execution deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> dtExecDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get termination start timestamp.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> terminateStartpoint(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get voting deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> votingDeadline(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Check if a file is registered.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> isRegistered(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get number of registered files.</font>
    <font style="color:#569cd6;">function</font> qtyOfFiles() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/// @notice Get list of registered file addresses.</font>
    <font style="color:#569cd6;">function</font> getFilesList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get file record by address.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> getFile(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (FilesRepo.File <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get file header by address.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> getHeadOfFile(<font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (FilesRepo.Head <font style="color:#569cd6;">memory</font> head);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IMeetingMinutes.sol

---

| |
|:---|
| **contracts/comps/common/components/IMeetingMinutes.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/BallotsBox.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/MotionsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/DelegateMap.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../books/roc/IShareholdersAgreement.sol"</font>;

<font style="color:#6a9955;">/// @title IMeetingMinutes</font>
<font style="color:#6a9955;">/// @notice Interface for creating motions, voting, and executing resolutions.</font>
<font style="color:#569cd6;">interface</font> IMeetingMinutes {

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    error    ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">error</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    events    ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Emitted when a motion is created.</font>
    <font style="color:#6a9955;">/// @param snOfMotion Encoded motion head (type/seq/VR/creator/executor/date).</font>
    <font style="color:#6a9955;">/// @param contents Encoded contents hash or payload.</font>
    <font style="color:#569cd6;">event</font> CreateMotion(<font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">indexed</font> snOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> contents);

    <font style="color:#6a9955;">/// @notice Emitted when a motion is proposed to the general meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id.</font>
    <font style="color:#569cd6;">event</font> ProposeMotionToGeneralMeeting(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> proposer);

    <font style="color:#6a9955;">/// @notice Emitted when a motion is proposed to the board.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id.</font>
    <font style="color:#569cd6;">event</font> ProposeMotionToBoard(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> proposer);

    <font style="color:#6a9955;">/// @notice Emitted when a vote is delegated.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param delegate Delegate account id.</font>
    <font style="color:#6a9955;">/// @param principal Principal account id.</font>
    <font style="color:#569cd6;">event</font> EntrustDelegate(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> delegate, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> principal);

    <font style="color:#6a9955;">/// @notice Emitted when a vote is cast in the general meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param caller Voter account id.</font>
    <font style="color:#6a9955;">/// @param attitude Voting attitude (enum value defined by BallotsBox).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">event</font> CastVoteInGeneralMeeting(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> caller, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> attitude, <font style="color:#4ec9b0;">bytes32</font> sigHash);

    <font style="color:#6a9955;">/// @notice Emitted when a vote is cast in the board meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param caller Voter account id.</font>
    <font style="color:#6a9955;">/// @param attitude Voting attitude (enum value defined by BallotsBox).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">event</font> CastVoteInBoardMeeting(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> caller, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> attitude, <font style="color:#4ec9b0;">bytes32</font> sigHash);

    <font style="color:#6a9955;">/// @notice Emitted when vote counting completes.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param result Vote counting result code.</font>
    <font style="color:#569cd6;">event</font> VoteCounting(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint8</font> <font style="color:#569cd6;">indexed</font> result);

    <font style="color:#6a9955;">/// @notice Emitted when a resolution is executed.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @param caller Executor account id.</font>
    <font style="color:#569cd6;">event</font> ExecResolution(<font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">indexed</font> caller);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Nominate an officer for a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param canidate Candidate account id (> 0).</font>
    <font style="color:#6a9955;">/// @param nominator Nominator account id (> 0).</font>
    <font style="color:#569cd6;">function</font> nominateOfficer(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> canidate,
        <font style="color:#4ec9b0;">uint</font> nominator
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Create a motion to remove an officer.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param nominator Nominator account id (> 0).</font>
    <font style="color:#569cd6;">function</font> createMotionToRemoveOfficer(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> nominator
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Create a motion to approve a document.</font>
    <font style="color:#6a9955;">/// @param doc Document identifier (encoded or sequence number, > 0).</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param executor Executor account id (> 0).</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> createMotionToApproveDoc(
        <font style="color:#4ec9b0;">uint</font> doc,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Create a motion to distribute USD profits.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param expireDate Expiration timestamp (> current time).</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param para Extra parameter encoded by rule (>= 0).</font>
    <font style="color:#6a9955;">/// @param executor Executor account id (> 0).</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> createMotionToDistributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Create a motion to transfer funds.</font>
    <font style="color:#6a9955;">/// @param to Recipient address (non-zero).</font>
    <font style="color:#6a9955;">/// @param isCBP True if CBP token, false if USD.</font>
    <font style="color:#6a9955;">/// @param amt Amount to transfer (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param expireDate Expiration timestamp (> current time).</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param executor Executor account id (> 0).</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> createMotionToTransferFund(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Create a motion to approve an action bundle.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param targets Target contract addresses (non-zero).</font>
    <font style="color:#6a9955;">/// @param values ETH values for each call (>= 0).</font>
    <font style="color:#6a9955;">/// @param params Calldata for each call.</font>
    <font style="color:#6a9955;">/// @param desHash Description hash (bytes32).</font>
    <font style="color:#6a9955;">/// @param executor Executor account id (> 0).</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> createAction(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Create a motion to decrease capital.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share class sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param paid Total paid-in capital amount (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param par Par value per share (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param amt Amount to decrease (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param executor Executor account id (> 0).</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> createMotionToDecreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> executor, <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>);

    <font style="color:#6a9955;">/// @notice Propose a motion to the general meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param proposer Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> proposeMotionToGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a motion to the board.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Proposer account id (> 0).</font>
    <font style="color:#569cd6;">function</font> proposeMotionToBoard (
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Delegate voting power for a motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param delegate Delegate account id (> 0).</font>
    <font style="color:#6a9955;">/// @param principal Principal account id (> 0).</font>
    <font style="color:#569cd6;">function</font> entrustDelegate(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate,
        <font style="color:#4ec9b0;">uint</font> principal
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Vote ====</font>

    <font style="color:#6a9955;">/// @notice Cast a vote in the general meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param attitude Voting attitude (enum value defined by BallotsBox).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#6a9955;">/// @param caller Voter account id (> 0).</font>
    <font style="color:#569cd6;">function</font> castVoteInGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        <font style="color:#4ec9b0;">uint256</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Cast a vote in the board meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param attitude Voting attitude (enum value defined by BallotsBox).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#6a9955;">/// @param caller Voter account id (> 0).</font>
    <font style="color:#569cd6;">function</font> castVoteInBoardMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        <font style="color:#4ec9b0;">uint256</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== UpdateVoteResult ====</font>

    <font style="color:#6a9955;">/// @notice Count votes for a motion.</font>
    <font style="color:#6a9955;">/// @param flag0 Context flag (implementation-defined).</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param base Vote calculation base data.</font>
    <font style="color:#569cd6;">function</font> voteCounting(<font style="color:#4ec9b0;">bool</font> flag0, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint8</font>);

    <font style="color:#6a9955;">// ==== ExecResolution ====</font>

    <font style="color:#6a9955;">/// @notice Execute a resolution with verified contents.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param contents Encoded contents hash or payload.</font>
    <font style="color:#6a9955;">/// @param caller Executor account id (> 0).</font>
    <font style="color:#569cd6;">function</font> execResolution(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> contents, <font style="color:#4ec9b0;">uint</font> caller)
        <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute a USD distribution motion.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param expireDate Expiration timestamp (> current time).</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param para Extra parameter encoded by rule (>= 0).</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Executor account id (> 0).</font>
    <font style="color:#569cd6;">function</font> distributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute a fund transfer motion.</font>
    <font style="color:#6a9955;">/// @param to Recipient address (non-zero).</font>
    <font style="color:#6a9955;">/// @param isCBP True if CBP token, false if USD.</font>
    <font style="color:#6a9955;">/// @param amt Amount to transfer (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param expireDate Expiration timestamp (> current time).</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Executor account id (> 0).</font>
    <font style="color:#569cd6;">function</font> transferFund(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute an approved action bundle.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param targets Target contract addresses (non-zero).</font>
    <font style="color:#6a9955;">/// @param values ETH values for each call (>= 0).</font>
    <font style="color:#6a9955;">/// @param params Calldata for each call.</font>
    <font style="color:#6a9955;">/// @param desHash Description hash (bytes32).</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Executor account id (> 0).</font>
    <font style="color:#569cd6;">function</font> execAction(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> contents);

    <font style="color:#6a9955;">/// @notice Execute a capital decrease motion.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share class sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param paid Total paid-in capital amount (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param par Par value per share (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param amt Amount to decrease (>= 0, in smallest unit).</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param caller Executor account id (> 0).</font>
    <font style="color:#569cd6;">function</font> decreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Motions ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a motion is proposed.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> isProposed(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether voting has started.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> voteStarted(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether voting has ended.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> voteEnded(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">// ==== Delegate ====</font>

    <font style="color:#6a9955;">/// @notice Get the voter record for a delegate.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Delegate account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getVoterOfDelegateMap(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DelegateMap.Voter <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get delegate of an account for a motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getDelegateOf(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">// ==== motion ====</font>

    <font style="color:#6a9955;">/// @notice Get motion details.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getMotion(<font style="color:#4ec9b0;">uint256</font> seqOfMotion)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion);

    <font style="color:#6a9955;">// ==== voting ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account has voted.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> isVoted(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether an account voted for a specific attitude.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param atti Attitude value (enum value defined by BallotsBox).</font>
    <font style="color:#569cd6;">function</font> isVotedFor(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> atti
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get vote case for an attitude.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param atti Attitude value (enum value defined by BallotsBox).</font>
    <font style="color:#569cd6;">function</font> getCaseOfAttitude(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> atti)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (BallotsBox.Case <font style="color:#569cd6;">memory</font> );

    <font style="color:#6a9955;">/// @notice Get ballot of an account for a motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getBallot(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (BallotsBox.Ballot <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether a motion has passed.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> isPassed(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Get list of motion sequence numbers.</font>
    <font style="color:#569cd6;">function</font> getSeqList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ISigPage.sol

---

| |
|:---|
| **contracts/comps/common/components/ISigPage.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../../lib/books/SigsRepo.sol"</font>;

<font style="color:#6a9955;">/// @title ISigPage</font>
<font style="color:#6a9955;">/// @notice Interface for managing signature pages and signing status.</font>
<font style="color:#569cd6;">interface</font> ISigPage {

    <font style="color:#6a9955;">/// @notice Emitted when the document is circulated.</font>
    <font style="color:#569cd6;">event</font> CirculateDoc();

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Write I/O  ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Circulate the document and start timing.</font>
    <font style="color:#569cd6;">function</font> circulateDoc() <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Set signing and closing windows (in days).</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param signingDays Signing window in days.</font>
    <font style="color:#6a9955;">/// @param closingDays Closing window in days.</font>
    <font style="color:#569cd6;">function</font> setTiming(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint</font> signingDays, <font style="color:#4ec9b0;">uint</font> closingDays) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Add a blank (party + deal) to a page.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param beBuyer True if the party is a buyer.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> addBlank(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">bool</font> beBuyer, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a blank from a page.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> removeBlank(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Record a signature for a party.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param caller Party account id.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> signDoc(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> caller, <font style="color:#4ec9b0;">bytes32</font> sigHash)
        <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Register a signature with a provided date.</font>
    <font style="color:#6a9955;">/// @param signer Party account id.</font>
    <font style="color:#6a9955;">/// @param sigDate Signature timestamp.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> regSig(<font style="color:#4ec9b0;">uint256</font> signer, <font style="color:#4ec9b0;">uint</font> sigDate, <font style="color:#4ec9b0;">bytes32</font> sigHash)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Get base parameters of a page.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#569cd6;">function</font> getParasOfPage(<font style="color:#4ec9b0;">bool</font> initPage) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (SigsRepo.Signature <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Check whether the document has been circulated.</font>
    <font style="color:#569cd6;">function</font> circulated() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/// @notice Check whether all required signatures are collected.</font>
    <font style="color:#569cd6;">function</font> established() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Get circulate date.</font>
    <font style="color:#569cd6;">function</font> getCirculateDate() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get signing window in days.</font>
    <font style="color:#569cd6;">function</font> getSigningDays() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>);

    <font style="color:#6a9955;">/// @notice Get closing window in days.</font>
    <font style="color:#569cd6;">function</font> getClosingDays() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>);

    <font style="color:#6a9955;">/// @notice Get signature deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> getSigDeadline() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Get closing deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> getClosingDeadline() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>);

    <font style="color:#6a9955;">/// @notice Check whether an account is a buyer.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> isBuyer(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Check whether an account is a seller.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> isSeller(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Check whether an account is a party on any page.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> isParty(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Check whether an account signed the initial page.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> isInitSigner(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Check whether an account signed any page.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> isSigner(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Get buyers of a page.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#569cd6;">function</font> getBuyers(<font style="color:#4ec9b0;">bool</font> initPage)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> buyers);

    <font style="color:#6a9955;">/// @notice Get sellers of a page.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#569cd6;">function</font> getSellers(<font style="color:#4ec9b0;">bool</font> initPage)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> sellers);

    <font style="color:#6a9955;">/// @notice Get all parties across pages.</font>
    <font style="color:#569cd6;">function</font> getParties() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties);

    <font style="color:#6a9955;">/// @notice Get signature data of a party.</font>
    <font style="color:#6a9955;">/// @param initParty True for the initial page, false for the secondary page.</font>
    <font style="color:#6a9955;">/// @param acct Party account id.</font>
    <font style="color:#569cd6;">function</font> getSigOfParty(<font style="color:#4ec9b0;">bool</font> initParty, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (
            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> seqOfDeals,
            SigsRepo.Signature <font style="color:#569cd6;">memory</font> sig,
            <font style="color:#4ec9b0;">bytes32</font> sigHash
        );

    <font style="color:#6a9955;">/// @notice Get signatures for a page by buyers and sellers.</font>
    <font style="color:#6a9955;">/// @param initPage True for the initial page, false for the secondary page.</font>
    <font style="color:#569cd6;">function</font> getSigsOfPage(<font style="color:#4ec9b0;">bool</font> initPage) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (
            SigsRepo.Signature[] <font style="color:#569cd6;">memory</font> sigsOfBuyer,
            SigsRepo.Signature[] <font style="color:#569cd6;">memory</font> sigsOfSeller
        );
}</code></pre>
```
 |
| [Contents](#toc) |

---

## MeetingMinutes.sol

---

| |
|:---|
| **contracts/comps/common/components/MeetingMinutes.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../access/AccessControl.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IMeetingMinutes.sol"</font>;

<font style="color:#569cd6;">contract</font> MeetingMinutes <font style="color:#569cd6;">is</font> IMeetingMinutes, AccessControl {
    <font style="color:#569cd6;">using</font> MotionsRepo <font style="color:#569cd6;">for</font> MotionsRepo.Repo;
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// Repository for motions, their states, and their voting results.</font>
    MotionsRepo.Repo <font style="color:#569cd6;">private</font> _repo;

    <font style="color:#6a9955;">// ==== UUPS Upgradeable ====</font>
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Write     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> _addMotion(
        <font style="color:#4ec9b0;">uint</font> typeOfMotion,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> creator,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> contents
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        MotionsRepo.Head <font style="color:#569cd6;">memory</font> head = MotionsRepo.Head({
            typeOfMotion: <font style="color:#4ec9b0;">uint8</font>(typeOfMotion),
            seqOfMotion: <font style="color:#b5cea8;">0</font>,
            seqOfVR: <font style="color:#4ec9b0;">uint16</font>(seqOfVR),
            creator: <font style="color:#4ec9b0;">uint40</font>(creator),
            executor: <font style="color:#4ec9b0;">uint40</font>(executor),
            createDate: <font style="color:#b5cea8;">0</font>,
            data: <font style="color:#b5cea8;">0</font>
        });

        head = _repo.addMotion(head, contents);
        <font style="color:#569cd6;">emit</font> CreateMotion(MotionsRepo.codifyHead(head), contents);
        <font style="color:#569cd6;">return</font> head.seqOfMotion;
    }

    <font style="color:#569cd6;">function</font> nominateOfficer(
        <font style="color:#4ec9b0;">uint</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> candidate,
        <font style="color:#4ec9b0;">uint</font> nominator
    ) <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>) {

        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ElectOfficer),
            seqOfVR,
            nominator,
            candidate,
            seqOfPos
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToRemoveOfficer(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> nominator
    ) <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>) {

        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.RemoveOfficer),
            seqOfVR,
            nominator,
            nominator,
            seqOfPos
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToApproveDoc(
        <font style="color:#4ec9b0;">uint</font> doc,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>) {

        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc),
            seqOfVR,
            proposer,
            executor,
            doc
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToDistributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#4ec9b0;">uint</font> contents = _hashPayment(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(seqOfDR << <font style="color:#b5cea8;">40</font> + para)), <font style="color:#569cd6;">false</font>, amt, expireDate);
        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.DistributeProfits),
            seqOfVR,
            proposer,
            executor,
            contents
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToTransferFund(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#4ec9b0;">uint</font> contents = _hashPayment(to, isCBP, amt, expireDate);
        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.TransferFund),
            seqOfVR,
            proposer,
            executor,
            contents
        );
    }

    <font style="color:#569cd6;">function</font> _hashPayment(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font>
            <font style="color:#4ec9b0;">uint256</font>(
                keccak256(
                    abi.encode(to, isCBP, amt, expireDate)
                )
            );
    }

    <font style="color:#569cd6;">function</font> createAction(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>){

        <font style="color:#4ec9b0;">uint256</font> contents = _hashAction(
            seqOfVR,
            targets,
            values,
            params,
            desHash
        );

        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveAction),
            seqOfVR,
            proposer,
            executor,
            contents
        );
    }

    <font style="color:#569cd6;">function</font> _hashAction(
        <font style="color:#4ec9b0;">uint256</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font>
            <font style="color:#4ec9b0;">uint256</font>(
                keccak256(
                    abi.encode(seqOfVR, targets, values, params, desHash)
                )
            );
    }

    <font style="color:#569cd6;">function</font> createMotionToDecreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> executor, <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#4ec9b0;">uint</font> contents = _hashDecreaseCapital(
            seqOfVR, seqOfShare, paid, par, amt
        );
        <font style="color:#569cd6;">return</font> _addMotion(
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.DecreaseCapital),
            seqOfVR,
            proposer,
            executor,
            contents
        );
    }

    <font style="color:#569cd6;">function</font> _hashDecreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font>
            <font style="color:#4ec9b0;">uint256</font>(
                keccak256(
                    abi.encode(seqOfVR, seqOfShare, paid, par, amt)
                )
            );
    }

    <font style="color:#6a9955;">// ==== ProposeMotion ====</font>

    <font style="color:#569cd6;">function</font> proposeMotionToGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> proposer
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        IShareholdersAgreement _sha = _gk.getSHA();

        _repo.proposeMotionToGeneralMeeting(seqOfMotion, _sha, _gk.getROM(), _gk.getROD(), proposer);
        <font style="color:#569cd6;">emit</font> ProposeMotionToGeneralMeeting(seqOfMotion, proposer);
    }

    <font style="color:#569cd6;">function</font> proposeMotionToBoard (
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyDK {

        IShareholdersAgreement _sha = _gk.getSHA();

        _repo.proposeMotionToBoard(seqOfMotion, _sha, _gk.getROD(), caller);
        <font style="color:#569cd6;">emit</font> ProposeMotionToBoard(seqOfMotion, caller);
    }

    <font style="color:#6a9955;">// ==== delegate ====</font>

    <font style="color:#569cd6;">function</font> entrustDelegate(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate,
        <font style="color:#4ec9b0;">uint</font> principal
    ) <font style="color:#569cd6;">external</font> onlyDK {
        <font style="color:#569cd6;">if</font> (_repo.entrustDelegate(
            seqOfMotion,
            delegate,
            principal,
            _gk.getROM(),
            _gk.getROD()
        ))
        <font style="color:#569cd6;">emit</font> EntrustDelegate(seqOfMotion, delegate, principal);
    }

    <font style="color:#6a9955;">// ==== Vote ====</font>

    <font style="color:#569cd6;">function</font> castVoteInGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        <font style="color:#4ec9b0;">uint256</font> caller
    ) <font style="color:#569cd6;">external</font> onlyDK {
        _repo.castVoteInGeneralMeeting(seqOfMotion, caller, attitude, sigHash, _gk.getROM());
        <font style="color:#569cd6;">emit</font> CastVoteInGeneralMeeting(seqOfMotion, caller, attitude, sigHash);
    }

    <font style="color:#569cd6;">function</font> castVoteInBoardMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        <font style="color:#4ec9b0;">uint256</font> caller
    ) <font style="color:#569cd6;">external</font> onlyDK {
        _repo.castVoteInBoardMeeting(seqOfMotion, caller, attitude, sigHash, _gk.getROD());
        <font style="color:#569cd6;">emit</font> CastVoteInBoardMeeting(seqOfMotion, caller, attitude, sigHash);
    }

    <font style="color:#6a9955;">// ==== UpdateVoteResult ====</font>

    <font style="color:#569cd6;">function</font> voteCounting(<font style="color:#4ec9b0;">bool</font> flag0, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base)
        <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint8</font> result)
    {
        result = _repo.voteCounting(flag0, seqOfMotion, base);
        <font style="color:#569cd6;">emit</font> VoteCounting(seqOfMotion, result);
    }

    <font style="color:#6a9955;">// ==== ExecResolution ====</font>

    <font style="color:#569cd6;">function</font> execResolution(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> contents, <font style="color:#4ec9b0;">uint</font> caller)
        <font style="color:#569cd6;">public</font> onlyKeeper
    {
        _repo.execResolution(seqOfMotion, contents, caller);
        <font style="color:#569cd6;">emit</font> ExecResolution(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> distributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        <font style="color:#569cd6;">if</font>(block.timestamp >= expireDate)
            <font style="color:#569cd6;">revert</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MM_ExpireDateNotFuture"</font>));

        <font style="color:#569cd6;">if</font>( _repo.getMotion(seqOfMotion).head.typeOfMotion !=
                <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.DistributeProfits)
        ) <font style="color:#569cd6;">revert</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MM_WrongTypeOfMotion"</font>));

        <font style="color:#4ec9b0;">uint</font> contents = _hashPayment(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(seqOfDR << <font style="color:#b5cea8;">40</font> + para)), <font style="color:#569cd6;">false</font>, amt, expireDate);

        execResolution(seqOfMotion, contents, caller);
    }

    <font style="color:#569cd6;">function</font> transferFund(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {

        <font style="color:#569cd6;">if</font>(block.timestamp >= expireDate)
            <font style="color:#569cd6;">revert</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MM_TF_ExpireDateNotFuture"</font>));

        <font style="color:#569cd6;">if</font> (_repo.getMotion(seqOfMotion).head.typeOfMotion !=
                <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.TransferFund)
        ) <font style="color:#569cd6;">revert</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MM_TF_WrongTypeOfMotion"</font>));

        <font style="color:#4ec9b0;">uint</font> contents = _hashPayment(to, isCBP, amt, expireDate);

        execResolution(seqOfMotion, contents, caller);
    }

    <font style="color:#569cd6;">function</font> execAction(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyDK <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font> contents) {

        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion =
            _repo.getMotion(seqOfMotion);

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion !=
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveAction)
        ) <font style="color:#569cd6;">revert</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MM_EA_WrongTypeOfMotion"</font>));

        contents = _hashAction(
            seqOfVR,
            targets,
            values,
            params,
            desHash
        );

        execResolution(seqOfMotion, contents, caller);
    }

    <font style="color:#569cd6;">function</font> decreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">external</font> onlyKeeper {
        <font style="color:#569cd6;">if</font> (_repo.getMotion(seqOfMotion).head.typeOfMotion !=
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.DecreaseCapital)
        ) <font style="color:#569cd6;">revert</font> MM_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MM_DC_WrongTypeOfMotion"</font>));

        <font style="color:#4ec9b0;">uint</font> contents = _hashDecreaseCapital(seqOfVR, seqOfShare, paid, par, amt);

        execResolution(seqOfMotion, contents, caller);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Motions ====</font>

    <font style="color:#569cd6;">function</font> isProposed(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isProposed(seqOfMotion);
    }

    <font style="color:#569cd6;">function</font> voteStarted(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.voteStarted(seqOfMotion);
    }

    <font style="color:#569cd6;">function</font> voteEnded(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>){
        <font style="color:#569cd6;">return</font> _repo.voteEnded(seqOfMotion);
    }

    <font style="color:#6a9955;">// ==== Delegate ====</font>

    <font style="color:#569cd6;">function</font> getVoterOfDelegateMap(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DelegateMap.Voter <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getVoterOfDelegateMap(seqOfMotion, acct);
    }

    <font style="color:#569cd6;">function</font> getDelegateOf(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getDelegateOf(seqOfMotion, acct);
    }

    <font style="color:#6a9955;">// ==== motion ====</font>

    <font style="color:#569cd6;">function</font> getMotion(<font style="color:#4ec9b0;">uint256</font> seqOfMotion)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion)
    {
        motion = _repo.getMotion(seqOfMotion);
    }

    <font style="color:#6a9955;">// ==== voting ====</font>

    <font style="color:#569cd6;">function</font> isVoted(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.isVoted(seqOfMotion, acct);
    }

    <font style="color:#569cd6;">function</font> isVotedFor(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> atti
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isVotedFor(seqOfMotion, acct, atti);
    }

    <font style="color:#569cd6;">function</font> getCaseOfAttitude(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> atti)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (BallotsBox.Case <font style="color:#569cd6;">memory</font> )
    {
        <font style="color:#569cd6;">return</font> _repo.getCaseOfAttitude(seqOfMotion, atti);
    }

    <font style="color:#569cd6;">function</font> getBallot(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (BallotsBox.Ballot <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> _repo.getBallot(seqOfMotion, acct);
    }

    <font style="color:#569cd6;">function</font> isPassed(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _repo.isPassed(seqOfMotion);
    }

    <font style="color:#6a9955;">// ==== SeqList ====</font>

    <font style="color:#569cd6;">function</font> getSeqList() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _repo.getSeqList();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## SigPage.sol

---

| |
|:---|
| **contracts/comps/common/components/SigPage.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ISigPage.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../access/DraftControl.sol"</font>;

<font style="color:#569cd6;">contract</font> SigPage <font style="color:#569cd6;">is</font> ISigPage, DraftControl {
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint256</font>[];
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> SigsRepo <font style="color:#569cd6;">for</font> SigsRepo.Page;

    <font style="color:#6a9955;">// Repository for signatures, their deadlines, and the parties involved in the</font>
    SigsRepo.Page[<font style="color:#b5cea8;">2</font>] <font style="color:#569cd6;">internal</font> _sigPages;

    <font style="color:#6a9955;">// ==== UUPS Upgradeable ====</font>
    <font style="color:#4ec9b0;">uint256</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Write  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#569cd6;">function</font> circulateDoc() <font style="color:#569cd6;">external</font> onlyKeeper {
        _sigPages[<font style="color:#b5cea8;">0</font>].circulateDoc();
        _sigPages[<font style="color:#b5cea8;">1</font>].circulateDoc();
        <font style="color:#569cd6;">emit</font> CirculateDoc();
    }

    <font style="color:#569cd6;">function</font> setTiming(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint</font> signingDays, <font style="color:#4ec9b0;">uint</font> closingDays)
        <font style="color:#569cd6;">external</font> attorneyOrGK
    {
        initPage ? _sigPages[<font style="color:#b5cea8;">0</font>].setTiming(signingDays, closingDays) :
            _sigPages[<font style="color:#b5cea8;">1</font>].setTiming(signingDays, closingDays);
    }

    <font style="color:#569cd6;">function</font> addBlank(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">bool</font> beBuyer, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> attorneyOrGK
    {
        initPage ? _sigPages[<font style="color:#b5cea8;">0</font>].addBlank(beBuyer, seqOfDeal, acct) :
            _sigPages[<font style="color:#b5cea8;">1</font>].addBlank(beBuyer, seqOfDeal, acct);
    }

    <font style="color:#569cd6;">function</font> removeBlank(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> attorneyOrGK
    {
        initPage ? _sigPages[<font style="color:#b5cea8;">0</font>].removeBlank(seqOfDeal, acct) :
            _sigPages[<font style="color:#b5cea8;">1</font>].removeBlank(seqOfDeal, acct);
    }

    <font style="color:#569cd6;">function</font> signDoc(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> caller, <font style="color:#4ec9b0;">bytes32</font> sigHash)
        <font style="color:#569cd6;">external</font> onlyKeeper
    {
        <font style="color:#569cd6;">if</font> (initPage) {
            _sigPages[<font style="color:#b5cea8;">0</font>].signDoc(caller, sigHash);
        } <font style="color:#569cd6;">else</font> {
            _sigPages[<font style="color:#b5cea8;">1</font>].signDoc(caller, sigHash);
        }
    }

    <font style="color:#569cd6;">function</font> regSig(<font style="color:#4ec9b0;">uint256</font> signer, <font style="color:#4ec9b0;">uint</font> sigDate, <font style="color:#4ec9b0;">bytes32</font> sigHash)
        <font style="color:#569cd6;">external</font> onlyKeeper <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _sigPages[<font style="color:#b5cea8;">1</font>].regSig(signer, sigDate, sigHash);
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">function</font> getParasOfPage(<font style="color:#4ec9b0;">bool</font> initPage) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (SigsRepo.Signature <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> initPage ? _sigPages[<font style="color:#b5cea8;">0</font>].blanks[<font style="color:#b5cea8;">0</font>].sig :
            _sigPages[<font style="color:#b5cea8;">1</font>].blanks[<font style="color:#b5cea8;">0</font>].sig;
    }

    <font style="color:#569cd6;">function</font> circulated() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].circulated();
    }

    <font style="color:#569cd6;">function</font> established() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag =  _sigPages[<font style="color:#b5cea8;">1</font>].buyers.length() > <font style="color:#b5cea8;">0</font>
                ? _sigPages[<font style="color:#b5cea8;">1</font>].established() && _sigPages[<font style="color:#b5cea8;">0</font>].established()
                : _sigPages[<font style="color:#b5cea8;">0</font>].established();
    }

    <font style="color:#569cd6;">function</font> getCirculateDate() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].getCirculateDate();
    }

    <font style="color:#569cd6;">function</font> getSigningDays() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].getSigningDays();
    }

    <font style="color:#569cd6;">function</font> getClosingDays() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].getClosingDays();
    }

    <font style="color:#569cd6;">function</font> getSigDeadline() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].getSigDeadline();
    }

    <font style="color:#569cd6;">function</font> getClosingDeadline() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].getClosingDeadline();
    }

    <font style="color:#569cd6;">function</font> isBuyer(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = initPage ? _sigPages[<font style="color:#b5cea8;">0</font>].buyers.contains(acct) :
            _sigPages[<font style="color:#b5cea8;">1</font>].buyers.contains(acct);
    }

    <font style="color:#569cd6;">function</font> isSeller(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = initPage ? _sigPages[<font style="color:#b5cea8;">0</font>].sellers.contains(acct) :
            _sigPages[<font style="color:#b5cea8;">1</font>].sellers.contains(acct);
    }

    <font style="color:#569cd6;">function</font> isParty(<font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = _sigPages[<font style="color:#b5cea8;">0</font>].buyers.contains(acct) ||
            _sigPages[<font style="color:#b5cea8;">0</font>].sellers.contains(acct) ||
            _sigPages[<font style="color:#b5cea8;">1</font>].buyers.contains(acct) ||
            _sigPages[<font style="color:#b5cea8;">1</font>].sellers.contains(acct);
    }

    <font style="color:#569cd6;">function</font> isInitSigner(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _sigPages[<font style="color:#b5cea8;">0</font>].isSigner(acct);
    }

    <font style="color:#569cd6;">function</font> isSigner(<font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = _sigPages[<font style="color:#b5cea8;">0</font>].isSigner(acct) ||
            _sigPages[<font style="color:#b5cea8;">1</font>].isSigner(acct);
    }

    <font style="color:#569cd6;">function</font> getBuyers(<font style="color:#4ec9b0;">bool</font> initPage)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> buyers)
    {
        buyers = initPage
            ? _sigPages[<font style="color:#b5cea8;">0</font>].buyers.values()
            : _sigPages[<font style="color:#b5cea8;">1</font>].buyers.values();
    }

    <font style="color:#569cd6;">function</font> getSellers(<font style="color:#4ec9b0;">bool</font> initPage)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> sellers)
    {
        sellers = initPage
            ? _sigPages[<font style="color:#b5cea8;">0</font>].sellers.values()
            : _sigPages[<font style="color:#b5cea8;">1</font>].sellers.values();
    }

    <font style="color:#569cd6;">function</font> getParties() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> buyers =
            getBuyers(<font style="color:#569cd6;">true</font>).merge(getBuyers(<font style="color:#569cd6;">false</font>));

        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> sellers =
            getSellers(<font style="color:#569cd6;">true</font>).merge(getSellers(<font style="color:#569cd6;">false</font>));

        parties = buyers.merge(sellers);
    }

    <font style="color:#569cd6;">function</font> getSigOfParty(<font style="color:#4ec9b0;">bool</font> initPage, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (
            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> seqOfDeals,
            SigsRepo.Signature <font style="color:#569cd6;">memory</font> sig,
            <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) {
        <font style="color:#569cd6;">if</font> (initPage) {
            <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].sigOfParty(acct);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">1</font>].sigOfParty(acct);
        }
    }

    <font style="color:#569cd6;">function</font> getSigsOfPage(<font style="color:#4ec9b0;">bool</font> initPage)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (
            SigsRepo.Signature[] <font style="color:#569cd6;">memory</font> sigsOfBuyer,
            SigsRepo.Signature[] <font style="color:#569cd6;">memory</font> sigsOfSeller
        )
    {
        <font style="color:#569cd6;">if</font> (initPage) {
            <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">0</font>].sigsOfPage();
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">return</font> _sigPages[<font style="color:#b5cea8;">1</font>].sigsOfPage();
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## GeneralKeeper.sol

---

| |
|:---|
| **contracts/comps/GeneralKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IGeneralKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./common/access/AccessControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../openzeppelin/utils/Address.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../lib/books/UsersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">contract</font> GeneralKeeper <font style="color:#569cd6;">is</font> IGeneralKeeper, AccessControl {
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">/// @notice Company registry info stored in this keeper.</font>
    CompInfo <font style="color:#569cd6;">internal</font> _info;

    <font style="color:#6a9955;">/// @notice Book registry (title => book address).</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#4ec9b0;">address</font>) <font style="color:#569cd6;">private</font> _books;
    <font style="color:#6a9955;">/// @notice Keeper registry (title => keeper address).</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#4ec9b0;">address</font>) <font style="color:#569cd6;">private</font> _keepers;
    <font style="color:#6a9955;">/// @notice Reverse lookup for keeper registry (keeper address => title).</font>
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint</font>) <font style="color:#569cd6;">private</font> _titleOfKeeper;
    <font style="color:#6a9955;">/// @notice Reference to RegCenter for user registration and queries.</font>
    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">private</font> _router;

    <font style="color:#6a9955;">// ==== UUPSUpgradable ====</font>

    <font style="color:#6a9955;">/// @dev Storage gap for upgrade safety.</font>
    <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">50</font>] <font style="color:#569cd6;">private</font> __gap;

    <font style="color:#6a9955;">/// @notice Register this company in RegCenter and store registry metadata.</font>
    <font style="color:#569cd6;">function</font> createCorpSeal(
        <font style="color:#4ec9b0;">uint</font> _typeOfEntity
    ) <font style="color:#569cd6;">external</font> reinitializer(<font style="color:#b5cea8;">3</font>) onlyOwner{
        _rc.getRC().regUser();
        _info.regNum = _rc.getRC().getMyUserNo();
        _info.regDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        _info.typeOfEntity = <font style="color:#4ec9b0;">uint8</font>(_typeOfEntity);
    }

    <font style="color:#6a9955;">// ---- Entity ----</font>

    <font style="color:#569cd6;">function</font> setCompInfo (
        <font style="color:#4ec9b0;">uint8</font> _currency,
        <font style="color:#4ec9b0;">bytes18</font> _symbol,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> _name
    ) <font style="color:#569cd6;">external</font> onlyDK {
        _info.currency = _currency;
        _info.symbol = _symbol;
        _info.name = _name;
    }

    <font style="color:#569cd6;">function</font> getCompInfo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(CompInfo <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _info;
    }

    <font style="color:#569cd6;">function</font> getCompUser() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> onlyOwner <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _rc.getRC().getMyUser();
    }

    <font style="color:#6a9955;">// ---- Keepers ----</font>

    <font style="color:#569cd6;">function</font> regKeeper(<font style="color:#4ec9b0;">uint256</font> title, <font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">external</font> onlyDK {
        <font style="color:#569cd6;">if</font> (title == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_ZeroTitle"</font>));
        }
        <font style="color:#569cd6;">if</font> (_titleOfKeeper[keeper] != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_KeeperAlreadyReg"</font>));
        }
        _keepers[title] = keeper;
        _titleOfKeeper[keeper] = title;
        <font style="color:#569cd6;">emit</font> RegKeeper(title, keeper, msg.sender);
    }

    <font style="color:#569cd6;">function</font> isKeeper(<font style="color:#4ec9b0;">address</font> target) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _titleOfKeeper[target] != <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#569cd6;">function</font> getKeeper(<font style="color:#4ec9b0;">uint256</font> title) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">if</font> (title == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_ZeroTitle"</font>));
        }
        <font style="color:#569cd6;">if</font> (_keepers[title] == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_TitleNotReg"</font>));
        }
        <font style="color:#569cd6;">return</font> _keepers[title];
    }

    <font style="color:#569cd6;">function</font> getTitleOfKeeper(<font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">if</font> (keeper == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_ZeroKeeper"</font>));
        }
        <font style="color:#569cd6;">if</font> (_titleOfKeeper[keeper] == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_KeeperNotReg"</font>));
        }
        <font style="color:#569cd6;">return</font> _titleOfKeeper[keeper];
    }

    <font style="color:#6a9955;">// ---- Router ----</font>

    <font style="color:#569cd6;">function</font> setRouter(<font style="color:#4ec9b0;">address</font> router) <font style="color:#569cd6;">external</font> onlyDK {
        <font style="color:#569cd6;">if</font> (router == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_ZeroRouter"</font>));
        }
        _router = router;
        <font style="color:#569cd6;">emit</font> SetRouter(router, msg.sender);
    }

    <font style="color:#569cd6;">function</font> getRouter() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">if</font> (_router == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_RouterNotSet"</font>));
        }
        <font style="color:#569cd6;">return</font> _router;
    }

    <font style="color:#6a9955;">// ---- Books ----</font>

    <font style="color:#569cd6;">function</font> regBook(<font style="color:#4ec9b0;">uint256</font> title, <font style="color:#4ec9b0;">address</font> book) <font style="color:#569cd6;">external</font> onlyDK {
        <font style="color:#569cd6;">if</font> (title == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_ZeroTitle"</font>));
        }
        _books[title] = book;
        <font style="color:#569cd6;">emit</font> RegBook(title, book, msg.sender);
    }

    <font style="color:#569cd6;">function</font> getBook(<font style="color:#4ec9b0;">uint256</font> title) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">if</font> (title == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_ZeroTitle"</font>));
        }
        <font style="color:#569cd6;">if</font> (_books[title] == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GK_BookNotReg"</font>));
        }
        <font style="color:#569cd6;">return</font> _books[title];
    }

    <font style="color:#6a9955;">/// @notice Fallback router for keeper calls.</font>
    <font style="color:#6a9955;">/// @dev Looks up `msg.sig` in keeper registry and delegates the call to the</font>
    <font style="color:#6a9955;">///      corresponding keeper. Uses `delegatecall`, so storage writes affect</font>
    <font style="color:#6a9955;">///      this contract and `msg.sender` remains the original caller.</font>
    <font style="color:#6a9955;">///      Reverts if the selector is not registered, and bubbles up revert data.</font>
    <font style="color:#569cd6;">fallback</font>() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">payable</font> {
        <font style="color:#4ec9b0;">uint</font> title = _router.getRouter().getTitleBySelector(msg.sig);
        <font style="color:#4ec9b0;">address</font> keeper = getKeeper(title);
        (<font style="color:#4ec9b0;">bool</font> success, ) = keeper.delegatecall(msg.data);

        <font style="color:#569cd6;">if</font> (success) {
            <font style="color:#569cd6;">emit</font> ForwardedCall(keeper, msg.sender, msg.sig);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#6a9955;">// Bubble up revert reason from delegatecall</font>
            <font style="color:#569cd6;">assembly</font> {
                let returndata_size := returndatasize()
                returndatacopy(<font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, returndata_size)
                <font style="color:#569cd6;">revert</font>(<font style="color:#b5cea8;">0</font>, returndata_size)
            }
        }
    }

    <font style="color:#6a9955;">/// @notice Accept ETH transfers.</font>
    <font style="color:#569cd6;">receive</font> () <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">payable</font>{
        <font style="color:#569cd6;">emit</font> ReceivedEth(msg.sender, msg.value);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IGeneralKeeper.sol

---

| |
|:---|
| **contracts/comps/IGeneralKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../lib/books/UsersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../openzeppelin/utils/Address.sol"</font>;

<font style="color:#6a9955;">/// @title IGeneralKeeper</font>
<font style="color:#6a9955;">/// @notice General keeper interface for corporate registry configuration and role management.</font>
<font style="color:#6a9955;">/// @dev Exposes company info, keeper/book registration, and basic queries.</font>
<font style="color:#569cd6;">interface</font> IGeneralKeeper {

    <font style="color:#6a9955;">/// @notice Company information record.</font>
    <font style="color:#6a9955;">/// @dev `regNum` is userNo; `regDate` is unix timestamp; `symbol` is fixed-length bytes.</font>
    <font style="color:#569cd6;">struct</font> CompInfo {
        <font style="color:#4ec9b0;">uint40</font> regNum;
        <font style="color:#4ec9b0;">uint48</font> regDate;
        <font style="color:#4ec9b0;">uint8</font> typeOfEntity;
        <font style="color:#4ec9b0;">uint8</font> currency;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">bytes18</font> symbol;
        <font style="color:#4ec9b0;">string</font> name;
    }

    <font style="color:#6a9955;">/// @notice Company type enumeration.</font>
    <font style="color:#569cd6;">enum</font> TypeOfEntity {
        ZeroPoint,
        PrivateCompany,
        GrowingCompany,
        ListedCompany,
        GeneralCompany,
        CloseFund,
        ListedCloseFund,
        OpenFund,
        ListedOpenFund,
        GeneralFund
    }

    <font style="color:#569cd6;">error</font> GK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##   Event   ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">/// @notice Emitted when a keeper is registered.</font>
    <font style="color:#6a9955;">/// @param title Keeper title.</font>
    <font style="color:#6a9955;">/// @param keeper Keeper address.</font>
    <font style="color:#6a9955;">/// @param dk Direct keeper address.</font>
    <font style="color:#569cd6;">event</font> RegKeeper(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> title, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> keeper, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> dk);

    <font style="color:#6a9955;">/// @notice Emitted when a book is registered.</font>
    <font style="color:#6a9955;">/// @param title Book title.</font>
    <font style="color:#6a9955;">/// @param book Book address.</font>
    <font style="color:#6a9955;">/// @param dk Direct keeper address.</font>
    <font style="color:#569cd6;">event</font> RegBook(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> title, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> book, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> dk);

    <font style="color:#6a9955;">/// @notice Emitted when a call is forwarded to a keeper or book.</font>
    <font style="color:#6a9955;">/// @param target Target contract address.</font>
    <font style="color:#6a9955;">/// @param msgSender Original caller address.</font>
    <font style="color:#6a9955;">/// @param sig Function signature of the forwarded call.</font>
    <font style="color:#569cd6;">event</font> ForwardedCall(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> target, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> msgSender, <font style="color:#4ec9b0;">bytes4</font> <font style="color:#569cd6;">indexed</font> sig);

    <font style="color:#6a9955;">/// @notice Emitted when ETH is received.</font>
    <font style="color:#6a9955;">/// @param sender ETH sender.</font>
    <font style="color:#6a9955;">/// @param amount ETH amount.</font>
    <font style="color:#569cd6;">event</font> ReceivedEth(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> sender, <font style="color:#4ec9b0;">uint</font> amount);

    <font style="color:#6a9955;">/// @notice Emitted when the keepers router is set.</font>
    <font style="color:#6a9955;">/// @param router Router address.</font>
    <font style="color:#6a9955;">/// @param dk Direct keeper address.</font>
    <font style="color:#569cd6;">event</font> SetRouter(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> router, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> dk);

    <font style="color:#6a9955;">// ######################</font>
    <font style="color:#6a9955;">// ##   Configuration  ##</font>
    <font style="color:#6a9955;">// ######################</font>

    <font style="color:#6a9955;">// ---- Config ----</font>

    <font style="color:#6a9955;">/// @notice Create the corporate seal and register the entity in RegCenter.</font>
    <font style="color:#6a9955;">/// @param _typeOfEntity Entity type code (see {TypeOfEntity}).</font>
    <font style="color:#569cd6;">function</font> createCorpSeal(<font style="color:#4ec9b0;">uint</font> _typeOfEntity) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Set company information.</font>
    <font style="color:#6a9955;">/// @param _currency Currency code (uint8, implementation-defined range).</font>
    <font style="color:#6a9955;">/// @param _symbol Fixed-length symbol (bytes18).</font>
    <font style="color:#6a9955;">/// @param _name Company name (non-empty string expected).</font>
    <font style="color:#569cd6;">function</font> setCompInfo (
        <font style="color:#4ec9b0;">uint8</font> _currency,
        <font style="color:#4ec9b0;">bytes18</font> _symbol,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> _name
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Get company information.</font>
    <font style="color:#6a9955;">/// @return Company info record; fields are zeroed if unset.</font>
    <font style="color:#569cd6;">function</font> getCompInfo() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(CompInfo <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/// @notice Get company user record from registry.</font>
    <font style="color:#6a9955;">/// @return User record (zeroed if not registered).</font>
    <font style="color:#569cd6;">function</font> getCompUser() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (UsersRepo.User <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">// ---- Keepers ----</font>

    <font style="color:#6a9955;">/// @notice Register a keeper address by title.</font>
    <font style="color:#6a9955;">/// @param title Keeper title (uint, expected > 0).</font>
    <font style="color:#6a9955;">/// @param keeper Keeper address (non-zero).</font>
    <font style="color:#569cd6;">function</font> regKeeper(<font style="color:#4ec9b0;">uint256</font> title, <font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Check if an address is a registered keeper.</font>
    <font style="color:#6a9955;">/// @param caller Address to check.</font>
    <font style="color:#6a9955;">/// @return flag True if registered; false otherwise.</font>
    <font style="color:#569cd6;">function</font> isKeeper(<font style="color:#4ec9b0;">address</font> caller) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag);

    <font style="color:#6a9955;">/// @notice Get keeper address by title.</font>
    <font style="color:#6a9955;">/// @param title Keeper title (uint, expected > 0).</font>
    <font style="color:#6a9955;">/// @return keeper Keeper address (zero if not set).</font>
    <font style="color:#569cd6;">function</font> getKeeper(<font style="color:#4ec9b0;">uint256</font> title) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">address</font> keeper);

    <font style="color:#6a9955;">/// @notice Get keeper title by address.</font>
    <font style="color:#6a9955;">/// @param keeper Keeper address.</font>
    <font style="color:#6a9955;">/// @return title Keeper title (0 if not registered).</font>
    <font style="color:#569cd6;">function</font> getTitleOfKeeper(<font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>);

    <font style="color:#6a9955;">// ---- Router ----</font>

    <font style="color:#6a9955;">/// @notice Set the address of the keepers router.</font>
    <font style="color:#6a9955;">/// @param router Keepers router address (non-zero).</font>
    <font style="color:#569cd6;">function</font> setRouter(<font style="color:#4ec9b0;">address</font> router) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Get the address of the keepers router.</font>
    <font style="color:#6a9955;">/// @return router Keepers router address (zero if not set).</font>
    <font style="color:#569cd6;">function</font> getRouter() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font> router);

    <font style="color:#6a9955;">// ---- Books ----</font>

    <font style="color:#6a9955;">/// @notice Register a book address by title.</font>
    <font style="color:#6a9955;">/// @param title Book title (uint, expected > 0).</font>
    <font style="color:#6a9955;">/// @param keeper Book address (non-zero).</font>
    <font style="color:#569cd6;">function</font> regBook(<font style="color:#4ec9b0;">uint256</font> title, <font style="color:#4ec9b0;">address</font> keeper) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Get book address by title.</font>
    <font style="color:#6a9955;">/// @param title Book title (uint, expected > 0).</font>
    <font style="color:#6a9955;">/// @return Book address (zero if not set).</font>
    <font style="color:#569cd6;">function</font> getBook(<font style="color:#4ec9b0;">uint256</font> title) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

}</code></pre>
```
 |
| [Contents](#toc) |

---

## Accountant.sol

---

| |
|:---|
| **contracts/comps/keepers/Accountant.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/WaterfallsRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IAccountant.sol"</font>;

<font style="color:#569cd6;">contract</font> Accountant <font style="color:#569cd6;">is</font> IAccountant {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("Accountant")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x671969be;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">error</font> ACTT_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">function</font> initClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (msg.sender != IAccessControl(_gk).getDK())
            <font style="color:#569cd6;">revert</font> ACTT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ACTT_NotDK"</font>));

        <font style="color:#4ec9b0;">uint</font> sum = _gk.getROS().getInfoOfClass(class).body.paid;
        _gk.getCashier().initClass(class, sum);
    }

    <font style="color:#569cd6;">function</font> distrProfits(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gk.getGMM().distributeUsd(
            amt,
            expireDate,
            seqOfDR,
            <font style="color:#b5cea8;">0</font>,
            seqOfMotion,
            caller
        );

        _gk.getCashier().distrProfits(amt, seqOfDR);
    }

    <font style="color:#569cd6;">function</font> distrIncome(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> fundManager,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        IRegisterOfShares _ros = _gk.getROS();
        ICashier _cashier = _gk.getCashier();

        _gk.getGMM().distributeUsd(
            amt,
            expireDate,
            seqOfDR,
            fundManager,
            seqOfMotion,
            caller
        );

        (,WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list) =
            _cashier.distrIncome(amt, seqOfDR, fundManager);

        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {

            WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop = list[len-<font style="color:#b5cea8;">1</font>];

            <font style="color:#569cd6;">if</font> (drop.principal > <font style="color:#b5cea8;">0</font>) {
                SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
                    _ros.getShare(drop.distrDate);
                _ros.decreaseCapital(share.head.seqOfShare, drop.principal/<font style="color:#b5cea8;">100</font>, <font style="color:#b5cea8;">0</font>);
            }

            len--;
        }
    }

    <font style="color:#569cd6;">function</font> transferFund(
        <font style="color:#4ec9b0;">bool</font> fromBMM,
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">76000</font>);

        <font style="color:#569cd6;">if</font> (fromBMM) {
            _gk.getBMM().transferFund(
                to,
                isCBP,
                amt,
                expireDate,
                seqOfMotion,
                caller
            );
        } <font style="color:#569cd6;">else</font> {
            _gk.getGMM().transferFund(
                to,
                isCBP,
                amt,
                expireDate,
                seqOfMotion,
                caller
            );
        }

        <font style="color:#569cd6;">if</font> (!isCBP) {
            _gk.getCashier().transferUsd(to, amt, <font style="color:#4ec9b0;">bytes32</font>(seqOfMotion));
        } <font style="color:#569cd6;">else</font> {
            _gk.getRCByGK().transfer(to, amt);
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## BMMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/BMMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/OfficersRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IBMMKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> BMMKeeper <font style="color:#569cd6;">is</font> IBMMKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint</font>[];
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("BMMKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0xca6e13b7;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">//######################</font>
    <font style="color:#6a9955;">//##   Error & Event  ##</font>
    <font style="color:#6a9955;">//######################</font>

    <font style="color:#569cd6;">error</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> BMMK_WrongAmt(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> BMMK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when a board motion executes an action.</font>
    <font style="color:#6a9955;">/// @param targets Target contract address.</font>
    <font style="color:#6a9955;">/// @param values ETH value.</font>
    <font style="color:#6a9955;">/// @param params Encoded parameters blob.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">event</font> ExecAction(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> targets,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> values,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">indexed</font> params,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    );

    <font style="color:#6a9955;">// ==== CreateMotion ====</font>

    <font style="color:#6a9955;">// ---- Officers ----</font>

    <font style="color:#569cd6;">function</font> nominateOfficer(<font style="color:#4ec9b0;">uint256</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> candidate) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        IRegisterOfDirectors _rod = _gk.getROD();

        <font style="color:#569cd6;">if</font> (!_rod.hasNominationRight(seqOfPos, caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_HasNoNominationRight"</font>));

        _gk.getBMM().nominateOfficer(
            seqOfPos,
            _rod.getPosition(seqOfPos).seqOfVR, candidate, caller
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToRemoveOfficer(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#6a9955;">// if (!_gk.getROD().isDirector(caller))</font>
        <font style="color:#6a9955;">//     revert BMMK_WrongParty(bytes32("BMMK_NotDirector"));</font>

        IRegisterOfDirectors _rod = _gk.getROD();

        <font style="color:#569cd6;">if</font> (!_rod.hasNominationRight(seqOfPos, caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_HasNoNominationRight"</font>));

        _gk.getBMM().createMotionToRemoveOfficer(
            seqOfPos, _rod.getPosition(seqOfPos).seqOfVR, caller
        );
    }

    <font style="color:#6a9955;">// ---- Docs ----</font>

    <font style="color:#569cd6;">function</font> createMotionToApproveDoc(
        <font style="color:#4ec9b0;">uint</font> doc,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_NotDirector"</font>));

        _gk.getBMM().createMotionToApproveDoc(
            doc, seqOfVR, executor, caller
        );
    }

    <font style="color:#569cd6;">function</font> proposeToTransferFundWithBoard(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">66000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_NotDirector"</font>));

        IMeetingMinutes _bmm = _gk.getBMM();

        <font style="color:#569cd6;">if</font> (amt >
            <font style="color:#4ec9b0;">uint</font>(_gk.getSHA().getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser().fundApprovalThreshold) *
            (isCBP ? <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">18</font> : <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">6</font>))
        {
            <font style="color:#569cd6;">revert</font> BMMK_WrongAmt(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_AmtOverflow"</font>));
        }

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _bmm.createMotionToTransferFund(
                to, isCBP, amt, expireDate, seqOfVR, executor, caller
            );
        _bmm.proposeMotionToBoard(seqOfMotion, caller);
    }

    <font style="color:#6a9955;">// ---- Actions ----</font>

    <font style="color:#569cd6;">function</font> createAction(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">66000</font>);
        <font style="color:#569cd6;">if</font> (!_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_NotDirector"</font>));

        _gk.getBMM().createAction(
            seqOfVR,
            targets,
            values,
            params,
            desHash,
            executor,
            caller
        );
    }

    <font style="color:#6a9955;">// ==== Cast Vote ====</font>

    <font style="color:#569cd6;">function</font> entrustDelegaterForBoardMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        <font style="color:#569cd6;">if</font> (!_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_NotDirector"</font>));

        _avoidanceCheck(_gk, seqOfMotion, caller);
        _gk.getBMM().entrustDelegate(seqOfMotion, delegate, caller);
    }

    <font style="color:#569cd6;">function</font> proposeMotionToBoard (
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);
        <font style="color:#569cd6;">if</font> (!_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_NotDirector"</font>));

        _gk.getBMM().proposeMotionToBoard(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> castVote(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _avoidanceCheck(_gk, seqOfMotion, caller);
        _gk.getBMM().castVoteInBoardMeeting(
            seqOfMotion, attitude, sigHash, caller
        );
    }

    <font style="color:#569cd6;">function</font> _avoidanceCheck(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {

        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion = _gk.getBMM().getMotion(seqOfMotion);

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
                <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc) &&
                motion.head.seqOfVR < <font style="color:#b5cea8;">9</font>)
        {
            <font style="color:#4ec9b0;">address</font> doc = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents));

            OfficersRepo.Position[] <font style="color:#569cd6;">memory</font> poses =
                _gk.getROD().getFullPosInfoInHand(caller);
            <font style="color:#4ec9b0;">uint256</font> len = poses.length;
            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">if</font> (ISigPage(doc).isSigner(poses[len-<font style="color:#b5cea8;">1</font>].nominator))
                    <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_NominatorIsSigner"</font>));
                len --;
            }
            <font style="color:#569cd6;">if</font> (ISigPage(doc).isSigner(caller))
                <font style="color:#569cd6;">revert</font> BMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_CallerIsSigner"</font>));

        }
    }

    <font style="color:#6a9955;">// ==== Vote Counting ====</font>

    <font style="color:#569cd6;">function</font> voteCounting(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        _voteCounting(_gk, seqOfMotion);
    }

    <font style="color:#569cd6;">function</font> _voteCounting(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">private</font> {
        IRegisterOfDirectors _rod = _gk.getROD();
        IMeetingMinutes _bmm = _gk.getBMM();

        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion =
            _bmm.getMotion(seqOfMotion);

        MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base;

        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0 = _bmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">if</font> (_allConsent(_bmm, _rod, motion, case0)) {
            base.unaniConsent = <font style="color:#569cd6;">true</font>;
        } <font style="color:#569cd6;">else</font> {
            base = _calBase(_bmm, _rod, motion, base, case0);
        }

        IShareholdersAgreement _sha = _gk.getSHA();

        <font style="color:#4ec9b0;">bool</font> quorumFlag = (<font style="color:#4ec9b0;">address</font>(_sha) == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>) ||
            base.attendHeadRatio >=
            _sha.getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser().quorumOfBoardMeeting);

        _bmm.voteCounting(quorumFlag, seqOfMotion, base);
    }

    <font style="color:#569cd6;">function</font> _allConsent(
        IMeetingMinutes _bmm,
        IRegisterOfDirectors _rod,
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion,
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {

        BallotsBox.Case <font style="color:#569cd6;">memory</font> case1 = _bmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">1</font>);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> consentVoters = case1.voters.combine(case1.principals);

        <font style="color:#6a9955;">// BallotsBox.Case memory case0 = _bmm.getCaseOfAttitude(motion.head.seqOfMotion, 0);         </font>
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> allVoters = case0.voters.combine(case0.principals);

        <font style="color:#569cd6;">if</font> (allVoters.length > consentVoters.length) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> directors = _rod.getDirectorsList();
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> restDirectors = directors.minus(consentVoters);

        <font style="color:#569cd6;">if</font> (restDirectors.length == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc) &&
            motion.head.seqOfVR < <font style="color:#b5cea8;">9</font>) {

            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties =
                ISigPage(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents))).getParties();

            <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> affiDirectors = restDirectors.minus(parties);

            <font style="color:#4ec9b0;">uint</font> len = affiDirectors.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> nominators = _nominators(_rod, affiDirectors[len-<font style="color:#b5cea8;">1</font>]);
                <font style="color:#569cd6;">if</font> (nominators.noOverlapWith(parties)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
                len--;
            }

            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _nominators(IRegisterOfDirectors _rod, <font style="color:#4ec9b0;">uint</font> director) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        OfficersRepo.Position[] <font style="color:#569cd6;">memory</font> poses =
            _rod.getFullPosInfoInHand(director);

        <font style="color:#4ec9b0;">uint</font> len = poses.length;
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> nominators = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint</font>[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            nominators[len-<font style="color:#b5cea8;">1</font>] = poses[len-<font style="color:#b5cea8;">1</font>].nominator;
            len--;
        }

        <font style="color:#569cd6;">return</font> nominators;
    }

    <font style="color:#569cd6;">function</font> _calBase(
        IMeetingMinutes _bmm,
        IRegisterOfDirectors _rod,
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion,
        MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base,
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font>) {

        BallotsBox.Case <font style="color:#569cd6;">memory</font> case3 = _bmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">3</font>);

        <font style="color:#4ec9b0;">uint32</font> numOfDirectors = <font style="color:#4ec9b0;">uint32</font>(_rod.getNumOfDirectors());
        base.attendHeadRatio = <font style="color:#4ec9b0;">uint16</font>(case0.sumOfHead * <font style="color:#b5cea8;">10000</font> / numOfDirectors);

        <font style="color:#569cd6;">if</font> (motion.votingRule.onlyAttendance) {
            base.totalHead = case0.sumOfHead - case3.sumOfHead;
        } <font style="color:#569cd6;">else</font> {
            base.totalHead = numOfDirectors - case3.sumOfHead;
            <font style="color:#569cd6;">if</font> (motion.votingRule.impliedConsent) {
                base.supportHead = (base.totalHead - case0.sumOfHead);
                base.attendHeadRatio = <font style="color:#b5cea8;">10000</font>;
            }
        }

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc))
        {
            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties =
                ISigPage((<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents)))).getParties();
            <font style="color:#4ec9b0;">uint256</font> len = parties.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#4ec9b0;">uint32</font> voteHead =
                    <font style="color:#4ec9b0;">uint32</font>(_rod.getBoardSeatsOccupied(<font style="color:#4ec9b0;">uint40</font>(parties[len - <font style="color:#b5cea8;">1</font>])));

                <font style="color:#569cd6;">if</font> (voteHead > <font style="color:#b5cea8;">0</font>) {
                    <font style="color:#569cd6;">if</font> (motion.votingRule.partyAsConsent) {

                        <font style="color:#569cd6;">if</font> (motion.votingRule.onlyAttendance) {
                            base.totalHead += voteHead;
                        }

                        <font style="color:#569cd6;">if</font> (!motion.votingRule.impliedConsent) {
                            base.supportHead += voteHead;

                            base.attendHeadRatio += <font style="color:#4ec9b0;">uint16</font>(voteHead * <font style="color:#b5cea8;">10000</font> / numOfDirectors);
                        }
                    } <font style="color:#569cd6;">else</font> {
                        <font style="color:#569cd6;">if</font> (!motion.votingRule.onlyAttendance) {
                            base.totalHead -= voteHead;
                        }

                        <font style="color:#569cd6;">if</font> (motion.votingRule.impliedConsent) {
                            base.supportHead -= voteHead;
                        } <font style="color:#569cd6;">else</font> {
                            base.attendHeadRatio += <font style="color:#4ec9b0;">uint16</font>(voteHead * <font style="color:#b5cea8;">10000</font> / numOfDirectors);
                        }

                        <font style="color:#569cd6;">if</font> (base.totalHead == <font style="color:#b5cea8;">0</font>)
                            base.unaniConsent = <font style="color:#569cd6;">true</font>;
                    }
                }

                len--;
            }
        }

        <font style="color:#569cd6;">return</font> base;
    }

    <font style="color:#6a9955;">// ==== Exec Action ====</font>

    <font style="color:#569cd6;">function</font> execAction(
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _execAction(
            caller, typeOfAction, targets, values,
            params, desHash, seqOfMotion
        );
    }

    <font style="color:#569cd6;">function</font> _execAction(
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font>(!(targets.length == values.length && targets.length == params.length))
            <font style="color:#569cd6;">revert</font> BMMK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BMMK_InputLenMismatch"</font>));

        <font style="color:#4ec9b0;">uint</font> len = targets.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            targets[len-<font style="color:#b5cea8;">1</font>].functionCallWithValue(params[len-<font style="color:#b5cea8;">1</font>], values[len-<font style="color:#b5cea8;">1</font>]);
            <font style="color:#569cd6;">emit</font> ExecAction(targets[len-<font style="color:#b5cea8;">1</font>], values[len-<font style="color:#b5cea8;">1</font>], params[len-<font style="color:#b5cea8;">1</font>], seqOfMotion, caller);
            len--;
        }

        <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getBMM().execAction(
            typeOfAction,
            targets,
            values,
            params,
            desHash,
            seqOfMotion,
            caller
        );
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## FundAccountant.sol

---

| |
|:---|
| **contracts/comps/keepers/FundAccountant.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/WaterfallsRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IAccountant.sol"</font>;

<font style="color:#569cd6;">contract</font> FundAccountant <font style="color:#569cd6;">is</font> IAccountant {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("FundAccountant")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x797eb8dd;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">error</font> FundACCT_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">modifier</font> onlyDK() {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#569cd6;">if</font> (msg.sender != IAccessControl(_gk).getDK()) {
            <font style="color:#569cd6;">revert</font> FundACCT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundACCT_NotDK"</font>));
        }
        _;
    }

    <font style="color:#569cd6;">function</font> initClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> onlyDK  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#4ec9b0;">uint</font> sum = _gk.getROS().getInfoOfClass(class).body.paid;
        _gk.getCashier().initClass(class, sum);
    }

    <font style="color:#569cd6;">function</font> distrProfits(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> FundACCT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundACCT_NotGP"</font>));
        }

        _gk.getGMM().distributeUsd(
            amt,
            expireDate,
            seqOfDR,
            <font style="color:#b5cea8;">0</font>,
            seqOfMotion,
            caller
        );

        _gk.getCashier().distrProfits(amt, seqOfDR);
    }

    <font style="color:#569cd6;">function</font> distrIncome(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> fundManager,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> FundACCT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundACCT_NotGP"</font>));
        }

        IRegisterOfShares _ros = _gk.getROS();
        ICashier _cashier = _gk.getCashier();

        _gk.getGMM().distributeUsd(
            amt,
            expireDate,
            seqOfDR,
            fundManager,
            seqOfMotion,
            caller
        );

        (,WaterfallsRepo.Drop[] <font style="color:#569cd6;">memory</font> list) =
            _cashier.distrIncome(amt, seqOfDR, fundManager);

        RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule =
            _gk.getSHA().getRule(seqOfDR).DistrRuleParser();

        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {

            WaterfallsRepo.Drop <font style="color:#569cd6;">memory</font> drop = list[len-<font style="color:#b5cea8;">1</font>];

            <font style="color:#569cd6;">if</font> (rule.typeOfDistr == <font style="color:#4ec9b0;">uint8</font>(RulesParser.TypeOfDistr.ProRata)) {

                <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqs =
                    _gk.getROM().sharesInHand(drop.member);
                <font style="color:#4ec9b0;">uint</font> paids = _gk.getROM().pointsOfMember(drop.member).paid * <font style="color:#b5cea8;">100</font>;

                <font style="color:#4ec9b0;">uint</font> lenOfShares = seqs.length;
                <font style="color:#569cd6;">while</font> (lenOfShares ><font style="color:#b5cea8;">0</font>) {
                    SharesRepo.Share <font style="color:#569cd6;">memory</font> share = _ros.getShare(seqs[lenOfShares - <font style="color:#b5cea8;">1</font>]);
                    <font style="color:#4ec9b0;">uint</font> deltaPaid = share.body.paid * drop.principal / paids;
                    _ros.decreaseCapital(share.head.seqOfShare, deltaPaid, <font style="color:#b5cea8;">0</font>);
                    lenOfShares--;
                }

            } <font style="color:#569cd6;">else</font> {

                <font style="color:#569cd6;">if</font> (drop.principal > <font style="color:#b5cea8;">0</font>) {
                    SharesRepo.Share <font style="color:#569cd6;">memory</font> share = _ros.getShare(drop.distrDate);
                    _ros.decreaseCapital(
                        share.head.seqOfShare,
                        drop.principal/<font style="color:#b5cea8;">100</font>,
                        <font style="color:#b5cea8;">0</font>
                    );
                }

            }

            len--;
        }
    }

    <font style="color:#569cd6;">function</font> transferFund(
        <font style="color:#4ec9b0;">bool</font> fromBMM,
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">76000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>) &&
            !_gk.getROD().isDirector(caller)) {
            <font style="color:#569cd6;">revert</font> FundACCT_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundACCT_NotGPorDirector"</font>));
        }

        <font style="color:#569cd6;">if</font> (fromBMM) {
            _gk.getBMM().transferFund(
                to,
                isCBP,
                amt,
                expireDate,
                seqOfMotion,
                caller
            );
        } <font style="color:#569cd6;">else</font> {
            _gk.getGMM().transferFund(
                to,
                isCBP,
                amt,
                expireDate,
                seqOfMotion,
                caller
            );
        }

        <font style="color:#569cd6;">if</font> (!isCBP) {
            _gk.getCashier().transferUsd(to, amt, <font style="color:#4ec9b0;">bytes32</font>(seqOfMotion));
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## FundGMMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/FundGMMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IGMMKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> FundGMMKeeper <font style="color:#569cd6;">is</font> IGMMKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint</font>[];
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("FundGMMKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x6c88e247;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">//######################</font>
    <font style="color:#6a9955;">//##   Error & Event  ##</font>
    <font style="color:#6a9955;">//######################</font>

    <font style="color:#569cd6;">modifier</font> onlyDK() {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);

        <font style="color:#569cd6;">if</font>( msg.sender != IAccessControl(_gk).getDK() )
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotDK"</font>));
        _;
    }

    <font style="color:#6a9955;">// ==== Function Modifiers ====</font>

    <font style="color:#569cd6;">function</font> _gpOrManager(<font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font>{
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#569cd6;">if</font>( !_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>) &&
            !_gk.getROD().isDirector(caller)
        ) <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotGPOrManager"</font>));
    }

    <font style="color:#569cd6;">function</font> _onlyGP(<font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font>{
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#569cd6;">if</font>( !_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>) )
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotGP"</font>));
    }

    <font style="color:#6a9955;">// ==== CreateMotion ====</font>

    <font style="color:#6a9955;">// ---- Officers ----</font>
    <font style="color:#569cd6;">function</font> nominateDirector(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> candidate
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">72000</font>);

        _onlyGP(caller);

        _gk.getGMM().nominateOfficer(
            seqOfPos,
            _gk.getROD().getPosition(seqOfPos).seqOfVR,
            candidate,
            caller
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToRemoveDirector(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">116000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isMember(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotMember"</font>));

        <font style="color:#4ec9b0;">uint</font> seqOfVR = _gk.getROD().getPosition(seqOfPos).seqOfVR;

        _gk.getGMM().createMotionToRemoveOfficer(
            seqOfPos,
            seqOfVR,
            caller
        );
    }

    <font style="color:#569cd6;">function</font> proposeDocOfGM(
        <font style="color:#4ec9b0;">uint</font> doc,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">116000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isMember(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotMember"</font>));

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _gmm.createMotionToApproveDoc(doc, seqOfVR, executor, caller);

        _gmm.proposeMotionToGeneralMeeting(seqOfMotion, caller);

        <font style="color:#569cd6;">if</font> (seqOfVR < <font style="color:#b5cea8;">9</font>) {

            <font style="color:#4ec9b0;">address</font> addr = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(doc));

            <font style="color:#569cd6;">if</font>(!ISigPage(addr).isSigner(caller))
                <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotSignerOfDoc"</font>));

            <font style="color:#569cd6;">if</font>(!ISigPage(addr).established())
                <font style="color:#569cd6;">revert</font> GMMK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_DocNotEstablished"</font>));

            <font style="color:#569cd6;">if</font> (seqOfVR == <font style="color:#b5cea8;">8</font>) {
                _gk.getROC().proposeFile(addr, seqOfMotion);
            } <font style="color:#569cd6;">else</font> {
                _gk.getROA().proposeFile(addr, seqOfMotion);
            }
        }
    }

    <font style="color:#569cd6;">function</font> proposeToDistributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">68000</font>);

        _gpOrManager(caller);

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _gmm.createMotionToDistributeUsd(amt, expireDate, seqOfVR, seqOfDR, para, executor, caller);

        _gmm.proposeMotionToGeneralMeeting(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> proposeToTransferFundWithGM(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">99000</font>);

        _gpOrManager(caller);

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _gmm.createMotionToTransferFund(to, isCBP, amt, expireDate, seqOfVR, executor, caller);

        _gmm.proposeMotionToGeneralMeeting(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> createActionOfGM(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">99000</font>);

        _gpOrManager(caller);

        _gk.getGMM().createAction(
            seqOfVR,
            targets,
            values,
            params,
            desHash,
            executor,
            caller
        );
    }

    <font style="color:#6a9955;">// ==== ProposeMotion ====</font>

    <font style="color:#569cd6;">function</font> entrustDelegaterForGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _avoidanceCheck(_gk, seqOfMotion, caller);

        _gk.getGMM().entrustDelegate(seqOfMotion, delegate, caller);
    }

    <font style="color:#569cd6;">function</font> proposeMotionToGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">72000</font>);

        _gk.getGMM().proposeMotionToGeneralMeeting(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> castVoteOfGM(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">72000</font>);

        _avoidanceCheck(_gk, seqOfMotion, caller);

        _gk.getGMM().castVoteInGeneralMeeting(seqOfMotion, attitude, sigHash, caller);
    }

    <font style="color:#569cd6;">function</font> _avoidanceCheck(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion = _gk.getGMM().getMotion(seqOfMotion);

        <font style="color:#569cd6;">if</font> (motion.votingRule.class != <font style="color:#b5cea8;">0</font> &&
            !_gk.getROM().isClassMember(caller, motion.votingRule.class)) {
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_NotClassMember"</font>));
        }

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc) &&
            motion.head.seqOfVR < <font style="color:#b5cea8;">9</font>)
        {
            <font style="color:#4ec9b0;">address</font> doc = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents));
            <font style="color:#569cd6;">if</font> (ISigPage(doc).isSigner(caller)) {
                <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_IsSignerOfDoc"</font>));
            }
        }
    }

    <font style="color:#6a9955;">// ==== VoteCounting ====</font>

    <font style="color:#569cd6;">function</font> voteCountingOfGM(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        _voteCountingOfGM(_gk, seqOfMotion);
    }

    <font style="color:#569cd6;">function</font> _voteCountingOfGM(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">private</font> {
        IRegisterOfMembers _rom = _gk.getROM();
        IMeetingMinutes _gmm = _gk.getGMM();

        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion =
            _gmm.getMotion(seqOfMotion);

        MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base;

        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0 = _gmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">if</font> (_allConsent(_gmm, _rom, motion, case0)) {
            base.unaniConsent = <font style="color:#569cd6;">true</font>;
        } <font style="color:#569cd6;">else</font> {
            base = _calBase(_gk, _gmm, _rom, motion, base, case0);
        }

        <font style="color:#4ec9b0;">bool</font> quorumFlag = (<font style="color:#4ec9b0;">address</font>(_gk.getSHA()) == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>) ||
            base.attendWeightRatio >=
            _gk.getSHA().getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser().quorumOfGM);

        <font style="color:#4ec9b0;">bool</font> approved = _gmm.voteCounting(quorumFlag, seqOfMotion, base) ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Passed);

        <font style="color:#569cd6;">if</font> (motion.head.seqOfVR < <font style="color:#b5cea8;">9</font>) {
            <font style="color:#4ec9b0;">address</font> doc = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents));

            <font style="color:#569cd6;">if</font> (motion.head.seqOfVR == <font style="color:#b5cea8;">8</font>) {
                _gk.getROC().voteCountingForFile(doc, approved);
            } <font style="color:#569cd6;">else</font> {
                _gk.getROA().voteCountingForFile(doc, approved);
            }
        }
    }

    <font style="color:#569cd6;">function</font> _allConsent(
        IMeetingMinutes _gmm,
        IRegisterOfMembers _rom,
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion,
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case1 = _gmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">1</font>);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> consentVoters = case1.voters.combine(case1.principals);

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> allVoters = case0.voters.combine(case0.principals);

        <font style="color:#569cd6;">if</font> (allVoters.length > consentVoters.length) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members = motion.votingRule.class == <font style="color:#b5cea8;">0</font>
            ? _rom.membersList()
            : _rom.getMembersOfClass(motion.votingRule.class);

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> restMembers = members.minus(consentVoters);

        <font style="color:#569cd6;">if</font> (restMembers.length == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc)) {

            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties =
                ISigPage(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents))).getParties();

            <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> vetoMembers = restMembers.minus(parties);

            <font style="color:#4ec9b0;">uint</font> len = vetoMembers.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">if</font> (_rom.votesAtDate(vetoMembers[len - <font style="color:#b5cea8;">1</font>], motion.body.shareRegDate) > <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
                len--;
            }

            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _calBase(
        <font style="color:#4ec9b0;">address</font> _gk,
        IMeetingMinutes _gmm,
        IRegisterOfMembers _rom,
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion,
        MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base,
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font>) {
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case3 = _gmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">3</font>);

        <font style="color:#4ec9b0;">uint64</font> votesOfMembers;
        <font style="color:#569cd6;">if</font> (motion.votingRule.class == <font style="color:#b5cea8;">0</font>) {
            votesOfMembers = _rom.totalVotes();
        } <font style="color:#569cd6;">else</font> {
            SharesRepo.Share <font style="color:#569cd6;">memory</font> classInfo =
                _gk.getROS().getInfoOfClass(motion.votingRule.class);
            votesOfMembers = _rom.basedOnPar()
                ? classInfo.head.votingWeight * classInfo.body.par
                : classInfo.head.votingWeight * classInfo.body.paid;
        }

        base.attendWeightRatio = <font style="color:#4ec9b0;">uint16</font>(case0.sumOfWeight * <font style="color:#b5cea8;">10000</font> / votesOfMembers);

        <font style="color:#569cd6;">if</font> (motion.votingRule.onlyAttendance) {

            base.totalHead = (case0.sumOfHead - case3.sumOfHead);
            base.totalWeight = (case0.sumOfWeight - case3.sumOfWeight);

        } <font style="color:#569cd6;">else</font> {

            base.totalHead = motion.votingRule.class == <font style="color:#b5cea8;">0</font>
                ? <font style="color:#4ec9b0;">uint32</font>(_rom.qtyOfMembers())
                : <font style="color:#4ec9b0;">uint32</font>(_rom.qtyOfClassMember(motion.votingRule.class));

            base.totalWeight = votesOfMembers;

            <font style="color:#569cd6;">if</font> (motion.votingRule.impliedConsent) {

                base.supportHead = base.totalHead - case0.sumOfHead;
                base.supportWeight = base.totalWeight > case0.sumOfWeight
                        ? (base.totalWeight - case0.sumOfWeight)
                        : <font style="color:#b5cea8;">0</font>;
                base.attendWeightRatio = <font style="color:#b5cea8;">10000</font>;
            }

            base.totalHead -= case3.sumOfHead;
            base.totalWeight = base.totalWeight > case3.sumOfWeight
                    ? base.totalWeight - case3.sumOfWeight
                    : <font style="color:#b5cea8;">0</font> ;
        }

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc)) {

            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties =
                ISigPage(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents))).getParties();
            <font style="color:#4ec9b0;">uint256</font> len = parties.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#4ec9b0;">uint64</font> votesAtDate =
                    _rom.votesAtDate(parties[len - <font style="color:#b5cea8;">1</font>], motion.body.shareRegDate);

                <font style="color:#569cd6;">if</font> (votesAtDate > <font style="color:#b5cea8;">0</font>) {
                    <font style="color:#569cd6;">if</font> (motion.votingRule.partyAsConsent) {

                        <font style="color:#569cd6;">if</font> (motion.votingRule.onlyAttendance) {
                            base.totalHead++;
                            base.totalWeight += votesAtDate;
                        }

                        <font style="color:#569cd6;">if</font> (!motion.votingRule.impliedConsent) {
                            base.supportHead ++;
                            base.supportWeight += votesAtDate;

                            base.attendWeightRatio += <font style="color:#4ec9b0;">uint16</font>(votesAtDate * <font style="color:#b5cea8;">10000</font> / votesOfMembers);
                        }

                    } <font style="color:#569cd6;">else</font> {

                        <font style="color:#569cd6;">if</font> (!motion.votingRule.onlyAttendance) {
                            base.totalHead --;

                            base.totalWeight = base.totalWeight > votesAtDate
                                    ? base.totalWeight - votesAtDate
                                    : <font style="color:#b5cea8;">0</font>;
                        }

                        <font style="color:#569cd6;">if</font> (motion.votingRule.impliedConsent) {
                            base.supportHead --;

                            base.supportWeight = base.supportWeight > votesAtDate
                                    ? base.supportWeight - votesAtDate
                                    : <font style="color:#b5cea8;">0</font>;
                        } <font style="color:#569cd6;">else</font> {
                            base.attendWeightRatio += <font style="color:#4ec9b0;">uint16</font>(votesAtDate * <font style="color:#b5cea8;">10000</font> / votesOfMembers);
                        }
                    }
                }

                len--;
            }
        }

        <font style="color:#569cd6;">return</font> base;
    }

    <font style="color:#6a9955;">// ==== ExecAction ====</font>

    <font style="color:#569cd6;">function</font> execActionOfGM(
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _execActionOfGM(
            caller,
            typeOfAction,
            targets,
            values,
            params,
            desHash,
            seqOfMotion
        );
    }

    <font style="color:#569cd6;">function</font> _execActionOfGM(
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font>(
            targets.length != values.length || targets.length != params.length
        ) {
            <font style="color:#569cd6;">revert</font> GMMK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundGMMK_InputLenMismatch"</font>));
        }

        <font style="color:#4ec9b0;">uint</font> len = targets.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            targets[len - <font style="color:#b5cea8;">1</font>].functionCallWithValue(params[len - <font style="color:#b5cea8;">1</font>], values[len - <font style="color:#b5cea8;">1</font>]);
            <font style="color:#569cd6;">emit</font> ExecAction(targets[len - <font style="color:#b5cea8;">1</font>], values[len - <font style="color:#b5cea8;">1</font>], params[len - <font style="color:#b5cea8;">1</font>], seqOfMotion, caller);
            len--;
        }

        <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getGMM().execAction(
            typeOfAction,
            targets,
            values,
            params,
            desHash,
            seqOfMotion,
            caller
        );
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## FundLOOKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/FundLOOKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ILOOKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> FundLOOKeeper <font style="color:#569cd6;">is</font> ILOOKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("FundLOOKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> TYPE_OF_DOC = 0x6ab7d4a6;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#569cd6;">modifier</font> whenNotPaused() {
        <font style="color:#569cd6;">if</font>(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROI().isPaused()) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_LooPaused"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// ==== Offers ====</font>

    <font style="color:#569cd6;">function</font> placeInitialOffer(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> whenNotPaused {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        IRegisterOfShares _ros = _gk.getROS();

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotGP"</font>));
        }

        <font style="color:#569cd6;">if</font>(_gk.getCashier().getGulfInfo(classOfShare).principal != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_ClassEstablished"</font>));
        }

        <font style="color:#569cd6;">if</font>(lr.classOfShare != classOfShare) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_WrongClass"</font>));
        }

        <font style="color:#569cd6;">if</font>(<font style="color:#4ec9b0;">uint32</font>(price) < lr.floorPrice) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_PriceLowerFloor"</font>));
        }

        <font style="color:#569cd6;">if</font>(lr.ceilingPrice != <font style="color:#b5cea8;">0</font> && <font style="color:#4ec9b0;">uint32</font>(price) > lr.ceilingPrice) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_PriceHigherCeiling"</font>));
        }

        <font style="color:#569cd6;">if</font> (_ros.getInfoOfClass(classOfShare).body.cleanPaid +
            paid > <font style="color:#4ec9b0;">uint64</font>(lr.maxTotalPar) * <font style="color:#b5cea8;">10000</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_PaidOverflow"</font>));
        }

        _ros.increaseEquityOfClass(<font style="color:#569cd6;">true</font>, classOfShare, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, paid);

        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

        input.classOfShare = <font style="color:#4ec9b0;">uint16</font>(classOfShare);
        input.votingWeight = lr.votingWeight;
        input.distrWeight = lr.distrWeight;
        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        input.price = <font style="color:#4ec9b0;">uint32</font>(price);
        input.seller = <font style="color:#4ec9b0;">uint40</font>(caller);
        input.isOffer = <font style="color:#569cd6;">true</font>;

        _placeSellOrder(_gk, input, execHours);
    }

    <font style="color:#569cd6;">function</font> withdrawInitialOffer(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        IListOfOrders _loo = _gk.getLOO();

        GoldChain.Order <font style="color:#569cd6;">memory</font> order =
            _loo.getOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        <font style="color:#569cd6;">if</font>(order.data.seqOfShare != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotInitOrder"</font>));
        }

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotGP"</font>));
        }

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font>(!_gk.getROD().hasTitle(caller, lr.titleOfIssuer)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotIssuer"</font>));
        }

        order = _loo.withdrawOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        _restoreOrder(_gk, order);
    }

    <font style="color:#569cd6;">function</font> placeSellOrder(
        <font style="color:#4ec9b0;">uint</font> seqOfClass, <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> whenNotPaused  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#569cd6;">if</font>(_gk.getROI().getInvestor(caller).state !=
            <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotQualifiedInvestor"</font>));
        }

        IRegisterOfShares _ros = _gk.getROS();

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font>(seqOfClass != lr.classOfShare) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_WrongClass"</font>));
        }

        <font style="color:#569cd6;">if</font>(<font style="color:#4ec9b0;">uint32</font>(price) < lr.offPrice) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_PriceLowerOff"</font>));
        }

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> sharesInhand =
            _gk.getROM().sharesInClass(caller, lr.classOfShare);

        <font style="color:#4ec9b0;">uint</font> len = sharesInhand.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font> && paid > <font style="color:#b5cea8;">0</font>) {

            SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
                _ros.getShare(sharesInhand[len - <font style="color:#b5cea8;">1</font>]);
            len--;

            <font style="color:#569cd6;">if</font> (!_ros.notLocked(share.head.seqOfShare, block.timestamp)) {
                <font style="color:#569cd6;">continue</font>;
            }

            <font style="color:#569cd6;">if</font> (lr.lockupDays == <font style="color:#b5cea8;">0</font> ||
                share.head.issueDate +
                <font style="color:#4ec9b0;">uint48</font>(lr.lockupDays) * <font style="color:#b5cea8;">86400</font> < block.timestamp)
            {
                <font style="color:#569cd6;">if</font> (share.body.cleanPaid > <font style="color:#b5cea8;">0</font>) {

                    UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

                    input.to = msg.sender;
                    input.seller = share.head.shareholder;
                    input.classOfShare = share.head.class;
                    input.seqOfShare = share.head.seqOfShare;
                    input.price = <font style="color:#4ec9b0;">uint32</font>(price);
                    input.votingWeight = share.head.votingWeight;
                    input.distrWeight = share.body.distrWeight;
                    input.isOffer = <font style="color:#569cd6;">true</font>;

                    <font style="color:#569cd6;">if</font> (paid >= share.body.cleanPaid) {
                        input.paid = <font style="color:#4ec9b0;">uint64</font>(share.body.cleanPaid);
                        paid -=input.paid;
                        _ros.decreaseCleanPaid(share.head.seqOfShare, input.paid);
                        _placeSellOrder(_gk,input, execHours);
                    } <font style="color:#569cd6;">else</font> {
                        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
                        _ros.decreaseCleanPaid(share.head.seqOfShare, input.paid);
                        _placeSellOrder(_gk,input, execHours);
                        <font style="color:#569cd6;">break</font>;
                    }

                }
            }
        }
    }

    <font style="color:#569cd6;">function</font> withdrawSellOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        IListOfOrders _loo = _gk.getLOO();
        IRegisterOfShares _ros = _gk.getROS();

        GoldChain.Order <font style="color:#569cd6;">memory</font> order =
            _loo.getOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        <font style="color:#569cd6;">if</font>(order.data.seqOfShare == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_ZeroSeqOfShare"</font>));
        }

        SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
            _ros.getShare(order.data.seqOfShare);

        <font style="color:#569cd6;">if</font>(share.head.shareholder != caller) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotShareholder"</font>));
        }

        order = _loo.withdrawOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        _restoreOrder(_gk, order);
    }

    <font style="color:#6a9955;">// ==== Bid ====</font>

    <font style="color:#569cd6;">function</font> placeBuyOrder(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> whenNotPaused  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        InvestorsRepo.Investor <font style="color:#569cd6;">memory</font> investor =
            _gk.getROI().getInvestor(caller);

        <font style="color:#569cd6;">if</font>(investor.state != <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotQualifiedInvestor"</font>));
        }

        <font style="color:#569cd6;">if</font>(price == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_ZeroPrice"</font>));
        }

        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

        input.<font style="color:#569cd6;">from</font> = msg.sender;
        input.buyer = <font style="color:#4ec9b0;">uint40</font>(caller);
        input.groupRep = investor.groupRep;
        input.classOfShare = <font style="color:#4ec9b0;">uint16</font>(classOfShare);
        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        input.price = <font style="color:#4ec9b0;">uint32</font>(price);
        input.consideration = <font style="color:#4ec9b0;">uint128</font>(paid * price);

        auth.<font style="color:#569cd6;">from</font> = input.<font style="color:#569cd6;">from</font>;
        auth.value = input.consideration / <font style="color:#b5cea8;">100</font>;
        _placeBuyOrder(_gk, auth, input, execHours);
    }

    <font style="color:#569cd6;">function</font> placeMarketBuyOrder(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> whenNotPaused {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        InvestorsRepo.Investor <font style="color:#569cd6;">memory</font> investor =
            _gk.getROI().getInvestor(caller);

        <font style="color:#569cd6;">if</font>(investor.state != <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotQualifiedInvestor"</font>));
        }

        <font style="color:#569cd6;">if</font>(auth.value == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_ZeroMargin"</font>));
        }

        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

        input.<font style="color:#569cd6;">from</font> = msg.sender;
        input.buyer = <font style="color:#4ec9b0;">uint40</font>(caller);
        input.groupRep = investor.groupRep;
        input.classOfShare = <font style="color:#4ec9b0;">uint16</font>(classOfShare);
        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        input.consideration = <font style="color:#4ec9b0;">uint128</font>(auth.value * <font style="color:#b5cea8;">100</font>);

        auth.<font style="color:#569cd6;">from</font> = input.<font style="color:#569cd6;">from</font>;
        _placeBuyOrder(_gk, auth, input, execHours);
    }

    <font style="color:#569cd6;">function</font> withdrawBuyOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        IListOfOrders _loo = _gk.getLOO();

        GoldChain.Order <font style="color:#569cd6;">memory</font> order =
            _loo.getOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">false</font>);

        <font style="color:#569cd6;">if</font>(order.node.issuer != caller) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundLOOK_NotBuyer"</font>));
        }

        order = _loo.withdrawOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">false</font>);

        _restoreOrder(_gk, order);
    }

    <font style="color:#6a9955;">// ==== Settlement ====</font>

    <font style="color:#569cd6;">function</font> _placeSellOrder(
        <font style="color:#4ec9b0;">address</font> _gk,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">private</font> {
        (
            UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
            <font style="color:#4ec9b0;">uint</font> lenOfDeals,
            GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
            <font style="color:#4ec9b0;">uint</font> lenOfExpired,
            UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> offer
        ) = _gk.getLOO().placeSellOrder(input, execHours);

        <font style="color:#569cd6;">if</font> (lenOfDeals > <font style="color:#b5cea8;">0</font>) {
            _closeDeals(_gk, deals, lenOfDeals, <font style="color:#569cd6;">true</font>);
        }
        <font style="color:#569cd6;">if</font> (lenOfExpired > <font style="color:#b5cea8;">0</font>) {
            _restoreExpiredOrders(_gk, expired, lenOfExpired);
        }
        <font style="color:#569cd6;">if</font> (offer.price == <font style="color:#b5cea8;">0</font> && offer.paid > <font style="color:#b5cea8;">0</font>) {
            GoldChain.Order <font style="color:#569cd6;">memory</font> balance;
            balance.data.classOfShare = offer.classOfShare;
            balance.data.seqOfShare = offer.seqOfShare;
            balance.data.pubKey = offer.to;
            balance.node.paid = offer.paid;
            _restoreOrder(_gk, balance);
        }
    }

    <font style="color:#569cd6;">function</font> _placeBuyOrder(
        <font style="color:#4ec9b0;">address</font> _gk,
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">private</font> {
        ICashier _cashier = _gk.getCashier();

        _cashier.custodyUsd(
            auth,
            <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CustodyValueOfBid"</font>)
        );

        (
            UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
            <font style="color:#4ec9b0;">uint</font> lenOfDeals,
            GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
            <font style="color:#4ec9b0;">uint</font> lenOfExpired,
            UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> bid
        ) = _gk.getLOO().placeBuyOrder(input, execHours);

        <font style="color:#569cd6;">if</font> (lenOfDeals > <font style="color:#b5cea8;">0</font>) {
            _closeDeals(_gk, deals, lenOfDeals, <font style="color:#569cd6;">false</font>);
        }
        <font style="color:#569cd6;">if</font> (lenOfExpired > <font style="color:#b5cea8;">0</font>) {
            _restoreExpiredOrders(_gk, expired, lenOfExpired);
        }
        <font style="color:#569cd6;">if</font> (bid.paid == <font style="color:#b5cea8;">0</font> && bid.consideration > <font style="color:#b5cea8;">0</font>) {
            _cashier.releaseUsd(
                bid.<font style="color:#569cd6;">from</font>,
                bid.<font style="color:#569cd6;">from</font>,
                _eightToSix(bid.consideration),
                <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RefundBalanceOfBidOrder"</font>)
            );
        }
    }

    <font style="color:#569cd6;">function</font> _restoreOrder(
        <font style="color:#4ec9b0;">address</font> _gk,
        GoldChain.Order <font style="color:#569cd6;">memory</font> order
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (order.node.isOffer) {
            IRegisterOfShares _ros = _gk.getROS();
            <font style="color:#569cd6;">if</font> (order.data.seqOfShare > <font style="color:#b5cea8;">0</font>) {
                _ros.increaseCleanPaid(order.data.seqOfShare, order.node.paid);
            } <font style="color:#569cd6;">else</font> {
                _ros.increaseEquityOfClass(<font style="color:#569cd6;">false</font>, order.data.classOfShare, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, order.node.paid);
            }
        } <font style="color:#569cd6;">else</font> {
            _gk.getCashier().releaseUsd(
                order.data.pubKey,
                order.data.pubKey,
                _eightToSix(order.data.margin),
                <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RefundValueOfBidOrder"</font>)
            );
        }
    }

    <font style="color:#569cd6;">function</font> _restoreExpiredOrders(
        <font style="color:#4ec9b0;">address</font> _gk,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> orders,
        <font style="color:#4ec9b0;">uint</font> len
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            _restoreOrder(_gk, orders[len - <font style="color:#b5cea8;">1</font>]);
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> _closeDeals(
        <font style="color:#4ec9b0;">address</font> _gk,
        UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> len,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">private</font> {
        ICashier _cashier = _gk.getCashier();
        IRegisterOfShares _ros = _gk.getROS();
        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> deal = deals[len - <font style="color:#b5cea8;">1</font>];
            len--;

            <font style="color:#569cd6;">if</font> (deal.seqOfShare > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">if</font> (!_ros.notLocked(deal.seqOfShare, block.timestamp)) {
                    <font style="color:#569cd6;">continue</font>;
                }

                <font style="color:#569cd6;">if</font> (isOffer) {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        deal.to,
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseOfferAgainstBid"</font>)
                    );
                } <font style="color:#569cd6;">else</font> {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        deal.to,
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseBidAgainstOffer"</font>)
                    );
                }

                _ros.increaseCleanPaid(deal.seqOfShare, deal.paid);
                _ros.transferShare(
                    deal.seqOfShare,
                    deal.paid,
                    deal.paid,
                    deal.buyer,
                    deal.price,
                    <font style="color:#b5cea8;">0</font>
                );
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">if</font> (isOffer) {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        <font style="color:#4ec9b0;">address</font>(_cashier),
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseInitOfferAgainstBid"</font>)
                    );
                } <font style="color:#569cd6;">else</font> {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        <font style="color:#4ec9b0;">address</font>(_cashier),
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseBidAgainstInitOffer"</font>)
                    );
                }

                SharesRepo.Share <font style="color:#569cd6;">memory</font> share;
                share.head = SharesRepo.Head({
                    class: deal.classOfShare,
                    seqOfShare: <font style="color:#b5cea8;">0</font>,
                    preSeq: <font style="color:#b5cea8;">0</font>,
                    issueDate: <font style="color:#b5cea8;">0</font>,
                    shareholder: deal.buyer,
                    priceOfPaid: deal.price,
                    priceOfPar: <font style="color:#b5cea8;">0</font>,
                    votingWeight: deal.votingWeight,
                    argu: <font style="color:#b5cea8;">0</font>
                });

                share.body = SharesRepo.Body({
                    payInDeadline: <font style="color:#4ec9b0;">uint48</font>(block.timestamp + <font style="color:#b5cea8;">86400</font>),
                    paid: deal.paid,
                    par: deal.paid,
                    cleanPaid: deal.paid,
                    distrWeight: deal.distrWeight
                });

                _ros.addShare(share);
            }

            <font style="color:#569cd6;">if</font> (deal.groupRep != deal.buyer &&
                deal.groupRep != _rom.groupRep(deal.buyer)) {
                _rom.addMemberToGroup(deal.buyer, deal.groupRep);
            }
        }
    }

    <font style="color:#569cd6;">function</font> _eightToSix(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> amt / <font style="color:#b5cea8;">100</font>;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## FundROCKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/FundROCKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/OfficersRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROCKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> FundROCKeeper <font style="color:#569cd6;">is</font> IROCKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint</font>[];
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("FundROCKeeper")))</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> TYPE_OF_DOC = 0x1590b2fb;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// ##########################</font>
    <font style="color:#6a9955;">// ##   Error & Modifier   ##</font>
    <font style="color:#6a9955;">// ##########################</font>

    <font style="color:#569cd6;">modifier</font> onlyDK() {
        <font style="color:#569cd6;">if</font> (msg.sender != IAccessControl(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)).getDK()) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#ce9178;">"FundROCK_NotDK"</font>);
        }
        _;
    }

    <font style="color:#6a9955;">// ==== Draft SHA ====</font>

    <font style="color:#569cd6;">function</font> createSHA(
        <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#ce9178;">"FundROCK_NotGP"</font>);
        }

        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _gk.getRCByGK().cloneDoc(
            <font style="color:#6a9955;">// uint32(uint(keccak256("ShareholdersAgreement")))</font>
            0x8c5a073d,version
        );

        IAccessControl(doc.body).initKeepers(
            <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>),
            _gk
        );

        IShareholdersAgreement(doc.body).initDefaultRules();

        _gk.getROC().regFile(DocsRepo.codifyHead(doc.head), doc.body);

        IOwnable(doc.body).setNewOwner(msg.sender);
    }

    <font style="color:#569cd6;">function</font> circulateSHA(
        <font style="color:#4ec9b0;">address</font> sha,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#ce9178;">"FundROCK_NotGP"</font>);
        }

        <font style="color:#569cd6;">if</font>(!IDraftControl(sha).isFinalized()) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongState(<font style="color:#ce9178;">"FundROCK_ShaNotFinalized"</font>);
        }

        IShareholdersAgreement _sha = IShareholdersAgreement(sha);

        _sha.circulateDoc();

        <font style="color:#4ec9b0;">uint16</font> signingDays = _sha.getSigningDays();
        <font style="color:#4ec9b0;">uint16</font> closingDays = _sha.getClosingDays();

        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr = <font style="color:#4ec9b0;">address</font>(_gk.getSHA()) == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)
            ? _sha.getRule(<font style="color:#b5cea8;">8</font>).votingRuleParser()
            : _gk.getSHA().getRule(<font style="color:#b5cea8;">8</font>).votingRuleParser();

        _gk.getROC().circulateFile(sha, signingDays, closingDays, vr, docUrl, docHash);
    }

    <font style="color:#6a9955;">// ======== Sign SHA ========</font>

    <font style="color:#569cd6;">function</font> signSHA(
        <font style="color:#4ec9b0;">address</font> sha,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font>(!ISigPage(sha).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#ce9178;">"FundROCK_NotPartyOfSha"</font>);
        }

        <font style="color:#569cd6;">if</font>(_gk.getROC().getHeadOfFile(sha).state != <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Circulated)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongState(<font style="color:#ce9178;">"FundROCK_ShaNotCirculated"</font>);
        }

        ISigPage(sha).signDoc(<font style="color:#569cd6;">true</font>, caller, sigHash);
    }

    <font style="color:#569cd6;">function</font> _membersAllSigned(
        IRegisterOfMembers _rom,
        IShareholdersAgreement _sha
    ) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members = _rom.membersList();
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> parties = _sha.getParties();

        <font style="color:#569cd6;">if</font> (parties.length == <font style="color:#b5cea8;">0</font> || parties.length != members.length) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        }

        <font style="color:#569cd6;">return</font> members.fullyCoveredBy(parties);
    }

    <font style="color:#569cd6;">function</font> activateSHA(<font style="color:#4ec9b0;">address</font> sha) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#569cd6;">if</font>(!ISigPage(sha).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#ce9178;">"FundROCK_NotPartyOfSha"</font>);
        }

        IRegisterOfConstitution _roc = _gk.getROC();
        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#569cd6;">if</font>(sha == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#ce9178;">"FundROCK_ZeroShaAddr"</font>);
        }
        IShareholdersAgreement _sha = IShareholdersAgreement(sha);

        <font style="color:#4ec9b0;">uint</font> seqOfMotion = _roc.getHeadOfFile(sha).seqOfMotion;

        <font style="color:#569cd6;">if</font> (seqOfMotion > <font style="color:#b5cea8;">0</font>) {
            _gk.getGMM().execResolution(
                seqOfMotion,
                <font style="color:#4ec9b0;">uint</font>(<font style="color:#4ec9b0;">uint160</font>(sha)),
                caller
            );
            _roc.execFile(sha);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_membersAllSigned(_rom, _sha)) {
            _roc.setStateOfFile(sha, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Closed));
        }

        _roc.changePointer(sha);

        RulesParser.GovernanceRule <font style="color:#569cd6;">memory</font> gr =
            _sha.getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser();

        <font style="color:#569cd6;">if</font> (_rom.maxQtyOfMembers() != gr.maxQtyOfMembers)
            _rom.setMaxQtyOfMembers(gr.maxQtyOfMembers);

        _rom.setVoteBase(gr.basedOnPar);

        <font style="color:#569cd6;">if</font> (_rom.minVoteRatioOnChain() != gr.minVoteRatioOnChain)
            _rom.setMinVoteRatioOnChain(gr.minVoteRatioOnChain);

        <font style="color:#569cd6;">if</font> (_sha.hasTitle(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.Options)))
            _regOptionTerms(_gk, _sha);

        _updatePositionSetting(_gk, _sha);
        _updateGrouping(_gk, _sha);
    }

    <font style="color:#569cd6;">function</font> _regOptionTerms(<font style="color:#4ec9b0;">address</font> _gk, IShareholdersAgreement _sha) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">address</font> opts = _sha.getTerm(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.Options));
        _gk.getROO().regOptionTerms(opts);
    }

    <font style="color:#569cd6;">function</font> _updatePositionSetting(<font style="color:#4ec9b0;">address</font> _gk, IShareholdersAgreement _sha) <font style="color:#569cd6;">private</font> {
        IRegisterOfDirectors _rod = _gk.getROD();

        <font style="color:#4ec9b0;">uint256</font> len = _sha.getRule(<font style="color:#b5cea8;">256</font>).positionAllocateRuleParser().qtyOfSubRule;
        <font style="color:#4ec9b0;">uint256</font> i;
        <font style="color:#569cd6;">while</font> (i < len) {
            RulesParser.PositionAllocateRule <font style="color:#569cd6;">memory</font> rule =
                _sha.getRule(<font style="color:#b5cea8;">256</font>+i).positionAllocateRuleParser();

            <font style="color:#569cd6;">if</font> (rule.removePos) {
                _rod.removePosition(rule.seqOfPos);
            } <font style="color:#569cd6;">else</font> {
                OfficersRepo.Position <font style="color:#569cd6;">memory</font> pos = _rod.getPosition(rule.seqOfPos);
                pos = OfficersRepo.Position({
                    title: rule.titleOfPos,
                    seqOfPos: rule.seqOfPos,
                    acct: pos.acct,
                    nominator: rule.nominator,
                    startDate: pos.startDate,
                    endDate: rule.endDate,
                    seqOfVR: rule.seqOfVR,
                    titleOfNominator: rule.titleOfNominator,
                    argu: rule.argu
                });

                _rod.updatePosition(pos);
            }

            i++;
        }
    }

    <font style="color:#569cd6;">function</font> _updateGrouping(<font style="color:#4ec9b0;">address</font> _gk, IShareholdersAgreement _sha) <font style="color:#569cd6;">private</font> {
        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#4ec9b0;">uint256</font> len = _sha.getRule(<font style="color:#b5cea8;">768</font>).groupUpdateOrderParser().qtyOfSubRule;
        <font style="color:#4ec9b0;">uint256</font> i;

        <font style="color:#569cd6;">while</font> (i < len) {
            RulesParser.GroupUpdateOrder <font style="color:#569cd6;">memory</font> order =
                _sha.getRule(<font style="color:#b5cea8;">768</font>+i).groupUpdateOrderParser();

            <font style="color:#4ec9b0;">uint256</font> j;
            <font style="color:#569cd6;">if</font> (order.addMember) {
                <font style="color:#569cd6;">while</font> (j < <font style="color:#b5cea8;">4</font>) {
                    <font style="color:#569cd6;">if</font> (order.members[j] > <font style="color:#b5cea8;">0</font>)
                        _rom.addMemberToGroup(order.members[j], order.groupRep);
                    j++;
                }
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">while</font> (j < <font style="color:#b5cea8;">4</font>) {
                    <font style="color:#569cd6;">if</font> (order.members[j] > <font style="color:#b5cea8;">0</font>)
                        _rom.removeMemberFromGroup(order.members[j]);
                    j++;
                }
            }

            i++;
        }
    }

    <font style="color:#569cd6;">function</font> acceptSHA(<font style="color:#4ec9b0;">bytes32</font> sigHash) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        IShareholdersAgreement _sha = _gk.getSHA();
        _sha.addBlank(<font style="color:#569cd6;">false</font>, <font style="color:#569cd6;">true</font>, <font style="color:#b5cea8;">1</font>, caller);
        _sha.signDoc(<font style="color:#569cd6;">false</font>, caller, sigHash);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## FundROIKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/FundROIKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROIKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> FundROIKeeper <font style="color:#569cd6;">is</font> IROIKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("FundROIKeeper")))</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> TYPE_OF_DOC = 0x918b186a;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// ==== Pause LOO ====</font>

    <font style="color:#569cd6;">function</font> _checkVerifierLicense(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font>{
        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();
        <font style="color:#569cd6;">if</font>(!_gk.getROD().hasTitle(caller, lr.titleOfVerifier)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_NotVerifier"</font>);
        }
    }

    <font style="color:#569cd6;">function</font> _checkEnforcerLicense(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font>{
        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();
        <font style="color:#569cd6;">if</font>(!_gk.getROD().hasTitle(caller, lr.para)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_NotEnforcer"</font>);
        }
    }

    <font style="color:#569cd6;">function</font> pause(<font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        _gk.getROI().pause(caller);
    }

    <font style="color:#569cd6;">function</font> unPause(<font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        _gk.getROI().unPause(caller);
    }

    <font style="color:#6a9955;">// ==== Freeze Share ====</font>

    <font style="color:#569cd6;">function</font> freezeShare(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        IRegisterOfShares _ros = _gk.getROS();
        _ros.decreaseCleanPaid(seqOfShare, paid);
        <font style="color:#4ec9b0;">uint</font> shareholder = _ros.getShare(seqOfShare).head.shareholder;
        _gk.getROI().freezeShare(shareholder, seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#569cd6;">function</font> unfreezeShare(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        IRegisterOfShares _ros = _gk.getROS();
        _ros.increaseCleanPaid(seqOfShare, paid);
        <font style="color:#4ec9b0;">uint</font> shareholder = _ros.getShare(seqOfShare).head.shareholder;
        _gk.getROI().unfreezeShare(shareholder, seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#569cd6;">function</font> forceTransfer(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">address</font> addrTo, <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        IRegisterOfInvestors _roi = _gk.getROI();
        <font style="color:#4ec9b0;">uint</font> to = addrTo.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);
        <font style="color:#569cd6;">if</font> (!_roi.isInvestor(to)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_NotInvestor"</font>);
        }

        IRegisterOfShares _ros = _gk.getROS();
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share = _ros.getShare(seqOfShare);
        _ros.increaseCleanPaid(seqOfShare, paid);

        _roi.forceTransfer(share.head.shareholder, seqOfShare, paid, caller, hashOrder);
        _ros.transferShare(seqOfShare, paid, paid, to, share.head.priceOfPaid, share.head.priceOfPar);
    }

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#569cd6;">function</font> regInvestor(
        <font style="color:#4ec9b0;">address</font> bKey, <font style="color:#4ec9b0;">uint</font> groupRep, <font style="color:#4ec9b0;">bytes32</font> idHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font>(msg.sender == bKey) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_SameKey"</font>);
        }

        <font style="color:#569cd6;">if</font>(caller != bKey.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_WrongBackupKey"</font>);
        }

        <font style="color:#569cd6;">if</font> (msg.sender.isContract()) {
            <font style="color:#6a9955;">// uint32(uint(keccak256("GeneralKeeper")))</font>
            <font style="color:#569cd6;">if</font>(_gk.getRCByGK().getHeadByBody(msg.sender).typeOfDoc != 0x25586efd) {
                <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_NotGK"</font>);
            }
        }

        <font style="color:#569cd6;">if</font> (bKey.isContract()) {
            <font style="color:#569cd6;">if</font> (_gk.getRCByGK().getHeadByBody(bKey).typeOfDoc != 0x25586efd) {
                <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_BKeyNotGK"</font>);
            }
        }

        _gk.getROI().regInvestor(caller, groupRep, idHash);
    }

    <font style="color:#569cd6;">function</font> approveInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkVerifierLicense(_gk, seqOfLR, caller);

        IRegisterOfInvestors _roi = _gk.getROI();

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_NotGP"</font>);
        }

        <font style="color:#569cd6;">if</font>(lr.maxQtyOfInvestors != <font style="color:#b5cea8;">0</font> && _roi.getQtyOfInvestors() >= lr.maxQtyOfInvestors) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongInput(<font style="color:#ce9178;">"FundROIK_NoQuotaForNewInvestor"</font>);
        }

        _roi.approveInvestor(userNo, caller);
    }

    <font style="color:#569cd6;">function</font> revokeInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkVerifierLicense(_gk, seqOfLR, caller);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#ce9178;">"FundROIK_NotGP"</font>);
        }

        _gk.getROI().revokeInvestor(userNo, caller);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## FundRORKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/FundRORKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRORKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> FundRORKeeper <font style="color:#569cd6;">is</font> IRORKeeper {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("FundRORKeeper")))</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> TYPE_OF_DOC = 0x7ecb1211;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">constant</font> <font style="color:#569cd6;">public</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#569cd6;">function</font> _gpOrManager(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font>{
        <font style="color:#569cd6;">if</font> (!(_gk.getROM().isClassMember(caller, <font style="color:#b5cea8;">1</font>) ||
            _gk.getROD().isDirector(caller))) {
            <font style="color:#569cd6;">revert</font> FundRORK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundRORK_NotGPOrManager"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> addRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        _gpOrManager(_gk, caller);
        _gk.getROR().addRedeemableClass(class);
    }

    <font style="color:#569cd6;">function</font> removeRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        _gpOrManager(_gk, caller);
        _gk.getROR().removeRedeemableClass(class);
    }

    <font style="color:#569cd6;">function</font> updateNavPrice(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> price) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        _gpOrManager(_gk, caller);
        <font style="color:#569cd6;">if</font> (price == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> FundRORK_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundRORK_ZeroPrice"</font>));
        }
        _gk.getROR().updateNavPrice(class, price);
    }

    <font style="color:#569cd6;">function</font> requestForRedemption(
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        IRegisterOfMembers _rom = _gk.getROM();
        IRegisterOfShares _ros = _gk.getROS();
        IRegisterOfRedemptions _ror = _gk.getROR();

        <font style="color:#569cd6;">if</font> (!_rom.isClassMember(caller, class)) {
            <font style="color:#569cd6;">revert</font> FundRORK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundRORK_NotClassMember"</font>));
        }
        <font style="color:#569cd6;">if</font> (paid == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> FundRORK_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundRORK_ZeroPaid"</font>));
        }

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> sharesInhand =
            _rom.sharesInClass(caller, class);

        <font style="color:#4ec9b0;">uint</font> len = sharesInhand.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font> && paid > <font style="color:#b5cea8;">0</font>) {

            SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
                _ros.getShare(sharesInhand[len - <font style="color:#b5cea8;">1</font>]);
            len--;

            <font style="color:#569cd6;">if</font> (!_ros.notLocked(share.head.seqOfShare, block.timestamp)) {
                <font style="color:#569cd6;">continue</font>;
            }

            <font style="color:#569cd6;">if</font> (share.body.cleanPaid > <font style="color:#b5cea8;">0</font>) {

                <font style="color:#4ec9b0;">uint</font> redPaid;

                <font style="color:#569cd6;">if</font> (paid >= share.body.cleanPaid) {
                    redPaid = share.body.cleanPaid;
                } <font style="color:#569cd6;">else</font> {
                    redPaid = paid;
                }

                paid -= redPaid;
                _ros.decreaseCleanPaid(share.head.seqOfShare, redPaid);
                _ror.requestForRedemption(caller, class, share.head.seqOfShare, redPaid);

            }
        }

    }

    <font style="color:#569cd6;">function</font> redeem(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gpOrManager(_gk, caller);

        (RedemptionsRepo.Request[] <font style="color:#569cd6;">memory</font> list, RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> info) =
            _gk.getROR().redeem(class, seqOfPack);

        ICashier _cashier = _gk.getCashier();
        IRegisterOfShares _ros = _gk.getROS();

        <font style="color:#569cd6;">if</font> (info.value * <font style="color:#b5cea8;">100</font> > _cashier.balanceOfComp()) {
            <font style="color:#569cd6;">revert</font> FundRORK_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FundRORK_InsufficientBalance"</font>));
        }

        _cashier.redeemClass(class, info.paid);

        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            RedemptionsRepo.Request <font style="color:#569cd6;">memory</font> request = list[len-<font style="color:#b5cea8;">1</font>];

            _ros.increaseCleanPaid(request.seqOfShare, request.paid);
            _ros.decreaseCapital(request.seqOfShare, request.paid, request.paid);

            _cashier.depositUsd(
                request.value * <font style="color:#b5cea8;">100</font>,
                request.shareholder,
                <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RedeemShare"</font>)
            );

            len--;
        }

    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## GMMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/GMMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IGMMKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> GMMKeeper <font style="color:#569cd6;">is</font> IGMMKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint</font>[];
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("GMMKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x49148247;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#6a9955;">// ==== CreateMotion ====</font>

    <font style="color:#6a9955;">// ---- Officers ----</font>
    <font style="color:#569cd6;">function</font> nominateDirector(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> candidate
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">72000</font>);

        IRegisterOfDirectors _rod = _gk.getROD();

        <font style="color:#569cd6;">if</font>(!_rod.hasNominationRight(seqOfPos, caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NoNominationRight"</font>));

        _gk.getGMM().nominateOfficer(
            seqOfPos,
            _rod.getPosition(seqOfPos).seqOfVR,
            candidate,
            caller
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToRemoveDirector(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">116000</font>);

        IRegisterOfDirectors _rod = _gk.getROD();

        <font style="color:#569cd6;">if</font>(!_rod.hasNominationRight(seqOfPos, caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NoNominationRight"</font>));

        _gk.getGMM().createMotionToRemoveOfficer(
            seqOfPos,
            _rod.getPosition(seqOfPos).seqOfVR,
            caller
        );
    }

    <font style="color:#569cd6;">function</font> proposeDocOfGM(
        <font style="color:#4ec9b0;">uint</font> doc,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">116000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isMember(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NotMember"</font>));

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _gmm.createMotionToApproveDoc(doc, seqOfVR, executor, caller);

        _gmm.proposeMotionToGeneralMeeting(seqOfMotion, caller);

        <font style="color:#569cd6;">if</font> (seqOfVR < <font style="color:#b5cea8;">9</font>) {

            <font style="color:#4ec9b0;">address</font> addr = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(doc));

            <font style="color:#569cd6;">if</font>(!ISigPage(addr).isSigner(caller))
                <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NotSignerOfDoc"</font>));

            <font style="color:#569cd6;">if</font>(!ISigPage(addr).established())
                <font style="color:#569cd6;">revert</font> GMMK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_DocNotEstablished"</font>));

            <font style="color:#569cd6;">if</font> (seqOfVR == <font style="color:#b5cea8;">8</font>) {
                _gk.getROC().proposeFile(addr, seqOfMotion);
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">if</font>(!_gk.getROA().allClaimsAccepted(addr))
                    <font style="color:#569cd6;">revert</font> GMMK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_RoaHasOpenClaims"</font>));
                _gk.getROA().proposeFile(addr, seqOfMotion);
            }
        }
    }

    <font style="color:#569cd6;">function</font> proposeToDistributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">68000</font>);

        <font style="color:#569cd6;">if</font>( !_gk.getROM().isMember(caller) && !_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NoProposalRight"</font>));

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _gmm.createMotionToDistributeUsd(amt, expireDate, seqOfVR, seqOfDR, para, executor, caller);

        _gmm.proposeMotionToGeneralMeeting(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> proposeToTransferFundWithGM(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">99000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isMember(caller) && !_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NoProposalRight"</font>));

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#4ec9b0;">uint64</font> seqOfMotion =
            _gmm.createMotionToTransferFund(to, isCBP, amt, expireDate, seqOfVR, executor, caller);

        _gmm.proposeMotionToGeneralMeeting(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> createActionOfGM(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">99000</font>);
        <font style="color:#569cd6;">if</font>(!_gk.getROM().isMember(caller) && !_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NoProposalRight"</font>));

        _gk.getGMM().createAction(
            seqOfVR,
            targets,
            values,
            params,
            desHash,
            executor,
            caller
        );
    }

    <font style="color:#569cd6;">function</font> createMotionToDecreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font>(!_gk.getROM().isMember(caller) && !_gk.getROD().isDirector(caller))
            <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NoProposalRight"</font>));

        _gk.getGMM().createMotionToDecreaseCapital(
            seqOfVR, seqOfShare,
            paid, par, amt,
            executor, caller
        );
    }

    <font style="color:#6a9955;">// ==== ProposeMotion ====</font>

    <font style="color:#569cd6;">function</font> entrustDelegaterForGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _avoidanceCheck(_gk, seqOfMotion, caller);
        _gk.getGMM().entrustDelegate(seqOfMotion, delegate, caller);
    }

    <font style="color:#569cd6;">function</font> proposeMotionToGeneralMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">72000</font>);

        _gk.getGMM().proposeMotionToGeneralMeeting(seqOfMotion, caller);
    }

    <font style="color:#569cd6;">function</font> castVoteOfGM(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">72000</font>);

        _avoidanceCheck(_gk, seqOfMotion, caller);
        _gk.getGMM().castVoteInGeneralMeeting(seqOfMotion, attitude, sigHash, caller);
    }

    <font style="color:#569cd6;">function</font> _avoidanceCheck(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion = _gk.getGMM().getMotion(seqOfMotion);

        <font style="color:#569cd6;">if</font> (motion.votingRule.class > <font style="color:#b5cea8;">0</font> &&
            !_gk.getROM().isClassMember(caller, motion.votingRule.class)
        ) <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_NotClassMember"</font>));

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc) &&
            motion.head.seqOfVR < <font style="color:#b5cea8;">9</font>)
        {
            <font style="color:#4ec9b0;">address</font> doc = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents));
            <font style="color:#569cd6;">if</font> (ISigPage(doc).isSigner(caller))
                <font style="color:#569cd6;">revert</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GMMK_IsRelatedParty"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> voteCountingOfGM(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        _voteCountingOfGM(_gk, seqOfMotion);
    }

    <font style="color:#6a9955;">// ==== Vote Counting ====</font>

    <font style="color:#569cd6;">function</font> _voteCountingOfGM(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">private</font> {
        IRegisterOfMembers _rom = _gk.getROM();
        IMeetingMinutes _gmm = _gk.getGMM();

        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion =
            _gmm.getMotion(seqOfMotion);

        MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base;

        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0 = _gmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">if</font> (_allConsent(_gmm, _rom, motion, case0)) {
            base.unaniConsent = <font style="color:#569cd6;">true</font>;
        } <font style="color:#569cd6;">else</font> {
            base = _calBase(_gk, _gmm, _rom, motion, base, case0);
        }

        <font style="color:#4ec9b0;">bool</font> quorumFlag = (<font style="color:#4ec9b0;">address</font>(_gk.getSHA()) == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>) ||
            base.attendWeightRatio >=
            _gk.getSHA().getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser().quorumOfGM);

        <font style="color:#4ec9b0;">bool</font> approved = _gmm.voteCounting(quorumFlag, seqOfMotion, base) ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Passed);

        <font style="color:#569cd6;">if</font> (motion.head.seqOfVR < <font style="color:#b5cea8;">9</font>) {
            <font style="color:#4ec9b0;">address</font> doc = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents));

            <font style="color:#569cd6;">if</font> (motion.head.seqOfVR == <font style="color:#b5cea8;">8</font>) {
                _gk.getROC().voteCountingForFile(doc, approved);
            } <font style="color:#569cd6;">else</font> {
                _gk.getROA().voteCountingForFile(doc, approved);
            }
        }
    }

    <font style="color:#569cd6;">function</font> _allConsent(
        IMeetingMinutes _gmm,
        IRegisterOfMembers _rom,
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion,
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case1 = _gmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">1</font>);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> consentVoters = case1.voters.combine(case1.principals);

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> allVoters = case0.voters.combine(case0.principals);

        <font style="color:#569cd6;">if</font> (allVoters.length > consentVoters.length) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members = motion.votingRule.class == <font style="color:#b5cea8;">0</font>
            ? _rom.membersList()
            : _rom.getMembersOfClass(motion.votingRule.class);

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> restMembers = members.minus(consentVoters);

        <font style="color:#569cd6;">if</font> (restMembers.length == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc)) {

            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties =
                ISigPage(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents))).getParties();

            <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> vetoMembers = restMembers.minus(parties);

            <font style="color:#4ec9b0;">uint</font> len = vetoMembers.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">if</font> (_rom.votesAtDate(vetoMembers[len - <font style="color:#b5cea8;">1</font>], motion.body.shareRegDate) > <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
                len--;
            }

            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _calBase(
        <font style="color:#4ec9b0;">address</font> _gk,
        IMeetingMinutes _gmm,
        IRegisterOfMembers _rom,
        MotionsRepo.Motion <font style="color:#569cd6;">memory</font> motion,
        MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font> base,
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case0
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (MotionsRepo.VoteCalBase <font style="color:#569cd6;">memory</font>) {
        BallotsBox.Case <font style="color:#569cd6;">memory</font> case3 =
            _gmm.getCaseOfAttitude(motion.head.seqOfMotion, <font style="color:#b5cea8;">3</font>);

        <font style="color:#4ec9b0;">uint64</font> votesOfMembers;
        <font style="color:#569cd6;">if</font> (motion.votingRule.class == <font style="color:#b5cea8;">0</font>) {
            votesOfMembers = _rom.totalVotes();
        } <font style="color:#569cd6;">else</font> {
            SharesRepo.Share <font style="color:#569cd6;">memory</font> classInfo =
                _gk.getROS().getInfoOfClass(motion.votingRule.class);
            votesOfMembers = _rom.basedOnPar()
                ? classInfo.head.votingWeight * classInfo.body.par
                : classInfo.head.votingWeight * classInfo.body.paid;
        }

        base.attendWeightRatio = <font style="color:#4ec9b0;">uint16</font>(case0.sumOfWeight * <font style="color:#b5cea8;">10000</font> / votesOfMembers);

        <font style="color:#569cd6;">if</font> (motion.votingRule.onlyAttendance) {

            base.totalHead = (case0.sumOfHead - case3.sumOfHead);
            base.totalWeight = (case0.sumOfWeight - case3.sumOfWeight);

        } <font style="color:#569cd6;">else</font> {

            base.totalHead = motion.votingRule.class == <font style="color:#b5cea8;">0</font>
                ? <font style="color:#4ec9b0;">uint32</font>(_rom.qtyOfMembers())
                : <font style="color:#4ec9b0;">uint32</font>(_rom.qtyOfClassMember(motion.votingRule.class));

            base.totalWeight = votesOfMembers;

            <font style="color:#569cd6;">if</font> (motion.votingRule.impliedConsent) {

                base.supportHead = base.totalHead - case0.sumOfHead;
                base.supportWeight = base.totalWeight > case0.sumOfWeight
                        ? (base.totalWeight - case0.sumOfWeight)
                        : <font style="color:#b5cea8;">0</font>;
                base.attendWeightRatio = <font style="color:#b5cea8;">10000</font>;
            }

            base.totalHead -= case3.sumOfHead;
            base.totalWeight = base.totalWeight > case3.sumOfWeight
                    ? base.totalWeight - case3.sumOfWeight
                    : <font style="color:#b5cea8;">0</font> ;
        }

        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion ==
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ApproveDoc)) {

            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties =
                ISigPage(<font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(motion.contents))).getParties();
            <font style="color:#4ec9b0;">uint256</font> len = parties.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#4ec9b0;">uint64</font> votesAtDate =
                    _rom.votesAtDate(parties[len - <font style="color:#b5cea8;">1</font>], motion.body.shareRegDate);

                <font style="color:#569cd6;">if</font> (votesAtDate > <font style="color:#b5cea8;">0</font>) {
                    <font style="color:#569cd6;">if</font> (motion.votingRule.partyAsConsent) {

                        <font style="color:#569cd6;">if</font> (motion.votingRule.onlyAttendance) {
                            base.totalHead++;
                            base.totalWeight += votesAtDate;
                        }

                        <font style="color:#569cd6;">if</font> (!motion.votingRule.impliedConsent) {
                            base.supportHead ++;
                            base.supportWeight += votesAtDate;

                            base.attendWeightRatio += <font style="color:#4ec9b0;">uint16</font>(votesAtDate * <font style="color:#b5cea8;">10000</font> / votesOfMembers);
                        }

                    } <font style="color:#569cd6;">else</font> {

                        <font style="color:#569cd6;">if</font> (!motion.votingRule.onlyAttendance) {
                            base.totalHead --;

                            base.totalWeight = base.totalWeight > votesAtDate
                                    ? base.totalWeight - votesAtDate
                                    : <font style="color:#b5cea8;">0</font>;
                        }

                        <font style="color:#569cd6;">if</font> (motion.votingRule.impliedConsent) {
                            base.supportHead --;

                            base.supportWeight = base.supportWeight > votesAtDate
                                    ? base.supportWeight - votesAtDate
                                    : <font style="color:#b5cea8;">0</font>;
                        } <font style="color:#569cd6;">else</font> {
                            base.attendWeightRatio += <font style="color:#4ec9b0;">uint16</font>(votesAtDate * <font style="color:#b5cea8;">10000</font> / votesOfMembers);
                        }
                    }
                }

                len--;
            }
        }

        <font style="color:#569cd6;">return</font> base;
    }

    <font style="color:#6a9955;">// ==== Execute Action ====</font>

    <font style="color:#569cd6;">function</font> execActionOfGM(
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _execActionOfGM(
            caller,
            typeOfAction,
            targets,
            values,
            params,
            desHash,
            seqOfMotion
        );
    }

    <font style="color:#569cd6;">function</font> _execActionOfGM(
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font>(!(targets.length == values.length && targets.length == params.length))
            <font style="color:#569cd6;">revert</font> GMMK_WrongInput(<font style="color:#ce9178;">"GMMK_InputLenMismatch"</font>);

        <font style="color:#4ec9b0;">uint</font> len = targets.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            targets[len - <font style="color:#b5cea8;">1</font>].functionCallWithValue(params[len - <font style="color:#b5cea8;">1</font>], values[len - <font style="color:#b5cea8;">1</font>]);
            <font style="color:#569cd6;">emit</font> ExecAction(targets[len - <font style="color:#b5cea8;">1</font>], values[len - <font style="color:#b5cea8;">1</font>], params[len - <font style="color:#b5cea8;">1</font>], seqOfMotion, caller);
            len--;
        }

        <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getGMM().execAction(
            typeOfAction,
            targets,
            values,
            params,
            desHash,
            seqOfMotion,
            caller
        );
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IAccountant.sol

---

| |
|:---|
| **contracts/comps/keepers/IAccountant.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IAccountant</font>
<font style="color:#6a9955;">/// @notice Interface for class initialization, distributions, and fund transfers.</font>
<font style="color:#569cd6;">interface</font> IAccountant {

    <font style="color:#6a9955;">/// @notice Initialize waterfall class data.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">function</font> initClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Distribute profits by distribution rule.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param expireDate Distribution expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> distrProfits(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Distribute income to fund manager and recipients.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param expireDate Distribution expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @param fundManager Fund manager user number.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> distrIncome(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> fundManager,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Transfer funds from treasury to a recipient.</font>
    <font style="color:#6a9955;">/// @param fromBMM True if triggered by BMM, false for GMM.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param isCBP True if paid in CBP, false for USDC.</font>
    <font style="color:#6a9955;">/// @param amt Amount to transfer.</font>
    <font style="color:#6a9955;">/// @param expireDate Transfer expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> transferFund(
        <font style="color:#4ec9b0;">bool</font> fromBMM,
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IBMMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IBMMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IBMMKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for board meeting motions and executions.</font>
<font style="color:#569cd6;">interface</font> IBMMKeeper {

    <font style="color:#6a9955;">/// @notice Nominate an officer for a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#6a9955;">/// @param candidate Candidate user number.</font>
    <font style="color:#569cd6;">function</font> nominateOfficer(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> candidate
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create a motion to remove an officer.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> createMotionToRemoveOfficer(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ---- Docs ----</font>

    <font style="color:#6a9955;">/// @notice Create a motion to approve a document.</font>
    <font style="color:#6a9955;">/// @param doc Document id.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> createMotionToApproveDoc(
        <font style="color:#4ec9b0;">uint</font> doc,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ---- TransferFund ----</font>

    <font style="color:#6a9955;">/// @notice Propose a fund transfer motion.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param isCBP True if paid in CBP, false for USDC.</font>
    <font style="color:#6a9955;">/// @param amt Amount to transfer.</font>
    <font style="color:#6a9955;">/// @param expireDate Motion expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> proposeToTransferFundWithBoard(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ---- Action ----</font>

    <font style="color:#6a9955;">/// @notice Create a motion to execute an arbitrary action.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param targets Target contract list.</font>
    <font style="color:#6a9955;">/// @param values ETH values list.</font>
    <font style="color:#6a9955;">/// @param params Encoded params list.</font>
    <font style="color:#6a9955;">/// @param desHash Description hash.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> createAction(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Cast Vote ====</font>

    <font style="color:#6a9955;">/// @notice Entrust voting to a delegate.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param delegate Delegate user number.</font>
    <font style="color:#569cd6;">function</font> entrustDelegaterForBoardMeeting(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a motion to the board.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> proposeMotionToBoard (
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Cast vote on a motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param attitude Vote attitude.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> castVote(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Count votes for a motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> voteCounting(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Exec Motion ====</font>

    <font style="color:#6a9955;">/// @notice Execute an action motion.</font>
    <font style="color:#6a9955;">/// @param typeOfAction Action type.</font>
    <font style="color:#6a9955;">/// @param targets Target contract list.</font>
    <font style="color:#6a9955;">/// @param values ETH values list.</font>
    <font style="color:#6a9955;">/// @param params Encoded params list.</font>
    <font style="color:#6a9955;">/// @param desHash Description hash.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> execAction(
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IGMMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IGMMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IGMMKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for general meeting motions and executions.</font>
<font style="color:#569cd6;">interface</font> IGMMKeeper {

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">error</font> GMMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> GMMK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> GMMK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when a general meeting action is executed.</font>
    <font style="color:#6a9955;">/// @param targets Target contract address.</font>
    <font style="color:#6a9955;">/// @param values ETH value.</font>
    <font style="color:#6a9955;">/// @param params Encoded parameters blob.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">event</font> ExecAction(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> targets,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> values,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">indexed</font> params,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller
    );

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##   Motion   ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Nominate a director for a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#6a9955;">/// @param candidate Candidate user number.</font>
    <font style="color:#569cd6;">function</font> nominateDirector(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> candidate
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create a motion to remove a director.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> createMotionToRemoveDirector(
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a document for general meeting approval.</font>
    <font style="color:#6a9955;">/// @param doc Document id.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> proposeDocOfGM(<font style="color:#4ec9b0;">uint</font> doc, <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint</font> executor) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a USDC distribution motion.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param expireDate Motion expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfDR Distribution rule sequence.</font>
    <font style="color:#6a9955;">/// @param para Extra parameter.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> proposeToDistributeUsd(
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> seqOfDR,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a fund transfer motion.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param isCBP True if paid in CBP, false for USDC.</font>
    <font style="color:#6a9955;">/// @param amt Amount to transfer.</font>
    <font style="color:#6a9955;">/// @param expireDate Motion expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> proposeToTransferFundWithGM(
        <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">bool</font> isCBP,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> expireDate,
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create a general meeting action motion.</font>
    <font style="color:#6a9955;">/// @param seqOfVR Voting rule sequence.</font>
    <font style="color:#6a9955;">/// @param targets Target contract list.</font>
    <font style="color:#6a9955;">/// @param values ETH values list.</font>
    <font style="color:#6a9955;">/// @param params Encoded params list.</font>
    <font style="color:#6a9955;">/// @param desHash Description hash.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> createActionOfGM(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Entrust voting to a delegate for GM.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param delegate Delegate user number.</font>
    <font style="color:#569cd6;">function</font> entrustDelegaterForGeneralMeeting(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> delegate) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Propose a motion to general meeting.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> proposeMotionToGeneralMeeting(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Cast vote on a GM motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param attitude Vote attitude.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> castVoteOfGM(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Count votes for a motion.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> voteCountingOfGM(<font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute an action motion.</font>
    <font style="color:#6a9955;">/// @param typeOfAction Action type.</font>
    <font style="color:#6a9955;">/// @param targets Target contract list.</font>
    <font style="color:#6a9955;">/// @param values ETH values list.</font>
    <font style="color:#6a9955;">/// @param params Encoded params list.</font>
    <font style="color:#6a9955;">/// @param desHash Description hash.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.   </font>
    <font style="color:#569cd6;">function</font> execActionOfGM(
        <font style="color:#4ec9b0;">uint</font> typeOfAction,
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> targets,
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> values,
        <font style="color:#4ec9b0;">bytes</font>[] <font style="color:#569cd6;">memory</font> params,
        <font style="color:#4ec9b0;">bytes32</font> desHash,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IKeepersRouter.sol

---

| |
|:---|
| **contracts/comps/keepers/IKeepersRouter.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">interface</font> IKeepersRouter  {

    <font style="color:#569cd6;">error</font> KeeprsRouter_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Get the title associated with a function selector.</font>
    <font style="color:#6a9955;">/// @param sig Function selector (first 4 bytes of calldata).</font>
    <font style="color:#6a9955;">/// @return title number (0 if not found).</font>
    <font style="color:#569cd6;">function</font> getTitleBySelector(<font style="color:#4ec9b0;">bytes4</font> sig) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font> title);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ILOOKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ILOOKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../books/cashier/ICashier.sol"</font>;

<font style="color:#6a9955;">/// @title ILOOKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for placing and withdrawing LOO orders.</font>
<font style="color:#569cd6;">interface</font> ILOOKeeper {

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Error   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#569cd6;">error</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">/// @notice Place an initial offer for a class.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param execHours Execution window in hours.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param price Unit price.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> placeInitialOffer(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> price,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Withdraw an initial offer.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> withdrawInitialOffer(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Place a sell order.</font>
    <font style="color:#6a9955;">/// @param seqOfClass Share class id.</font>
    <font style="color:#6a9955;">/// @param execHours Execution window in hours.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param price Unit price.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> placeSellOrder(
        <font style="color:#4ec9b0;">uint</font> seqOfClass,
        <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> price,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Withdraw a sell order.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#569cd6;">function</font> withdrawSellOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Place a buy order with transfer authorization.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param price Unit price.</font>
    <font style="color:#6a9955;">/// @param execHours Execution window in hours.</font>
    <font style="color:#569cd6;">function</font> placeBuyOrder(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Place a market buy order with transfer authorization.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param execHours Execution window in hours.</font>
    <font style="color:#569cd6;">function</font> placeMarketBuyOrder(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Withdraw a buy order.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#569cd6;">function</font> withdrawBuyOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IROAKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IROAKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../books/cashier/ICashier.sol"</font>;

<font style="color:#6a9955;">/// @title IROAKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for investment agreements and deal execution.</font>
<font style="color:#569cd6;">interface</font> IROAKeeper {

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##   Write IO  ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Create a new investment agreement.</font>
    <font style="color:#6a9955;">/// @param version Agreement version.</font>
    <font style="color:#569cd6;">function</font> createIA(<font style="color:#4ec9b0;">uint256</font> version) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Circulate an IA document for signature.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param docUrl Document URL hash.</font>
    <font style="color:#6a9955;">/// @param docHash Document content hash.</font>
    <font style="color:#569cd6;">function</font> circulateIA(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Sign an IA document.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> signIA(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Deal & IA ====</font>

    <font style="color:#6a9955;">/// @notice Push deal funds into coffer with hash lock.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock for closing.</font>
    <font style="color:#6a9955;">/// @param closingDeadline Closing deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> pushToCoffer(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> closingDeadline
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Close a deal using hash key.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Hash key for closing.</font>
    <font style="color:#569cd6;">function</font> closeDeal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Transfer target share per deal terms.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> transferTargetShare(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Issue new share for a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> issueNewShare(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Terminate a deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> terminateDeal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Pay off an approved deal with transfer authorization.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#569cd6;">function</font> payOffApprovedDeal(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">address</font> to
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IROCKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IROCKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IROCKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for shareholder agreement lifecycle actions.</font>
<font style="color:#569cd6;">interface</font> IROCKeeper {

    <font style="color:#6a9955;">// ##########################</font>
    <font style="color:#6a9955;">// ##   Error & Modifier   ##</font>
    <font style="color:#6a9955;">// ##########################</font>

    <font style="color:#569cd6;">error</font> ROCK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROCK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROCK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Create a shareholder agreement.</font>
    <font style="color:#6a9955;">/// @param version Agreement version.</font>
    <font style="color:#569cd6;">function</font> createSHA(<font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Circulate SHA document for signature.</font>
    <font style="color:#6a9955;">/// @param sha Shareholders agreement address.</font>
    <font style="color:#6a9955;">/// @param docUrl Document URL hash.</font>
    <font style="color:#6a9955;">/// @param docHash Document content hash.</font>
    <font style="color:#569cd6;">function</font> circulateSHA(
        <font style="color:#4ec9b0;">address</font> sha,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Sign SHA document.</font>
    <font style="color:#6a9955;">/// @param sha Shareholders agreement address.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> signSHA(
        <font style="color:#4ec9b0;">address</font> sha,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Activate a SHA.</font>
    <font style="color:#6a9955;">/// @param sha Shareholders agreement address.</font>
    <font style="color:#569cd6;">function</font> activateSHA(<font style="color:#4ec9b0;">address</font> sha) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Accept SHA with signature hash.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> acceptSHA(<font style="color:#4ec9b0;">bytes32</font> sigHash) <font style="color:#569cd6;">external</font>;
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRODKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IRODKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IRODKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for director and officer appointment actions.</font>
<font style="color:#569cd6;">interface</font> IRODKeeper {

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Error   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#569cd6;">error</font> RODK_WrongTypeOfMotion(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ==== Directors ====</font>

    <font style="color:#6a9955;">/// @notice Take a director seat after motion approval.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> takeSeat(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a director after motion approval.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> removeDirector (
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Officers ====</font>

    <font style="color:#6a9955;">/// @notice Take an officer position after motion approval.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> takePosition(
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove an officer after motion approval.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> removeOfficer (
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> seqOfPos
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Quit ====</font>

    <font style="color:#6a9955;">/// @notice Quit an officer position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence.</font>
    <font style="color:#569cd6;">function</font> quitPosition(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IROIKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IROIKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * v.0.2.5
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IROIKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for investor compliance actions and LOO pause.</font>
<font style="color:#569cd6;">interface</font> IROIKeeper {

    <font style="color:#6a9955;">//##########################</font>
    <font style="color:#6a9955;">//##     Error & Event    ##</font>
    <font style="color:#6a9955;">//##########################</font>

    <font style="color:#569cd6;">error</font> ROIK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROIK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROIK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">// ==== Pause LOO ====</font>

    <font style="color:#6a9955;">/// @notice Pause LOO operations.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> pause(<font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Unpause LOO operations.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> unPause(<font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Freeze Share ====</font>

    <font style="color:#6a9955;">/// @notice Freeze a share for compliance.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param hashOrder Related order hash.</font>
    <font style="color:#569cd6;">function</font> freezeShare(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Unfreeze a share.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param hashOrder Related order hash.</font>
    <font style="color:#569cd6;">function</font> unfreezeShare(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Force transfer a frozen share.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param addrTo Recipient address.</font>
    <font style="color:#6a9955;">/// @param hashOrder Related order hash.</font>
    <font style="color:#569cd6;">function</font> forceTransfer(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">address</font> addrTo, <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#6a9955;">/// @notice Register an investor.</font>
    <font style="color:#6a9955;">/// @param bKey Investor key address.</font>
    <font style="color:#6a9955;">/// @param groupRep Group representative user number.</font>
    <font style="color:#6a9955;">/// @param idHash Investor id hash.</font>
    <font style="color:#569cd6;">function</font> regInvestor(<font style="color:#4ec9b0;">address</font> bKey, <font style="color:#4ec9b0;">uint</font> groupRep, <font style="color:#4ec9b0;">bytes32</font> idHash) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Approve an investor.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> approveInvestor(<font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Revoke an investor approval.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param seqOfLR Listing rule sequence.</font>
    <font style="color:#569cd6;">function</font> revokeInvestor(<font style="color:#4ec9b0;">uint</font> userNo, <font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IROMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IROMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../books/cashier/ICashier.sol"</font>;

<font style="color:#6a9955;">/// @title IROMKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for member/pay-in related actions.</font>
<font style="color:#569cd6;">interface</font> IROMKeeper {

    <font style="color:#6a9955;">// ######################</font>
    <font style="color:#6a9955;">// ##   Error & Event  ##</font>
    <font style="color:#6a9955;">// ######################</font>

    <font style="color:#569cd6;">error</font> ROMK_WrongAccess(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when capital is paid in and recorded with deal value.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param amt Paid-in amount.</font>
    <font style="color:#6a9955;">/// @param valueOfDeal Deal value.</font>
    <font style="color:#569cd6;">event</font> PayInCapital(<font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> amt, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> valueOfDeal);

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##   Write IO  ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">// ==== BOS funcs ====</font>

    <font style="color:#6a9955;">/// @notice Set maximum number of members.</font>
    <font style="color:#6a9955;">/// @param max Max member count.</font>
    <font style="color:#569cd6;">function</font> setMaxQtyOfMembers(<font style="color:#4ec9b0;">uint</font> max) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Set a pay-in amount with hash lock.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param amt Amount to pay in.</font>
    <font style="color:#6a9955;">/// @param expireDate Lock expiry timestamp.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#569cd6;">function</font> setPayInAmt(<font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> hashLock) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Request paid-in capital release by hash key.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#6a9955;">/// @param hashKey Hash key.</font>
    <font style="color:#569cd6;">function</font> requestPaidInCapital(<font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Withdraw locked pay-in amount.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> withdrawPayInAmt(<font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Pay in capital for a share using transfer authorization.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#569cd6;">function</font> payInCapital(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Decrease capital for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount decreased.</font>
    <font style="color:#6a9955;">/// @param par Par amount decreased.</font>
    <font style="color:#6a9955;">/// @param amt Amount to deduct.</font>
    <font style="color:#569cd6;">function</font> decreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR,
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Update paid-in deadline for a share.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param line New deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> updatePaidInDeadline(<font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> line) <font style="color:#569cd6;">external</font>;
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IROOKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IROOKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../books/cashier/ICashier.sol"</font>;

<font style="color:#6a9955;">/// @title IROOKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for option swaps and related transfers.</font>
<font style="color:#569cd6;">interface</font> IROOKeeper {

    <font style="color:#6a9955;">// #####################</font>
    <font style="color:#6a9955;">// ##  Error & Event  ##</font>
    <font style="color:#6a9955;">// #####################</font>

    <font style="color:#569cd6;">error</font> ROOK_WrongAccess(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROOK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Emitted when an option swap is paid off.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @param from Payer address.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param valueOfDeal Deal value.</font>
    <font style="color:#569cd6;">event</font> PayOffSwap(
        <font style="color:#4ec9b0;">uint</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> seqOfSwap, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>,
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> valueOfDeal
    );

    <font style="color:#6a9955;">/// @notice Emitted when a rejected deal swap is paid off.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @param from Payer address.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#6a9955;">/// @param valueOfDeal Deal value.</font>
    <font style="color:#569cd6;">event</font> PayOffRejectedDeal(
        <font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint</font> seqOfDeal, <font style="color:#4ec9b0;">uint</font> seqOfSwap, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>,
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> valueOfDeal
    );

    <font style="color:#6a9955;">/// @notice Update oracle data for an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param d1 Data slot 1.</font>
    <font style="color:#6a9955;">/// @param d2 Data slot 2.</font>
    <font style="color:#6a9955;">/// @param d3 Data slot 3.</font>
    <font style="color:#569cd6;">function</font> updateOracle(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> d1,
        <font style="color:#4ec9b0;">uint</font> d2,
        <font style="color:#4ec9b0;">uint</font> d3
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#569cd6;">function</font> execOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt)<font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Create a swap for an option.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfTarget Target share sequence.</font>
    <font style="color:#6a9955;">/// @param paidOfTarget Paid target amount.</font>
    <font style="color:#6a9955;">/// @param seqOfPledge Pledge share sequence.</font>
    <font style="color:#569cd6;">function</font> createSwap(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfTarget,
        <font style="color:#4ec9b0;">uint</font> paidOfTarget,
        <font style="color:#4ec9b0;">uint</font> seqOfPledge
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Pay off an option swap.</font>
    <font style="color:#6a9955;">/// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">/// @param to Recipient address.</font>
    <font style="color:#569cd6;">function</font> payOffSwap(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfSwap, <font style="color:#4ec9b0;">address</font> to
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Terminate an option swap.</font>
    <font style="color:#6a9955;">/// @param seqOfOpt Option sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">function</font> terminateSwap(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> seqOfSwap
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ==== Swap ====</font>

    <font style="color:#6a9955;">// /// @notice Request to buy a target share via swap.</font>
    <font style="color:#6a9955;">// /// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">// /// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">// /// @param paidOfTarget Paid target amount.</font>
    <font style="color:#6a9955;">// /// @param seqOfPledge Pledge share sequence.</font>
    <font style="color:#6a9955;">// function requestToBuy(</font>
    <font style="color:#6a9955;">//     address ia,</font>
    <font style="color:#6a9955;">//     uint seqOfDeal,</font>
    <font style="color:#6a9955;">//     uint paidOfTarget,</font>
    <font style="color:#6a9955;">//     uint seqOfPledge</font>
    <font style="color:#6a9955;">// ) external;</font>

    <font style="color:#6a9955;">// /// @notice Pay off a rejected deal swap.</font>
    <font style="color:#6a9955;">// /// @param auth Transfer authorization.</font>
    <font style="color:#6a9955;">// /// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">// /// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">// /// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">// /// @param to Recipient address.</font>
    <font style="color:#6a9955;">// function payOffRejectedDeal(</font>
    <font style="color:#6a9955;">//     ICashier.TransferAuth memory auth, address ia, uint seqOfDeal, </font>
    <font style="color:#6a9955;">//     uint seqOfSwap, address to</font>
    <font style="color:#6a9955;">// ) external;</font>

    <font style="color:#6a9955;">// /// @notice Pick up pledged share for a rejected deal.</font>
    <font style="color:#6a9955;">// /// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">// /// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">// /// @param seqOfSwap Swap sequence.</font>
    <font style="color:#6a9955;">// function pickupPledgedShare(</font>
    <font style="color:#6a9955;">//     address ia,</font>
    <font style="color:#6a9955;">//     uint seqOfDeal,</font>
    <font style="color:#6a9955;">//     uint seqOfSwap</font>
    <font style="color:#6a9955;">// ) external;</font>

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IROPKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IROPKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IROPKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for pledge operations via keeper.</font>
<font style="color:#569cd6;">interface</font> IROPKeeper {

    <font style="color:#6a9955;">// ###################</font>
    <font style="color:#6a9955;">// ##   ROPKeeper   ##</font>
    <font style="color:#6a9955;">// ###################</font>

    <font style="color:#6a9955;">/// @notice Create a pledge.</font>
    <font style="color:#6a9955;">/// @param snOfPld Pledge serial number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount pledged.</font>
    <font style="color:#6a9955;">/// @param par Par amount pledged.</font>
    <font style="color:#6a9955;">/// @param guaranteedAmt Guaranteed amount.</font>
    <font style="color:#6a9955;">/// @param execDays Execution days after default.</font>
    <font style="color:#569cd6;">function</font> createPledge(
        <font style="color:#4ec9b0;">bytes32</font> snOfPld,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Transfer a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param buyer New creditor user number.</font>
    <font style="color:#6a9955;">/// @param amt Transfer amount.</font>
    <font style="color:#569cd6;">function</font> transferPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Refund debt against a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param amt Refunded amount.</font>
    <font style="color:#569cd6;">function</font> refundDebt(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Extend pledge execution days.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param extDays Extension days.</font>
    <font style="color:#569cd6;">function</font> extendPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> extDays
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Lock a pledge with hash lock.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock.</font>
    <font style="color:#569cd6;">function</font> lockPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Release a pledge with hash key.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Hash key.</font>
    <font style="color:#569cd6;">function</font> releasePledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Execute a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param buyer Buyer user number.</font>
    <font style="color:#6a9955;">/// @param groupOfBuyer Buyer group number.</font>
    <font style="color:#569cd6;">function</font> execPledge(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> groupOfBuyer
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Revoke a pledge.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#569cd6;">function</font> revokePledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld
    ) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## IRORKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/IRORKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * v.0.2.5
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title IRORKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for redemption configuration and execution.</font>
<font style="color:#569cd6;">interface</font> IRORKeeper {

    <font style="color:#6a9955;">//######################</font>
    <font style="color:#6a9955;">//##   Error & Event  ##</font>
    <font style="color:#6a9955;">//######################</font>

    <font style="color:#569cd6;">error</font> FundRORK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> FundRORK_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> FundRORK_ZeroValue(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Add a redeemable class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">function</font> addRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Remove a redeemable class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#569cd6;">function</font> removeRedeemableClass(<font style="color:#4ec9b0;">uint</font> class) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Update NAV price for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param price NAV price.</font>
    <font style="color:#569cd6;">function</font> updateNavPrice(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> price) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Request redemption for a share.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount to redeem.</font>
    <font style="color:#569cd6;">function</font> requestForRedemption(
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Redeem a pack for a class.</font>
    <font style="color:#6a9955;">/// @param class Share class id.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#569cd6;">function</font> redeem(<font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack) <font style="color:#569cd6;">external</font>;

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ISHAKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ISHAKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title ISHAKeeper</font>
<font style="color:#6a9955;">/// @notice Interface for SHA rights execution (along, anti-dilution, refusal).</font>
<font style="color:#569cd6;">interface</font> ISHAKeeper {

    <font style="color:#6a9955;">// #######################</font>
    <font style="color:#6a9955;">// ##   Error & Event   ##</font>
    <font style="color:#6a9955;">// #######################</font>

    <font style="color:#569cd6;">error</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SHAK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SHAK_AmtOverflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SHAK_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ======== TagAlong & DragAlong ========</font>

    <font style="color:#6a9955;">/// @notice Execute drag-along or tag-along right.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param snOfClaim Serial number of the claim, encoded with claim head data.</font>
    <font style="color:#6a9955;">// / @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">// / @param dragAlong True for drag-along, false for tag-along.</font>
    <font style="color:#6a9955;">// / @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">// / @param paid Paid amount.</font>
    <font style="color:#6a9955;">// / @param par Par amount.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> execAlongRight(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> snOfClaim,
        <font style="color:#6a9955;">// uint256 seqOfDeal,</font>
        <font style="color:#6a9955;">// bool dragAlong,</font>
        <font style="color:#6a9955;">// uint256 seqOfShare,</font>
        <font style="color:#6a9955;">// uint paid,</font>
        <font style="color:#6a9955;">// uint par,</font>
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Accept an along deal.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> acceptAlongDeal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ======== AntiDilution ========</font>

    <font style="color:#6a9955;">/// @notice Execute anti-dilution adjustment.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> execAntiDilution(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Take gift shares generated by anti-dilution.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> takeGiftShares(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">// ======== FirstRefusal ========</font>

    <font style="color:#6a9955;">/// @notice Execute first refusal right.</font>
    <font style="color:#6a9955;">/// @param seqOfFRRule First refusal rule sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfRightholder Rightholder sequence.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> execFirstRefusal(
        <font style="color:#4ec9b0;">uint256</font> seqOfFRRule,
        <font style="color:#4ec9b0;">uint256</font> seqOfRightholder,
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font>;

    <font style="color:#6a9955;">/// @notice Compute first refusal results.</font>
    <font style="color:#6a9955;">/// @param ia Investment agreement address.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> computeFirstRefusal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font>;
}</code></pre>
```
 |
| [Contents](#toc) |

---

## KeepersRouter.sol

---

| |
|:---|
| **contracts/comps/keepers/KeepersRouter.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IKeepersRouter.sol"</font>;

<font style="color:#569cd6;">contract</font> KeepersRouter <font style="color:#569cd6;">is</font> IKeepersRouter {
    <font style="color:#4ec9b0;">bytes4</font>[<font style="color:#b5cea8;">90</font>] <font style="color:#569cd6;">public</font> selectors = [
        <font style="color:#4ec9b0;">bytes4</font>(0x04726d7a), <font style="color:#4ec9b0;">bytes4</font>(0x04e417ef), <font style="color:#4ec9b0;">bytes4</font>(0x04f2c63d), <font style="color:#4ec9b0;">bytes4</font>(0x07124bcf), <font style="color:#4ec9b0;">bytes4</font>(0x07f2990e),
        <font style="color:#4ec9b0;">bytes4</font>(0x0a672cbc), <font style="color:#4ec9b0;">bytes4</font>(0x136439dd), <font style="color:#4ec9b0;">bytes4</font>(0x18c678aa), <font style="color:#4ec9b0;">bytes4</font>(0x1c3a1ce3), <font style="color:#4ec9b0;">bytes4</font>(0x1f6b2609),
        <font style="color:#4ec9b0;">bytes4</font>(0x1fbbd398), <font style="color:#4ec9b0;">bytes4</font>(0x202bc98a), <font style="color:#4ec9b0;">bytes4</font>(0x205969bd), <font style="color:#4ec9b0;">bytes4</font>(0x22675a27), <font style="color:#4ec9b0;">bytes4</font>(0x2463d9ba),
        <font style="color:#4ec9b0;">bytes4</font>(0x295dd720), <font style="color:#4ec9b0;">bytes4</font>(0x2c425acc), <font style="color:#4ec9b0;">bytes4</font>(0x2cd7aa21), <font style="color:#4ec9b0;">bytes4</font>(0x2dae6617), <font style="color:#4ec9b0;">bytes4</font>(0x2e04d0a5),
        <font style="color:#4ec9b0;">bytes4</font>(0x2e8310da), <font style="color:#4ec9b0;">bytes4</font>(0x326b0e08), <font style="color:#4ec9b0;">bytes4</font>(0x329c43c1), <font style="color:#4ec9b0;">bytes4</font>(0x34d1c581), <font style="color:#4ec9b0;">bytes4</font>(0x36dfcf94),
        <font style="color:#4ec9b0;">bytes4</font>(0x392c8cd6), <font style="color:#4ec9b0;">bytes4</font>(0x3c851592), <font style="color:#4ec9b0;">bytes4</font>(0x40d8d8d2), <font style="color:#4ec9b0;">bytes4</font>(0x4462f61b), <font style="color:#4ec9b0;">bytes4</font>(0x452558b0),
        <font style="color:#4ec9b0;">bytes4</font>(0x498ec436), <font style="color:#4ec9b0;">bytes4</font>(0x4b4b972f), <font style="color:#4ec9b0;">bytes4</font>(0x4d5931f0), <font style="color:#4ec9b0;">bytes4</font>(0x501d9cca), <font style="color:#4ec9b0;">bytes4</font>(0x50235307),
        <font style="color:#4ec9b0;">bytes4</font>(0x5233f2ff), <font style="color:#4ec9b0;">bytes4</font>(0x569e1006),                                         <font style="color:#4ec9b0;">bytes4</font>(0x5abba148),
        <font style="color:#4ec9b0;">bytes4</font>(0x610bd881), <font style="color:#4ec9b0;">bytes4</font>(0x61d65d55), <font style="color:#4ec9b0;">bytes4</font>(0x6555ff7a), <font style="color:#4ec9b0;">bytes4</font>(0x6998d28d), <font style="color:#4ec9b0;">bytes4</font>(0x6e8d3873),
        <font style="color:#4ec9b0;">bytes4</font>(0x6e93dcce), <font style="color:#4ec9b0;">bytes4</font>(0x71944b39), <font style="color:#4ec9b0;">bytes4</font>(0x73ce8858), <font style="color:#4ec9b0;">bytes4</font>(0x7504e5a0), <font style="color:#4ec9b0;">bytes4</font>(0x75daba71),
        <font style="color:#4ec9b0;">bytes4</font>(0x76f2736f), <font style="color:#4ec9b0;">bytes4</font>(0x77a9dfa0), <font style="color:#4ec9b0;">bytes4</font>(0x7cbc2373), <font style="color:#4ec9b0;">bytes4</font>(0x8506c43f), <font style="color:#4ec9b0;">bytes4</font>(0x851aa5a0),
        <font style="color:#4ec9b0;">bytes4</font>(0x88ca46ed), <font style="color:#4ec9b0;">bytes4</font>(0x8d74e9ab), <font style="color:#4ec9b0;">bytes4</font>(0x92bcd2e2), <font style="color:#4ec9b0;">bytes4</font>(0x92c2c3d3), <font style="color:#4ec9b0;">bytes4</font>(0x946088cd),
        <font style="color:#4ec9b0;">bytes4</font>(0x959efc85), <font style="color:#4ec9b0;">bytes4</font>(0x974b0a6b), <font style="color:#4ec9b0;">bytes4</font>(0x991a1c37), <font style="color:#4ec9b0;">bytes4</font>(0xa023707d), <font style="color:#4ec9b0;">bytes4</font>(0xa2333df0), <font style="color:#4ec9b0;">bytes4</font>(0xa6f93889),
        <font style="color:#4ec9b0;">bytes4</font>(0xaa22742b), <font style="color:#4ec9b0;">bytes4</font>(0xab4e66b6), <font style="color:#4ec9b0;">bytes4</font>(0xacf12377), <font style="color:#4ec9b0;">bytes4</font>(0xb3a9d19b), <font style="color:#4ec9b0;">bytes4</font>(0xb4c6a008),
        <font style="color:#4ec9b0;">bytes4</font>(0xb791f1f5), <font style="color:#4ec9b0;">bytes4</font>(0xbe29b077), <font style="color:#4ec9b0;">bytes4</font>(0xc0e4aecd), <font style="color:#4ec9b0;">bytes4</font>(0xc0f869c2), <font style="color:#4ec9b0;">bytes4</font>(0xc297ddd0),
        <font style="color:#4ec9b0;">bytes4</font>(0xcb385133), <font style="color:#4ec9b0;">bytes4</font>(0xcebb34a8), <font style="color:#4ec9b0;">bytes4</font>(0xd2f4dc25), <font style="color:#4ec9b0;">bytes4</font>(0xd6eb75ec), <font style="color:#4ec9b0;">bytes4</font>(0xd8d53890),
        <font style="color:#4ec9b0;">bytes4</font>(0xdc09fd29), <font style="color:#4ec9b0;">bytes4</font>(0xe0fcbcfa), <font style="color:#4ec9b0;">bytes4</font>(0xe322799d), <font style="color:#4ec9b0;">bytes4</font>(0xe5421a98), <font style="color:#4ec9b0;">bytes4</font>(0xf424672b), <font style="color:#4ec9b0;">bytes4</font>(0xf584accb),
        <font style="color:#4ec9b0;">bytes4</font>(0xf89f622e), <font style="color:#4ec9b0;">bytes4</font>(0xf8be81ac), <font style="color:#4ec9b0;">bytes4</font>(0xf8fb9e1d), <font style="color:#4ec9b0;">bytes4</font>(0xfa0be085), <font style="color:#4ec9b0;">bytes4</font>(0xfd95c4c0)
    ];

    <font style="color:#4ec9b0;">uint8</font>[<font style="color:#b5cea8;">90</font>] <font style="color:#569cd6;">public</font> titles = [
        <font style="color:#b5cea8;">4</font>,  <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">16</font>,  <font style="color:#b5cea8;">9</font>,  <font style="color:#b5cea8;">5</font>,
        <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">6</font>,   <font style="color:#b5cea8;">7</font>,  <font style="color:#b5cea8;">1</font>,
        <font style="color:#b5cea8;">12</font>, <font style="color:#b5cea8;">2</font>,  <font style="color:#b5cea8;">8</font>,   <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">5</font>,
        <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">1</font>,  <font style="color:#b5cea8;">11</font>,  <font style="color:#b5cea8;">16</font>, <font style="color:#b5cea8;">7</font>,
        <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">3</font>,  <font style="color:#b5cea8;">3</font>,   <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">8</font>,
        <font style="color:#b5cea8;">6</font>,  <font style="color:#b5cea8;">8</font>,  <font style="color:#b5cea8;">9</font>,   <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">6</font>,
        <font style="color:#b5cea8;">4</font>,  <font style="color:#b5cea8;">4</font>,  <font style="color:#b5cea8;">12</font>,  <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">8</font>,
        <font style="color:#b5cea8;">12</font>, <font style="color:#b5cea8;">9</font>,           <font style="color:#b5cea8;">11</font>,
        <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">8</font>,  <font style="color:#b5cea8;">7</font>,   <font style="color:#b5cea8;">2</font>,  <font style="color:#b5cea8;">3</font>,
        <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">3</font>,  <font style="color:#b5cea8;">16</font>,  <font style="color:#b5cea8;">3</font>,  <font style="color:#b5cea8;">3</font>,
        <font style="color:#b5cea8;">7</font>,  <font style="color:#b5cea8;">9</font>,  <font style="color:#b5cea8;">16</font>,  <font style="color:#b5cea8;">6</font>,  <font style="color:#b5cea8;">4</font>,
        <font style="color:#b5cea8;">1</font>,  <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">5</font>,   <font style="color:#b5cea8;">2</font>,  <font style="color:#b5cea8;">6</font>,
        <font style="color:#b5cea8;">3</font>,  <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">8</font>,   <font style="color:#b5cea8;">8</font>,  <font style="color:#b5cea8;">4</font>,  <font style="color:#b5cea8;">6</font>,
        <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">6</font>,  <font style="color:#b5cea8;">10</font>,  <font style="color:#b5cea8;">12</font>, <font style="color:#b5cea8;">16</font>,
        <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">1</font>,  <font style="color:#b5cea8;">9</font>,   <font style="color:#b5cea8;">1</font>,  <font style="color:#b5cea8;">5</font>,
        <font style="color:#b5cea8;">5</font>,  <font style="color:#b5cea8;">4</font>,  <font style="color:#b5cea8;">4</font>,   <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">7</font>,
        <font style="color:#b5cea8;">2</font>,  <font style="color:#b5cea8;">10</font>, <font style="color:#b5cea8;">3</font>,   <font style="color:#b5cea8;">3</font>,  <font style="color:#b5cea8;">8</font>,  <font style="color:#b5cea8;">9</font>,
        <font style="color:#b5cea8;">11</font>, <font style="color:#b5cea8;">2</font>,  <font style="color:#b5cea8;">3</font>,   <font style="color:#b5cea8;">6</font>,  <font style="color:#b5cea8;">6</font>
    ];

    <font style="color:#6a9955;">/// @notice Get the title associated with a function selector.</font>
    <font style="color:#6a9955;">/// @param sig Function selector (first 4 bytes of calldata).</font>
    <font style="color:#6a9955;">/// @return title number (revert if not found).</font>
    <font style="color:#569cd6;">function</font> getTitleBySelector(<font style="color:#4ec9b0;">bytes4</font> sig) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font> title) {
        <font style="color:#4ec9b0;">uint</font> low = <font style="color:#b5cea8;">0</font>;
        <font style="color:#4ec9b0;">uint</font> high = selectors.length;
        <font style="color:#569cd6;">while</font> (low < high) {
            <font style="color:#4ec9b0;">uint</font> mid = low + (high - low) / <font style="color:#b5cea8;">2</font>;
            <font style="color:#569cd6;">if</font> (selectors[mid] == sig) {
                <font style="color:#569cd6;">return</font> titles[mid];
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (selectors[mid] < sig) {
                low = mid + <font style="color:#b5cea8;">1</font>;
            } <font style="color:#569cd6;">else</font> {
                high = mid;
            }
        }
        <font style="color:#569cd6;">revert</font> KeeprsRouter_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"KR_SigNotRegistered"</font>));
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## LOOKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/LOOKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ILOOKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> LOOKeeper <font style="color:#569cd6;">is</font> ILOOKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("LOOKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0xf9b45faf;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#569cd6;">modifier</font> whenNotPaused() {
        <font style="color:#569cd6;">if</font> (<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROI().isPaused())
            <font style="color:#569cd6;">revert</font> LOOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_IsPaused"</font>));
        _;
    }

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Write   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">// ==== Offers ====</font>

    <font style="color:#569cd6;">function</font> placeInitialOffer(
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> whenNotPaused {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        IRegisterOfShares _ros = _gk.getROS();

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font> (!_gk.getROD().hasTitle(caller, lr.titleOfIssuer))
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotIssuer"</font>));

        <font style="color:#569cd6;">if</font> (lr.classOfShare != classOfShare)
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_WrongClass"</font>));

        <font style="color:#569cd6;">if</font> (<font style="color:#4ec9b0;">uint32</font>(price) < lr.floorPrice)
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_LowerThanFloor"</font>));

        <font style="color:#569cd6;">if</font> (lr.ceilingPrice > <font style="color:#b5cea8;">0</font> && <font style="color:#4ec9b0;">uint32</font>(price) > lr.ceilingPrice)
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_HigherThanCeiling"</font>));

        <font style="color:#569cd6;">if</font> (_ros.getInfoOfClass(classOfShare).body.cleanPaid + paid >
            <font style="color:#4ec9b0;">uint64</font>(lr.maxTotalPar) * <font style="color:#b5cea8;">10000</font>
        ) <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_PaidOverflow"</font>));

        _ros.increaseEquityOfClass(<font style="color:#569cd6;">true</font>, classOfShare, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, paid);

        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

        input.classOfShare = <font style="color:#4ec9b0;">uint16</font>(classOfShare);
        input.votingWeight = lr.votingWeight;
        input.distrWeight = lr.distrWeight;
        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        input.price = <font style="color:#4ec9b0;">uint32</font>(price);
        input.seller = <font style="color:#4ec9b0;">uint40</font>(caller);
        input.isOffer = <font style="color:#569cd6;">true</font>;

        _placeSellOrder(_gk, input, execHours);
    }

    <font style="color:#6a9955;">// ==== Withdraw Initial Offer ====</font>

    <font style="color:#569cd6;">function</font> withdrawInitialOffer(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        IListOfOrders _loo = _gk.getLOO();

        GoldChain.Order <font style="color:#569cd6;">memory</font> order =
            _loo.getOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        <font style="color:#569cd6;">if</font> (order.data.seqOfShare > <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotInitOrder"</font>));

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font> (!_gk.getROD().hasTitle(caller, lr.titleOfIssuer))
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotIssuer"</font>));

        order = _loo.withdrawOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        _restoreOrder(_gk, order);
    }

    <font style="color:#6a9955;">// ==== Place & Withdraw Sell Orders ====</font>

    <font style="color:#569cd6;">function</font> placeSellOrder(
        <font style="color:#4ec9b0;">uint</font> seqOfClass, <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> whenNotPaused {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#569cd6;">if</font>(_gk.getROI().getInvestor(caller).state !=
            <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved))
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotQualifiedInvestor"</font>));

        IRegisterOfShares _ros = _gk.getROS();

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font> (seqOfClass != lr.classOfShare)
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_WrongClass"</font>));

        <font style="color:#569cd6;">if</font> (<font style="color:#4ec9b0;">uint32</font>(price) < lr.offPrice)
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_LowerThanOffPrice"</font>));

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> sharesInhand =
            _gk.getROM().sharesInClass(caller, lr.classOfShare);

        <font style="color:#4ec9b0;">uint</font> len = sharesInhand.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font> && paid > <font style="color:#b5cea8;">0</font>) {

            SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
                _ros.getShare(sharesInhand[len - <font style="color:#b5cea8;">1</font>]);
            len--;

            <font style="color:#569cd6;">if</font> (!_ros.notLocked(share.head.seqOfShare, block.timestamp)) {
                <font style="color:#569cd6;">continue</font>;
            }

            <font style="color:#569cd6;">if</font> (lr.lockupDays == <font style="color:#b5cea8;">0</font> ||
                share.head.issueDate +
                <font style="color:#4ec9b0;">uint48</font>(lr.lockupDays) * <font style="color:#b5cea8;">86400</font> < block.timestamp)
            {
                <font style="color:#569cd6;">if</font> (share.body.cleanPaid > <font style="color:#b5cea8;">0</font>) {

                    UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

                    input.to = msg.sender;
                    input.seller = share.head.shareholder;
                    input.classOfShare = share.head.class;
                    input.seqOfShare = share.head.seqOfShare;
                    input.price = <font style="color:#4ec9b0;">uint32</font>(price);
                    input.votingWeight = share.head.votingWeight;
                    input.distrWeight = share.body.distrWeight;
                    input.isOffer = <font style="color:#569cd6;">true</font>;

                    <font style="color:#569cd6;">if</font> (paid >= share.body.cleanPaid) {
                        input.paid = <font style="color:#4ec9b0;">uint64</font>(share.body.cleanPaid);
                        paid -=input.paid;
                        _ros.decreaseCleanPaid(share.head.seqOfShare, input.paid);
                        _placeSellOrder(_gk, input, execHours);
                    } <font style="color:#569cd6;">else</font> {
                        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
                        _ros.decreaseCleanPaid(share.head.seqOfShare, input.paid);
                        _placeSellOrder(_gk, input, execHours);
                        <font style="color:#569cd6;">break</font>;
                    }
                }
            }
        }
    }

    <font style="color:#569cd6;">function</font> withdrawSellOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        IListOfOrders _loo = _gk.getLOO();
        IRegisterOfShares _ros = _gk.getROS();

        GoldChain.Order <font style="color:#569cd6;">memory</font> order =
            _loo.getOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        <font style="color:#569cd6;">if</font>(order.data.seqOfShare == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NoTargetShare"</font>));
        }

        SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
            _ros.getShare(order.data.seqOfShare);

        <font style="color:#569cd6;">if</font>(share.head.shareholder != caller) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotShareholder"</font>));
        }

        order = _loo.withdrawOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">true</font>);

        _restoreOrder(_gk, order);
    }

    <font style="color:#6a9955;">// ==== Place & Withdraw Buy Orders ====</font>

    <font style="color:#569cd6;">function</font> placeBuyOrder(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> whenNotPaused {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        InvestorsRepo.Investor <font style="color:#569cd6;">memory</font> investor =
            _gk.getROI().getInvestor(caller);

        <font style="color:#569cd6;">if</font> (investor.state != <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotQualifiedInvestor"</font>));
        }

        <font style="color:#569cd6;">if</font> (price == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_ZeroPrice"</font>));
        }

        <font style="color:#569cd6;">if</font> (!_gk.getSHA().isSigner(caller)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_BuyerNotSignerOfSHA"</font>));
        }

        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

        input.<font style="color:#569cd6;">from</font> = msg.sender;
        input.buyer = <font style="color:#4ec9b0;">uint40</font>(caller);
        input.groupRep = investor.groupRep;
        input.classOfShare = <font style="color:#4ec9b0;">uint16</font>(classOfShare);
        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        input.price = <font style="color:#4ec9b0;">uint32</font>(price);
        input.consideration = <font style="color:#4ec9b0;">uint128</font>(paid * price);

        auth.<font style="color:#569cd6;">from</font> = input.<font style="color:#569cd6;">from</font>;
        auth.value = input.consideration / <font style="color:#b5cea8;">100</font>;
        _placeBuyOrder(_gk, auth, input, execHours);
    }

    <font style="color:#569cd6;">function</font> placeMarketBuyOrder(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> classOfShare, <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">external</font> whenNotPaused {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        InvestorsRepo.Investor <font style="color:#569cd6;">memory</font> investor =
            _gk.getROI().getInvestor(caller);

        <font style="color:#569cd6;">if</font> (investor.state != <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotQualifiedInvestor"</font>));
        }

        <font style="color:#569cd6;">if</font> (auth.value == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_ZeroMargin"</font>));
        }

        <font style="color:#569cd6;">if</font> (!_gk.getSHA().isSigner(caller)) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotSignerOfSHA"</font>));
        }

        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input;

        input.<font style="color:#569cd6;">from</font> = msg.sender;
        input.buyer = <font style="color:#4ec9b0;">uint40</font>(caller);
        input.groupRep = investor.groupRep;
        input.classOfShare = <font style="color:#4ec9b0;">uint16</font>(classOfShare);
        input.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        input.consideration = <font style="color:#4ec9b0;">uint128</font>(auth.value * <font style="color:#b5cea8;">100</font>);

        auth.<font style="color:#569cd6;">from</font> = input.<font style="color:#569cd6;">from</font>;

        _placeBuyOrder(_gk, auth, input, execHours);
    }

    <font style="color:#569cd6;">function</font> withdrawBuyOrder(
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        IListOfOrders _loo = _gk.getLOO();

        GoldChain.Order <font style="color:#569cd6;">memory</font> order =
            _loo.getOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">false</font>);

        <font style="color:#569cd6;">if</font> (order.node.issuer != caller) {
            <font style="color:#569cd6;">revert</font> LOOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LOOK_NotBuyer"</font>));
        }

        order = _loo.withdrawOrder(classOfShare, seqOfOrder, <font style="color:#569cd6;">false</font>);

        _restoreOrder(_gk, order);
    }

    <font style="color:#6a9955;">// ==== Place Buy & Sell Orders ====</font>

    <font style="color:#569cd6;">function</font> _placeSellOrder(
        <font style="color:#4ec9b0;">address</font> _gk,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">private</font> {
        (
            UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
            <font style="color:#4ec9b0;">uint</font> lenOfDeals,
            GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
            <font style="color:#4ec9b0;">uint</font> lenOfExpired,
            UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> offer
        ) = _gk.getLOO().placeSellOrder(input, execHours);

        <font style="color:#569cd6;">if</font> (lenOfDeals > <font style="color:#b5cea8;">0</font>) {
            _closeDeals(_gk, deals, lenOfDeals, <font style="color:#569cd6;">true</font>);
        }
        <font style="color:#569cd6;">if</font> (lenOfExpired > <font style="color:#b5cea8;">0</font>) {
            _restoreExpiredOrders(_gk, expired, lenOfExpired);
        }
        <font style="color:#569cd6;">if</font> (offer.price == <font style="color:#b5cea8;">0</font> && offer.paid > <font style="color:#b5cea8;">0</font>) {
            GoldChain.Order <font style="color:#569cd6;">memory</font> balance;
            balance.data.classOfShare = offer.classOfShare;
            balance.data.seqOfShare = offer.seqOfShare;
            balance.data.pubKey = offer.to;
            balance.node.paid = offer.paid;
            _restoreOrder(_gk, balance);
        }
    }

    <font style="color:#569cd6;">function</font> _placeBuyOrder(
        <font style="color:#4ec9b0;">address</font> _gk,
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">private</font> {
        ICashier _cashier = _gk.getCashier();

        _cashier.custodyUsd(
            auth,
            <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CustodyValueOfBid"</font>)
        );

        (
            UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
            <font style="color:#4ec9b0;">uint</font> lenOfDeals,
            GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
            <font style="color:#4ec9b0;">uint</font> lenOfExpired,
            UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> bid
        ) = _gk.getLOO().placeBuyOrder(input, execHours);

        <font style="color:#569cd6;">if</font> (lenOfDeals > <font style="color:#b5cea8;">0</font>) {
            _closeDeals(_gk, deals, lenOfDeals, <font style="color:#569cd6;">false</font>);
        }
        <font style="color:#569cd6;">if</font> (lenOfExpired > <font style="color:#b5cea8;">0</font>) {
            _restoreExpiredOrders(_gk, expired, lenOfExpired);
        }
        <font style="color:#569cd6;">if</font> (bid.paid == <font style="color:#b5cea8;">0</font> && bid.consideration > <font style="color:#b5cea8;">0</font>) {
            _cashier.releaseUsd(
                bid.<font style="color:#569cd6;">from</font>,
                bid.<font style="color:#569cd6;">from</font>,
                _eightToSix(bid.consideration),
                <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RefundBalanceOfBidOrder"</font>)
            );
        }
    }

    <font style="color:#6a9955;">// ==== Settle & Restore Orders ====</font>

    <font style="color:#569cd6;">function</font> _closeDeals(
        <font style="color:#4ec9b0;">address</font> _gk,
        UsdOrdersRepo.Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> len,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">private</font> {
        ICashier _cashier = _gk.getCashier();
        IRegisterOfShares _ros = _gk.getROS();
        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            UsdOrdersRepo.Deal <font style="color:#569cd6;">memory</font> deal = deals[len - <font style="color:#b5cea8;">1</font>];
            len--;

            <font style="color:#569cd6;">if</font> (deal.seqOfShare > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">if</font> (!_ros.notLocked(deal.seqOfShare, block.timestamp)) {
                    <font style="color:#569cd6;">continue</font>;
                }

                <font style="color:#569cd6;">if</font> (isOffer) {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        deal.to,
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseOfferAgainstBid"</font>)
                    );
                } <font style="color:#569cd6;">else</font> {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        deal.to,
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseBidAgainstOffer"</font>)
                    );
                }

                _ros.increaseCleanPaid(deal.seqOfShare, deal.paid);
                _ros.transferShare(
                    deal.seqOfShare,
                    deal.paid,
                    deal.paid,
                    deal.buyer,
                    deal.price,
                    <font style="color:#b5cea8;">0</font>
                );
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">if</font> (isOffer) {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        <font style="color:#4ec9b0;">address</font>(_cashier),
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseInitOfferAgainstBid"</font>)
                    );
                } <font style="color:#569cd6;">else</font> {
                    _cashier.releaseUsd(
                        deal.<font style="color:#569cd6;">from</font>,
                        <font style="color:#4ec9b0;">address</font>(_cashier),
                        _eightToSix(deal.consideration),
                        <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CloseBidAgainstInitOffer"</font>)
                    );
                }

                SharesRepo.Share <font style="color:#569cd6;">memory</font> share;
                share.head = SharesRepo.Head({
                    class: deal.classOfShare,
                    seqOfShare: <font style="color:#b5cea8;">0</font>,
                    preSeq: <font style="color:#b5cea8;">0</font>,
                    issueDate: <font style="color:#b5cea8;">0</font>,
                    shareholder: deal.buyer,
                    priceOfPaid: deal.price,
                    priceOfPar: <font style="color:#b5cea8;">0</font>,
                    votingWeight: deal.votingWeight,
                    argu: <font style="color:#b5cea8;">0</font>
                });

                share.body = SharesRepo.Body({
                    payInDeadline: <font style="color:#4ec9b0;">uint48</font>(block.timestamp + <font style="color:#b5cea8;">86400</font>),
                    paid: deal.paid,
                    par: deal.paid,
                    cleanPaid: deal.paid,
                    distrWeight: deal.distrWeight
                });

                _ros.addShare(share);
            }

            <font style="color:#569cd6;">if</font> (deal.groupRep != deal.buyer &&
                deal.groupRep != _rom.groupRep(deal.buyer)) {
                _rom.addMemberToGroup(deal.buyer, deal.groupRep);
            }
        }
    }

    <font style="color:#569cd6;">function</font> _eightToSix(<font style="color:#4ec9b0;">uint</font> amt) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> amt / <font style="color:#b5cea8;">100</font>;
    }

    <font style="color:#569cd6;">function</font> _restoreExpiredOrders(
        <font style="color:#4ec9b0;">address</font> _gk,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> orders,
        <font style="color:#4ec9b0;">uint</font> len
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            _restoreOrder(_gk, orders[len - <font style="color:#b5cea8;">1</font>]);
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> _restoreOrder(
        <font style="color:#4ec9b0;">address</font> _gk,
        GoldChain.Order <font style="color:#569cd6;">memory</font> order
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (order.node.isOffer) {
            IRegisterOfShares _ros = _gk.getROS();
            <font style="color:#569cd6;">if</font> (order.data.seqOfShare > <font style="color:#b5cea8;">0</font>) {
                _ros.increaseCleanPaid(order.data.seqOfShare, order.node.paid);
            } <font style="color:#569cd6;">else</font> {
                _ros.increaseEquityOfClass(<font style="color:#569cd6;">false</font>, order.data.classOfShare, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, order.node.paid);
            }
        } <font style="color:#569cd6;">else</font> {
            _gk.getCashier().releaseUsd(
                order.data.pubKey,
                order.data.pubKey,
                _eightToSix(order.data.margin),
                <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RefundValueOfBidOrder"</font>)
            );
        }
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ROAKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ROAKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/DocsRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROAKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> ROAKeeper <font style="color:#569cd6;">is</font> IROAKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> DocsRepo <font style="color:#569cd6;">for</font> DocsRepo.Head;

    <font style="color:#6a9955;">// uint32(uint(keccak256("ROAKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x7eaeb1a4;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##   Error   ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#569cd6;">error</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROAK_ShareLocked(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ==== Create IA ====</font>

    <font style="color:#569cd6;">function</font> createIA(<font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROM().isMember(caller))
            <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotMember"</font>));

        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _gk.getRCByGK().cloneDoc(
            <font style="color:#4ec9b0;">uint32</font>(<font style="color:#4ec9b0;">uint</font>(keccak256(<font style="color:#ce9178;">"InvestmentAgreement"</font>))),
            version
        );

        IAccessControl(doc.body).initKeepers(
            _gk, _gk
        );

        _gk.getROA().regFile(DocsRepo.codifyHead(doc.head), doc.body);

        IOwnable(doc.body).setNewOwner(msg.sender);
    }

    <font style="color:#6a9955;">// ======== Circulate IA ========</font>

    <font style="color:#569cd6;">function</font> circulateIA(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        <font style="color:#569cd6;">if</font> (!ISigPage(ia).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotPartyOfIA"</font>));
        }

        <font style="color:#569cd6;">if</font> (!IDraftControl(ia).isFinalized()) {
            <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_IANotFinalized"</font>));
        }

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        _ia.circulateDoc();
        <font style="color:#4ec9b0;">uint16</font> signingDays = _ia.getSigningDays();
        <font style="color:#4ec9b0;">uint16</font> closingDays = _ia.getClosingDays();

        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr =
            _gk.getSHA().getRule(_ia.getTypeOfIA()).votingRuleParser();

        _ia.setTiming(<font style="color:#569cd6;">false</font>, signingDays + vr.frExecDays + vr.dtExecDays + vr.dtConfirmDays, closingDays);

        _gk.getROA().circulateFile(ia, signingDays, closingDays, vr, docUrl, docHash);
    }

    <font style="color:#6a9955;">// ======== Sign IA ========</font>

    <font style="color:#569cd6;">function</font> signIA(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        <font style="color:#569cd6;">if</font> (!ISigPage(ia).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotPartyOfIA"</font>));
        }

        IRegisterOfAgreements _roa = _gk.getROA();

        <font style="color:#569cd6;">if</font> (
            _roa.getHeadOfFile(ia).state != <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Circulated)
        ) {
            <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_IaNotCirculated"</font>));
        }

        _lockDealsOfParty(_gk, ia, caller);

        ISigPage(ia).signDoc(<font style="color:#569cd6;">true</font>, caller, sigHash);

    }

    <font style="color:#569cd6;">function</font> _lockDealsOfParty(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> caller) <font style="color:#569cd6;">private</font> {

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list = IInvestmentAgreement(ia).getSeqList();
        <font style="color:#4ec9b0;">uint256</font> len = list.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint</font> seq = list[len - <font style="color:#b5cea8;">1</font>];
            len--;

            DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal =
                IInvestmentAgreement(ia).getDeal(seq);

            <font style="color:#569cd6;">if</font> (deal.head.seller == caller) {

                <font style="color:#569cd6;">if</font> (IInvestmentAgreement(ia).lockDealSubject(seq)) {
                    _gk.getROS().decreaseCleanPaid(deal.head.seqOfShare, deal.body.paid);
                }

            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (deal.body.buyer == caller) {

                _buyerIsVerified(_gk, deal.body.buyer);

                <font style="color:#569cd6;">if</font> (deal.head.typeOfDeal ==
                   <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.CapitalIncrease)) {
                    IInvestmentAgreement(ia).lockDealSubject(seq);
                }

            }
        }
    }

    <font style="color:#569cd6;">function</font> _buyerIsVerified(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> buyer) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        <font style="color:#569cd6;">if</font> (
            _gk.getROI().getInvestor(buyer).state !=
            <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)
        ) <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_BuyerNotVerified"</font>));

        <font style="color:#569cd6;">if</font> (!_gk.getSHA().isSigner(buyer))
            <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_BuyerNotSignerOfSHA"</font>));
    }

    <font style="color:#6a9955;">// ======== Deal Closing ========</font>

    <font style="color:#569cd6;">function</font> pushToCoffer(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> closingDeadline
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        <font style="color:#4ec9b0;">bool</font> isST = (deal.head.seqOfShare != <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">if</font> (isST) {
            <font style="color:#569cd6;">if</font> (deal.head.seller != caller)
                <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_CallerNotSeller"</font>));
            <font style="color:#569cd6;">if</font> (!_lockUpCheck(_gk, ia, deal, closingDeadline))
                <font style="color:#569cd6;">revert</font> ROAK_ShareLocked(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_TargetShareLocked"</font>));
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (
                !_gk.getROD().isDirector(caller) &&
                _gk.getROM().controllor() != caller
            ) <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotDirectorOrControllor"</font>));
        }

        _vrAndSHACheck(_gk, _ia);

        _ia.clearDealCP(seqOfDeal, hashLock, closingDeadline);
    }

    <font style="color:#569cd6;">function</font> _vrAndSHACheck(<font style="color:#4ec9b0;">address</font> _gk, IInvestmentAgreement _ia) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        IMeetingMinutes _bmm = _gk.getBMM();
        IMeetingMinutes _gmm = _gk.getGMM();
        IRegisterOfAgreements _roa = _gk.getROA();

        <font style="color:#569cd6;">if</font> (_roa.getHeadOfFile(<font style="color:#4ec9b0;">address</font>(_ia)).state != <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Approved)) {
            <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_IaNotApproved"</font>));
        }

        <font style="color:#4ec9b0;">uint256</font> typeOfIA = _ia.getTypeOfIA();

        IShareholdersAgreement _sha = _gk.getSHA();

        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr =
            _sha.getRule(typeOfIA).votingRuleParser();

        <font style="color:#4ec9b0;">uint</font> seqOfMotion = _roa.getHeadOfFile(<font style="color:#4ec9b0;">address</font>(_ia)).seqOfMotion;

        <font style="color:#569cd6;">if</font> (vr.amountRatio > <font style="color:#b5cea8;">0</font> || vr.headRatio > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (vr.authority == <font style="color:#b5cea8;">1</font>) {
                <font style="color:#569cd6;">if</font> (!_gmm.isPassed(seqOfMotion)) {
                    <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_GMMNotApproved"</font>));
                }
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (vr.authority == <font style="color:#b5cea8;">2</font>) {
                <font style="color:#569cd6;">if</font> (!_bmm.isPassed(seqOfMotion)) {
                    <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_BMMNotApproved"</font>));
                }
            }
        }
    }

    <font style="color:#6a9955;">// ==== Close Deal ====</font>

    <font style="color:#569cd6;">function</font> closeDeal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        <font style="color:#569cd6;">if</font> (_ia.closeDeal(deal.head.seqOfDeal, hashKey))
            <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROA().execFile(ia);

        _closeDeal(_gk, _ia, deal);
    }

    <font style="color:#569cd6;">function</font> _closeDeal(
        <font style="color:#4ec9b0;">address</font> _gk,
        IInvestmentAgreement _ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (deal.head.seqOfShare > <font style="color:#b5cea8;">0</font>) {
            _shareTransfer(_gk, _ia, deal.head.seqOfDeal);
        } <font style="color:#569cd6;">else</font> {
            _issueNewShare(_gk, _ia, deal.head.seqOfDeal);
        }
    }

    <font style="color:#569cd6;">function</font> _shareTransfer(<font style="color:#4ec9b0;">address</font> _gk, IInvestmentAgreement _ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">private</font> {
        IRegisterOfShares _ros = _gk.getROS();
        IRegisterOfMembers _rom = _gk.getROM();

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        _buyerIsVerified(_gk, deal.body.buyer);

        <font style="color:#569cd6;">if</font> (!_lockUpCheck(_gk, <font style="color:#4ec9b0;">address</font>(_ia), deal, block.timestamp)) {
            <font style="color:#569cd6;">revert</font> ROAK_ShareLocked(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_TargetShareLocked"</font>));
        }

        <font style="color:#569cd6;">if</font> (!_checkAlong(_ia, seqOfDeal)) {
            <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_AlongDealOpen"</font>));
        }

        _ros.increaseCleanPaid(deal.head.seqOfShare, deal.body.paid);
        _ros.transferShare(deal.head.seqOfShare, deal.body.paid, deal.body.par,
            deal.body.buyer, deal.head.priceOfPaid, deal.head.priceOfPar);

        <font style="color:#569cd6;">if</font> (deal.body.buyer != deal.body.groupOfBuyer &&
            deal.body.groupOfBuyer != _rom.groupRep(deal.body.buyer))
                _rom.addMemberToGroup(deal.body.buyer, deal.body.groupOfBuyer);
    }

    <font style="color:#569cd6;">function</font> _lockUpCheck(
        <font style="color:#4ec9b0;">address</font> _gk,
        <font style="color:#4ec9b0;">address</font> _ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        <font style="color:#4ec9b0;">uint</font> closingDate
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {

        IShareholdersAgreement _sha = _gk.getSHA();

        <font style="color:#569cd6;">if</font> (!_sha.hasTitle(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.LockUp))) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#4ec9b0;">address</font> lu = _sha.getTerm(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.LockUp));

        <font style="color:#569cd6;">if</font> (closingDate > <font style="color:#b5cea8;">0</font>) {
            deal.head.closingDeadline = <font style="color:#4ec9b0;">uint48</font>(closingDate);
        }

        <font style="color:#569cd6;">if</font> (!ILockUp(lu).isTriggered(deal)) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (ILockUp(lu).isExempted(_ia, deal)) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _checkAlong(IInvestmentAgreement _ia, <font style="color:#4ec9b0;">uint</font> seqOfDeal) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList = _ia.getSeqList();
        <font style="color:#4ec9b0;">uint</font> len = seqList.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqList[len - <font style="color:#b5cea8;">1</font>]);
            <font style="color:#569cd6;">if</font> ((deal.head.typeOfDeal == <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.TagAlong) ||
                deal.head.typeOfDeal == <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.DragAlong)) &&
                deal.head.preSeq == <font style="color:#4ec9b0;">uint16</font>(seqOfDeal) &&
                deal.body.state != <font style="color:#4ec9b0;">uint8</font>(DealsRepo.StateOfDeal.Closed))
            {
                <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
            }
            len--;
        }
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">// ==== Issue New Share ====</font>

    <font style="color:#569cd6;">function</font> issueNewShare(<font style="color:#4ec9b0;">address</font> ia, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        <font style="color:#569cd6;">if</font>(
            !_gk.getROD().isDirector(caller) &&
            _gk.getROM().controllor() != caller
        ) <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotDirectorOrControllor"</font>));

        _vrAndSHACheck(_gk, _ia);

        <font style="color:#569cd6;">if</font> (_ia.directCloseDeal(seqOfDeal)) _gk.getROA().execFile(ia);

        _issueNewShare(_gk, _ia, seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> _issueNewShare(<font style="color:#4ec9b0;">address</font> _gk, IInvestmentAgreement _ia, <font style="color:#4ec9b0;">uint</font> seqOfDeal) <font style="color:#569cd6;">private</font> {
        IRegisterOfShares _ros = _gk.getROS();
        IRegisterOfMembers _rom = _gk.getROM();

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        _buyerIsVerified(_gk, deal.body.buyer);

        SharesRepo.Share <font style="color:#569cd6;">memory</font> share;

        share.head = SharesRepo.Head({
            seqOfShare: <font style="color:#b5cea8;">0</font>,
            preSeq: <font style="color:#b5cea8;">0</font>,
            class: deal.head.classOfShare,
            issueDate: <font style="color:#4ec9b0;">uint48</font>(block.timestamp),
            shareholder: deal.body.buyer,
            priceOfPaid: deal.head.priceOfPaid,
            priceOfPar: deal.head.priceOfPar,
            votingWeight: deal.head.votingWeight,
            argu: <font style="color:#b5cea8;">0</font>
        });

        share.body = SharesRepo.Body({
            payInDeadline: <font style="color:#4ec9b0;">uint48</font>(block.timestamp) + <font style="color:#b5cea8;">43200</font>,
            paid: deal.body.paid,
            par: deal.body.par,
            cleanPaid: deal.body.paid,
            distrWeight: deal.body.distrWeight
        });

        _ros.addShare(share);

        <font style="color:#569cd6;">if</font> (deal.body.buyer != deal.body.groupOfBuyer &&
            deal.body.groupOfBuyer != _rom.groupRep(deal.body.buyer))
                _rom.addMemberToGroup(deal.body.buyer, deal.body.groupOfBuyer);
    }

    <font style="color:#6a9955;">// ==== Transfer Target Share ====</font>

    <font style="color:#569cd6;">function</font> transferTargetShare(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        <font style="color:#569cd6;">if</font> (caller != _ia.getDeal(seqOfDeal).head.seller)
            <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotSeller"</font>));

        _vrAndSHACheck(_gk, _ia);

        <font style="color:#569cd6;">if</font> (_ia.directCloseDeal(seqOfDeal))
            _gk.getROA().execFile(ia);

        _shareTransfer(_gk, _ia, seqOfDeal);
    }

    <font style="color:#6a9955;">// ==== Terminate Deal ====</font>

    <font style="color:#569cd6;">function</font> terminateDeal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        IRegisterOfAgreements _roa = _gk.getROA();

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = IInvestmentAgreement(ia).getDeal(seqOfDeal);

        <font style="color:#569cd6;">if</font> (caller != deal.head.seller)
            <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_NotSeller"</font>));

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        <font style="color:#4ec9b0;">uint8</font> state = _roa.getHeadOfFile(ia).state;

        <font style="color:#569cd6;">if</font> ((state < <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Proposed) &&
                block.timestamp >= _roa.terminateStartpoint(ia)) ||
            (state == <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Rejected)) ||
            (state == <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Approved) &&
                block.timestamp >= _ia.getDeal(seqOfDeal).head.closingDeadline)
        ) {
            <font style="color:#569cd6;">if</font> (_ia.terminateDeal(seqOfDeal))
                _roa.terminateFile(ia);
            <font style="color:#569cd6;">if</font> (_ia.releaseDealSubject(seqOfDeal))
                _gk.getROS().increaseCleanPaid(deal.head.seqOfShare, deal.body.paid);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> ROAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_IaNotTerminatable"</font>));
    }

    <font style="color:#6a9955;">// ==== Pay Off Approved Deal ====</font>

    <font style="color:#569cd6;">function</font> payOffApprovedDeal(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth, <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal, <font style="color:#4ec9b0;">address</font> to
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        ICashier _cashier = _gk.getCashier();

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = IInvestmentAgreement(ia).getDeal(seqOfDeal);

        auth.value = (deal.body.paid * deal.head.priceOfPaid +
            (deal.body.par - deal.body.paid) * deal.head.priceOfPar) / <font style="color:#b5cea8;">100</font>;
        auth.<font style="color:#569cd6;">from</font> = msg.sender;

        <font style="color:#569cd6;">if</font> (deal.head.seqOfShare > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (deal.head.seller !=
                to.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>))
                <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_PayeeNotSeller"</font>));

            <font style="color:#6a9955;">// remark: PayOffShareTransferDeal</font>
            _cashier.forwardUsd(
                auth, to,
                <font style="color:#4ec9b0;">bytes32</font>(0x5061794f666653686172655472616e736665724465616c000000000000000000)
            );
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (<font style="color:#4ec9b0;">address</font>(_cashier) != to)
                <font style="color:#569cd6;">revert</font> ROAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROAK_PayeeNotCashier"</font>));

            <font style="color:#6a9955;">// remark: PayOffCapIncreaseDeal</font>
            ICashier(_cashier).forwardUsd(
                auth, to,
                <font style="color:#4ec9b0;">bytes32</font>(0x5061794f6666436170496e6372656173654465616c0000000000000000000000)
            );
        }

        _payOffApprovedDeal(_gk, ia, seqOfDeal, auth.value, caller);
    }

    <font style="color:#569cd6;">function</font> _payOffApprovedDeal(
        <font style="color:#4ec9b0;">address</font> _gk,
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> valueOfDeal,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">private</font> {
        IInvestmentAgreement _ia = IInvestmentAgreement(ia);
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        _vrAndSHACheck(_gk, _ia);

        <font style="color:#569cd6;">if</font> (_ia.payOffApprovedDeal(seqOfDeal, valueOfDeal, caller))
            _gk.getROA().execFile(ia);

        _closeDeal(_gk, _ia, deal);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ROCKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ROCKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/ArrayUtils.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/OfficersRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/DocsRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROCKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> ROCKeeper <font style="color:#569cd6;">is</font> IROCKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> DocsRepo <font style="color:#569cd6;">for</font> DocsRepo.Head;
    <font style="color:#569cd6;">using</font> ArrayUtils <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">uint</font>[];
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("ROCKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x4c9c9582;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// #############</font>
    <font style="color:#6a9955;">// ##  Error  ##</font>
    <font style="color:#6a9955;">// #############</font>

    <font style="color:#6a9955;">// ==== Functions ====</font>

    <font style="color:#569cd6;">function</font> createSHA(<font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (!_gk.getROM().isMember(caller)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_NotMember"</font>));
        }

        DocsRepo.Doc <font style="color:#569cd6;">memory</font> doc = _gk.getRCByGK().cloneDoc(
            <font style="color:#6a9955;">// uint32(uint(keccak256("ShareholdersAgreement")))</font>
            0x8c5a073d, version
        );

        IAccessControl(doc.body).initKeepers(
            _gk, _gk
        );

        IShareholdersAgreement(doc.body).initDefaultRules();

        _gk.getROC().regFile(DocsRepo.codifyHead(doc.head), doc.body);

        IOwnable(doc.body).setNewOwner(msg.sender);
    }

    <font style="color:#569cd6;">function</font> circulateSHA(
        <font style="color:#4ec9b0;">address</font> sha,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (!ISigPage(sha).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_NotPartyOfSha"</font>));
        }

        <font style="color:#569cd6;">if</font> (!IDraftControl(sha).isFinalized()) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_ShaNotFinalized"</font>));
        }

        IShareholdersAgreement _sha = IShareholdersAgreement(sha);

        _sha.circulateDoc();

        <font style="color:#4ec9b0;">uint16</font> signingDays = _sha.getSigningDays();
        <font style="color:#4ec9b0;">uint16</font> closingDays = _sha.getClosingDays();

        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr = <font style="color:#4ec9b0;">address</font>(_gk.getSHA()) == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)
            ? _sha.getRule(<font style="color:#b5cea8;">8</font>).votingRuleParser()
            : _gk.getSHA().getRule(<font style="color:#b5cea8;">8</font>).votingRuleParser();

        _gk.getROC().circulateFile(sha, signingDays, closingDays, vr, docUrl, docHash);
    }

    <font style="color:#6a9955;">// ======== Sign SHA ========</font>

    <font style="color:#569cd6;">function</font> signSHA(
        <font style="color:#4ec9b0;">address</font> sha,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (!ISigPage(sha).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_NotPartyOfSha"</font>));
        }

        <font style="color:#569cd6;">if</font> (
            _gk.getROC().getHeadOfFile(sha).state !=
            <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Circulated)
        ) <font style="color:#569cd6;">revert</font> ROCK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_ShaNotCirculated"</font>));

        ISigPage(sha).signDoc(<font style="color:#569cd6;">true</font>, caller, sigHash);
    }

    <font style="color:#6a9955;">// ==== Activate SHA ====</font>

    <font style="color:#569cd6;">function</font> activateSHA(<font style="color:#4ec9b0;">address</font> sha) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#569cd6;">if</font> (!ISigPage(sha).isParty(caller)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_NotPartyOfSha"</font>));
        }

        IRegisterOfConstitution _roc = _gk.getROC();
        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#569cd6;">if</font> (sha == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ROCK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROCK_ZeroAddr"</font>));
        }

        IShareholdersAgreement _sha = IShareholdersAgreement(sha);

        <font style="color:#4ec9b0;">uint</font> seqOfMotion = _roc.getHeadOfFile(sha).seqOfMotion;

        <font style="color:#569cd6;">if</font> (seqOfMotion > <font style="color:#b5cea8;">0</font>) {
            _gk.getGMM().execResolution(
                seqOfMotion,
                <font style="color:#4ec9b0;">uint</font>(<font style="color:#4ec9b0;">uint160</font>(sha)),
                caller
            );
            _roc.execFile(sha);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_membersAllSigned(_rom, _sha)) {
            _roc.setStateOfFile(sha, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Closed));
        }

        _roc.changePointer(sha);

        RulesParser.GovernanceRule <font style="color:#569cd6;">memory</font> gr =
            _sha.getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser();

        <font style="color:#569cd6;">if</font> (_rom.maxQtyOfMembers() != gr.maxQtyOfMembers)
            _rom.setMaxQtyOfMembers(gr.maxQtyOfMembers);

        _rom.setVoteBase(gr.basedOnPar);

        <font style="color:#569cd6;">if</font> (_rom.minVoteRatioOnChain() != gr.minVoteRatioOnChain)
            _rom.setMinVoteRatioOnChain(gr.minVoteRatioOnChain);

        <font style="color:#569cd6;">if</font> (_sha.hasTitle(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.Options)))
            _regOptionTerms(_sha);

        _updatePositionSetting(_sha);
        _updateGrouping(_sha);
    }

    <font style="color:#569cd6;">function</font> _membersAllSigned(
        IRegisterOfMembers _rom,
        IShareholdersAgreement _sha
    ) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members = _rom.membersList();
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> parties = _sha.getParties();

        <font style="color:#569cd6;">if</font> (parties.length == <font style="color:#b5cea8;">0</font> || parties.length != members.length) {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        }

        <font style="color:#569cd6;">return</font> members.fullyCoveredBy(parties);
    }

    <font style="color:#569cd6;">function</font> _regOptionTerms(IShareholdersAgreement _sha) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">address</font> opts = _sha.getTerm(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.Options));
        <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROO().regOptionTerms(opts);
    }

    <font style="color:#569cd6;">function</font> _updatePositionSetting(IShareholdersAgreement _sha) <font style="color:#569cd6;">private</font> {
        IRegisterOfDirectors _rod = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROD();

        <font style="color:#4ec9b0;">uint256</font> len = _sha.getRule(<font style="color:#b5cea8;">256</font>).positionAllocateRuleParser().qtyOfSubRule;
        <font style="color:#4ec9b0;">uint256</font> i;
        <font style="color:#569cd6;">while</font> (i < len) {
            RulesParser.PositionAllocateRule <font style="color:#569cd6;">memory</font> rule =
                _sha.getRule(<font style="color:#b5cea8;">256</font>+i).positionAllocateRuleParser();

            <font style="color:#569cd6;">if</font> (rule.removePos) {
                _rod.removePosition(rule.seqOfPos);
            } <font style="color:#569cd6;">else</font> {
                OfficersRepo.Position <font style="color:#569cd6;">memory</font> pos = _rod.getPosition(rule.seqOfPos);
                pos = OfficersRepo.Position({
                    title: rule.titleOfPos,
                    seqOfPos: rule.seqOfPos,
                    acct: pos.acct,
                    nominator: rule.nominator,
                    startDate: pos.startDate,
                    endDate: rule.endDate,
                    seqOfVR: rule.seqOfVR,
                    titleOfNominator: rule.titleOfNominator,
                    argu: rule.argu
                });

                _rod.updatePosition(pos);
            }

            i++;
        }
    }

    <font style="color:#569cd6;">function</font> _updateGrouping(IShareholdersAgreement _sha) <font style="color:#569cd6;">private</font> {
        IRegisterOfMembers _rom = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROM();

        <font style="color:#4ec9b0;">uint256</font> len = _sha.getRule(<font style="color:#b5cea8;">768</font>).groupUpdateOrderParser().qtyOfSubRule;
        <font style="color:#4ec9b0;">uint256</font> i;

        <font style="color:#569cd6;">while</font> (i < len) {
            RulesParser.GroupUpdateOrder <font style="color:#569cd6;">memory</font> order =
                _sha.getRule(<font style="color:#b5cea8;">768</font>+i).groupUpdateOrderParser();

            <font style="color:#4ec9b0;">uint256</font> j;
            <font style="color:#569cd6;">if</font> (order.addMember) {
                <font style="color:#569cd6;">while</font> (j < <font style="color:#b5cea8;">4</font>) {
                    <font style="color:#569cd6;">if</font> (order.members[j] > <font style="color:#b5cea8;">0</font>)
                        _rom.addMemberToGroup(order.members[j], order.groupRep);
                    j++;
                }
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">while</font> (j < <font style="color:#b5cea8;">4</font>) {
                    <font style="color:#569cd6;">if</font> (order.members[j] > <font style="color:#b5cea8;">0</font>)
                        _rom.removeMemberFromGroup(order.members[j]);
                    j++;
                }
            }

            i++;
        }
    }

    <font style="color:#6a9955;">// ==== Accept SHA ====</font>

    <font style="color:#569cd6;">function</font> acceptSHA(<font style="color:#4ec9b0;">bytes32</font> sigHash) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        IShareholdersAgreement _sha = _gk.getSHA();
        _sha.addBlank(<font style="color:#569cd6;">false</font>, <font style="color:#569cd6;">true</font>, <font style="color:#b5cea8;">1</font>, caller);
        _sha.signDoc(<font style="color:#569cd6;">false</font>, caller, sigHash);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RODKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/RODKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IRODKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> RODKeeper <font style="color:#569cd6;">is</font> IRODKeeper {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("RODKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x4218a169;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// ==== Directors ====</font>

    <font style="color:#569cd6;">function</font> takeSeat(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#569cd6;">if</font> (_gmm.getMotion(seqOfMotion).head.typeOfMotion !=
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ElectOfficer)) {
            <font style="color:#569cd6;">revert</font> RODK_WrongTypeOfMotion(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RODK_NotElectOfficer"</font>));
        }

        _gmm.execResolution(seqOfMotion, seqOfPos, caller);
        _gk.getROD().takePosition(seqOfPos, caller);
    }

    <font style="color:#569cd6;">function</font> removeDirector (<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IMeetingMinutes _gmm = _gk.getGMM();

        <font style="color:#569cd6;">if</font> (_gmm.getMotion(seqOfMotion).head.typeOfMotion !=
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.RemoveOfficer)) {
            <font style="color:#569cd6;">revert</font> RODK_WrongTypeOfMotion(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RODK_NotRemoveOfficer"</font>));
        }

        _gmm.execResolution(seqOfMotion, seqOfPos, caller);
        _gk.getROD().removeOfficer(seqOfPos);
    }

    <font style="color:#6a9955;">// ==== Officers ====</font>

    <font style="color:#569cd6;">function</font> takePosition(<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        IMeetingMinutes _bmm = _gk.getBMM();

        <font style="color:#569cd6;">if</font> (_bmm.getMotion(seqOfMotion).head.typeOfMotion !=
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.ElectOfficer)) {
            <font style="color:#569cd6;">revert</font> RODK_WrongTypeOfMotion(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RODK_NotElectOfficer"</font>));
        }

        _bmm.execResolution(seqOfMotion, seqOfPos, caller);
        _gk.getROD().takePosition(seqOfPos, caller);
    }

    <font style="color:#569cd6;">function</font> removeOfficer (<font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IMeetingMinutes _bmm = _gk.getBMM();

        <font style="color:#569cd6;">if</font> (_bmm.getMotion(seqOfMotion).head.typeOfMotion !=
            <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.TypeOfMotion.RemoveOfficer)) {
            <font style="color:#569cd6;">revert</font> RODK_WrongTypeOfMotion(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RODK_NotRemoveOfficer"</font>));
        }

        _bmm.execResolution(seqOfMotion, seqOfPos, caller);
        _gk.getROD().removeOfficer(seqOfPos);
    }

    <font style="color:#6a9955;">// ==== Quit ====</font>

    <font style="color:#569cd6;">function</font> quitPosition(<font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        _gk.getROD().quitPosition(seqOfPos, caller);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ROIKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ROIKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/Address.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROIKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> ROIKeeper <font style="color:#569cd6;">is</font> IROIKeeper {
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> Address <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("ROIKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0xd042852b;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// ######################</font>
    <font style="color:#6a9955;">// ##   Error & Event  ##</font>
    <font style="color:#6a9955;">// ######################</font>

    <font style="color:#6a9955;">// ==== Pause LOO ====</font>

    <font style="color:#569cd6;">function</font> _checkVerifierLicense(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();
        <font style="color:#569cd6;">if</font>(!_gk.getROD().hasTitle(caller, lr.titleOfVerifier)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_NoRightOfVerify"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> _checkEnforcerLicense(<font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();
        <font style="color:#569cd6;">if</font>(!_gk.getROD().hasTitle(caller, lr.para)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_NoRightOfEnforce"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> pause(<font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        _gk.getROI().pause(caller);
    }

    <font style="color:#569cd6;">function</font> unPause(<font style="color:#4ec9b0;">uint</font> seqOfLR) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);
        _gk.getROI().unPause(caller);
    }

    <font style="color:#6a9955;">// ==== Freeze Share ====</font>

    <font style="color:#569cd6;">function</font> freezeShare(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        IRegisterOfShares _ros = _gk.getROS();
        _ros.decreaseCleanPaid(seqOfShare, paid);
        <font style="color:#4ec9b0;">uint</font> shareholder = _ros.getShare(seqOfShare).head.shareholder;
        _gk.getROI().freezeShare(shareholder, seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#569cd6;">function</font> unfreezeShare(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        IRegisterOfShares _ros = _gk.getROS();
        _ros.increaseCleanPaid(seqOfShare, paid);
        <font style="color:#4ec9b0;">uint</font> shareholder = _ros.getShare(seqOfShare).head.shareholder;
        _gk.getROI().unfreezeShare(shareholder, seqOfShare, paid, caller, hashOrder);
    }

    <font style="color:#569cd6;">function</font> forceTransfer(
        <font style="color:#4ec9b0;">uint</font> seqOfLR, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">address</font> addrTo, <font style="color:#4ec9b0;">bytes32</font> hashOrder
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkEnforcerLicense(_gk, seqOfLR, caller);

        IRegisterOfInvestors _roi = _gk.getROI();
        <font style="color:#4ec9b0;">uint</font> to = addrTo.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        <font style="color:#569cd6;">if</font>(!_roi.isInvestor(to)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_NotInvestor"</font>));
        }

        IRegisterOfShares _ros = _gk.getROS();
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share = _ros.getShare(seqOfShare);
        _ros.increaseCleanPaid(seqOfShare, paid);

        _roi.forceTransfer(share.head.shareholder, seqOfShare, paid, caller, hashOrder);
        _ros.transferShare(seqOfShare, paid, paid, to, share.head.priceOfPaid, share.head.priceOfPar);
    }
    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#569cd6;">function</font> regInvestor(
        <font style="color:#4ec9b0;">address</font> bKey, <font style="color:#4ec9b0;">uint</font> groupRep, <font style="color:#4ec9b0;">bytes32</font> idHash
    ) <font style="color:#569cd6;">external</font> {

        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#6a9955;">// address _rc = _gk.getRCByGK();</font>

        <font style="color:#569cd6;">if</font>(msg.sender == bKey)
            <font style="color:#569cd6;">revert</font> ROIK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_SameKey"</font>));

        <font style="color:#569cd6;">if</font>(caller != bKey.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>)) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_WrongBackupKey"</font>));
        }

        <font style="color:#569cd6;">if</font> (msg.sender.isContract()) {
            <font style="color:#6a9955;">// uint32(uint(keccak256("GeneralKeeper"))</font>
            <font style="color:#569cd6;">if</font>(_gk.getRCByGK().getHeadByBody(msg.sender).typeOfDoc != 0x25586efd)
                <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_COAApplicantNotGK"</font>));
        }

        <font style="color:#569cd6;">if</font> (bKey.isContract()) {
            <font style="color:#569cd6;">if</font>(_gk.getRCByGK().getHeadByBody(bKey).typeOfDoc != 0x25586efd)
                <font style="color:#569cd6;">revert</font> ROIK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_COABackupKeyNotGK"</font>));
        }

        _gk.getROI().regInvestor(caller, groupRep, idHash);
    }

    <font style="color:#569cd6;">function</font> approveInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkVerifierLicense(_gk, seqOfLR, caller);

        IRegisterOfInvestors _roi = _gk.getROI();

        RulesParser.ListingRule <font style="color:#569cd6;">memory</font> lr =
            _gk.getSHA().getRule(seqOfLR).listingRuleParser();

        <font style="color:#569cd6;">if</font>(lr.maxQtyOfInvestors != <font style="color:#b5cea8;">0</font> &&
            _roi.getQtyOfInvestors() >= lr.maxQtyOfInvestors
        ) {
            <font style="color:#569cd6;">revert</font> ROIK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROIK_NoQuotaOfInvestors"</font>));
        }

        _roi.approveInvestor(userNo, caller);
    }

    <font style="color:#569cd6;">function</font> revokeInvestor(
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> seqOfLR
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _checkVerifierLicense(_gk, seqOfLR, caller);

        _gk.getROI().revokeInvestor(userNo, caller);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ROMKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ROMKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROMKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> ROMKeeper <font style="color:#569cd6;">is</font> IROMKeeper {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// = uint32(uint(keccak256("ROMKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0xa223ca65;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#569cd6;">modifier</font> onlyDK() {
        <font style="color:#569cd6;">if</font>(msg.sender != IAccessControl(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)).getDK())
            <font style="color:#569cd6;">revert</font> ROMK_WrongAccess(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROMK_NotDK"</font>));
        _;
    }

    <font style="color:#569cd6;">function</font> setMaxQtyOfMembers(<font style="color:#4ec9b0;">uint</font> max) <font style="color:#569cd6;">external</font> onlyDK  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        _gk.getROM().setMaxQtyOfMembers(max);
    }

    <font style="color:#569cd6;">function</font> setPayInAmt(
        <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font> onlyDK  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gk.getROS().setPayInAmt(seqOfShare, amt, expireDate, hashLock);
    }

    <font style="color:#569cd6;">function</font> requestPaidInCapital(
        <font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font>  {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gk.getROS().requestPaidInCapital(hashLock, hashKey);
    }

    <font style="color:#569cd6;">function</font> withdrawPayInAmt(
        <font style="color:#4ec9b0;">bytes32</font> hashLock, <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">external</font> onlyDK {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gk.getROS().withdrawPayInAmt(hashLock, seqOfShare);
    }

    <font style="color:#569cd6;">function</font> payInCapital(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        IRegisterOfShares _ros = _gk.getROS();
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share = _ros.getShare(seqOfShare);

        <font style="color:#569cd6;">if</font>(share.head.shareholder != caller)
            <font style="color:#569cd6;">revert</font> ROMK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROMK_NotShareholder"</font>));

        auth.<font style="color:#569cd6;">from</font> = msg.sender;
        auth.value = share.head.priceOfPaid * paid / <font style="color:#b5cea8;">100</font>;

        _gk.getCashier().collectUsd(auth, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"PayInCapital"</font>));

        _ros.payInCapital(seqOfShare, paid);

        <font style="color:#569cd6;">emit</font> PayInCapital(seqOfShare, paid, auth.value);
    }

    <font style="color:#569cd6;">function</font> decreaseCapital(
        <font style="color:#4ec9b0;">uint</font> seqOfVR, <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> par, <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gk.getGMM().decreaseCapital(
            seqOfVR, seqOfShare, paid, par, amt, seqOfMotion, caller
        );
        IRegisterOfShares _ros=_gk.getROS();
        <font style="color:#4ec9b0;">uint</font> shareholder = _ros.getShare(seqOfShare).head.shareholder;
        _ros.decreaseCapital(seqOfShare, paid, par);
        _gk.getCashier().depositUsd(shareholder, amt, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DecreaseCapital"</font>));
    }

    <font style="color:#569cd6;">function</font> updatePaidInDeadline(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> line
    ) <font style="color:#569cd6;">external</font> onlyDK {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        _gk.getROS().updatePaidInDeadline(seqOfShare, line);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ROOKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ROOKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROOKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> ROOKeeper <font style="color:#569cd6;">is</font> IROOKeeper {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("ROOKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x3ac07862;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#569cd6;">function</font> updateOracle(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> d1,
        <font style="color:#4ec9b0;">uint</font> d2,
        <font style="color:#4ec9b0;">uint</font> d3
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (IAccessControl(_gk).getDK() != msg.sender)
            <font style="color:#569cd6;">revert</font> ROOK_WrongAccess(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_NotDK"</font>));

        _gk.getROO().updateOracle(seqOfOpt, d1, d2, d3);
    }

    <font style="color:#569cd6;">function</font> execOption(<font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);
        <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROO().execOption(seqOfOpt, caller);
    }

    <font style="color:#569cd6;">function</font> createSwap(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfTarget,
        <font style="color:#4ec9b0;">uint</font> paidOfTarget,
        <font style="color:#4ec9b0;">uint</font> seqOfPledge
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>);

        <font style="color:#4ec9b0;">uint</font> closingDate = _gk.getROO().getOption(seqOfOpt).body.closingDeadline;

        IRegisterOfOptions _roo = _gk.getROO();
        IRegisterOfShares _ros = _gk.getROS();

        <font style="color:#569cd6;">if</font> (!_ros.notLocked(seqOfTarget, closingDate))
            <font style="color:#569cd6;">revert</font> ROOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_TargetLocked"</font>));

        <font style="color:#569cd6;">if</font> (!_ros.notLocked(seqOfPledge, closingDate))
            <font style="color:#569cd6;">revert</font> ROOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_PledgeLocked"</font>));

        SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap =
            _roo.createSwap(seqOfOpt, seqOfTarget, paidOfTarget, seqOfPledge, caller);

        _ros.decreaseCleanPaid(swap.seqOfTarget, swap.paidOfTarget);
        <font style="color:#569cd6;">if</font> (swap.isPutOpt)
            _ros.decreaseCleanPaid(swap.seqOfPledge, swap.paidOfPledge);
    }

    <font style="color:#569cd6;">function</font> payOffSwap(
        ICashier.TransferAuth <font style="color:#569cd6;">memory</font> auth,
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> seqOfSwap,
        <font style="color:#4ec9b0;">address</font> to
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">40000</font>);

        IRegisterOfShares _ros = _gk.getROS();
        SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap =
            _gk.getROO().getSwap(seqOfOpt, seqOfSwap);

        <font style="color:#4ec9b0;">uint</font> seller = to.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>);

        <font style="color:#569cd6;">if</font> (seller != _ros.getShare(swap.seqOfTarget).head.shareholder)
            <font style="color:#569cd6;">revert</font> ROOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_WrongPayee"</font>));

        <font style="color:#4ec9b0;">uint</font> valueOfDeal = swap.paidOfTarget * swap.priceOfDeal / <font style="color:#b5cea8;">100</font>;

        auth.<font style="color:#569cd6;">from</font> = msg.sender;
        auth.value = valueOfDeal;

        <font style="color:#6a9955;">// remark: PayOffSwap</font>
        _gk.getCashier().forwardUsd(
            auth,
            to,
            <font style="color:#4ec9b0;">bytes32</font>(0x5061794f66665377617000000000000000000000000000000000000000000000)
        );
        <font style="color:#569cd6;">emit</font> PayOffSwap(seqOfOpt, seqOfSwap, msg.sender, to, auth.value);

        _payOffSwap(_gk, seqOfOpt, seqOfSwap, caller);
    }

    <font style="color:#569cd6;">function</font> _payOffSwap(
        <font style="color:#4ec9b0;">address</font> _gk, <font style="color:#4ec9b0;">uint</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> seqOfSwap, <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">private</font> {

        IRegisterOfShares _ros = _gk.getROS();

        SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap =
            _gk.getROO().payOffSwap(seqOfOpt, seqOfSwap);

        <font style="color:#569cd6;">if</font> (!_ros.notLocked(swap.seqOfTarget, block.timestamp))
            <font style="color:#569cd6;">revert</font> ROOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_TargetLocked"</font>));

        <font style="color:#4ec9b0;">uint</font> buyer = _ros.getShare(swap.seqOfPledge).head.shareholder;

        <font style="color:#569cd6;">if</font> (caller != buyer)
            <font style="color:#569cd6;">revert</font> ROOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_WrongPayer"</font>));

        _ros.increaseCleanPaid(swap.seqOfTarget, swap.paidOfTarget);
        _ros.transferShare(
            swap.seqOfTarget, swap.paidOfTarget, swap.paidOfTarget,
            buyer, swap.priceOfDeal, swap.priceOfDeal
        );

        <font style="color:#569cd6;">if</font> (swap.isPutOpt) {
            _ros.increaseCleanPaid(swap.seqOfPledge, swap.paidOfPledge);
        }
    }

    <font style="color:#569cd6;">function</font> terminateSwap(
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint256</font> seqOfSwap
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap =
            _gk.getROO().terminateSwap(seqOfOpt, seqOfSwap);

        IRegisterOfShares _ros = _gk.getROS();
        <font style="color:#4ec9b0;">uint</font> seller = _ros.getShare(swap.seqOfTarget).head.shareholder;

        <font style="color:#569cd6;">if</font>(caller != seller)
            <font style="color:#569cd6;">revert</font> ROOK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_NotSeller"</font>));

        <font style="color:#569cd6;">if</font>(!_ros.notLocked(swap.seqOfPledge, block.timestamp))
            <font style="color:#569cd6;">revert</font> ROOK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROOK_PledgeLocked"</font>));

        _ros.increaseCleanPaid(swap.seqOfTarget, swap.paidOfTarget);

        <font style="color:#569cd6;">if</font>(swap.isPutOpt) {
            _ros.increaseCleanPaid(swap.seqOfPledge, swap.paidOfPledge);
            _ros.transferShare(swap.seqOfPledge, swap.paidOfPledge, swap.paidOfPledge,
                seller, swap.priceOfDeal, swap.priceOfDeal);
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ROPKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/ROPKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/PledgesRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IROPKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> ROPKeeper <font style="color:#569cd6;">is</font> IROPKeeper {
    <font style="color:#569cd6;">using</font> PledgesRepo <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("ROPKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x4fcfb5a7;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// #######################</font>
    <font style="color:#6a9955;">// ##   Error & Event   ##</font>
    <font style="color:#6a9955;">// #######################</font>

    <font style="color:#6a9955;">// error ROPK_WrongParty(bytes32 reason);</font>

    <font style="color:#569cd6;">error</font> ROPK_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> ROPK_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">function</font> _pledgerIsVerified(
        <font style="color:#4ec9b0;">address</font> _gk,
        <font style="color:#4ec9b0;">uint</font> pledgor
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        <font style="color:#569cd6;">if</font> (_gk.getROI().getInvestor(pledgor).state !=
            <font style="color:#4ec9b0;">uint8</font>(InvestorsRepo.StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_PledgorNotVerified"</font>));
        }
        <font style="color:#569cd6;">if</font> (!_gk.getSHA().isSigner(pledgor)) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_ShaNotSignedByPledgor"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> createPledge(
        <font style="color:#4ec9b0;">bytes32</font> snOfPld,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">66000</font>
        );

        IRegisterOfShares _ros = _gk.getROS();

        PledgesRepo.Head <font style="color:#569cd6;">memory</font> head = snOfPld.snParser();

        head.pledgor = _ros.getShare(head.seqOfShare).head.shareholder;

        <font style="color:#569cd6;">if</font> (head.pledgor != caller) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_NotPledgor"</font>));
        }

        <font style="color:#569cd6;">if</font> (!_ros.notLocked(head.seqOfShare, block.timestamp)) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_ShareLocked"</font>));
        }

        head = _gk.getROP().createPledge(
            snOfPld,
            paid,
            par,
            guaranteedAmt,
            execDays
        );

        _ros.decreaseCleanPaid(head.seqOfShare, paid);
    }

    <font style="color:#569cd6;">function</font> transferPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>
        );
        _gk.getROP().transferPledge(seqOfShare, seqOfPld, buyer, amt, caller);
    }

    <font style="color:#569cd6;">function</font> refundDebt(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">36000</font>
        );

        PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> pld =
            _gk.getROP().refundDebt(seqOfShare, seqOfPld, amt, caller);

        _gk.getROS().increaseCleanPaid(seqOfShare, pld.body.paid);
    }

    <font style="color:#569cd6;">function</font> extendPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> extDays
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">18000</font>
        );
        _gk.getROP().extendPledge(seqOfShare, seqOfPld, extDays, caller);
    }

    <font style="color:#569cd6;">function</font> lockPledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>
        );
        _gk.getROP().lockPledge(seqOfShare, seqOfPld, hashLock, caller);
    }

    <font style="color:#569cd6;">function</font> releasePledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        <font style="color:#4ec9b0;">uint64</font> paid = _gk.getROP().releasePledge(seqOfShare, seqOfPld, hashKey);
        _gk.getROS().increaseCleanPaid(seqOfShare, paid);
    }

    <font style="color:#569cd6;">function</font> execPledge(
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> groupOfBuyer
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>);

        _pledgerIsVerified(_gk, buyer);

        IRegisterOfPledges _rop = _gk.getROP();
        _rop.execPledge(seqOfShare, seqOfPld, caller);

        PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> pld =
            _rop.getPledge(seqOfShare, seqOfPld);

        IRegisterOfShares _ros = _gk.getROS();
        IRegisterOfMembers _rom = _gk.getROM();

        <font style="color:#569cd6;">if</font> (!_ros.notLocked(pld.head.seqOfShare, block.timestamp)) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_ShareLocked"</font>));
        }

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal;

        deal.head.priceOfPaid = <font style="color:#4ec9b0;">uint32</font>(pld.body.guaranteedAmt * <font style="color:#b5cea8;">10000</font> / pld.body.paid);
        deal.head.priceOfPar = <font style="color:#4ec9b0;">uint32</font>(pld.body.guaranteedAmt * <font style="color:#b5cea8;">10000</font> / pld.body.par);

        deal.body.buyer = <font style="color:#4ec9b0;">uint40</font>(buyer);
        deal.body.groupOfBuyer = <font style="color:#4ec9b0;">uint40</font>(groupOfBuyer);

        _ros.increaseCleanPaid(pld.head.seqOfShare, pld.body.paid);
        _ros.transferShare(pld.head.seqOfShare, pld.body.paid, pld.body.par,
            deal.body.buyer, deal.head.priceOfPaid, deal.head.priceOfPar);

        <font style="color:#569cd6;">if</font> (deal.body.buyer != deal.body.groupOfBuyer &&
            deal.body.groupOfBuyer != _rom.groupRep(deal.body.buyer)) {
                _rom.addMemberToGroup(deal.body.buyer, deal.body.groupOfBuyer);
        }

    }

    <font style="color:#569cd6;">function</font> revokePledge(
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">58000</font>);

        IRegisterOfPledges _rop = _gk.getROP();

        PledgesRepo.Pledge <font style="color:#569cd6;">memory</font> pld = _rop.getPledge(seqOfShare, seqOfPld);
        <font style="color:#569cd6;">if</font> (pld.head.pledgor != caller) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_NotPledgor"</font>));
        }

        <font style="color:#569cd6;">if</font> (!_gk.getROS().notLocked(pld.head.seqOfShare, block.timestamp)) {
            <font style="color:#569cd6;">revert</font> ROPK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ROPK_ShareLocked"</font>));
        }

        _rop.revokePledge(seqOfShare, seqOfPld, caller);
        _gk.getROS().increaseCleanPaid(seqOfShare, pld.body.paid);

    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## SHAKeeper.sol

---

| |
|:---|
| **contracts/comps/keepers/SHAKeeper.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/InterfacesHub.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/utils/RoyaltyCharge.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../lib/books/DTClaims.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ISHAKeeper.sol"</font>;

<font style="color:#569cd6;">contract</font> SHAKeeper <font style="color:#569cd6;">is</font> ISHAKeeper {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RoyaltyCharge <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> DTClaims <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;

    <font style="color:#6a9955;">// uint32(uint(keccak256("SHAKeeper")));</font>
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TYPE_OF_DOC = 0x2beb4fa1;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> VERSION = <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">// ======== TagAlong & DragAlong ========</font>

    <font style="color:#569cd6;">function</font> execAlongRight(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> snOfClaim,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>
        );

        DTClaims.Head <font style="color:#569cd6;">memory</font> head = snOfClaim.snParser();

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = IInvestmentAgreement(ia).getDeal(head.seqOfDeal);
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROS().getShare(head.seqOfShare);

        _checkCaller(head.dragAlong, ia, deal, share, caller);

        _checkFRClaimAndMockIA(ia, caller, share);

        IAlongs _al = _getAlongTerm(head.dragAlong);

        _isTriggered(_al, ia, deal, share);

        _checkAmt(_al, deal, share, head.paid, head.par);

        head.caller = <font style="color:#4ec9b0;">uint40</font>(caller);
        snOfClaim = DTClaims.codifyHead(head);

        _execAlongRight(ia, snOfClaim, sigHash);
    }

    <font style="color:#569cd6;">function</font> _checkCaller(
        <font style="color:#4ec9b0;">bool</font> dragAlong,
        <font style="color:#4ec9b0;">address</font> ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        <font style="color:#569cd6;">if</font> (dragAlong) {
            <font style="color:#569cd6;">if</font>(caller != deal.head.seller)
                <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotSeller"</font>));
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font>(caller != share.head.shareholder)
                <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotShareholder"</font>));
            <font style="color:#569cd6;">if</font>(ISigPage(ia).isBuyer(<font style="color:#569cd6;">true</font>, caller))
                <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_BuyerNotAllowed"</font>));
        }
    }

    <font style="color:#569cd6;">function</font> _checkFRClaimAndMockIA(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> caller,
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">private</font> {
        IRegisterOfAgreements _roa = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROA();
        <font style="color:#569cd6;">if</font>(_roa.isFRClaimer(ia, caller))
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_CallerIsFRClaimer"</font>));
        <font style="color:#569cd6;">if</font>(_roa.isFRClaimer(ia, share.head.shareholder))
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_ShareholderIsFRClaimer"</font>));
        _roa.createMockOfIA(ia);
    }

    <font style="color:#569cd6;">function</font> _getAlongTerm(
        <font style="color:#4ec9b0;">bool</font> dragAlong
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(IAlongs) {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#569cd6;">return</font> dragAlong
            ? IAlongs(_gk.getSHA().
                getTerm(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.DragAlong)))
            : IAlongs(_gk.getSHA().
                getTerm(<font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.TagAlong)));
    }

    <font style="color:#569cd6;">function</font> _isTriggered(
        IAlongs _al,
        <font style="color:#4ec9b0;">address</font> ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        <font style="color:#569cd6;">if</font>(deal.body.state != <font style="color:#4ec9b0;">uint8</font>(DealsRepo.StateOfDeal.Locked))
            <font style="color:#569cd6;">revert</font> SHAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotLocked"</font>));
        <font style="color:#569cd6;">if</font>(!_al.isFollower(deal.head.seller, share.head.shareholder))
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotLinked"</font>));
        <font style="color:#569cd6;">if</font>(!_al.isTriggered(ia, deal))
            <font style="color:#569cd6;">revert</font> SHAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_AlongsNotTriggered"</font>));
    }

    <font style="color:#569cd6;">function</font> _checkAmt(
        IAlongs _al,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> subjectVW = _gk.getROS().getShare(deal.head.seqOfShare).head.votingWeight;

        <font style="color:#569cd6;">if</font>(_al.getLinkRule(deal.head.seller).proRata) {
            IRegisterOfMembers _rom = _gk.getROM();

            <font style="color:#569cd6;">if</font> (_rom.basedOnPar()) {
                <font style="color:#569cd6;">if</font>( par >
                subjectVW * deal.body.par * share.body.par / _rom.votesOfGroup(deal.head.seller) / <font style="color:#b5cea8;">100</font> )
                    <font style="color:#569cd6;">revert</font> SHAK_AmtOverflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_ParOverflow"</font>));
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">if</font> ( paid >
                 subjectVW * deal.body.paid * share.body.paid / _rom.votesOfGroup(deal.head.seller) / <font style="color:#b5cea8;">100</font> )
                <font style="color:#569cd6;">revert</font> SHAK_AmtOverflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_PaidOverflow"</font>));
            }
        }
    }

    <font style="color:#569cd6;">function</font> _execAlongRight(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">bytes32</font> snOfClaim,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">private</font> {
        IRegisterOfAgreements _roa = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).getROA();
        _roa.execAlongRight(ia, snOfClaim, sigHash);
    }

    <font style="color:#569cd6;">function</font> acceptAlongDeal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION,<font style="color:#b5cea8;">36000</font>
        );

        IRegisterOfAgreements _roa = _gk.getROA();
        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        <font style="color:#569cd6;">if</font>(caller != deal.body.buyer)
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotBuyer"</font>));

        DTClaims.Claim[] <font style="color:#569cd6;">memory</font> claims = _roa.acceptAlongClaims(ia, seqOfDeal);

        <font style="color:#4ec9b0;">uint</font> len = claims.length;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            DTClaims.Claim <font style="color:#569cd6;">memory</font> claim = claims[len - <font style="color:#b5cea8;">1</font>];

            SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
                _gk.getROS().getShare(claim.seqOfShare);

            _createAlongDeal(_gk, _ia, claim, deal, share);

            _ia.regSig(share.head.shareholder, claim.sigDate, claim.sigHash);
            _ia.regSig(caller, <font style="color:#4ec9b0;">uint48</font>(block.timestamp), sigHash);

            len--;
        }
    }

    <font style="color:#569cd6;">function</font> _createAlongDeal(
        <font style="color:#4ec9b0;">address</font> _gk,
        IInvestmentAgreement _ia,
        DTClaims.Claim <font style="color:#569cd6;">memory</font> claim,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share
    ) <font style="color:#569cd6;">private</font> {
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> aDeal;
        aDeal.head = DealsRepo.Head({
            typeOfDeal: claim.typeOfClaim == <font style="color:#b5cea8;">0</font>
                ? <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.DragAlong)
                : <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.TagAlong),
            seqOfDeal: <font style="color:#b5cea8;">0</font>,
            preSeq: deal.head.seqOfDeal,
            classOfShare: share.head.class,
            seqOfShare: share.head.seqOfShare,
            seller: share.head.shareholder,
            priceOfPaid: deal.head.priceOfPaid,
            priceOfPar: deal.head.priceOfPar,
            closingDeadline: deal.head.closingDeadline,
            votingWeight: share.head.votingWeight
        });

        aDeal.body = DealsRepo.Body({
            buyer: deal.body.buyer,
            groupOfBuyer: deal.body.groupOfBuyer,
            paid: claim.paid,
            par: claim.par,
            state: <font style="color:#4ec9b0;">uint8</font>(DealsRepo.StateOfDeal.Locked),
            para: <font style="color:#b5cea8;">0</font>,
            distrWeight: deal.body.distrWeight,
            flag: <font style="color:#569cd6;">false</font>
        });

        _ia.regDeal(aDeal);

        _gk.getROS().decreaseCleanPaid(share.head.seqOfShare, claim.paid);
    }

    <font style="color:#6a9955;">// ======== Anti-Dilution ========</font>

    <font style="color:#569cd6;">function</font> execAntiDilution(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION, <font style="color:#b5cea8;">88000</font>
        );

        IRegisterOfShares _ros = _gk.getROS();
        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        SharesRepo.Share <font style="color:#569cd6;">memory</font> tShare = _ros.getShare(seqOfShare);

        <font style="color:#569cd6;">if</font>(caller != tShare.head.shareholder)
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotShareholder"</font>));

        <font style="color:#569cd6;">if</font>(_ia.isInitSigner(caller))
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_IsInitSigner"</font>));

        <font style="color:#569cd6;">if</font>( _gk.getROA().getHeadOfFile(ia).state !=
            <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Circulated)
        ) <font style="color:#569cd6;">revert</font> SHAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_WrongFileState"</font>));

        _ia.requestPriceDiff(seqOfDeal, seqOfShare);

        IAntiDilution _ad = IAntiDilution(_gk.getSHA().getTerm(
            <font style="color:#4ec9b0;">uint8</font>(IShareholdersAgreement.TitleOfTerm.AntiDilution)
        ));

        <font style="color:#4ec9b0;">uint64</font> giftPaid = _ad.getGiftPaid(ia, seqOfDeal, tShare.head.seqOfShare);
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> obligors = _ad.getObligorsOfAD(tShare.head.class);

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        deal.head.typeOfDeal = <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.FreeGift);
        deal.head.preSeq = deal.head.seqOfDeal;
        deal.head.seqOfDeal = <font style="color:#b5cea8;">0</font>;
        deal.head.priceOfPar = tShare.head.seqOfShare;

        deal.body.buyer = tShare.head.shareholder;
        deal.body.state = <font style="color:#4ec9b0;">uint8</font>(DealsRepo.StateOfDeal.Locked);

        _deductShares(obligors, _ia, deal, giftPaid, _ros, sigHash);
    }

    <font style="color:#569cd6;">function</font> _deductShares(
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> obligors,
        IInvestmentAgreement _ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        <font style="color:#4ec9b0;">uint64</font> giftPaid,
        IRegisterOfShares _ros,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        IRegisterOfMembers _rom = _gk.getROM();

        deal.body.groupOfBuyer = _rom.groupRep(deal.body.buyer);

        <font style="color:#4ec9b0;">uint</font> i = obligors.length;

        <font style="color:#569cd6;">while</font> (i > <font style="color:#b5cea8;">0</font>) {

            <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> sharesInHand = _rom.sharesInHand(obligors[i - <font style="color:#b5cea8;">1</font>]);

            <font style="color:#4ec9b0;">uint</font> j = sharesInHand.length;

            <font style="color:#569cd6;">while</font> (j > <font style="color:#b5cea8;">0</font>) {

                <font style="color:#569cd6;">if</font> (!_ros.notLocked(sharesInHand[j-<font style="color:#b5cea8;">1</font>], deal.head.closingDeadline)) {
                    j--;
                    <font style="color:#569cd6;">continue</font>;
                }

                giftPaid = _createGift(
                    _ia,
                    deal,
                    sharesInHand[j - <font style="color:#b5cea8;">1</font>],
                    giftPaid,
                    _ros,
                    sigHash
                );

                <font style="color:#569cd6;">if</font> (giftPaid == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;
                j--;
            }

            <font style="color:#569cd6;">if</font> (giftPaid == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;
            i--;
        }
    }

    <font style="color:#569cd6;">function</font> _createGift(
        IInvestmentAgreement _ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint64</font> giftPaid,
        IRegisterOfShares _ros,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font> result) {
        SharesRepo.Share <font style="color:#569cd6;">memory</font> cShare = _ros.getShare(seqOfShare);

        <font style="color:#4ec9b0;">uint64</font> lockAmount;

        <font style="color:#569cd6;">if</font> (cShare.body.cleanPaid > <font style="color:#b5cea8;">0</font>) {

            lockAmount = (cShare.body.cleanPaid < giftPaid) ? cShare.body.cleanPaid : giftPaid;

            deal.head.classOfShare = cShare.head.class;
            deal.head.seqOfShare = cShare.head.seqOfShare;
            deal.head.seller = cShare.head.shareholder;

            deal.body.paid = lockAmount;
            deal.body.par = lockAmount;

            _ia.regDeal(deal);
            _ia.regSig(deal.head.seller, <font style="color:#4ec9b0;">uint48</font>(block.timestamp), <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint</font>(deal.head.seqOfShare)));
            _ia.regSig(deal.body.buyer, <font style="color:#4ec9b0;">uint48</font>(block.timestamp), sigHash);

            _ros.decreaseCleanPaid(cShare.head.seqOfShare, lockAmount);
        }
        result = giftPaid - lockAmount;
    }

    <font style="color:#569cd6;">function</font> takeGiftShares(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION,<font style="color:#b5cea8;">58000</font>
        );

        IRegisterOfShares _ros = _gk.getROS();
        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        <font style="color:#569cd6;">if</font>(caller != deal.body.buyer)
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotBuyer"</font>));

        <font style="color:#569cd6;">if</font>(!_ros.notLocked(deal.head.seqOfShare, block.timestamp))
            <font style="color:#569cd6;">revert</font> SHAK_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_ShareLocked"</font>));

        <font style="color:#569cd6;">if</font> (_ia.takeGift(seqOfDeal))
            _gk.getROA().setStateOfFile(ia, <font style="color:#4ec9b0;">uint8</font>(FilesRepo.StateOfFile.Closed));

        _ros.increaseCleanPaid(deal.head.seqOfShare, deal.body.paid);
        _ros.transferShare(
            deal.head.seqOfShare,
            deal.body.paid,
            deal.body.par,
            deal.body.buyer,
            deal.head.priceOfPaid,
            deal.head.priceOfPaid
        );

        SharesRepo.Share <font style="color:#569cd6;">memory</font> tShare = _ros.getShare(deal.head.priceOfPar);
        <font style="color:#569cd6;">if</font> (tShare.head.priceOfPaid > deal.head.priceOfPaid)
            _ros.updatePriceOfPaid(tShare.head.seqOfShare, deal.head.priceOfPaid);

    }

    <font style="color:#6a9955;">// ==== First Refusal ========</font>

    <font style="color:#569cd6;">function</font> execFirstRefusal(
        <font style="color:#4ec9b0;">uint256</font> seqOfFRRule,
        <font style="color:#4ec9b0;">uint256</font> seqOfRightholder,
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION,<font style="color:#b5cea8;">88000</font>
        );

        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        <font style="color:#569cd6;">if</font>(_ia.isSeller(<font style="color:#569cd6;">true</font>, caller))
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_frClaimerIsSeller"</font>));

        DealsRepo.Head <font style="color:#569cd6;">memory</font> headOfDeal =
            _ia.getDeal(seqOfDeal).head;

        RulesParser.FirstRefusalRule <font style="color:#569cd6;">memory</font> rule =
            _gk.getSHA().getRule(seqOfFRRule).firstRefusalRuleParser();

        <font style="color:#569cd6;">if</font>(rule.typeOfDeal != headOfDeal.typeOfDeal)
            <font style="color:#569cd6;">revert</font> SHAK_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_WrongTypeOfDeal"</font>));

        <font style="color:#569cd6;">if</font>(
            rule.membersEqual &&
            !_gk.getROM().isMember(caller)
        ) <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotMember"</font>));

        <font style="color:#569cd6;">if</font> (
            !rule.membersEqual &&
            rule.rightholders[seqOfRightholder] != caller
        ) <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotRightholder"</font>));

        _gk.getROA().claimFirstRefusal(ia, seqOfDeal, caller, sigHash);

        <font style="color:#569cd6;">if</font> (_ia.getDeal(seqOfDeal).body.state !=
            <font style="color:#4ec9b0;">uint8</font>(DealsRepo.StateOfDeal.Terminated))
                _ia.terminateDeal(seqOfDeal);

    }

    <font style="color:#569cd6;">function</font> computeFirstRefusal(
        <font style="color:#4ec9b0;">address</font> ia,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal
    ) <font style="color:#569cd6;">external</font> {
        <font style="color:#4ec9b0;">address</font> _gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> caller = msg.sender.msgSender(
            TYPE_OF_DOC, VERSION,<font style="color:#b5cea8;">18000</font>
        );

        IRegisterOfMembers _rom = _gk.getROM();
        IInvestmentAgreement _ia = IInvestmentAgreement(ia);

        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqOfDeal);

        (,, <font style="color:#4ec9b0;">bytes32</font> sigHashOfSeller) = _ia.getSigOfParty(<font style="color:#569cd6;">true</font>, deal.head.seller);

        <font style="color:#569cd6;">if</font>(!_rom.isMember(caller))
            <font style="color:#569cd6;">revert</font> SHAK_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHAK_NotMember"</font>));

        <font style="color:#569cd6;">if</font> (deal.head.seqOfShare != <font style="color:#b5cea8;">0</font>) {
            deal.head.typeOfDeal = <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.FirstRefusal);
        } <font style="color:#569cd6;">else</font>  deal.head.typeOfDeal = <font style="color:#4ec9b0;">uint8</font>(DealsRepo.TypeOfDeal.PreEmptive);

        deal.head.preSeq = deal.head.seqOfDeal;
        deal.body.state = <font style="color:#4ec9b0;">uint8</font>(DealsRepo.StateOfDeal.Locked);

        FRClaims.Claim[] <font style="color:#569cd6;">memory</font> cls =
            _gk.getROA().computeFirstRefusal(ia, seqOfDeal);

        <font style="color:#4ec9b0;">uint256</font> len = cls.length;
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> frDeal;
        <font style="color:#4ec9b0;">uint</font> paid = deal.body.paid;
        <font style="color:#4ec9b0;">uint</font> par = deal.body.par;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            frDeal = _createFRDeal(deal, cls[len-<font style="color:#b5cea8;">1</font>], _rom);
            <font style="color:#569cd6;">if</font> (len > <font style="color:#b5cea8;">1</font>) {
                paid -= frDeal.body.paid;
                par -= frDeal.body.par;
            } <font style="color:#569cd6;">else</font> {
                frDeal.body.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
                frDeal.body.par = <font style="color:#4ec9b0;">uint64</font>(par);
            }
            _regFRDeal(_ia, frDeal, cls[len-<font style="color:#b5cea8;">1</font>], sigHashOfSeller);
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> _createFRDeal(
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        FRClaims.Claim <font style="color:#569cd6;">memory</font> cl,
        IRegisterOfMembers _rom
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(DealsRepo.Deal <font style="color:#569cd6;">memory</font> frDeal) {

        frDeal = deal;

        frDeal.body.buyer = cl.claimer;
        frDeal.body.groupOfBuyer = _rom.groupRep(cl.claimer);
        frDeal.body.paid = (deal.body.paid * cl.ratio) / <font style="color:#b5cea8;">10000</font>;
        frDeal.body.par = (deal.body.par * cl.ratio) / <font style="color:#b5cea8;">10000</font>;
    }

    <font style="color:#569cd6;">function</font> _regFRDeal(
        IInvestmentAgreement _ia,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        FRClaims.Claim <font style="color:#569cd6;">memory</font> cl,
        <font style="color:#4ec9b0;">bytes32</font> sigHashOfSeller
    ) <font style="color:#569cd6;">private</font> {
        _ia.regDeal(deal);
        _ia.regSig(cl.claimer, cl.sigDate, cl.sigHash);

        <font style="color:#569cd6;">if</font> (deal.head.seller > <font style="color:#b5cea8;">0</font>)
            _ia.regSig(deal.head.seller, <font style="color:#4ec9b0;">uint48</font>(block.timestamp), sigHashOfSeller);
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## BallotsBox.sol

---

| |
|:---|
| **contracts/lib/books/BallotsBox.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title BallotsBox</font>
<font style="color:#6a9955;">/// @notice Library for ballot storage and vote aggregation.</font>
<font style="color:#569cd6;">library</font> BallotsBox {

    <font style="color:#6a9955;">/// @notice Vote attitudes.</font>
    <font style="color:#569cd6;">enum</font> AttitudeOfVote {
        All,
        Support,
        Against,
        Abstain
    }

    <font style="color:#6a9955;">/// @notice Ballot record of a voter.</font>
    <font style="color:#569cd6;">struct</font> Ballot {
        <font style="color:#4ec9b0;">uint40</font> acct;
        <font style="color:#4ec9b0;">uint8</font> attitude;
        <font style="color:#4ec9b0;">uint32</font> head;
        <font style="color:#4ec9b0;">uint64</font> weight;
        <font style="color:#4ec9b0;">uint48</font> sigDate;
        <font style="color:#4ec9b0;">uint64</font> blocknumber;
        <font style="color:#4ec9b0;">bytes32</font> sigHash;
        <font style="color:#4ec9b0;">uint</font>[] principals;
    }

    <font style="color:#6a9955;">/// @notice Aggregate case for an attitude.</font>
    <font style="color:#569cd6;">struct</font> Case {
        <font style="color:#4ec9b0;">uint32</font> sumOfHead;
        <font style="color:#4ec9b0;">uint64</font> sumOfWeight;
        <font style="color:#4ec9b0;">uint256</font>[] voters;
        <font style="color:#4ec9b0;">uint256</font>[] principals;
    }

    <font style="color:#6a9955;">/// @notice Ballot storage container.</font>
    <font style="color:#569cd6;">struct</font> Box {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Case) cases;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Ballot) ballots;
    }

    <font style="color:#569cd6;">error</font> BB_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Cast a vote if not already voted.</font>
    <font style="color:#6a9955;">/// @param box Storage box.</font>
    <font style="color:#6a9955;">/// @param acct Voter account id (> 0).</font>
    <font style="color:#6a9955;">/// @param attitude Vote attitude (Support/Against/Abstain).</font>
    <font style="color:#6a9955;">/// @param head Headcount weight (>= 0).</font>
    <font style="color:#6a9955;">/// @param weight Share weight (>= 0).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#6a9955;">/// @param principals Delegated principals list.</font>
    <font style="color:#569cd6;">function</font> castVote(
        Box <font style="color:#569cd6;">storage</font> box,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">uint</font> head,
        <font style="color:#4ec9b0;">uint</font> weight,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> principals
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {

        <font style="color:#569cd6;">if</font> (
            attitude != <font style="color:#4ec9b0;">uint8</font>(AttitudeOfVote.Support) &&
            attitude != <font style="color:#4ec9b0;">uint8</font>(AttitudeOfVote.Against) &&
            attitude != <font style="color:#4ec9b0;">uint8</font>(AttitudeOfVote.Abstain)
        ) {
            <font style="color:#569cd6;">revert</font> BB_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"BB_AttitudeOverflow"</font>));
        }

        Ballot <font style="color:#569cd6;">storage</font> b = box.ballots[acct];

        <font style="color:#569cd6;">if</font> (b.sigDate == <font style="color:#b5cea8;">0</font>) {
            box.ballots[acct] = Ballot({
                acct: <font style="color:#4ec9b0;">uint40</font>(acct),
                attitude: <font style="color:#4ec9b0;">uint8</font>(attitude),
                head: <font style="color:#4ec9b0;">uint32</font>(head),
                weight: <font style="color:#4ec9b0;">uint64</font>(weight),
                sigDate: <font style="color:#4ec9b0;">uint48</font>(block.timestamp),
                blocknumber: <font style="color:#4ec9b0;">uint64</font>(block.number),
                sigHash: sigHash,
                principals: principals
            });

            _pushToCase(box.cases[attitude], b);
            _pushToCase(box.cases[<font style="color:#4ec9b0;">uint8</font>(AttitudeOfVote.All)], b);

            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @dev Push ballot stats into an aggregate case.</font>
    <font style="color:#569cd6;">function</font> _pushToCase(Case <font style="color:#569cd6;">storage</font> c, Ballot <font style="color:#569cd6;">memory</font> b) <font style="color:#569cd6;">private</font> {
            c.sumOfHead += b.head;
            c.sumOfWeight += b.weight;
            c.voters.push(b.acct);

            <font style="color:#4ec9b0;">uint</font> len = b.principals.length;
            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                c.principals.push(b.principals[len - <font style="color:#b5cea8;">1</font>]);
                len--;
            }
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Read     ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Check whether an account has voted.</font>
    <font style="color:#6a9955;">/// @param box Storage box.</font>
    <font style="color:#6a9955;">/// @param acct Voter account id (> 0).</font>
    <font style="color:#569cd6;">function</font> isVoted(Box <font style="color:#569cd6;">storage</font> box, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> box.ballots[acct].sigDate > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Check whether an account voted for a given attitude.</font>
    <font style="color:#6a9955;">/// @param box Storage box.</font>
    <font style="color:#6a9955;">/// @param acct Voter account id (> 0).</font>
    <font style="color:#6a9955;">/// @param atti Attitude value.</font>
    <font style="color:#569cd6;">function</font> isVotedFor(
        Box <font style="color:#569cd6;">storage</font> box,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint256</font> atti
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> box.ballots[acct].attitude == atti;
    }

    <font style="color:#6a9955;">/// @notice Get aggregate case of an attitude.</font>
    <font style="color:#6a9955;">/// @param box Storage box.</font>
    <font style="color:#6a9955;">/// @param atti Attitude value.</font>
    <font style="color:#569cd6;">function</font> getCaseOfAttitude(Box <font style="color:#569cd6;">storage</font> box, <font style="color:#4ec9b0;">uint256</font> atti)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Case <font style="color:#569cd6;">memory</font> )
    {
        <font style="color:#569cd6;">return</font> box.cases[atti];
    }

    <font style="color:#6a9955;">/// @notice Get ballot of an account.</font>
    <font style="color:#6a9955;">/// @param box Storage box.</font>
    <font style="color:#6a9955;">/// @param acct Voter account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getBallot(Box <font style="color:#569cd6;">storage</font> box, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Ballot <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> box.ballots[acct];
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## Checkpoints.sol

---

| |
|:---|
| **contracts/lib/books/Checkpoints.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title Checkpoints</font>
<font style="color:#6a9955;">/// @notice Library for timestamped checkpoint history.</font>
<font style="color:#6a9955;">/// @dev Uses index 0 as metadata storage.</font>
<font style="color:#569cd6;">library</font> Checkpoints {

    <font style="color:#6a9955;">/// @notice Snapshot of values at a timestamp.</font>
    <font style="color:#569cd6;">struct</font> Checkpoint {
        <font style="color:#4ec9b0;">uint48</font> timestamp;
        <font style="color:#4ec9b0;">uint16</font> rate;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint64</font> points;
    }

    <font style="color:#6a9955;">// checkpoints[0] {</font>
    <font style="color:#6a9955;">//     timestamp: counter;</font>
    <font style="color:#6a9955;">//     rate: distrWeight;</font>
    <font style="color:#6a9955;">//     paid;</font>
    <font style="color:#6a9955;">//     par;</font>
    <font style="color:#6a9955;">//     points: distrPoints;</font>
    <font style="color:#6a9955;">// }</font>

    <font style="color:#6a9955;">/// @notice Checkpoint history mapping.</font>
    <font style="color:#569cd6;">struct</font> History {
        <font style="color:#569cd6;">mapping</font> (<font style="color:#4ec9b0;">uint256</font> => Checkpoint) checkpoints;
    }

    <font style="color:#569cd6;">error</font> Checkpoints_WrongDate(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Append a checkpoint at the current block time.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#6a9955;">/// @param rate Distribution rate (uint16 range).</font>
    <font style="color:#6a9955;">/// @param paid Paid amount (uint64 range).</font>
    <font style="color:#6a9955;">/// @param par Par amount (uint64 range).</font>
    <font style="color:#6a9955;">/// @param points Distribution points (uint64 range).</font>
    <font style="color:#569cd6;">function</font> push(
        History <font style="color:#569cd6;">storage</font> self,
        <font style="color:#4ec9b0;">uint</font> rate,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> points
    ) <font style="color:#569cd6;">public</font> {

        <font style="color:#4ec9b0;">uint256</font> pos = counterOfPoints(self);

        Checkpoint <font style="color:#569cd6;">memory</font> point = Checkpoint({
            timestamp: <font style="color:#4ec9b0;">uint48</font>(block.timestamp),
            rate: <font style="color:#4ec9b0;">uint16</font>(rate),
            paid: <font style="color:#4ec9b0;">uint64</font>(paid),
            par: <font style="color:#4ec9b0;">uint64</font>(par),
            points: <font style="color:#4ec9b0;">uint64</font>(points)
        });

        <font style="color:#569cd6;">if</font> (self.checkpoints[pos].timestamp == point.timestamp) {
            self.checkpoints[pos] = point;
        } <font style="color:#569cd6;">else</font> {
            self.checkpoints[pos+<font style="color:#b5cea8;">1</font>] = point;
            _increaseCounter(self);
        }
    }

    <font style="color:#6a9955;">/// @dev Increase checkpoint counter with wrap avoidance.</font>
    <font style="color:#569cd6;">function</font> _increaseCounter(History <font style="color:#569cd6;">storage</font> self)
        <font style="color:#569cd6;">public</font>
    {
        <font style="color:#569cd6;">unchecked</font> {
            self.checkpoints[<font style="color:#b5cea8;">0</font>].timestamp =
                self.checkpoints[<font style="color:#b5cea8;">0</font>].timestamp == type(<font style="color:#4ec9b0;">uint48</font>).max
                    ? <font style="color:#b5cea8;">1</font>
                    : self.checkpoints[<font style="color:#b5cea8;">0</font>].timestamp + <font style="color:#b5cea8;">1</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Update distribution parameters stored at index 0.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#6a9955;">/// @param rate Distribution rate (uint16 range).</font>
    <font style="color:#6a9955;">/// @param paid Paid amount (uint64 range).</font>
    <font style="color:#6a9955;">/// @param par Par amount (uint64 range).</font>
    <font style="color:#6a9955;">/// @param points Distribution points (uint64 range).</font>
    <font style="color:#569cd6;">function</font> updateDistrPoints(
        History <font style="color:#569cd6;">storage</font> self,
        <font style="color:#4ec9b0;">uint</font> rate,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> points
    ) <font style="color:#569cd6;">public</font> {
        Checkpoint <font style="color:#569cd6;">storage</font> c = self.checkpoints[<font style="color:#b5cea8;">0</font>];
        c.rate = <font style="color:#4ec9b0;">uint16</font>(rate);
        c.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        c.par = <font style="color:#4ec9b0;">uint64</font>(par);
        c.points = <font style="color:#4ec9b0;">uint64</font>(points);
    }

    <font style="color:#6a9955;">/// @notice Restore history from a list.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#6a9955;">/// @param list Checkpoints ordered by index.</font>
    <font style="color:#569cd6;">function</font> restoreHistory(History <font style="color:#569cd6;">storage</font> self, Checkpoint[] <font style="color:#569cd6;">memory</font> list) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            self.checkpoints[len] = list[len-<font style="color:#b5cea8;">1</font>];
            len--;
        }
        self.checkpoints[<font style="color:#b5cea8;">0</font>].timestamp = <font style="color:#4ec9b0;">uint48</font>(list.length);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Get number of checkpoints.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#569cd6;">function</font> counterOfPoints(History <font style="color:#569cd6;">storage</font> self)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>)
    {
        <font style="color:#569cd6;">return</font> self.checkpoints[<font style="color:#b5cea8;">0</font>].timestamp;
    }

    <font style="color:#6a9955;">/// @notice Get the latest checkpoint.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#569cd6;">function</font> latest(History <font style="color:#569cd6;">storage</font> self)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Checkpoint <font style="color:#569cd6;">memory</font> point)
    {
        point = self.checkpoints[counterOfPoints(self)];
    }

    <font style="color:#569cd6;">function</font> _average(<font style="color:#4ec9b0;">uint256</font> a, <font style="color:#4ec9b0;">uint256</font> b) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> (a & b) + ((a ^ b) >> <font style="color:#b5cea8;">1</font>);
    }

    <font style="color:#6a9955;">/// @notice Get checkpoint at or before a timestamp.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#6a9955;">/// @param timestamp Unix timestamp (<= block.timestamp).</font>
    <font style="color:#569cd6;">function</font> getAtDate(History <font style="color:#569cd6;">storage</font> self, <font style="color:#4ec9b0;">uint256</font> timestamp)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Checkpoint <font style="color:#569cd6;">memory</font> point)
    {
        <font style="color:#569cd6;">if</font> (timestamp > block.timestamp) {
            <font style="color:#569cd6;">revert</font> Checkpoints_WrongDate(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CP_FutureDate"</font>));
        }

        <font style="color:#4ec9b0;">uint256</font> high = counterOfPoints(self) + <font style="color:#b5cea8;">1</font>;
        <font style="color:#4ec9b0;">uint256</font> low = <font style="color:#b5cea8;">1</font>;
        <font style="color:#569cd6;">while</font> (low < high) {
            <font style="color:#4ec9b0;">uint256</font> mid = _average(low, high);
            <font style="color:#569cd6;">if</font> (self.checkpoints[mid].timestamp > timestamp) {
                high = mid;
            } <font style="color:#569cd6;">else</font> {
                low = mid + <font style="color:#b5cea8;">1</font>;
            }
        }
        <font style="color:#569cd6;">if</font> (high > <font style="color:#b5cea8;">1</font>) point = self.checkpoints[high - <font style="color:#b5cea8;">1</font>];
    }

    <font style="color:#6a9955;">/// @notice Get all checkpoints in history order.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#569cd6;">function</font> pointsOfHistory(History <font style="color:#569cd6;">storage</font> self)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> len = counterOfPoints(self);

        Checkpoint[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> Checkpoint[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            output[len-<font style="color:#b5cea8;">1</font>] = self.checkpoints[len];
            len--;
        }

        <font style="color:#569cd6;">return</font> output;
    }

    <font style="color:#6a9955;">/// @notice Get distribution parameters stored at index 0.</font>
    <font style="color:#6a9955;">/// @param self Storage history.</font>
    <font style="color:#569cd6;">function</font> getDistrPoints(History <font style="color:#569cd6;">storage</font> self)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> self.checkpoints[<font style="color:#b5cea8;">0</font>];
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## CondsRepo.sol

---

| |
|:---|
| **contracts/lib/books/CondsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title CondsRepo</font>
<font style="color:#6a9955;">/// @notice Library for condition encoding and evaluation.</font>
<font style="color:#569cd6;">library</font> CondsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.Bytes32Set;

    <font style="color:#6a9955;">/// @notice Logical operator codes.</font>
    <font style="color:#569cd6;">enum</font> LogOps {
        ZeroPoint,  <font style="color:#6a9955;">// 0</font>
        And,
        Or,
        Equal,
        NotEqual,   <font style="color:#6a9955;">// 4</font>
        AndAnd,
        OrOr,
        AndOr,
        OrAnd,
        EqEq,
        NeNe,
        EqNe,
        NeEq,
        AndEq,
        EqAnd,
        OrEq,
        EqOr,
        AndNe,
        NeAnd,
        OrNe,
        NeOr
    }

    <font style="color:#6a9955;">/// @notice Comparison operator codes.</font>
    <font style="color:#569cd6;">enum</font> ComOps {
        ZeroPoint,
        Equal,
        NotEqual,
        Bigger,
        Smaller,
        BiggerOrEqual,
        SmallerOrEqual
    }

    <font style="color:#6a9955;">/// @notice Encoded condition.</font>
    <font style="color:#569cd6;">struct</font> Cond {
        <font style="color:#4ec9b0;">uint32</font> seqOfCond;
        <font style="color:#4ec9b0;">uint8</font> logicOpr;
        <font style="color:#4ec9b0;">uint8</font> compOpr1;
        <font style="color:#4ec9b0;">uint64</font> para1;
        <font style="color:#4ec9b0;">uint8</font> compOpr2;
        <font style="color:#4ec9b0;">uint64</font> para2;
        <font style="color:#4ec9b0;">uint8</font> compOpr3;
        <font style="color:#4ec9b0;">uint64</font> para3;
    }

    <font style="color:#6a9955;">/// @notice Repository of conditions.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Cond) conds;
        EnumerableSet.Bytes32Set seqList;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">// ==== codify / parser ====</font>

    <font style="color:#6a9955;">/// @notice Parse encoded condition.</font>
    <font style="color:#6a9955;">/// @param sn Encoded condition bytes32.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Cond <font style="color:#569cd6;">memory</font> cond)
    {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        cond = Cond({
            seqOfCond: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            logicOpr: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            compOpr1: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">208</font>),
            para1: <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">144</font>),
            compOpr2: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">136</font>),
            para2: <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">72</font>),
            compOpr3: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">64</font>),
            para3: <font style="color:#4ec9b0;">uint64</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Encode condition into bytes32.</font>
    <font style="color:#6a9955;">/// @param cond Condition struct.</font>
    <font style="color:#569cd6;">function</font> codifyCond(Cond <font style="color:#569cd6;">memory</font> cond) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn)
    {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            cond.seqOfCond,
                            cond.logicOpr,
                            cond.compOpr1,
                            cond.para1,
                            cond.compOpr2,
                            cond.para2,
                            cond.compOpr3,
                            cond.para3);

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== create / reg ====</font>
    <font style="color:#6a9955;">/// @notice Create and register a condition.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param sn Encoded condition bytes32.</font>
    <font style="color:#569cd6;">function</font> createCond(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font> seqOfCond)
    {
        seqOfCond = regCond(repo, snParser(sn));
    }

    <font style="color:#6a9955;">/// @notice Register a condition struct.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param cond Condition struct.</font>
    <font style="color:#569cd6;">function</font> regCond(Repo <font style="color:#569cd6;">storage</font> repo, Cond <font style="color:#569cd6;">memory</font> cond) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font> seqOfCond)
    {
        cond.seqOfCond = _increaseCounterOfConds(repo);
        repo.conds[cond.seqOfCond] = cond;
        repo.seqList.add(codifyCond(cond));
        seqOfCond = cond.seqOfCond;
    }

    <font style="color:#6a9955;">/// @dev Increase condition counter.</font>
    <font style="color:#569cd6;">function</font> _increaseCounterOfConds(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>)
    {
        repo.conds[<font style="color:#b5cea8;">0</font>].seqOfCond++;
        <font style="color:#569cd6;">return</font> repo.conds[<font style="color:#b5cea8;">0</font>].seqOfCond;
    }

    <font style="color:#6a9955;">/// @notice Remove a condition by sequence number.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfCond Condition sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> removeCond(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfCond) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#569cd6;">if</font> (repo.seqList.remove(codifyCond(repo.conds[seqOfCond])))
        {
            <font style="color:#569cd6;">delete</font> repo.conds[seqOfCond];
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#569cd6;">error</font> CondsRepo_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##   Write I/O  ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @notice Get number of conditions.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> counterOfConds(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font> seqOfCond) {
        seqOfCond = repo.conds[<font style="color:#b5cea8;">0</font>].seqOfCond;
    }

    <font style="color:#6a9955;">/// @notice Get all conditions.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getConds(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Cond[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> len = repo.seqList.length();
        Cond[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> Cond[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            output[len -<font style="color:#b5cea8;">1</font>] = repo.conds[len];
            len--;
        }

        <font style="color:#569cd6;">return</font> output;
    }

    <font style="color:#6a9955;">/// @notice Evaluate a comparison.</font>
    <font style="color:#6a9955;">/// @param compOpr Comparison operator (see ComOps).</font>
    <font style="color:#6a9955;">/// @param para Comparison parameter.</font>
    <font style="color:#6a9955;">/// @param data Data to compare.</font>
    <font style="color:#569cd6;">function</font> checkCond(
        <font style="color:#4ec9b0;">uint</font> compOpr,
        <font style="color:#4ec9b0;">uint</font> para,
        <font style="color:#4ec9b0;">uint</font> data
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (compOpr == <font style="color:#4ec9b0;">uint8</font>(ComOps.Equal)) flag = data == para;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (compOpr == <font style="color:#4ec9b0;">uint8</font>(ComOps.NotEqual)) flag = data != para;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (compOpr == <font style="color:#4ec9b0;">uint8</font>(ComOps.Bigger)) flag = data > para;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (compOpr == <font style="color:#4ec9b0;">uint8</font>(ComOps.Smaller)) flag = data < para;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (compOpr == <font style="color:#4ec9b0;">uint8</font>(ComOps.BiggerOrEqual)) flag = data >= para;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (compOpr == <font style="color:#4ec9b0;">uint8</font>(ComOps.SmallerOrEqual)) flag = data <= para;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> CondsRepo_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CR_CompOprOverflow"</font>));
    }

    <font style="color:#6a9955;">/// @notice Evaluate a single condition.</font>
    <font style="color:#569cd6;">function</font> checkSoleCond(
        Cond <font style="color:#569cd6;">memory</font> cond,
        <font style="color:#4ec9b0;">uint</font> data
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = checkCond(cond.compOpr1, cond.para1, data);
    }

    <font style="color:#6a9955;">/// @notice Evaluate a condition with two inputs.</font>
    <font style="color:#569cd6;">function</font> checkCondsOfTwo(
        Cond <font style="color:#569cd6;">memory</font> cond,
        <font style="color:#4ec9b0;">uint</font> data1,
        <font style="color:#4ec9b0;">uint</font> data2
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#4ec9b0;">bool</font> flag1;
        <font style="color:#4ec9b0;">bool</font> flag2;

        flag1 = checkCond(cond.compOpr1, cond.para1, data1);
        flag2 = checkCond(cond.compOpr2, cond.para2, data2);

        <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.And)) flag = flag1 && flag2;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.Or)) flag = flag1 || flag2;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.Equal)) flag = flag1 == flag2;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.NotEqual)) flag = flag1 != flag2;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> CondsRepo_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CR_LogicOprOverflow"</font>));
    }

    <font style="color:#6a9955;">/// @notice Evaluate a condition with three inputs.</font>
    <font style="color:#569cd6;">function</font> checkCondsOfThree(
        Cond <font style="color:#569cd6;">memory</font> cond,
        <font style="color:#4ec9b0;">uint</font> data1,
        <font style="color:#4ec9b0;">uint</font> data2,
        <font style="color:#4ec9b0;">uint</font> data3
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#4ec9b0;">bool</font> flag1;
        <font style="color:#4ec9b0;">bool</font> flag2;
        <font style="color:#4ec9b0;">bool</font> flag3;

        flag1 = checkCond(cond.compOpr1, cond.para1, data1);
        flag2 = checkCond(cond.compOpr2, cond.para2, data2);
        flag3 = checkCond(cond.compOpr3, cond.para3, data3);

        <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.AndAnd)) flag = flag1 && flag2 && flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.OrOr)) flag = flag1 || flag2 || flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.AndOr)) flag = flag1 && flag2 || flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.OrAnd)) flag = flag1 || flag2 && flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.EqEq)) flag = flag1 == flag2 == flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.NeNe)) flag = flag1 != flag2 != flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.EqNe)) flag = flag1 == flag2 != flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.NeEq)) flag = flag1 != flag2 == flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.AndEq)) flag = flag1 && flag2 == flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.EqAnd)) flag = flag1 == flag2 && flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.OrEq)) flag = flag1 || flag2 == flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.EqOr)) flag = flag1 == flag2 || flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.AndNe)) flag = flag1 && flag2 != flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.NeAnd)) flag = flag1 != flag2 && flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.OrNe)) flag = flag1 || flag2 != flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(LogOps.NeOr)) flag = flag1 != flag2 || flag3;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> CondsRepo_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"CR_LogicOprOverflow"</font>));
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## DealsRepo.sol

---

| |
|:---|
| **contracts/lib/books/DealsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./MotionsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./SharesRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/common/components/IMeetingMinutes.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/ros/IRegisterOfShares.sol"</font>;

<font style="color:#6a9955;">/// @title DealsRepo</font>
<font style="color:#6a9955;">/// @notice Repository for investment agreements and deal lifecycle.</font>
<font style="color:#569cd6;">library</font> DealsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">// _deals[0].head {</font>
    <font style="color:#6a9955;">//     seqOfDeal: counterOfClosedDeal;</font>
    <font style="color:#6a9955;">//     preSeq: counterOfDeal;</font>
    <font style="color:#6a9955;">//     typeOfDeal: typeOfIA;</font>
    <font style="color:#6a9955;">// }    </font>

    <font style="color:#6a9955;">/// @notice Deal types.</font>
    <font style="color:#569cd6;">enum</font> TypeOfDeal {
        ZeroPoint,
        CapitalIncrease,
        ShareTransferExt,
        ShareTransferInt,
        PreEmptive,
        TagAlong,
        DragAlong,
        FirstRefusal,
        FreeGift
    }

    <font style="color:#6a9955;">/// @notice Composite IA type based on deal mix.</font>
    <font style="color:#569cd6;">enum</font> TypeOfIA {
        ZeroPoint,
        CapitalIncrease,
        ShareTransferExt,
        ShareTransferInt,
        CI_STint,
        SText_STint,
        CI_SText_STint,
        CI_SText
    }

    <font style="color:#6a9955;">/// @notice Deal lifecycle state.</font>
    <font style="color:#569cd6;">enum</font> StateOfDeal {
        Drafting,
        Locked,
        Cleared,
        Closed,
        Terminated
    }

    <font style="color:#6a9955;">/// @notice Deal head fields.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint8</font> typeOfDeal;
        <font style="color:#4ec9b0;">uint16</font> seqOfDeal;
        <font style="color:#4ec9b0;">uint16</font> preSeq;
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint40</font> seller;
        <font style="color:#4ec9b0;">uint32</font> priceOfPaid;
        <font style="color:#4ec9b0;">uint32</font> priceOfPar;
        <font style="color:#4ec9b0;">uint48</font> closingDeadline;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
    }

    <font style="color:#6a9955;">/// @notice Deal body fields.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">uint40</font> buyer;
        <font style="color:#4ec9b0;">uint40</font> groupOfBuyer;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
        <font style="color:#4ec9b0;">bool</font> flag;
    }

    <font style="color:#6a9955;">/// @notice Full deal record.</font>
    <font style="color:#569cd6;">struct</font> Deal {
        Head head;
        Body body;
        <font style="color:#4ec9b0;">bytes32</font> hashLock;
    }

    <font style="color:#6a9955;">/// @notice Repository of deals and swaps.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// seqOfDeal => Deal</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Deal) deals;
        <font style="color:#6a9955;">//seqOfDeal => seqOfShare => bool</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => <font style="color:#4ec9b0;">bool</font>)) priceDiffRequested;
        EnumerableSet.UintSet seqList;
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Error     ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">error</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DealsRepo_ZeroValue(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DealsRepo_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DealsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DealsRepo_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Modifier   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Ensure deal is cleared.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">modifier</font> onlyCleared(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) {
        <font style="color:#569cd6;">if</font> (
            repo.deals[seqOfDeal].body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Cleared)
        ) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DealNotCleared"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">/// @notice Ensure deal exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">modifier</font> dealExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDeal) {
        <font style="color:#569cd6;">if</font> (!isDeal(repo, seqOfDeal)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_NoSuchDeal"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Parse deal head from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed head bytes32.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head = Head({
            typeOfDeal: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">248</font>),
            seqOfDeal: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">232</font>),
            preSeq: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            classOfShare: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">200</font>),
            seqOfShare: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">168</font>),
            seller: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">128</font>),
            priceOfPaid: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">96</font>),
            priceOfPar: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">64</font>),
            closingDeadline: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">16</font>),
            votingWeight: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });

    }

    <font style="color:#6a9955;">/// @notice Pack deal head into bytes32.</font>
    <font style="color:#6a9955;">/// @param head Deal head.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.typeOfDeal,
                            head.seqOfDeal,
                            head.preSeq,
                            head.classOfShare,
                            head.seqOfShare,
                            head.seller,
                            head.priceOfPaid,
                            head.priceOfPaid,
                            head.closingDeadline,
                            head.votingWeight);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">/// @notice Add a deal from packed head.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param sn Packed head bytes32.</font>
    <font style="color:#6a9955;">/// @param buyer Buyer user number.</font>
    <font style="color:#6a9955;">/// @param groupOfBuyer Buyer group number.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight.</font>
    <font style="color:#569cd6;">function</font> addDeal(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> sn,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> groupOfBuyer,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> distrWeight
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font> seqOfDeal)  {

        Deal <font style="color:#569cd6;">memory</font> deal;

        deal.head = snParser(sn);

        deal.body.buyer = <font style="color:#4ec9b0;">uint40</font>(buyer);
        deal.body.groupOfBuyer = <font style="color:#4ec9b0;">uint40</font>(groupOfBuyer);
        deal.body.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        deal.body.par = <font style="color:#4ec9b0;">uint64</font>(par);
        deal.body.distrWeight = <font style="color:#4ec9b0;">uint16</font>(distrWeight);

        seqOfDeal = regDeal(repo, deal);
    }

    <font style="color:#6a9955;">/// @notice Register a deal in storage.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param deal Deal record.</font>
    <font style="color:#569cd6;">function</font> regDeal(Repo <font style="color:#569cd6;">storage</font> repo, Deal <font style="color:#569cd6;">memory</font> deal)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font> seqOfDeal)
    {
        <font style="color:#569cd6;">if</font> (deal.body.par == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> DealsRepo_ZeroValue(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroPar"</font>));
        }

        <font style="color:#569cd6;">if</font> (deal.body.par < deal.body.paid) {
            <font style="color:#569cd6;">revert</font> DealsRepo_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_PaidExceedsPar"</font>));
        }

        deal.head.seqOfDeal = _increaseCounterOfDeal(repo);
        repo.seqList.add(deal.head.seqOfDeal);

        repo.deals[deal.head.seqOfDeal] = Deal({
            head: deal.head,
            body: deal.body,
            hashLock: <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#b5cea8;">0</font>)
        });
        seqOfDeal = deal.head.seqOfDeal;
    }

    <font style="color:#569cd6;">function</font> _increaseCounterOfDeal(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font> seqOfDeal){
        repo.deals[<font style="color:#b5cea8;">0</font>].head.preSeq++;
        seqOfDeal = repo.deals[<font style="color:#b5cea8;">0</font>].head.preSeq;
    }

    <font style="color:#6a9955;">/// @notice Delete a deal by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> delDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (repo.seqList.remove(seqOfDeal)) {
            <font style="color:#569cd6;">delete</font> repo.deals[seqOfDeal];
            repo.deals[<font style="color:#b5cea8;">0</font>].head.preSeq--;
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Lock a deal subject.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> lockDealSubject(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (repo.deals[seqOfDeal].body.state == <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Drafting)) {
            repo.deals[seqOfDeal].body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Locked);
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Release a deal subject back to drafting.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> releaseDealSubject(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#4ec9b0;">uint8</font> state = repo.deals[seqOfDeal].body.state;

        <font style="color:#569cd6;">if</font> ( state < <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Closed) ) {

            repo.deals[seqOfDeal].body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Drafting);
            flag = <font style="color:#569cd6;">true</font>;

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (state == <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Terminated)) {

            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Clear a deal with hash lock and deadline.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#6a9955;">/// @param closingDeadline Closing deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> clearDealCP(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> closingDeadline
    ) <font style="color:#569cd6;">public</font> {
        Deal <font style="color:#569cd6;">storage</font> deal = repo.deals[seqOfDeal];

        <font style="color:#569cd6;">if</font> (deal.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Locked)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DealNotLocked"</font>));
        }

        deal.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Cleared);
        deal.hashLock = hashLock;

        <font style="color:#569cd6;">if</font> (closingDeadline > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (block.timestamp < closingDeadline)
                deal.head.closingDeadline = <font style="color:#4ec9b0;">uint48</font>(closingDeadline);
            <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DeadlineNotFuture"</font>));
        }
    }

    <font style="color:#6a9955;">/// @notice Close a deal using hash preimage.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param hashKey Preimage string.</font>
    <font style="color:#569cd6;">function</font> closeDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey)
        <font style="color:#569cd6;">public</font> onlyCleared(repo, seqOfDeal) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#569cd6;">if</font> (repo.deals[seqOfDeal].hashLock != keccak256(<font style="color:#4ec9b0;">bytes</font>(hashKey))) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_HashKeyNotCorrect"</font>));
        }

        <font style="color:#569cd6;">return</font> _closeDeal(repo, seqOfDeal);
    }

    <font style="color:#6a9955;">/// @notice Close a locked deal directly.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> directCloseDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDeal)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#569cd6;">if</font> (repo.deals[seqOfDeal].body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Locked)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DealNotLocked"</font>));
        }

        <font style="color:#569cd6;">return</font> _closeDeal(repo, seqOfDeal);
    }

    <font style="color:#569cd6;">function</font> _closeDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDeal)
        <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag)
    {

        Deal <font style="color:#569cd6;">storage</font> deal = repo.deals[seqOfDeal];

        <font style="color:#569cd6;">if</font> (block.timestamp >= deal.head.closingDeadline) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_MissedDeadline"</font>));
        }

        deal.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Closed);

        _increaseCounterOfClosedDeal(repo);

        flag = (counterOfDeal(repo) == counterOfClosedDeal(repo));
    }

    <font style="color:#6a9955;">/// @notice Terminate a locked/cleared deal.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> terminateDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag){
        Body <font style="color:#569cd6;">storage</font> body = repo.deals[seqOfDeal].body;

        <font style="color:#569cd6;">if</font> (body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Locked) && body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Cleared)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DealNotLockedOrCleared"</font>));
        }

        body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Terminated);

        _increaseCounterOfClosedDeal(repo);
        flag = (counterOfDeal(repo) == counterOfClosedDeal(repo));
    }

    <font style="color:#6a9955;">/// @notice Accept a free gift deal.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> takeGift(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        Deal <font style="color:#569cd6;">storage</font> deal = repo.deals[seqOfDeal];

        <font style="color:#569cd6;">if</font> (deal.head.typeOfDeal != <font style="color:#4ec9b0;">uint8</font>(TypeOfDeal.FreeGift)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_NotGiftDeal"</font>));
        }

        <font style="color:#569cd6;">if</font> (repo.deals[deal.head.preSeq].body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Closed)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_CapitalIncreaseNotClosed"</font>));
        }

        <font style="color:#569cd6;">if</font> (deal.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Locked)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DealNotLocked"</font>));
        }

        deal.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Closed);

        _increaseCounterOfClosedDeal(repo);
        flag = (counterOfDeal(repo) == counterOfClosedDeal(repo));
    }

    <font style="color:#569cd6;">function</font> _increaseCounterOfClosedDeal(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">private</font> {
        repo.deals[<font style="color:#b5cea8;">0</font>].head.seqOfDeal++;
    }

    <font style="color:#6a9955;">/// @notice Calculate composite IA type.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> calTypeOfIA(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint</font>[<font style="color:#b5cea8;">3</font>] <font style="color:#569cd6;">memory</font> types;

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList = repo.seqList.values();
        <font style="color:#4ec9b0;">uint</font> len = seqList.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint</font> typeOfDeal = repo.deals[seqList[len-<font style="color:#b5cea8;">1</font>]].head.typeOfDeal;
            len--;

            <font style="color:#569cd6;">if</font> (typeOfDeal == <font style="color:#b5cea8;">1</font>) {
                <font style="color:#569cd6;">if</font> (types[<font style="color:#b5cea8;">0</font>] == <font style="color:#b5cea8;">0</font>) types[<font style="color:#b5cea8;">0</font>] = <font style="color:#b5cea8;">1</font>;
                <font style="color:#569cd6;">continue</font>;
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (typeOfDeal == <font style="color:#b5cea8;">2</font>) {
                <font style="color:#569cd6;">if</font> (types[<font style="color:#b5cea8;">1</font>] == <font style="color:#b5cea8;">0</font>) types[<font style="color:#b5cea8;">1</font>] = <font style="color:#b5cea8;">2</font>;
                <font style="color:#569cd6;">continue</font>;
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (typeOfDeal == <font style="color:#b5cea8;">3</font>) {
                <font style="color:#569cd6;">if</font> (types[<font style="color:#b5cea8;">2</font>] == <font style="color:#b5cea8;">0</font>) types[<font style="color:#b5cea8;">2</font>] = <font style="color:#b5cea8;">3</font>;
                <font style="color:#569cd6;">continue</font>;
            }
        }

        <font style="color:#4ec9b0;">uint8</font> sum = <font style="color:#4ec9b0;">uint8</font>(types[<font style="color:#b5cea8;">0</font>] + types[<font style="color:#b5cea8;">1</font>] + types[<font style="color:#b5cea8;">2</font>]);
        repo.deals[<font style="color:#b5cea8;">0</font>].head.typeOfDeal = (sum == <font style="color:#b5cea8;">3</font>)
                ? (types[<font style="color:#b5cea8;">2</font>] == <font style="color:#b5cea8;">0</font>)
                    ? <font style="color:#b5cea8;">7</font>
                    : <font style="color:#b5cea8;">3</font>
                : sum;
    }

    <font style="color:#6a9955;">/// @notice Close an approved deal by buyer payment.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param caller Buyer user number.</font>
    <font style="color:#569cd6;">function</font> payOffApprovedDeal(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag){

        Deal <font style="color:#569cd6;">storage</font> deal = repo.deals[seqOfDeal];

        <font style="color:#569cd6;">if</font> (deal.head.typeOfDeal == <font style="color:#4ec9b0;">uint8</font>(TypeOfDeal.FreeGift)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_FreeGift"</font>));
        }

        <font style="color:#569cd6;">if</font> (caller != deal.body.buyer) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_NotBuyer"</font>));
        }

        <font style="color:#569cd6;">if</font> (deal.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Locked) &&
            deal.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Cleared)) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DealNotLockedOrCleared"</font>));
        }

        <font style="color:#569cd6;">if</font> (block.timestamp >= deal.head.closingDeadline) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_MissedClosingDeadline"</font>));
        }

        deal.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfDeal.Closed);

        _increaseCounterOfClosedDeal(repo);

        flag = (counterOfDeal(repo) == counterOfClosedDeal(repo));
    }

    <font style="color:#6a9955;">/// @notice Request price difference for a share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> requestPriceDiff(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> dealExist(repo, seqOfDeal) {
        <font style="color:#569cd6;">if</font> (repo.priceDiffRequested[seqOfDeal][seqOfShare]) {
            <font style="color:#569cd6;">revert</font> DealsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_RedundantRequests"</font>));
        }
        repo.priceDiffRequested[seqOfDeal][seqOfShare] = <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">//  ##########################</font>
    <font style="color:#6a9955;">//  ##       Read I/O       ##</font>
    <font style="color:#6a9955;">//  ##########################</font>

    <font style="color:#6a9955;">/// @notice Get composite IA type.</font>
    <font style="color:#6a9955;">/// @notice Get composite IA type.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getTypeOfIA(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {
        <font style="color:#569cd6;">return</font> repo.deals[<font style="color:#b5cea8;">0</font>].head.typeOfDeal;
    }

    <font style="color:#6a9955;">/// @notice Get deal counter.</font>
    <font style="color:#6a9955;">/// @notice Get deal counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> counterOfDeal(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> repo.deals[<font style="color:#b5cea8;">0</font>].head.preSeq;
    }

    <font style="color:#6a9955;">/// @notice Get closed deal counter.</font>
    <font style="color:#6a9955;">/// @notice Get closed deal counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> counterOfClosedDeal(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> repo.deals[<font style="color:#b5cea8;">0</font>].head.seqOfDeal;
    }

    <font style="color:#6a9955;">/// @notice Check whether a deal exists.</font>
    <font style="color:#6a9955;">/// @notice Check whether a deal exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">function</font> isDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfDeal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.seqList.contains(seqOfDeal);
    }

    <font style="color:#6a9955;">/// @notice Get deal by sequence.</font>
    <font style="color:#6a9955;">/// @notice Get deal by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seq Deal sequence.</font>
    <font style="color:#569cd6;">function</font> getDeal(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seq)
        <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> dealExist(repo, seq) <font style="color:#569cd6;">returns</font> (Deal <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.deals[seq];
    }

    <font style="color:#6a9955;">/// @notice Get deal sequence list.</font>
    <font style="color:#6a9955;">/// @notice Get deal sequence list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getSeqList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.seqList.values();
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## DelegateMap.sol

---

| |
|:---|
| **contracts/lib/books/DelegateMap.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rom/IRegisterOfMembers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rod/IRegisterOfDirectors.sol"</font>;

<font style="color:#6a9955;">/// @title DelegateMap</font>
<font style="color:#6a9955;">/// @notice Library for managing delegation relationships and derived voting weight.</font>
<font style="color:#569cd6;">library</font> DelegateMap {

    <font style="color:#6a9955;">/// @notice Aggregated info for delegated leaves.</font>
    <font style="color:#569cd6;">struct</font> LeavesInfo {
        <font style="color:#4ec9b0;">uint64</font> weight;
        <font style="color:#4ec9b0;">uint32</font> emptyHead;
    }

    <font style="color:#6a9955;">/// @notice Voter delegation data.</font>
    <font style="color:#569cd6;">struct</font> Voter {
        <font style="color:#4ec9b0;">uint40</font> delegate;
        <font style="color:#4ec9b0;">uint64</font> weight;
        <font style="color:#4ec9b0;">uint64</font> repWeight;
        <font style="color:#4ec9b0;">uint32</font> repHead;
        <font style="color:#4ec9b0;">uint</font>[] principals;
    }

    <font style="color:#6a9955;">/// @notice Delegate map storage.</font>
    <font style="color:#569cd6;">struct</font> Map {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Voter) voters;
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Error    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#569cd6;">error</font> DelegateMap_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Entrust a delegate for a principal.</font>
    <font style="color:#6a9955;">/// @param map Storage map.</font>
    <font style="color:#6a9955;">/// @param principal Principal account id (> 0).</font>
    <font style="color:#6a9955;">/// @param delegate Delegate account id (> 0, != principal).</font>
    <font style="color:#6a9955;">/// @param weight Voting weight of principal (>= 0).</font>
    <font style="color:#569cd6;">function</font> entrustDelegate(
        Map <font style="color:#569cd6;">storage</font> map,
        <font style="color:#4ec9b0;">uint</font> principal,
        <font style="color:#4ec9b0;">uint</font> delegate,
        <font style="color:#4ec9b0;">uint</font> weight
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (principal == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> DelegateMap_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DM_ZeroPrincipal"</font>));
        }
        <font style="color:#569cd6;">if</font> (delegate == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> DelegateMap_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DM_ZeroDelegate"</font>));
        }
        <font style="color:#569cd6;">if</font> (principal == delegate) {
            <font style="color:#569cd6;">revert</font> DelegateMap_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DM_SelfDelegate"</font>));
        }

        <font style="color:#569cd6;">if</font> (map.voters[principal].delegate == <font style="color:#b5cea8;">0</font> &&
            map.voters[delegate].delegate == <font style="color:#b5cea8;">0</font>)
        {
            Voter <font style="color:#569cd6;">storage</font> p = map.voters[principal];
            Voter <font style="color:#569cd6;">storage</font> d = map.voters[delegate];

            p.delegate = <font style="color:#4ec9b0;">uint40</font>(delegate);
            p.weight = <font style="color:#4ec9b0;">uint64</font>(weight);

            d.repHead += (p.repHead + <font style="color:#b5cea8;">1</font>);
            d.repWeight += (p.repWeight + p.weight);

            d.principals.push(<font style="color:#4ec9b0;">uint40</font>(principal));
            _consolidatePrincipals(p.principals, d);

            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @dev Append principals list to delegate record.</font>
    <font style="color:#569cd6;">function</font> _consolidatePrincipals(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> principals, Voter <font style="color:#569cd6;">storage</font> d) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">uint</font> len = principals.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            d.principals.push(principals[len-<font style="color:#b5cea8;">1</font>]);
            len--;
        }
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Read     ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Resolve the final delegate of an account (walks delegation chain).</font>
    <font style="color:#6a9955;">/// @param map Storage map.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getDelegateOf(Map <font style="color:#569cd6;">storage</font> map, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font> d)
    {
        <font style="color:#569cd6;">while</font> (acct > <font style="color:#b5cea8;">0</font>) {
            d = acct;
            acct = map.voters[d].delegate;
        }
    }

    <font style="color:#6a9955;">/// @notice Update delegate weights based on member votes at a date.</font>
    <font style="color:#6a9955;">/// @param map Storage map.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param baseDate Snapshot timestamp.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> updateLeavesWeightAtDate(Map <font style="color:#569cd6;">storage</font> map, <font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> baseDate, IRegisterOfMembers _rom)
        <font style="color:#569cd6;">public</font>
    {
        LeavesInfo <font style="color:#569cd6;">memory</font> info;
        Voter <font style="color:#569cd6;">storage</font> voter = map.voters[acct];

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> leaves = voter.principals;
        <font style="color:#4ec9b0;">uint256</font> len = leaves.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint64</font> w = _rom.votesAtDate(leaves[len-<font style="color:#b5cea8;">1</font>], baseDate);
            <font style="color:#569cd6;">if</font> (w > <font style="color:#b5cea8;">0</font>) {
                info.weight += w;
            } <font style="color:#569cd6;">else</font> {
                info.emptyHead++;
            }
            len--;
        }

        voter.weight = _rom.votesAtDate(acct, baseDate);
        voter.repWeight = info.weight;
        voter.repHead = <font style="color:#4ec9b0;">uint32</font>(leaves.length) - info.emptyHead;
    }

    <font style="color:#6a9955;">/// @notice Update delegate headcount based on director membership.</font>
    <font style="color:#6a9955;">/// @param map Storage map.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param _rod Register of directors.</font>
    <font style="color:#569cd6;">function</font> updateLeavesHeadcountOfDirectors(Map <font style="color:#569cd6;">storage</font> map, <font style="color:#4ec9b0;">uint256</font> acct, IRegisterOfDirectors _rod)
        <font style="color:#569cd6;">public</font>
    {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> leaves = map.voters[acct].principals;
        <font style="color:#4ec9b0;">uint256</font> len = leaves.length;

        <font style="color:#4ec9b0;">uint32</font> repHead;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (_rod.isDirector(leaves[len-<font style="color:#b5cea8;">1</font>])) repHead++;
            len--;
        }

        map.voters[acct].repHead = repHead;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## DocsRepo.sol

---

| |
|:---|
| **contracts/lib/books/DocsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#6a9955;">/// @notice typeOfDoc numbering rules (uint32): four 8-bit segments shown as two hex chars each.</font>
<font style="color:#6a9955;">/// @dev Bit ranges (MSB -> LSB):</font>
<font style="color:#6a9955;">///      (0~7)   Domain: RegCenter, Comps, Funds, OpenZeppelin, ...</font>
<font style="color:#6a9955;">///      (8~15)  Category: Libraries, Routers, Keepers, Registers, Utils, ...</font>
<font style="color:#6a9955;">///      (16~23) Feature: GeneralKeeper, ROAKeeper, ROCKeeper, ...</font>
<font style="color:#6a9955;">///      (24~32) Interface variants: e.g. GeneralKeeper -> PrivateComp, ListedComp, ListedOpenComp, ...</font>
<font style="color:#6a9955;">/// @dev For proxy upgrades, the top 24 bits (0~23) must match; only interface variants may differ.</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title DocsRepo - TypeOfDoc: 0x01010201 (Domain: RegCenter, Category: Libraries, Feature: DocsRepo, Interface: v1)</font>
<font style="color:#6a9955;">/// @notice In-memory indexed repository of document templates, proxies, and clones.</font>
<font style="color:#6a9955;">/// @dev Stores document metadata (Head) and body addresses in nested mappings keyed by</font>
<font style="color:#6a9955;">///      typeOfDoc -> version -> seqOfDoc. Provides registration, upgrade, and query helpers.</font>

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/common/access/IOwnable.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#569cd6;">library</font> DocsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice Document header metadata encoded in a 32-byte identifier.</font>
    <font style="color:#6a9955;">/// @dev Fields are packed when encoded via {codifyHead}.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint32</font> typeOfDoc;
        <font style="color:#4ec9b0;">uint32</font> version;
        <font style="color:#4ec9b0;">uint64</font> seqOfDoc;
        <font style="color:#4ec9b0;">uint40</font> author;
        <font style="color:#4ec9b0;">uint40</font> creator;
        <font style="color:#4ec9b0;">uint48</font> createDate;
    }

    <font style="color:#6a9955;">/// @notice Minimal body reference for a document instance.</font>
    <font style="color:#6a9955;">/// @dev `version` and `seq` are used to link upgrades.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">uint32</font> version;
        <font style="color:#4ec9b0;">uint64</font> seq;
        <font style="color:#4ec9b0;">address</font> addr;
    }

    <font style="color:#6a9955;">/// @notice Full document tuple (header + body).</font>
    <font style="color:#569cd6;">struct</font> Doc {
        Head head;
        <font style="color:#4ec9b0;">address</font> body;
    }

    <font style="color:#6a9955;">/// @notice Repository storage container.</font>
    <font style="color:#6a9955;">/// @dev `bodies[type][version][seq]` stores the body address for a specific doc instance.</font>
    <font style="color:#6a9955;">///      `heads[body]` stores the header for a given body address.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// typeOfDoc => version => seqOfDoc => Body</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Body))) bodies;
        <font style="color:#6a9955;">// body address => Head</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => Head) heads;
        <font style="color:#6a9955;">// typeOfDoc set</font>
        EnumerableSet.UintSet typesList;
    }

    <font style="color:#6a9955;">//#####################</font>
    <font style="color:#6a9955;">//##  Error & Event  ##</font>
    <font style="color:#6a9955;">//#####################</font>

    <font style="color:#569cd6;">error</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DocsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DocsRepo_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Decode a document identifier into a {Head}.</font>
    <font style="color:#6a9955;">/// @param sn Encoded document identifier.</font>
    <font style="color:#6a9955;">/// @return head Decoded document header.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head.typeOfDoc = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">224</font>);
        head.version = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">192</font>);
        head.seqOfDoc = <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">128</font>);
        head.author = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">88</font>);
    }

    <font style="color:#6a9955;">/// @notice Encode a {Head} into a 32-byte identifier.</font>
    <font style="color:#6a9955;">/// @param head Document header.</font>
    <font style="color:#6a9955;">/// @return sn Encoded identifier.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.typeOfDoc,
                            head.version,
                            head.seqOfDoc,
                            head.author,
                            head.creator,
                            head.createDate);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#569cd6;">function</font> getTypeByName(<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> name) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> typeOfDoc) {
        <font style="color:#569cd6;">if</font> (name.length == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroDocName"</font>));
        typeOfDoc = <font style="color:#4ec9b0;">uint32</font>(<font style="color:#4ec9b0;">uint</font>(keccak256(name)));
    }

    <font style="color:#6a9955;">/// @notice Register a template contract for a document type.</font>
    <font style="color:#6a9955;">/// @dev Creates version=1..n and seqOfDoc=0 for templates.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type (must be > 0).</font>
    <font style="color:#6a9955;">/// @param body Template contract address (non-zero, not registered).</font>
    <font style="color:#6a9955;">/// @param author Author userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @param caller Creator userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @return head The created template header.</font>
    <font style="color:#569cd6;">function</font> setTemplate(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">uint</font> author,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head) {
        head.typeOfDoc = <font style="color:#4ec9b0;">uint32</font>(typeOfDoc);
        head.author = <font style="color:#4ec9b0;">uint40</font>(author);
        head.creator = <font style="color:#4ec9b0;">uint40</font>(caller);

        <font style="color:#569cd6;">if</font> (body == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroBody"</font>));

        <font style="color:#569cd6;">if</font> (repo.heads[body].typeOfDoc != <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_AlreadyRegistered"</font>));

        <font style="color:#569cd6;">if</font> (head.typeOfDoc == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroType"</font>));

        <font style="color:#569cd6;">if</font> (head.author == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroAuthor"</font>));

        <font style="color:#569cd6;">if</font> (head.creator == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroCreator"</font>));

        repo.typesList.add(head.typeOfDoc);

        head.version = _increaseCounterOfVersions(repo, head.typeOfDoc);
        head.createDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

        repo.bodies[head.typeOfDoc][head.version][<font style="color:#b5cea8;">0</font>].addr = body;
        repo.heads[body] = head;
    }

    <font style="color:#6a9955;">/// @notice Check if a proxy points to the given template implementation.</font>
    <font style="color:#6a9955;">/// @param temp Template implementation address.</font>
    <font style="color:#6a9955;">/// @param proxy Proxy address.</font>
    <font style="color:#6a9955;">/// @return True if proxy implementation equals template.</font>
    <font style="color:#569cd6;">function</font> _isProxy(
        <font style="color:#4ec9b0;">address</font> temp, <font style="color:#4ec9b0;">address</font> proxy
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> temp == IOwnable(proxy).getImplementation();
    }

    <font style="color:#6a9955;">/// @notice Internal helper to register a document instance.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param doc Document instance (head + body).</font>
    <font style="color:#569cd6;">function</font> _regDoc(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Doc <font style="color:#569cd6;">memory</font> doc
    ) <font style="color:#569cd6;">private</font> {
        doc.head.seqOfDoc = _increaseCounterOfDocs(repo, doc.head.typeOfDoc, doc.head.version);
        doc.head.createDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

        repo.bodies[doc.head.typeOfDoc][doc.head.version][doc.head.seqOfDoc].addr = doc.body;
        repo.heads[doc.body] = doc.head;
    }

    <font style="color:#6a9955;">/// @notice Register a proxy instance created externally.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param temp Template implementation address (must exist).</font>
    <font style="color:#6a9955;">/// @param proxy Proxy address to register (non-zero, not already registered).</font>
    <font style="color:#6a9955;">/// @param caller Creator userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @return doc Registered document instance.</font>
    <font style="color:#569cd6;">function</font> regProxy(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> temp,
        <font style="color:#4ec9b0;">address</font> proxy,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Doc <font style="color:#569cd6;">memory</font> doc) {
        <font style="color:#569cd6;">if</font> (caller == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroCreator"</font>));
        <font style="color:#569cd6;">if</font> (!tempExist(repo, temp))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_TempNotExist"</font>));
        <font style="color:#569cd6;">if</font> (proxy == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroProxy"</font>));
        <font style="color:#569cd6;">if</font> (docExist(repo, proxy))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_AlreadyRegistered"</font>));
        <font style="color:#569cd6;">if</font> (!_isProxy(temp, proxy))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_WrongTemplate"</font>));

        doc.head = repo.heads[temp];
        doc.head.creator = <font style="color:#4ec9b0;">uint40</font>(caller);
        doc.body = proxy;

        _regDoc(repo, doc);

    }

    <font style="color:#6a9955;">/// @notice Create and register a minimal-proxy clone of a template.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param creator Creator userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @return doc Registered document instance.</font>
    <font style="color:#569cd6;">function</font> cloneDoc(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version,
        <font style="color:#4ec9b0;">uint</font> creator
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Doc <font style="color:#569cd6;">memory</font> doc)
    {
        doc = getTemp(repo, typeOfDoc, version);
        doc.head.creator = <font style="color:#4ec9b0;">uint40</font>(creator);

        <font style="color:#569cd6;">if</font> (doc.head.creator == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroCreator"</font>));

        doc.body = _createClone(doc.body);

        <font style="color:#569cd6;">if</font> (doc.body == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroProxy"</font>));

        _regDoc(repo, doc);
    }

    <font style="color:#6a9955;">/// @notice Create and register an ERC1967 proxy initialized via `initialize`.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param creator Creator userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @return doc Registered document instance.</font>
    <font style="color:#569cd6;">function</font> proxyDoc(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version,
        <font style="color:#4ec9b0;">uint</font> creator
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Doc <font style="color:#569cd6;">memory</font> doc) {
        doc = getTemp(repo, typeOfDoc, version);
        doc.head.creator = <font style="color:#4ec9b0;">uint40</font>(creator);
        <font style="color:#569cd6;">if</font> (doc.head.creator == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroCreator"</font>));

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data = abi.encodeWithSignature(
                    <font style="color:#ce9178;">"initialize(address,address)"</font>,
                    msg.sender,
                    <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)
                );

        doc.body = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">new</font> ERC1967Proxy(doc.body, data));

        _regDoc(repo, doc);
    }

    <font style="color:#6a9955;">/// @notice Register a proxy upgrade to a new template version.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param temp New template implementation (must exist).</font>
    <font style="color:#6a9955;">/// @param proxy Existing proxy address (must be registered).</font>
    <font style="color:#6a9955;">/// @return doc Registered upgraded document instance.</font>
    <font style="color:#569cd6;">function</font> upgradeDoc(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> temp,
        <font style="color:#4ec9b0;">address</font> proxy
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Doc <font style="color:#569cd6;">memory</font> doc) {
        <font style="color:#569cd6;">if</font> (!tempExist(repo, temp))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_TempNotExist"</font>));

        <font style="color:#569cd6;">if</font> (!docExist(repo, proxy))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ProxyNotExist"</font>));

        doc.head = repo.heads[temp];
        doc.body = proxy;

        Head <font style="color:#569cd6;">memory</font> oldHead = repo.heads[proxy];

        <font style="color:#569cd6;">if</font> (oldHead.typeOfDoc != doc.head.typeOfDoc)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_WrongTemplate"</font>));

        <font style="color:#569cd6;">if</font> (oldHead.version == doc.head.version)
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_WrongVersion"</font>));

        <font style="color:#569cd6;">if</font> (!_isProxy(temp, proxy))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_WrongTemplate"</font>));

        _regDoc(repo, doc);

        Body <font style="color:#569cd6;">storage</font> oldBody =
            repo.bodies[oldHead.typeOfDoc][oldHead.version][oldHead.seqOfDoc];

        oldBody.addr = <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>);
        oldBody.version = doc.head.version;
        oldBody.seq = doc.head.seqOfDoc;
    }

    <font style="color:#6a9955;">/// @notice Transfer IPR by updating author for a template.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param transferee New author userNo.</font>
    <font style="color:#6a9955;">/// @param caller Caller userNo (must equal current author).</font>
    <font style="color:#569cd6;">function</font> transferIPR(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version,
        <font style="color:#4ec9b0;">uint</font> transferee,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (caller != getAuthor(repo, typeOfDoc, version))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_NotAuthor"</font>));

        repo.heads[repo.bodies[typeOfDoc][version][<font style="color:#b5cea8;">0</font>].addr].author = <font style="color:#4ec9b0;">uint40</font>(transferee);
    }

    <font style="color:#6a9955;">/// @notice Increment template version counter for a document type.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @return New version (uint32), wraps to 1 on overflow.</font>
    <font style="color:#569cd6;">function</font> _increaseCounterOfVersions(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> typeOfDoc
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {

        <font style="color:#569cd6;">unchecked</font> {
            repo.bodies[typeOfDoc][<font style="color:#b5cea8;">0</font>][<font style="color:#b5cea8;">0</font>].seq =
                repo.bodies[typeOfDoc][<font style="color:#b5cea8;">0</font>][<font style="color:#b5cea8;">0</font>].seq == type(<font style="color:#4ec9b0;">uint32</font>).max
                    ? <font style="color:#b5cea8;">1</font>
                    : repo.bodies[typeOfDoc][<font style="color:#b5cea8;">0</font>][<font style="color:#b5cea8;">0</font>].seq + <font style="color:#b5cea8;">1</font>;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">uint32</font>(repo.bodies[typeOfDoc][<font style="color:#b5cea8;">0</font>][<font style="color:#b5cea8;">0</font>].seq);
    }

    <font style="color:#6a9955;">/// @notice Increment doc instance counter for a document type/version.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return New seqOfDoc (uint64), wraps to 1 on overflow.</font>
    <font style="color:#569cd6;">function</font> _increaseCounterOfDocs(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint256</font> version
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">unchecked</font> {
            repo.bodies[typeOfDoc][version][<font style="color:#b5cea8;">0</font>].seq =
                repo.bodies[typeOfDoc][version][<font style="color:#b5cea8;">0</font>].seq == type(<font style="color:#4ec9b0;">uint64</font>).max
                    ? <font style="color:#b5cea8;">1</font>
                    : repo.bodies[typeOfDoc][version][<font style="color:#b5cea8;">0</font>].seq + <font style="color:#b5cea8;">1</font>;
        }
        <font style="color:#569cd6;">return</font> repo.bodies[typeOfDoc][version][<font style="color:#b5cea8;">0</font>].seq;
    }

    <font style="color:#6a9955;">// ==== CloneFactory ====</font>

<font style="color:#6a9955;">/*
The MIT License (MIT)
Copyright (c) 2018 Murray Software, LLC.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/</font>
<font style="color:#6a9955;">//solhint-disable max-line-length</font>
<font style="color:#6a9955;">//solhint-disable no-inline-assembly</font>

    <font style="color:#6a9955;">/// @notice Create an EIP-1167 minimal proxy clone of `temp`.</font>
    <font style="color:#6a9955;">/// @param temp Template implementation address.</font>
    <font style="color:#6a9955;">/// @return result Clone address (zero on failure).</font>
    <font style="color:#569cd6;">function</font> _createClone(<font style="color:#4ec9b0;">address</font> temp) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font> result) {
        <font style="color:#4ec9b0;">bytes20</font> tempBytes = <font style="color:#4ec9b0;">bytes20</font>(temp);
        <font style="color:#569cd6;">assembly</font> {
            let clone := mload(0x40)
            mstore(
                clone,
                0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
            )
            mstore(add(clone, 0x14), tempBytes)
            mstore(
                add(clone, 0x28),
                0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
            )
            result := create(<font style="color:#b5cea8;">0</font>, clone, 0x37)
        }
    }

    <font style="color:#6a9955;">/// @notice Check if `query` is an EIP-1167 clone of `temp`.</font>
    <font style="color:#6a9955;">/// @param temp Template implementation address.</font>
    <font style="color:#6a9955;">/// @param query Address to test.</font>
    <font style="color:#6a9955;">/// @return result True if `query` is a clone of `temp`.</font>
    <font style="color:#569cd6;">function</font> _isClone(<font style="color:#4ec9b0;">address</font> temp, <font style="color:#4ec9b0;">address</font> query)
        <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> result)
    {
        <font style="color:#4ec9b0;">bytes20</font> tempBytes = <font style="color:#4ec9b0;">bytes20</font>(temp);
        <font style="color:#569cd6;">assembly</font> {
            let clone := mload(0x40)
            mstore(
                clone,
                0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000
            )
            mstore(add(clone, 0xa), tempBytes)
            mstore(
                add(clone, 0x1e),
                0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
            )

            let other := add(clone, 0x40)
            extcodecopy(query, other, <font style="color:#b5cea8;">0</font>, 0x2d)
            result := and(
                eq(mload(clone), mload(other)),
                eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
            )
        }
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">// ---- TypeOfDoc ---- </font>

    <font style="color:#6a9955;">/// @notice Get number of document types.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Number of types.</font>
    <font style="color:#569cd6;">function</font> counterOfTypes(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">uint32</font>(repo.typesList.length());
    }

    <font style="color:#6a9955;">/// @notice Check if a document type exists.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> typeExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.typesList.contains(typeOfDoc);
    }

    <font style="color:#6a9955;">/// @notice Get all document types.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Array of document types.</font>
    <font style="color:#569cd6;">function</font> getTypesList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.typesList.values();
    }

    <font style="color:#6a9955;">// ---- Counters ----</font>

    <font style="color:#6a9955;">/// @notice Get latest version for a document type.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @return Latest version counter.</font>
    <font style="color:#569cd6;">function</font> counterOfVersions(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> typeOfDoc) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">uint32</font>(repo.bodies[<font style="color:#4ec9b0;">uint32</font>(typeOfDoc)][<font style="color:#b5cea8;">0</font>][<font style="color:#b5cea8;">0</font>].seq);
    }

    <font style="color:#6a9955;">/// @notice Get count of docs for a document type/version.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return Latest doc counter.</font>
    <font style="color:#569cd6;">function</font> counterOfDocs(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">return</font> repo.bodies[<font style="color:#4ec9b0;">uint32</font>(typeOfDoc)][<font style="color:#4ec9b0;">uint32</font>(version)][<font style="color:#b5cea8;">0</font>].seq;
    }

    <font style="color:#6a9955;">// ---- Authors ----</font>

    <font style="color:#6a9955;">/// @notice Get author userNo for a template.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return Author userNo.</font>
    <font style="color:#569cd6;">function</font> getAuthor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#4ec9b0;">address</font> temp = repo.bodies[typeOfDoc][version][<font style="color:#b5cea8;">0</font>].addr;

        <font style="color:#569cd6;">if</font> (temp == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_ZeroTemp"</font>));

        <font style="color:#569cd6;">return</font> repo.heads[temp].author;
    }

    <font style="color:#6a9955;">/// @notice Get author userNo by body address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document body address.</font>
    <font style="color:#6a9955;">/// @return Author userNo.</font>
    <font style="color:#569cd6;">function</font> getAuthorByBody(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>) {
        Head <font style="color:#569cd6;">memory</font> head = getHeadByBody(repo, body);
        <font style="color:#569cd6;">return</font> getAuthor(repo, head.typeOfDoc, head.version);
    }

    <font style="color:#6a9955;">// ---- Temps ----</font>

    <font style="color:#6a9955;">/// @notice Check if a template exists for a body address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Template address.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> tempExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        Head <font style="color:#569cd6;">memory</font> head = repo.heads[body];
        <font style="color:#569cd6;">if</font> (   body == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)
            || head.typeOfDoc == <font style="color:#b5cea8;">0</font>
            || head.version == <font style="color:#b5cea8;">0</font>
            || head.seqOfDoc != <font style="color:#b5cea8;">0</font>
        ) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">return</font> repo.bodies[head.typeOfDoc][head.version][<font style="color:#b5cea8;">0</font>].addr == body;
    }

    <font style="color:#6a9955;">/// @notice Get template document for a type/version.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return doc Template document.</font>
    <font style="color:#569cd6;">function</font> getTemp(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Doc <font style="color:#569cd6;">memory</font> doc) {
        doc.body = repo.bodies[<font style="color:#4ec9b0;">uint32</font>(typeOfDoc)][<font style="color:#4ec9b0;">uint32</font>(version)][<font style="color:#b5cea8;">0</font>].addr;
        doc.head = repo.heads[doc.body];

        <font style="color:#569cd6;">if</font> (!tempExist(repo, doc.body))
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_TempNotExist"</font>));
    }

    <font style="color:#6a9955;">/// @notice Get all templates for a document type.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @return Array of templates ordered by version.</font>
    <font style="color:#569cd6;">function</font> getVersionsList(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Doc[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint32</font> len = counterOfVersions(repo, typeOfDoc);
        Doc[] <font style="color:#569cd6;">memory</font> out = <font style="color:#569cd6;">new</font> Doc[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            out[len - <font style="color:#b5cea8;">1</font>] = getTemp(repo, <font style="color:#4ec9b0;">uint32</font>(typeOfDoc), len);
            len--;
        }

        <font style="color:#569cd6;">return</font> out;
    }

    <font style="color:#6a9955;">// ---- Docs ----</font>

    <font style="color:#6a9955;">/// @notice Check if a document instance exists for a body address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document body address.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> docExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        Head <font style="color:#569cd6;">memory</font> head = repo.heads[body];
        <font style="color:#569cd6;">if</font> (   body == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)
            || head.typeOfDoc == <font style="color:#b5cea8;">0</font>
            || head.version == <font style="color:#b5cea8;">0</font>
            || head.seqOfDoc == <font style="color:#b5cea8;">0</font>
        ) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">return</font> repo.bodies[head.typeOfDoc][head.version][head.seqOfDoc].addr == body;
    }

    <font style="color:#6a9955;">/// @notice Get header by body address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document body address.</font>
    <font style="color:#6a9955;">/// @return Header (zeroed if not found).</font>
    <font style="color:#569cd6;">function</font> getHeadByBody(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> ) {
        <font style="color:#569cd6;">return</font> repo.heads[body];
    }

    <font style="color:#6a9955;">/// @notice Get a specific document instance by type/version/seq.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param seqOfDoc Document sequence number.</font>
    <font style="color:#6a9955;">/// @return doc Document instance.</font>
    <font style="color:#569cd6;">function</font> getDoc(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> seqOfDoc
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Doc <font style="color:#569cd6;">memory</font> doc) {
        doc.body = repo.bodies[<font style="color:#4ec9b0;">uint32</font>(typeOfDoc)][<font style="color:#4ec9b0;">uint32</font>(version)][<font style="color:#4ec9b0;">uint64</font>(seqOfDoc)].addr;
        doc.head = repo.heads[doc.body];
        <font style="color:#569cd6;">if</font> (!docExist(repo, doc.body)) {
            <font style="color:#569cd6;">revert</font> DocsRepo_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DR_DocNotExist"</font>));
        }
    }

    <font style="color:#6a9955;">/// @notice Get all documents for a type/version.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @return Array of documents ordered by seq.</font>
    <font style="color:#569cd6;">function</font> getDocsList(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Doc[] <font style="color:#569cd6;">memory</font>) {
        Head <font style="color:#569cd6;">memory</font> head;
        head.typeOfDoc = <font style="color:#4ec9b0;">uint32</font>(typeOfDoc);
        head.version = <font style="color:#4ec9b0;">uint32</font>(version);

        <font style="color:#4ec9b0;">uint64</font> len = counterOfDocs(repo, head.typeOfDoc, head.version);
        Doc[] <font style="color:#569cd6;">memory</font> out = <font style="color:#569cd6;">new</font> Doc[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            out[len - <font style="color:#b5cea8;">1</font>] = getDoc(repo, head.typeOfDoc, head.version, len);
            len--;
        }

        <font style="color:#569cd6;">return</font> out;
    }

    <font style="color:#6a9955;">// ---- Verification ----</font>

    <font style="color:#6a9955;">/// @notice Verify that a document instance is a valid clone or proxy of its template.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type.</font>
    <font style="color:#6a9955;">/// @param version Template version.</font>
    <font style="color:#6a9955;">/// @param seqOfDoc Document sequence number.</font>
    <font style="color:#6a9955;">/// @return True if the instance matches its template.</font>
    <font style="color:#569cd6;">function</font> verifyDoc(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> seqOfDoc
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        Head <font style="color:#569cd6;">memory</font> head;
        head.typeOfDoc = <font style="color:#4ec9b0;">uint32</font>(typeOfDoc);
        head.version = <font style="color:#4ec9b0;">uint32</font>(version);
        head.seqOfDoc = <font style="color:#4ec9b0;">uint64</font>(seqOfDoc);

        <font style="color:#4ec9b0;">address</font> temp = repo.bodies[head.typeOfDoc][head.version][<font style="color:#b5cea8;">0</font>].addr;
        <font style="color:#4ec9b0;">address</font> target = repo.bodies[head.typeOfDoc][head.version][head.seqOfDoc].addr;

        <font style="color:#569cd6;">return</font> tempExist(repo, temp) && docExist(repo, target) &&
                (_isClone(temp, target) || _isProxy(temp, target));
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## DTClaims.sol

---

| |
|:---|
| **contracts/lib/books/DTClaims.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title DTClaims</font>
<font style="color:#6a9955;">/// @notice Library for drag-along/tag-along claims tracking.</font>
<font style="color:#569cd6;">library</font> DTClaims {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice Encoded claim head data.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint16</font> seqOfDeal;
        <font style="color:#4ec9b0;">bool</font> dragAlong;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint40</font> caller;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Claim record for a share.</font>
    <font style="color:#569cd6;">struct</font> Claim {
        <font style="color:#4ec9b0;">uint8</font> typeOfClaim;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint40</font> claimer;
        <font style="color:#4ec9b0;">uint48</font> sigDate;
        <font style="color:#4ec9b0;">bytes32</font> sigHash;
    }

    <font style="color:#6a9955;">/// @notice Pack of claims for a deal and claim type.</font>
    <font style="color:#569cd6;">struct</font> Pack {
        <font style="color:#6a9955;">//seqOfShare => Claim</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Claim) claims;
        EnumerableSet.UintSet shares;
    }

    <font style="color:#6a9955;">/// @notice Claims repository keyed by deal.</font>
    <font style="color:#569cd6;">struct</font> Claims {
        <font style="color:#6a9955;">// seqOfDeal => drag/tag/merged => Pack</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Pack)) packs;
        EnumerableSet.UintSet deals;
    }

    <font style="color:#6a9955;">/// @dev Reverts if deal has no claims.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#569cd6;">modifier</font> dealExist(Claims <font style="color:#569cd6;">storage</font> cls, <font style="color:#4ec9b0;">uint</font> seqOfDeal) {
        <font style="color:#569cd6;">if</font> (!hasClaim(cls, seqOfDeal))
            <font style="color:#569cd6;">revert</font> DTClaims_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DTC_DealNotExist"</font>));
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Error    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#569cd6;">error</font> DTClaims_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> DTClaims_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Parse encoded claim head.</font>
    <font style="color:#6a9955;">/// @param sn Encoded head bytes32.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);
        head = Head({
            seqOfDeal: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            dragAlong: <font style="color:#4ec9b0;">bool</font>(<font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">232</font>) == <font style="color:#b5cea8;">1</font>),
            seqOfShare: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">200</font>),
            paid: <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">136</font>),
            par: <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">72</font>),
            caller: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">32</font>),
            para: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>),
            argu: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Encode claim head into bytes32.</font>
    <font style="color:#6a9955;">/// @param head Claim head.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.seqOfDeal,
                            head.dragAlong,
                            head.seqOfShare,
                            head.paid,
                            head.par,
                            head.caller,
                            head.para,
                            head.argu
        );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">/// @notice Register a drag-along or tag-along claim.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">// / @param dragAlong True for drag-along, false for tag-along.</font>
    <font style="color:#6a9955;">// / @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#6a9955;">// / @param seqOfShare Share sequence number (> 0).</font>
    <font style="color:#6a9955;">// / @param paid Paid amount (uint64 range).</font>
    <font style="color:#6a9955;">// / @param par Par amount (uint64 range).</font>
    <font style="color:#6a9955;">/// @param snOfClaim Encoded claim head.</font>
    <font style="color:#6a9955;">// / @param claimer Claimer account id (> 0).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> execAlongRight(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#6a9955;">// bool dragAlong,</font>
        <font style="color:#6a9955;">// uint256 seqOfDeal,</font>
        <font style="color:#6a9955;">// uint256 seqOfShare,</font>
        <font style="color:#6a9955;">// uint paid,</font>
        <font style="color:#6a9955;">// uint par,</font>
        <font style="color:#4ec9b0;">bytes32</font> snOfClaim,
        <font style="color:#6a9955;">// uint256 claimer,</font>
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">public</font> {

        Head <font style="color:#569cd6;">memory</font> head = snParser(snOfClaim);

        <font style="color:#6a9955;">// uint16 intSeqOfDeal = uint16(seqOfDeal);</font>
        <font style="color:#569cd6;">if</font> (head.seqOfDeal == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DTClaims_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DTC_ZeroSeqOfDeal"</font>));

        Claim <font style="color:#569cd6;">memory</font> newClaim = Claim({
            typeOfClaim: head.dragAlong ? <font style="color:#b5cea8;">0</font> : <font style="color:#b5cea8;">1</font>,
            seqOfShare: head.seqOfShare,
            paid: head.paid,
            par: head.par,
            claimer: head.caller,
            sigDate: <font style="color:#4ec9b0;">uint48</font>(block.timestamp),
            sigHash: sigHash
        });

        <font style="color:#569cd6;">if</font> (newClaim.seqOfShare == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> DTClaims_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DTC_ZeroSeqOfShare"</font>));

        Pack <font style="color:#569cd6;">storage</font> p = cls.packs[head.seqOfDeal][newClaim.typeOfClaim];

        <font style="color:#569cd6;">if</font> (p.shares.add(newClaim.seqOfShare)){

            p.claims[newClaim.seqOfShare] = newClaim;

            cls.deals.add(head.seqOfDeal);

            _consolidateClaimsOfShare(cls, head.seqOfDeal, newClaim);
        }
    }

    <font style="color:#6a9955;">/// @dev Consolidate per-share claims into merged pack.</font>
    <font style="color:#569cd6;">function</font> _consolidateClaimsOfShare(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> intSeqOfDeal,
        Claim <font style="color:#569cd6;">memory</font> newClaim
    ) <font style="color:#569cd6;">private</font> {
        Pack <font style="color:#569cd6;">storage</font> m = cls.packs[intSeqOfDeal][<font style="color:#b5cea8;">2</font>];

        <font style="color:#569cd6;">if</font> (m.shares.add(newClaim.seqOfShare)) {
            m.claims[newClaim.seqOfShare] = newClaim;
        } <font style="color:#569cd6;">else</font> {
            Claim <font style="color:#569cd6;">storage</font> mClaim = m.claims[newClaim.seqOfShare];

            mClaim.paid = newClaim.paid > mClaim.paid  ? newClaim.paid :  mClaim.paid;
            mClaim.par = newClaim.par > mClaim.par ? newClaim.par : mClaim.par;

            <font style="color:#569cd6;">if</font> (mClaim.typeOfClaim == <font style="color:#b5cea8;">0</font>){

                Claim <font style="color:#569cd6;">memory</font> tClaim = cls.packs[intSeqOfDeal][<font style="color:#b5cea8;">1</font>].claims[newClaim.seqOfShare];

                mClaim.typeOfClaim = <font style="color:#b5cea8;">1</font>;
                mClaim.claimer = tClaim.claimer;
                mClaim.sigDate = tClaim.sigDate;
                mClaim.sigHash = tClaim.sigHash;
            }
        }
    }

    <font style="color:#6a9955;">/// @notice Mark claims of a deal as accepted.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> acceptAlongClaims(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Claim[] <font style="color:#569cd6;">memory</font>) {
        cls.packs[seqOfDeal][<font style="color:#b5cea8;">2</font>].claims[<font style="color:#b5cea8;">0</font>].typeOfClaim = <font style="color:#b5cea8;">1</font>;
        <font style="color:#569cd6;">return</font> getClaimsOfDeal(cls, seqOfDeal);
    }

    <font style="color:#6a9955;">//  ################################</font>
    <font style="color:#6a9955;">//  ##       Read I/O             ##</font>
    <font style="color:#6a9955;">//  ################################</font>

    <font style="color:#6a9955;">/// @notice Check whether a deal has any claims.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> hasClaim(Claims <font style="color:#569cd6;">storage</font> cls, <font style="color:#4ec9b0;">uint</font> seqOfDeal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> cls.deals.contains(seqOfDeal);
    }

    <font style="color:#6a9955;">/// @notice Get list of deals with claims.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#569cd6;">function</font> getDeals(Claims <font style="color:#569cd6;">storage</font> cls) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> cls.deals.values();
    }

    <font style="color:#6a9955;">/// @notice Get all claims of a deal.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getClaimsOfDeal(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> dealExist(cls, seqOfDeal) <font style="color:#569cd6;">returns</font>(Claim[] <font style="color:#569cd6;">memory</font>) {

        Pack <font style="color:#569cd6;">storage</font> m = cls.packs[seqOfDeal][<font style="color:#b5cea8;">2</font>];

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> sharesList = m.shares.values();
        <font style="color:#4ec9b0;">uint</font> len = sharesList.length;

        Claim[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> Claim[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            output[len - <font style="color:#b5cea8;">1</font>] = m.claims[sharesList[len - <font style="color:#b5cea8;">1</font>]];
            len --;
        }

        <font style="color:#569cd6;">return</font> output;
    }

    <font style="color:#6a9955;">/// @notice Check whether a deal has a claim for a share.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> hasShare(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> dealExist(cls, seqOfDeal) <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> cls.packs[seqOfDeal][<font style="color:#b5cea8;">2</font>].shares.contains(seqOfShare);
    }

    <font style="color:#6a9955;">/// @notice Get claim for a specific share.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getClaimForShare(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Claim <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (!hasShare(cls, seqOfDeal, seqOfShare))
            <font style="color:#569cd6;">revert</font> DTClaims_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"DTC_ShareNotExist"</font>));
        <font style="color:#569cd6;">return</font> cls.packs[seqOfDeal][<font style="color:#b5cea8;">2</font>].claims[seqOfShare];
    }

    <font style="color:#6a9955;">/// @notice Check whether all deals' claims are accepted.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#569cd6;">function</font> allAccepted(Claims <font style="color:#569cd6;">storage</font> cls) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> dealsList = cls.deals.values();
        <font style="color:#4ec9b0;">uint</font> len = dealsList.length;

        flag = <font style="color:#569cd6;">true</font>;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (cls.packs[dealsList[len - <font style="color:#b5cea8;">1</font>]][<font style="color:#b5cea8;">2</font>].claims[<font style="color:#b5cea8;">0</font>].typeOfClaim == <font style="color:#b5cea8;">0</font>) {
                flag = <font style="color:#569cd6;">false</font>;
                <font style="color:#569cd6;">break</font>;
            }
            len--;
        }
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## FilesRepo.sol

---

| |
|:---|
| **contracts/lib/books/FilesRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./RulesParser.sol"</font>;

<font style="color:#6a9955;">/// @title FilesRepo</font>
<font style="color:#6a9955;">/// @notice Library for managing document file lifecycle and metadata.</font>
<font style="color:#6a9955;">/// @dev Stores file records keyed by document contract address.</font>
<font style="color:#569cd6;">library</font> FilesRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.AddressSet;

    <font style="color:#6a9955;">/// @notice File lifecycle state.</font>
    <font style="color:#569cd6;">enum</font> StateOfFile {
        ZeroPoint,  <font style="color:#6a9955;">// 0</font>
        Created,    <font style="color:#6a9955;">// 1</font>
        Circulated, <font style="color:#6a9955;">// 2</font>
        Proposed,   <font style="color:#6a9955;">// 3</font>
        Approved,   <font style="color:#6a9955;">// 4</font>
        Rejected,   <font style="color:#6a9955;">// 5</font>
        Closed,     <font style="color:#6a9955;">// 6</font>
        Revoked     <font style="color:#6a9955;">// 7</font>
    }

    <font style="color:#6a9955;">/// @notice Core lifecycle fields and voting windows for a file.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint48</font> circulateDate;
        <font style="color:#4ec9b0;">uint8</font> signingDays;
        <font style="color:#4ec9b0;">uint8</font> closingDays;
        <font style="color:#4ec9b0;">uint16</font> seqOfVR;
        <font style="color:#4ec9b0;">uint8</font> frExecDays;
        <font style="color:#4ec9b0;">uint8</font> dtExecDays;
        <font style="color:#4ec9b0;">uint8</font> dtConfirmDays;
        <font style="color:#4ec9b0;">uint48</font> proposeDate;
        <font style="color:#4ec9b0;">uint8</font> invExitDays;
        <font style="color:#4ec9b0;">uint8</font> votePrepareDays;
        <font style="color:#4ec9b0;">uint8</font> votingDays;
        <font style="color:#4ec9b0;">uint8</font> execDaysForPutOpt;
        <font style="color:#4ec9b0;">uint64</font> seqOfMotion;
        <font style="color:#4ec9b0;">uint8</font> state;
    }

    <font style="color:#6a9955;">/// @notice Off-chain reference metadata for a file.</font>
    <font style="color:#569cd6;">struct</font> Ref {
        <font style="color:#4ec9b0;">bytes32</font> docUrl;
        <font style="color:#4ec9b0;">bytes32</font> docHash;
    }

    <font style="color:#6a9955;">/// @notice Full file record.</font>
    <font style="color:#569cd6;">struct</font> File {
        <font style="color:#4ec9b0;">bytes32</font> snOfDoc;
        Head head;
        Ref ref;
    }

    <font style="color:#6a9955;">/// @notice Repository storage for files.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// Keyed by document contract address.</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => File) files;
        <font style="color:#6a9955;">// List of registered document contract addresses.</font>
        EnumerableSet.AddressSet filesList;
    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##      Error     ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#569cd6;">error</font> FR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> FR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##    modifier    ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">/// @dev Reverts if the file is not registered.</font>
    <font style="color:#569cd6;">modifier</font> onlyRegistered(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body) {
        <font style="color:#569cd6;">if</font> (!repo.filesList.contains(body)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_DocNotRegistered"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Register a document file.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param snOfDoc Encoded document identifier.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @return flag True if the file is newly registered.</font>
    <font style="color:#569cd6;">function</font> regFile(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> snOfDoc, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#569cd6;">if</font> (body == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> FR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_ZeroAddress"</font>));
        }
        <font style="color:#569cd6;">if</font> (repo.filesList.add(body)) {

            File <font style="color:#569cd6;">storage</font> file = repo.files[body];

            file.snOfDoc = snOfDoc;
            file.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Created);
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Circulate a file for signing and voting.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param signingDays Signing window in days.</font>
    <font style="color:#6a9955;">/// @param closingDays Total closing window in days.</font>
    <font style="color:#6a9955;">/// @param vr Voting rule parameters.</font>
    <font style="color:#6a9955;">/// @param docUrl Document URL hash.</font>
    <font style="color:#6a9955;">/// @param docHash Document content hash.</font>
    <font style="color:#6a9955;">/// @return head Updated head record.</font>
    <font style="color:#569cd6;">function</font> circulateFile(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">uint</font> signingDays,
        <font style="color:#4ec9b0;">uint</font> closingDays,
        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr,
        <font style="color:#4ec9b0;">bytes32</font> docUrl,
        <font style="color:#4ec9b0;">bytes32</font> docHash
    ) <font style="color:#569cd6;">public</font> onlyRegistered(repo, body) <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head){

        <font style="color:#569cd6;">if</font> (repo.files[body].head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Created)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_DocStateNotCreated"</font>));
        }

        head = Head({
            circulateDate: <font style="color:#4ec9b0;">uint48</font>(block.timestamp),
            signingDays: <font style="color:#4ec9b0;">uint8</font>(signingDays),
            closingDays: <font style="color:#4ec9b0;">uint8</font>(closingDays),
            seqOfVR: vr.seqOfRule,
            frExecDays: vr.frExecDays,
            dtExecDays: vr.dtExecDays,
            dtConfirmDays: vr.dtConfirmDays,
            proposeDate: <font style="color:#b5cea8;">0</font>,
            invExitDays: vr.invExitDays,
            votePrepareDays: vr.votePrepareDays,
            votingDays: vr.votingDays,
            execDaysForPutOpt: vr.execDaysForPutOpt,
            seqOfMotion: <font style="color:#b5cea8;">0</font>,
            state: <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Circulated)
        });

        <font style="color:#569cd6;">if</font> (head.signingDays == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> FR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_ZeroSigningDays"</font>));
        }

        <font style="color:#569cd6;">if</font> (head.closingDays < signingDays + vr.frExecDays + vr.dtExecDays + vr.dtConfirmDays +
                vr.invExitDays + vr.votePrepareDays + vr.votingDays) {
            <font style="color:#569cd6;">revert</font> FR_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_ExceedingClosingDays"</font>));
        }

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        file.head = head;

        <font style="color:#569cd6;">if</font> (docUrl != <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#b5cea8;">0</font>) || docHash != <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#b5cea8;">0</font>)){
            file.ref = Ref({
                docUrl: docUrl,
                docHash: docHash
            });
        }
        <font style="color:#569cd6;">return</font> file.head;
    }

    <font style="color:#6a9955;">/// @notice Propose a circulated file for voting.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence number.</font>
    <font style="color:#6a9955;">/// @return Updated head record.</font>
    <font style="color:#569cd6;">function</font> proposeFile(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">uint64</font> seqOfMotion
    ) <font style="color:#569cd6;">public</font> onlyRegistered(repo, body) <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font>){

        <font style="color:#569cd6;">if</font> (repo.files[body].head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Circulated)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_DocNotCirculated"</font>));
        }

        <font style="color:#4ec9b0;">uint48</font> timestamp = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

        <font style="color:#569cd6;">if</font> (timestamp < dtExecDeadline(repo, body)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_StillInDtExecPeriod"</font>));
        }

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">if</font> (!(timestamp < terminateStartpoint(repo, body) || (file.head.frExecDays
             + file.head.dtExecDays + file.head.dtConfirmDays) == <font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_MissedProposeDeadline"</font>));
        }

        file.head.proposeDate = timestamp;
        file.head.seqOfMotion = seqOfMotion;
        file.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Proposed);

        <font style="color:#569cd6;">return</font> file.head;
    }

    <font style="color:#6a9955;">/// @notice Record vote counting result for a proposed file.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param approved True if approved.</font>
    <font style="color:#569cd6;">function</font> voteCountingForFile(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body,
        <font style="color:#4ec9b0;">bool</font> approved
    ) <font style="color:#569cd6;">public</font> onlyRegistered(repo, body) {

        <font style="color:#569cd6;">if</font> (repo.files[body].head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Proposed)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_DocNotProposed"</font>));
        }

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        file.head.state = approved ?
            <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Approved) : <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Rejected);
    }

    <font style="color:#6a9955;">/// @notice Execute an approved file.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> execFile(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body
    ) <font style="color:#569cd6;">public</font> onlyRegistered(repo, body) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">if</font> (file.head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Approved)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_DocNotApproved"</font>));
        }

        <font style="color:#4ec9b0;">uint48</font> timestamp = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

        <font style="color:#569cd6;">if</font> (timestamp >= closingDeadline(repo, body)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_MissedClosingDeadline"</font>));
        }

        file.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Closed);
    }

    <font style="color:#6a9955;">/// @notice Revoke a file.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> terminateFile(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> body
    ) <font style="color:#569cd6;">public</font> onlyRegistered(repo, body) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">if</font> (file.head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Closed)) {
            <font style="color:#569cd6;">revert</font> FR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FR_DocClosed"</font>));
        }

        file.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfFile.Revoked);
    }

    <font style="color:#6a9955;">/// @notice Force set file state.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#6a9955;">/// @param state New state value.</font>
    <font style="color:#569cd6;">function</font> setStateOfFile(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body, <font style="color:#4ec9b0;">uint</font> state)
        <font style="color:#569cd6;">public</font> onlyRegistered(repo, body)
    {
        repo.files[body].head.state = <font style="color:#4ec9b0;">uint8</font>(state);
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Get signing deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> signingDeadline(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">return</font> file.head.circulateDate + <font style="color:#4ec9b0;">uint48</font>(file.head.signingDays) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Get closing deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> closingDeadline(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">return</font> file.head.circulateDate + <font style="color:#4ec9b0;">uint48</font>(file.head.closingDays) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Get first execution deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> frExecDeadline(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">return</font> file.head.circulateDate + <font style="color:#4ec9b0;">uint48</font>(file.head.signingDays +
            file.head.frExecDays) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Get second execution deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> dtExecDeadline(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">return</font> file.head.circulateDate + <font style="color:#4ec9b0;">uint48</font>(file.head.signingDays +
            file.head.frExecDays + file.head.dtExecDays) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Get termination start timestamp.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> terminateStartpoint(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">return</font> file.head.circulateDate + (<font style="color:#4ec9b0;">uint48</font>(file.head.signingDays +
            file.head.frExecDays + file.head.dtExecDays + file.head.dtConfirmDays)) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Get voting deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> votingDeadline(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint48</font>) {

        File <font style="color:#569cd6;">storage</font> file = repo.files[body];

        <font style="color:#569cd6;">return</font> file.head.proposeDate + (<font style="color:#4ec9b0;">uint48</font>(file.head.invExitDays +
            file.head.votePrepareDays + file.head.votingDays)) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Check if a file is registered.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> isRegistered(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.filesList.contains(body);
    }

    <font style="color:#6a9955;">/// @notice Get number of registered files.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#569cd6;">function</font> qtyOfFiles(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> repo.filesList.length();
    }

    <font style="color:#6a9955;">/// @notice Get list of registered file addresses.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#569cd6;">function</font> getFilesList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.filesList.values();
    }

    <font style="color:#6a9955;">/// @notice Get file record by address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> getFile(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (File <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.files[body];
    }

    <font style="color:#6a9955;">/// @notice Get file header by address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param body Document contract address.</font>
    <font style="color:#569cd6;">function</font> getHeadOfFile(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> body)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> onlyRegistered(repo, body) <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.files[body].head;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## FRClaims.sol

---

| |
|:---|
| **contracts/lib/books/FRClaims.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rom/IRegisterOfMembers.sol"</font>;

<font style="color:#6a9955;">/// @title FRClaims</font>
<font style="color:#6a9955;">/// @notice Library for first-refusal claims tracking and allocation.</font>
<font style="color:#569cd6;">library</font> FRClaims {

    <font style="color:#6a9955;">/// @notice Claim record for a deal.</font>
    <font style="color:#569cd6;">struct</font> Claim {
        <font style="color:#4ec9b0;">uint16</font> seqOfDeal;
        <font style="color:#4ec9b0;">uint40</font> claimer;
        <font style="color:#4ec9b0;">uint64</font> weight;
        <font style="color:#4ec9b0;">uint64</font> ratio;
        <font style="color:#4ec9b0;">uint48</font> sigDate;
        <font style="color:#4ec9b0;">bytes32</font> sigHash;
    }

    <font style="color:#6a9955;">/// @notice Package of claims for a deal.</font>
    <font style="color:#569cd6;">struct</font> Package {
        <font style="color:#4ec9b0;">uint64</font> sumOfWeight;
        Claim[] claims;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#4ec9b0;">bool</font>) isClaimer;
    }

    <font style="color:#6a9955;">// packages[0] {</font>
    <font style="color:#6a9955;">//     claims: deals;</font>
    <font style="color:#6a9955;">//     isClaimer: isClaimer;</font>
    <font style="color:#6a9955;">// }</font>

    <font style="color:#6a9955;">/// @notice Claims repository keyed by deal.</font>
    <font style="color:#569cd6;">struct</font> Claims {
        <font style="color:#6a9955;">// seqOfDeal => Package</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Package) packages;
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##     Error    ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#569cd6;">error</font> FRClaims_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> FRClaims_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> FRClaims_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Submit a first-refusal claim.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Claimer account id (> 0).</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#569cd6;">function</font> claimFirstRefusal(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">public</font> {

        Claim <font style="color:#569cd6;">memory</font> cl = Claim({
            seqOfDeal: <font style="color:#4ec9b0;">uint16</font>(seqOfDeal),
            claimer: <font style="color:#4ec9b0;">uint40</font>(acct),
            weight: <font style="color:#b5cea8;">0</font>,
            ratio: <font style="color:#b5cea8;">0</font>,
            sigDate: <font style="color:#4ec9b0;">uint48</font>(block.timestamp),
            sigHash: sigHash
        });

        <font style="color:#569cd6;">if</font> (cl.seqOfDeal == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> FRClaims_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FRC_ZeroSeqOfDeal"</font>));
        }

        <font style="color:#569cd6;">if</font> (isClaimerOfDeal(cls, cl.seqOfDeal, cl.claimer)) {
            <font style="color:#569cd6;">revert</font> FRClaims_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FRC_DoubleClaim"</font>));
        }

        <font style="color:#569cd6;">if</font> (!isDeal(cls, cl.seqOfDeal))
            cls.packages[<font style="color:#b5cea8;">0</font>].claims.push(cl);

        Package <font style="color:#569cd6;">storage</font> p = cls.packages[cl.seqOfDeal];

        p.isClaimer[cl.claimer] = <font style="color:#569cd6;">true</font>;
        p.claims.push(cl);

        cls.packages[<font style="color:#b5cea8;">0</font>].isClaimer[cl.claimer] = <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @notice Compute claim weights and ratios.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param rom Register of members.</font>
    <font style="color:#569cd6;">function</font> computeFirstRefusal(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint256</font> seqOfDeal,
        IRegisterOfMembers rom
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Claim[] <font style="color:#569cd6;">memory</font> output) {

        <font style="color:#569cd6;">if</font> (!isDeal(cls, seqOfDeal)) {
            <font style="color:#569cd6;">revert</font> FRClaims_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FRC_DealNotExist"</font>));
        }

        Package <font style="color:#569cd6;">storage</font> p = cls.packages[seqOfDeal];

        <font style="color:#569cd6;">if</font> (p.sumOfWeight == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint256</font> len = p.claims.length;
            <font style="color:#4ec9b0;">uint256</font> i;

            <font style="color:#569cd6;">while</font> (i < len) {
                Claim <font style="color:#569cd6;">storage</font> cl = p.claims[i];

                <font style="color:#4ec9b0;">uint64</font> weight = rom.votesInHand(cl.claimer);
                cl.weight = weight;
                p.sumOfWeight += weight;
                i++;
            }

            i = <font style="color:#b5cea8;">0</font>;
            <font style="color:#4ec9b0;">uint256</font> sum;
            len--;

            <font style="color:#569cd6;">while</font>(i < len) {
                Claim <font style="color:#569cd6;">storage</font> cl = p.claims[i];

                cl.ratio = cl.weight * <font style="color:#b5cea8;">10000</font> / p.sumOfWeight;
                sum += cl.ratio;
                i++;
            }

            p.claims[len].ratio = <font style="color:#b5cea8;">10000</font> - <font style="color:#4ec9b0;">uint64</font>(sum);

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> FRClaims_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FRClaims_AlreadyCreated"</font>));

        output = p.claims;
    }

    <font style="color:#6a9955;">//  ################################</font>
    <font style="color:#6a9955;">//  ##       Read I/O             ##</font>
    <font style="color:#6a9955;">//  ################################</font>

    <font style="color:#6a9955;">/// @notice Check whether an account has any claim.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> isClaimer(Claims <font style="color:#569cd6;">storage</font> cls, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> cls.packages[<font style="color:#b5cea8;">0</font>].isClaimer[acct];
    }

    <font style="color:#6a9955;">/// @notice Check whether an account claimed a deal.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> isClaimerOfDeal(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> cls.packages[seqOfDeal].isClaimer[acct];
    }

    <font style="color:#6a9955;">/// @notice Check whether a deal has claims.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> isDeal(
        Claims <font style="color:#569cd6;">storage</font> cls,
        <font style="color:#4ec9b0;">uint</font> seqOfDeal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> cls.packages[seqOfDeal].claims.length > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get list of deals with claims.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#569cd6;">function</font> getDeals(Claims <font style="color:#569cd6;">storage</font> cls) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        Claim[] <font style="color:#569cd6;">memory</font> claims = cls.packages[<font style="color:#b5cea8;">0</font>].claims;
        <font style="color:#4ec9b0;">uint</font> len = claims.length;
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> deals = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint</font>[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            deals[len - <font style="color:#b5cea8;">1</font>] = claims[len - <font style="color:#b5cea8;">1</font>].seqOfDeal;
            len--;
        }

        <font style="color:#569cd6;">return</font> deals;
    }

    <font style="color:#6a9955;">/// @notice Get claims of a deal.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#6a9955;">/// @param seqOfDeal Deal sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getClaimsOfDeal(Claims <font style="color:#569cd6;">storage</font> cls, <font style="color:#4ec9b0;">uint256</font> seqOfDeal)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Claim[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">if</font> (!isDeal(cls, seqOfDeal)) {
            <font style="color:#569cd6;">revert</font> FRClaims_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"FRC_DealNotExist"</font>));
        }
        <font style="color:#569cd6;">return</font> cls.packages[seqOfDeal].claims;
    }

    <font style="color:#6a9955;">/// @notice Check whether all deals have computed allocations.</font>
    <font style="color:#6a9955;">/// @param cls Storage claims.</font>
    <font style="color:#569cd6;">function</font> allAccepted(Claims <font style="color:#569cd6;">storage</font> cls) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> deals = getDeals(cls);
        <font style="color:#4ec9b0;">uint</font> len = deals.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (cls.packages[deals[len - <font style="color:#b5cea8;">1</font>]].sumOfWeight == <font style="color:#b5cea8;">0</font>)
                <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
            len--;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## GoldChain.sol

---

| |
|:---|
| **contracts/lib/books/GoldChain.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title GoldChain</font>
<font style="color:#6a9955;">/// @notice Sorted doubly-linked list for order book records.</font>
<font style="color:#569cd6;">library</font> GoldChain {

    <font style="color:#6a9955;">/// @notice Linked-list node data.</font>
    <font style="color:#569cd6;">struct</font> Node {
        <font style="color:#4ec9b0;">uint32</font> prev;
        <font style="color:#4ec9b0;">uint32</font> next;
        <font style="color:#4ec9b0;">uint40</font> issuer;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint32</font> price;
        <font style="color:#4ec9b0;">uint48</font> expireDate;
        <font style="color:#4ec9b0;">bool</font> isOffer;
    }

    <font style="color:#6a9955;">/// @notice Order payload data.</font>
    <font style="color:#569cd6;">struct</font> Data {
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint40</font> groupRep;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
        <font style="color:#4ec9b0;">uint128</font> margin;
        <font style="color:#4ec9b0;">bool</font> inEth;
        <font style="color:#4ec9b0;">address</font> pubKey;
        <font style="color:#4ec9b0;">uint48</font> date;
        <font style="color:#4ec9b0;">uint48</font> issueDate;
    }

    <font style="color:#6a9955;">/// @notice Full order record.</font>
    <font style="color:#569cd6;">struct</font> Order {
        Node node;
        Data data;
    }

    <font style="color:#6a9955;">/* node[0] {
        prev: tail;
        next: head;
        price: counter;
    } */</font>

   <font style="color:#6a9955;">/* data[0] {
        seqOfShare: length;
   }*/</font>

    <font style="color:#6a9955;">/// @notice Chain storage.</font>
    <font style="color:#569cd6;">struct</font> Chain {
        <font style="color:#569cd6;">mapping</font> (<font style="color:#4ec9b0;">uint</font> => Order) orders;
    }

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Error  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#569cd6;">error</font> GC_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> GC_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Node ====</font>

    <font style="color:#6a9955;">/// @notice Parse encoded node.</font>
    <font style="color:#6a9955;">/// @param sn Encoded node bytes32.</font>
    <font style="color:#569cd6;">function</font> parseNode(
        <font style="color:#4ec9b0;">bytes32</font> sn
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Node <font style="color:#569cd6;">memory</font> node) {

        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        node.prev = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">224</font>);
        node.next = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">192</font>);
        node.issuer = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">152</font>);
        node.paid = <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">88</font>);
        node.price = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">56</font>);
        node.expireDate = <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">8</font>);
        node.isOffer = <font style="color:#4ec9b0;">uint8</font>(_sn) == <font style="color:#b5cea8;">1</font>;
    }

    <font style="color:#6a9955;">/// @notice Encode node into bytes32.</font>
    <font style="color:#6a9955;">/// @param node Node data.</font>
    <font style="color:#569cd6;">function</font> codifyNode(
        Node <font style="color:#569cd6;">memory</font> node
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn =
            abi.encodePacked(
                node.prev,
                node.next,
                node.issuer,
                node.paid,
                node.price,
                node.expireDate,
                <font style="color:#4ec9b0;">uint8</font>(node.isOffer ? <font style="color:#b5cea8;">1</font> : <font style="color:#b5cea8;">0</font>)
            );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== Data ====</font>

    <font style="color:#6a9955;">/// @notice Parse encoded data.</font>
    <font style="color:#6a9955;">/// @param sn Encoded data bytes32.</font>
    <font style="color:#569cd6;">function</font> parseData(
        <font style="color:#4ec9b0;">bytes32</font> sn
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Data <font style="color:#569cd6;">memory</font> data) {

        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        data.classOfShare = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>);
        data.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">208</font>);
        data.groupRep = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">168</font>);
        data.votingWeight = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">152</font>);
        data.distrWeight = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">136</font>);
        data.margin = <font style="color:#4ec9b0;">uint128</font>(_sn >> <font style="color:#b5cea8;">8</font>);
        data.inEth = <font style="color:#4ec9b0;">bool</font>(<font style="color:#4ec9b0;">uint8</font>(_sn) == <font style="color:#b5cea8;">1</font>);
    }

    <font style="color:#6a9955;">/// @notice Encode data into bytes32.</font>
    <font style="color:#6a9955;">/// @param data Order payload data.</font>
    <font style="color:#569cd6;">function</font> codifyData(
        Data <font style="color:#569cd6;">memory</font> data
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn =
            abi.encodePacked(
                data.classOfShare,
                data.seqOfShare,
                data.groupRep,
                data.votingWeight,
                data.distrWeight,
                data.margin,
                <font style="color:#4ec9b0;">uint8</font>(data.inEth ? <font style="color:#b5cea8;">1</font> : <font style="color:#b5cea8;">0</font>)
            );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== Node ====</font>

    <font style="color:#6a9955;">/// @notice Create and insert an order node.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param issuer Issuer account id (> 0).</font>
    <font style="color:#6a9955;">/// @param paid Paid amount (uint64 range, > 0).</font>
    <font style="color:#6a9955;">/// @param price Price (uint32 range).</font>
    <font style="color:#6a9955;">/// @param execHours Validity window in hours (> 0).</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer side.</font>
    <font style="color:#6a9955;">/// @param data Order payload data.</font>
    <font style="color:#569cd6;">function</font> createNode(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint</font> issuer,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> price,
        <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">bool</font> isOffer,
        Data <font style="color:#569cd6;">memory</font> data
    ) <font style="color:#569cd6;">public</font> {

        <font style="color:#569cd6;">if</font> (<font style="color:#4ec9b0;">uint64</font>(paid) == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> GC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GC_ZeroPaid"</font>));
        }

        <font style="color:#569cd6;">if</font> (!isOffer) {
            <font style="color:#569cd6;">if</font> (data.margin == <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">revert</font> GC_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GC_ZeroMargin"</font>));
            }
        }

        <font style="color:#4ec9b0;">uint32</font> seqOfOrder = _increaseCounter(chain);

        chain.orders[seqOfOrder].node = Node({
            prev:<font style="color:#b5cea8;">0</font>,
            next:<font style="color:#b5cea8;">0</font>,
            issuer: <font style="color:#4ec9b0;">uint40</font>(issuer),
            paid: <font style="color:#4ec9b0;">uint64</font>(paid),
            price: <font style="color:#4ec9b0;">uint32</font>(price),
            expireDate: <font style="color:#4ec9b0;">uint48</font>(block.timestamp + <font style="color:#b5cea8;">3600</font> * execHours),
            isOffer: isOffer
        });

        chain.orders[seqOfOrder].data = data;

        _increaseLength(chain);
        _upChain(chain, seqOfOrder);
    }

    <font style="color:#6a9955;">/// @dev Absolute difference.</font>
    <font style="color:#569cd6;">function</font> _abs(<font style="color:#4ec9b0;">uint32</font> a, <font style="color:#4ec9b0;">uint32</font> b) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font> c) {
        c = a > b ? a - b : b - a;
    }

    <font style="color:#6a9955;">/// @dev Insert node into chain by price order.</font>
    <font style="color:#569cd6;">function</font> _upChain(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint32</font> seqOfOrder) <font style="color:#569cd6;">private</font> {

        Node <font style="color:#569cd6;">storage</font> node = chain.orders[seqOfOrder].node;

        <font style="color:#4ec9b0;">bool</font> sortFromHead =
            _abs(chain.orders[tail(chain)].node.price, node.price) >
            _abs(chain.orders[head(chain)].node.price, node.price);

        (<font style="color:#4ec9b0;">uint</font> prev, <font style="color:#4ec9b0;">uint</font> next) =
            _getPos(
                chain,
                node.price,
                sortFromHead ? <font style="color:#b5cea8;">0</font> : tail(chain),
                sortFromHead ? head(chain) : <font style="color:#b5cea8;">0</font>,
                sortFromHead,
                node.isOffer
            );

        node.prev = <font style="color:#4ec9b0;">uint32</font>(prev);
        node.next = <font style="color:#4ec9b0;">uint32</font>(next);

        chain.orders[prev].node.next = seqOfOrder;
        chain.orders[next].node.prev = seqOfOrder;
    }

    <font style="color:#6a9955;">/// @dev Find insertion position.</font>
    <font style="color:#569cd6;">function</font> _getPos(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint</font> price,
        <font style="color:#4ec9b0;">uint</font> prev,
        <font style="color:#4ec9b0;">uint</font> next,
        <font style="color:#4ec9b0;">bool</font> sortFromHead,
        <font style="color:#4ec9b0;">bool</font> isAscedning
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>, <font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">if</font> (sortFromHead) {
            <font style="color:#569cd6;">if</font> (isAscedning) {
                <font style="color:#569cd6;">while</font>(next > <font style="color:#b5cea8;">0</font> && chain.orders[next].node.price <= price) {
                    prev = next;
                    next = chain.orders[next].node.next;
                }
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">while</font>(next > <font style="color:#b5cea8;">0</font> && chain.orders[next].node.price >= price) {
                    prev = next;
                    next = chain.orders[next].node.next;
                }
            }
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (isAscedning) {
                <font style="color:#569cd6;">while</font>(prev > <font style="color:#b5cea8;">0</font> && chain.orders[prev].node.price > price) {
                    next = prev;
                    prev = chain.orders[prev].node.prev;
                }
            } <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">while</font>(prev > <font style="color:#b5cea8;">0</font> && chain.orders[prev].node.price < price) {
                    next = prev;
                    prev = chain.orders[prev].node.prev;
                }
            }
        }
        <font style="color:#569cd6;">return</font> (prev, next);
    }

    <font style="color:#6a9955;">/// @notice Remove an order from the chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> offChain(
        Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Order <font style="color:#569cd6;">memory</font> order) {

        <font style="color:#569cd6;">if</font> (!isNode(chain, seqOfOrder)) {
            <font style="color:#569cd6;">revert</font> GC_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"GC_OrderNotExist"</font>));
        }

        order = chain.orders[seqOfOrder];

        chain.orders[order.node.prev].node.next = order.node.next;
        chain.orders[order.node.next].node.prev = order.node.prev;

        <font style="color:#569cd6;">delete</font> chain.orders[seqOfOrder];

        _decreaseLength(chain);
    }

    <font style="color:#6a9955;">/// @dev Increase order counter to a free id.</font>
    <font style="color:#569cd6;">function</font> _increaseCounter(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font> out) {

        Node <font style="color:#569cd6;">storage</font> node = chain.orders[<font style="color:#b5cea8;">0</font>].node;
        out = node.price;

        <font style="color:#569cd6;">do</font> {
            <font style="color:#569cd6;">unchecked</font> {
                out++;
            }
        } <font style="color:#569cd6;">while</font>(isNode(chain, out) ||
            out == <font style="color:#b5cea8;">0</font>);

        node.price = out;
    }

    <font style="color:#6a9955;">/// @dev Increase chain length.</font>
    <font style="color:#569cd6;">function</font> _increaseLength(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">private</font> {
        chain.orders[<font style="color:#b5cea8;">0</font>].data.seqOfShare++;
    }

    <font style="color:#6a9955;">/// @dev Decrease chain length.</font>
    <font style="color:#569cd6;">function</font> _decreaseLength(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">private</font> {
        chain.orders[<font style="color:#b5cea8;">0</font>].data.seqOfShare--;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##   Read I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Node[0] ====</font>

    <font style="color:#6a9955;">/// @notice Get current order counter.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> counter(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.orders[<font style="color:#b5cea8;">0</font>].node.price;
    }

    <font style="color:#6a9955;">/// @notice Get number of active orders.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> length(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.orders[<font style="color:#b5cea8;">0</font>].data.seqOfShare;
    }

    <font style="color:#6a9955;">/// @notice Get head order id.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> head(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.orders[<font style="color:#b5cea8;">0</font>].node.next;
    }

    <font style="color:#6a9955;">/// @notice Get tail order id.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> tail(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.orders[<font style="color:#b5cea8;">0</font>].node.prev;
    }

    <font style="color:#6a9955;">// ==== Node ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an order exists.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> isNode(
        Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> chain.orders[seqOfOrder].node.expireDate > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get node data.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getNode(
        Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Node <font style="color:#569cd6;">memory</font> node) {
        node = chain.orders[seqOfOrder].node;
    }

    <font style="color:#6a9955;">/// @notice Get order payload data.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getData(
        Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Data <font style="color:#569cd6;">memory</font> data) {
        data = chain.orders[seqOfOrder].data;
    }

    <font style="color:#6a9955;">/// @notice Get full order record.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getOrder(
        Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Order <font style="color:#569cd6;">memory</font> order) {
        order = chain.orders[seqOfOrder];
    }

    <font style="color:#6a9955;">// ==== Chain ====</font>

    <font style="color:#6a9955;">/// @notice Get order ids in chain order.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> getSeqList(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">uint</font> len = length(chain);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint</font>[](len);

        Node <font style="color:#569cd6;">memory</font> node = chain.orders[<font style="color:#b5cea8;">0</font>].node;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            list[len-<font style="color:#b5cea8;">1</font>] = node.prev;
            node = chain.orders[node.prev].node;
            len--;
        }

        <font style="color:#569cd6;">return</font> list;
    }

    <font style="color:#6a9955;">/// @notice Get all orders in chain order.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> getChain(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Order[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">uint</font> len = length(chain);
        Order[] <font style="color:#569cd6;">memory</font> list = <font style="color:#569cd6;">new</font> Order[](len);

        Node <font style="color:#569cd6;">memory</font> node = chain.orders[<font style="color:#b5cea8;">0</font>].node;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            list[len-<font style="color:#b5cea8;">1</font>] = chain.orders[node.prev];
            node = chain.orders[node.prev].node;
            len--;
        }

        <font style="color:#569cd6;">return</font> list;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## InvestorsRepo.sol

---

| |
|:---|
| **contracts/lib/books/InvestorsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title InvestorsRepo</font>
<font style="color:#6a9955;">/// @notice Repository for investor onboarding and approval status.</font>
<font style="color:#569cd6;">library</font> InvestorsRepo {

    <font style="color:#6a9955;">/// @notice Lifecycle state of an investor.</font>
    <font style="color:#569cd6;">enum</font> StateOfInvestor {
        Pending,
        Approved,
        Revoked
    }

    <font style="color:#6a9955;">/// @notice Investor record.</font>
    <font style="color:#569cd6;">struct</font> Investor {
        <font style="color:#4ec9b0;">uint40</font> userNo;
        <font style="color:#4ec9b0;">uint40</font> groupRep;
        <font style="color:#4ec9b0;">uint48</font> regDate;
        <font style="color:#4ec9b0;">uint40</font> verifier;
        <font style="color:#4ec9b0;">uint48</font> approveDate;
        <font style="color:#4ec9b0;">uint32</font> data;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">bytes32</font> idHash;
    }

    <font style="color:#6a9955;">/// @notice Storage repo keyed by user number.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Investor) investors;
        <font style="color:#4ec9b0;">uint</font>[] investorsList;
    }

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Error  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#569cd6;">error</font> IR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> IR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> IR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Modifier  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Ensure the investor exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Investor user number.</font>
    <font style="color:#569cd6;">modifier</font> investorExist(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) {
        <font style="color:#569cd6;">if</font> (!isInvestor(repo, acct)) {
            <font style="color:#569cd6;">revert</font> IR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"IR_InvestorNotExist"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#6a9955;">/// @notice Register or update investor profile.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param userNo Investor user number.</font>
    <font style="color:#6a9955;">/// @param groupRep Group representative user number.</font>
    <font style="color:#6a9955;">/// @param idHash Hash of investor ID document.</font>
    <font style="color:#569cd6;">function</font> regInvestor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> groupRep,
        <font style="color:#4ec9b0;">bytes32</font> idHash
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (idHash == <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> IR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"IR_ZeroIdHash"</font>));
        }

        <font style="color:#4ec9b0;">uint40</font> user = <font style="color:#4ec9b0;">uint40</font>(userNo);

        <font style="color:#569cd6;">if</font> (user == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> IR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"IR_ZeroUserNo"</font>));
        }

        Investor <font style="color:#569cd6;">storage</font> investor = repo.investors[user];

        investor.userNo = user;
        investor.groupRep = <font style="color:#4ec9b0;">uint40</font>(groupRep);
        investor.idHash = idHash;

        <font style="color:#569cd6;">if</font> (!isInvestor(repo, userNo)) {
            repo.investorsList.push(user);
            investor.regDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (investor.state == <font style="color:#4ec9b0;">uint8</font>(StateOfInvestor.Approved))
                _decreaseQtyOfInvestors(repo);
            investor.state = <font style="color:#4ec9b0;">uint8</font>(StateOfInvestor.Pending);
        }
    }

    <font style="color:#6a9955;">/// @notice Approve a pending investor.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Investor user number.</font>
    <font style="color:#6a9955;">/// @param verifier Approver user number.</font>
    <font style="color:#569cd6;">function</font> approveInvestor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> verifier
    ) <font style="color:#569cd6;">public</font> investorExist(repo, acct) {

        Investor <font style="color:#569cd6;">storage</font> investor = repo.investors[acct];

        <font style="color:#569cd6;">if</font> (investor.state == <font style="color:#4ec9b0;">uint8</font>(StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> IR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"IR_AlreadyApproved"</font>));
        }

        investor.verifier = <font style="color:#4ec9b0;">uint40</font>(verifier);
        investor.approveDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        investor.state = <font style="color:#4ec9b0;">uint8</font>(StateOfInvestor.Approved);

        _increaseQtyOfInvestors(repo);
    }

    <font style="color:#6a9955;">/// @notice Revoke an approved investor.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Investor user number.</font>
    <font style="color:#6a9955;">/// @param verifier Revoker user number.</font>
    <font style="color:#569cd6;">function</font> revokeInvestor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> verifier
    ) <font style="color:#569cd6;">public</font> {

        Investor <font style="color:#569cd6;">storage</font> investor = repo.investors[acct];

        <font style="color:#569cd6;">if</font> (investor.state != <font style="color:#4ec9b0;">uint8</font>(StateOfInvestor.Approved)) {
            <font style="color:#569cd6;">revert</font> IR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"IR_NotApproved"</font>));
        }

        investor.verifier = <font style="color:#4ec9b0;">uint40</font>(verifier);
        investor.approveDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        investor.state = <font style="color:#4ec9b0;">uint8</font>(StateOfInvestor.Revoked);

        _decreaseQtyOfInvestors(repo);
    }

    <font style="color:#6a9955;">/// @notice Increment approved investor counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> _increaseQtyOfInvestors(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">private</font> {
        repo.investors[<font style="color:#b5cea8;">0</font>].verifier++;
    }

    <font style="color:#6a9955;">/// @notice Decrement approved investor counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> _decreaseQtyOfInvestors(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">private</font> {
        repo.investors[<font style="color:#b5cea8;">0</font>].verifier--;
    }

    <font style="color:#6a9955;">/// @notice Restore repo from snapshots.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param list Investor list to restore.</font>
    <font style="color:#6a9955;">/// @param qtyOfInvestors Approved investor count.</font>
    <font style="color:#569cd6;">function</font> restoreRepo(
        Repo <font style="color:#569cd6;">storage</font> repo, Investor[] <font style="color:#569cd6;">memory</font> list, <font style="color:#4ec9b0;">uint</font> qtyOfInvestors
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">while</font> (i < len) {
            Investor <font style="color:#569cd6;">memory</font> investor = list[i];
            repo.investors[investor.userNo] = investor;
            repo.investorsList.push(investor.userNo);
            i++;
        }
        repo.investors[<font style="color:#b5cea8;">0</font>].verifier = <font style="color:#4ec9b0;">uint40</font>(qtyOfInvestors);
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Investor ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an investor exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Investor user number.</font>
    <font style="color:#569cd6;">function</font> isInvestor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.investors[acct].regDate > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get investor record.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Investor user number.</font>
    <font style="color:#569cd6;">function</font> getInvestor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> investorExist(repo, acct) <font style="color:#569cd6;">returns</font>(Investor <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.investors[acct];
    }

    <font style="color:#6a9955;">/// @notice Get approved investor count.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getQtyOfInvestors(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.investors[<font style="color:#b5cea8;">0</font>].verifier;
    }

    <font style="color:#6a9955;">/// @notice Get list of investor user numbers.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> investorList(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.investorsList;
    }

    <font style="color:#6a9955;">/// @notice Get full investor info list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> investorInfoList(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Investor[] <font style="color:#569cd6;">memory</font> list) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList = repo.investorsList;
        <font style="color:#4ec9b0;">uint</font> len = seqList.length;

        list = <font style="color:#569cd6;">new</font> Investor[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            list[len - <font style="color:#b5cea8;">1</font>] = repo.investors[seqList[len - <font style="color:#b5cea8;">1</font>]];
            len--;
        }

        <font style="color:#569cd6;">return</font> list;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## LinksRepo.sol

---

| |
|:---|
| **contracts/lib/books/LinksRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rom/IRegisterOfMembers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/ros/IRegisterOfShares.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./DealsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./RulesParser.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./SharesRepo.sol"</font>;

<font style="color:#6a9955;">/// @title LinksRepo</font>
<font style="color:#6a9955;">/// @notice Library for managing drag-along/tag-along relationships and rules.</font>
<font style="color:#6a9955;">/// @dev Stores rules by group representative and tracks follower sets.</font>
<font style="color:#569cd6;">library</font> LinksRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;

    <font style="color:#6a9955;">/// @notice Trigger conditions for along rights.</font>
    <font style="color:#569cd6;">enum</font> TriggerTypeOfAlongs {
        NoConditions,
        ControlChanged,
        ControlChangedWithHigherPrice,
        ControlChangedWithHigherROE
    }

    <font style="color:#6a9955;">/// @notice Link rule and its followers set.</font>
    <font style="color:#569cd6;">struct</font> Link {
        RulesParser.LinkRule linkRule;
        EnumerableSet.UintSet followersList;
    }

    <font style="color:#6a9955;">/// @notice Repository storage for links by dragger group.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// dragger => Link</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Link) links;
        EnumerableSet.UintSet  draggersList;
    }

    <font style="color:#569cd6;">error</font> LinksRepo_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> LinksRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @dev Reverts if dragger is not registered.</font>
    <font style="color:#569cd6;">modifier</font> draggerExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> dragger, IRegisterOfMembers _rom) {
        <font style="color:#569cd6;">if</font> (!isDragger(repo, dragger, _rom)) {
            <font style="color:#569cd6;">revert</font> LinksRepo_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LinksR_NotDragger"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">/// @notice Add a dragger with a link rule.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param rule Encoded link rule.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> addDragger(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> rule, <font style="color:#4ec9b0;">uint256</font> dragger, IRegisterOfMembers _rom) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint40</font> groupRep = _rom.groupRep(dragger);
        <font style="color:#569cd6;">if</font> (repo.draggersList.add(groupRep))
            repo.links[groupRep].linkRule = rule.linkRuleParser();
    }

    <font style="color:#6a9955;">/// @notice Remove a dragger and its followers.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account (group representative).</font>
    <font style="color:#569cd6;">function</font> removeDragger(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> dragger) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (repo.draggersList.remove(dragger))
            <font style="color:#569cd6;">delete</font> repo.links[dragger];
        }

    <font style="color:#6a9955;">/// @notice Add a follower to a dragger.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account (group representative).</font>
    <font style="color:#6a9955;">/// @param follower Follower account.</font>
    <font style="color:#569cd6;">function</font> addFollower(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower) <font style="color:#569cd6;">public</font> {
        repo.links[dragger].followersList.add(<font style="color:#4ec9b0;">uint40</font>(follower));
    }

    <font style="color:#6a9955;">/// @notice Remove a follower from a dragger.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account (group representative).</font>
    <font style="color:#6a9955;">/// @param follower Follower account.</font>
    <font style="color:#569cd6;">function</font> removeFollower(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> dragger, <font style="color:#4ec9b0;">uint256</font> follower) <font style="color:#569cd6;">public</font> {
        repo.links[dragger].followersList.remove(follower);
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is a dragger.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> isDragger(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> dragger, IRegisterOfMembers _rom)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#4ec9b0;">uint40</font> groupRep = _rom.groupRep(dragger);
        <font style="color:#569cd6;">return</font> repo.draggersList.contains(groupRep);
    }

    <font style="color:#6a9955;">/// @notice Get link rule for a dragger.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> getLinkRule(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> dragger, IRegisterOfMembers _rom)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> draggerExist(repo, dragger, _rom)
        <font style="color:#569cd6;">returns</font> (RulesParser.LinkRule <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint40</font> groupRep = _rom.groupRep(dragger);
        <font style="color:#569cd6;">return</font> repo.links[groupRep].linkRule;
    }

    <font style="color:#6a9955;">/// @notice Check whether a follower is linked to a dragger.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param follower Follower account.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> isFollower(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> dragger,
        <font style="color:#4ec9b0;">uint256</font> follower,
        IRegisterOfMembers _rom
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> draggerExist(repo, dragger, _rom)
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#4ec9b0;">uint40</font> groupRep = _rom.groupRep(dragger);
        <font style="color:#569cd6;">return</font> repo.links[groupRep].followersList.contains(<font style="color:#4ec9b0;">uint40</font>(follower));
    }

    <font style="color:#6a9955;">/// @notice Get list of draggers (group representatives).</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#569cd6;">function</font> getDraggers(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.draggersList.values();
    }

    <font style="color:#6a9955;">/// @notice Get followers linked to a dragger.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param dragger Dragger account.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> getFollowers(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> dragger, IRegisterOfMembers _rom)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> draggerExist(repo, dragger, _rom) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint40</font> groupRep = _rom.groupRep(dragger);
        <font style="color:#569cd6;">return</font> repo.links[groupRep].followersList.values();
    }

    <font style="color:#6a9955;">/// @notice Check price/ROE constraints based on link rule.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#6a9955;">/// @param _ros Register of shares.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> priceCheck(
        Repo <font style="color:#569cd6;">storage</font> repo,
        DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal,
        IRegisterOfShares _ros,
        IRegisterOfMembers _rom
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {

        RulesParser.LinkRule <font style="color:#569cd6;">memory</font> lr =
            getLinkRule(repo, deal.head.seller, _rom);

        <font style="color:#569cd6;">if</font> (lr.triggerType == <font style="color:#4ec9b0;">uint8</font>(TriggerTypeOfAlongs.ControlChangedWithHigherPrice))
            <font style="color:#569cd6;">return</font> (deal.head.priceOfPaid >= lr.rate);

        SharesRepo.Share <font style="color:#569cd6;">memory</font> share =
            _ros.getShare(deal.head.seqOfShare);

        <font style="color:#569cd6;">if</font> (lr.triggerType == <font style="color:#4ec9b0;">uint8</font>(TriggerTypeOfAlongs.ControlChangedWithHigherROE))
            <font style="color:#569cd6;">return</font> (_roeOfDeal(
                deal.head.priceOfPaid,
                share.head.priceOfPaid,
                deal.head.closingDeadline,
                share.head.issueDate) >= lr.rate);

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @dev Compute annualized ROE in basis points (scaled).</font>
    <font style="color:#569cd6;">function</font> _roeOfDeal(
        <font style="color:#4ec9b0;">uint</font> dealPrice,
        <font style="color:#4ec9b0;">uint</font> issuePrice,
        <font style="color:#4ec9b0;">uint</font> closingDeadline,
        <font style="color:#4ec9b0;">uint</font> issueDateOfShare
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font> roe) {
        <font style="color:#569cd6;">if</font> (dealPrice <= issuePrice) {
            <font style="color:#569cd6;">revert</font> LinksRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LinksR_NonPositiveROE"</font>));
        }
        <font style="color:#569cd6;">if</font> (closingDeadline <= issueDateOfShare) {
            <font style="color:#569cd6;">revert</font> LinksRepo_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LinksR_NegativeHoldingPeriod"</font>));
        }

        roe = (dealPrice - issuePrice) * <font style="color:#b5cea8;">31536</font> * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">7</font> / issuePrice / (closingDeadline - issueDateOfShare);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## LockersRepo.sol

---

| |
|:---|
| **contracts/lib/books/LockersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title LockersRepo</font>
<font style="color:#6a9955;">/// @notice Hash-locked lockers for points/consideration.</font>
<font style="color:#569cd6;">library</font> LockersRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.Bytes32Set;

    <font style="color:#6a9955;">/// @notice Locker header fields.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint40</font> <font style="color:#569cd6;">from</font>;
        <font style="color:#4ec9b0;">uint40</font> to;
        <font style="color:#4ec9b0;">uint48</font> expireDate;
        <font style="color:#4ec9b0;">uint128</font> value;
    }
    <font style="color:#6a9955;">/// @notice Locker payload fields.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">address</font> counterLocker;
        <font style="color:#4ec9b0;">bytes</font> payload;
    }
    <font style="color:#6a9955;">/// @notice Full locker record.</font>
    <font style="color:#569cd6;">struct</font> Locker {
        Head head;
        Body body;
    }

    <font style="color:#6a9955;">/// @notice Repository of lockers by hashLock.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// hashLock => locker</font>
        <font style="color:#569cd6;">mapping</font> (<font style="color:#4ec9b0;">bytes32</font> => Locker) lockers;
        EnumerableSet.Bytes32Set snList;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Error    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#569cd6;">error</font> LR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> LR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> LR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Write    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Parse locker head from packed bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed head bytes32.</font>
    <font style="color:#569cd6;">function</font> headSnParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head = Head({
            <font style="color:#569cd6;">from</font>: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            to: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">176</font>),
            expireDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">128</font>),
            value: <font style="color:#4ec9b0;">uint128</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Pack locker head into bytes32.</font>
    <font style="color:#6a9955;">/// @param head Locker head.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> headSn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.<font style="color:#569cd6;">from</font>,
                            head.to,
                            head.expireDate,
                            head.value);
        <font style="color:#569cd6;">assembly</font> {
            headSn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">/// @notice Lock points without payload.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param head Locker header.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#569cd6;">function</font> lockPoints(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Head <font style="color:#569cd6;">memory</font> head,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">public</font> {
        Body <font style="color:#569cd6;">memory</font> body;
        lockConsideration(repo, head, body, hashLock);
    }

    <font style="color:#6a9955;">/// @notice Lock consideration with payload.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param head Locker header.</font>
    <font style="color:#6a9955;">/// @param body Locker payload.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#569cd6;">function</font> lockConsideration(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Head <font style="color:#569cd6;">memory</font> head,
        Body <font style="color:#569cd6;">memory</font> body,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (repo.snList.add(hashLock)) {
            Locker <font style="color:#569cd6;">storage</font> locker = repo.lockers[hashLock];
            locker.head = head;
            locker.body = body;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> (<font style="color:#ce9178;">"LR.lockConsideration: occupied"</font>);
    }

    <font style="color:#6a9955;">/// @notice Pickup locked points with preimage.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#6a9955;">/// @param hashKey Preimage string.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> pickupPoints(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head) {

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> key = <font style="color:#4ec9b0;">bytes</font>(hashKey);

        <font style="color:#569cd6;">if</font> (hashLock != keccak256(key)) {
            <font style="color:#569cd6;">revert</font> LR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LR_WrongKey"</font>));
        }

        Locker <font style="color:#569cd6;">storage</font> locker = repo.lockers[hashLock];

        <font style="color:#569cd6;">if</font> (block.timestamp >= locker.head.expireDate) {
            <font style="color:#569cd6;">revert</font> LR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LR_LockerExpired"</font>));
        }

        <font style="color:#4ec9b0;">bool</font> flag = <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">if</font> (locker.body.counterLocker != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">if</font> (locker.head.to != caller) {
                <font style="color:#569cd6;">revert</font> LR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LR_NotIntendedReceiver"</font>));
            }

            <font style="color:#4ec9b0;">uint</font> len = key.length;
            <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> zero = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">bytes</font>(<font style="color:#b5cea8;">32</font> - (len % <font style="color:#b5cea8;">32</font>));

            <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> payload = abi.encodePacked(locker.body.payload, len, key, zero);
            (flag, ) = locker.body.counterLocker.call(payload);
        }

        <font style="color:#569cd6;">if</font> (flag) {
            head = locker.head;
            <font style="color:#569cd6;">delete</font> repo.lockers[hashLock];
            repo.snList.remove(hashLock);
        }
    }

    <font style="color:#6a9955;">/// @notice Withdraw after locker expiry.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> withdrawDeposit(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint256</font> caller
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head) {

        Locker <font style="color:#569cd6;">memory</font> locker = repo.lockers[hashLock];

        <font style="color:#569cd6;">if</font> (block.timestamp < locker.head.expireDate) {
            <font style="color:#569cd6;">revert</font> LR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LR_LockerNotExpired"</font>));
        }

        <font style="color:#569cd6;">if</font> (locker.head.<font style="color:#569cd6;">from</font> != caller) {
            <font style="color:#569cd6;">revert</font> LR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LR_NotSettlor"</font>));
        }

        <font style="color:#569cd6;">if</font> (repo.snList.remove(hashLock)) {
            head = locker.head;
            <font style="color:#569cd6;">delete</font> repo.lockers[hashLock];
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> LR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"LR_LockerNotExist"</font>));
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Read     ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Get locker head by hashLock.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#569cd6;">function</font> getHeadOfLocker(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#569cd6;">return</font> repo.lockers[hashLock].head;
    }

    <font style="color:#6a9955;">/// @notice Get full locker by hashLock.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#569cd6;">function</font> getLocker(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Locker <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.lockers[hashLock];
    }

    <font style="color:#6a9955;">/// @notice Get list of hashLocks.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getSnList(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> ) {
        <font style="color:#569cd6;">return</font> repo.snList.values();
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## MembersRepo.sol

---

| |
|:---|
| **contracts/lib/books/MembersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./Checkpoints.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./SharesRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./TopChain.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/ros/IRegisterOfShares.sol"</font>;

<font style="color:#6a9955;">/// @title MembersRepo</font>
<font style="color:#6a9955;">/// @notice Repository for member votes, classes, and share holdings.</font>
<font style="color:#569cd6;">library</font> MembersRepo {
    <font style="color:#569cd6;">using</font> Checkpoints <font style="color:#569cd6;">for</font> Checkpoints.History;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> TopChain <font style="color:#569cd6;">for</font> TopChain.Chain;

    <font style="color:#6a9955;">/// @notice Member holdings and vote history.</font>
    <font style="color:#569cd6;">struct</font> Member {
        Checkpoints.History votesInHand;
        <font style="color:#6a9955;">// class => seqList</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => EnumerableSet.UintSet) sharesOfClass;
        EnumerableSet.UintSet classesBelonged;
    }

    <font style="color:#6a9955;">/*
        members[0] {
            votesInHand: ownersEquity;
        }
    */</font>

    <font style="color:#6a9955;">/* Node[0] {
        prev: tail;
        next: head;
        ptr: pending;
        amt: pending;
        sum: totalVotes;
        cat: basedOnPar;
    } */</font>

    <font style="color:#6a9955;">/// @notice Repository of members and class lists.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        TopChain.Chain chain;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Member) members;
        <font style="color:#6a9955;">// class => membersList</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => EnumerableSet.UintSet) membersOfClass;
    }

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Error  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#569cd6;">error</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##  Modifer  ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#6a9955;">/// @notice Ensure the member exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">modifier</font> memberExist(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) {
        <font style="color:#569cd6;">if</font> (!isMember(repo, acct)) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotMember"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">// ==== Zero Node Setting ====</font>

    <font style="color:#6a9955;">/// @notice Switch vote base between par and paid.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param ros Register of shares.</font>
    <font style="color:#6a9955;">/// @param _basedOnPar True for par-based votes.</font>
    <font style="color:#569cd6;">function</font> setVoteBase(
        Repo <font style="color:#569cd6;">storage</font> repo,
        IRegisterOfShares ros,
        <font style="color:#4ec9b0;">bool</font> _basedOnPar
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {

        <font style="color:#569cd6;">if</font> (repo.chain.basedOnPar() != _basedOnPar) {
            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> members =
                repo.membersOfClass[<font style="color:#b5cea8;">0</font>].values();
            <font style="color:#4ec9b0;">uint256</font> len = members.length;

            <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#4ec9b0;">uint256</font> cur = members[len - <font style="color:#b5cea8;">1</font>];

                Member <font style="color:#569cd6;">storage</font> m = repo.members[cur];

                Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> cp =
                    m.votesInHand.latest();

                <font style="color:#569cd6;">if</font> (cp.paid != cp.par) {

                    (<font style="color:#4ec9b0;">uint</font> sumOfVotes, <font style="color:#4ec9b0;">uint</font> sumOfDistrs) = _sortWeights(m, ros, _basedOnPar);

                    <font style="color:#569cd6;">if</font> (_basedOnPar) {
                        repo.chain.increaseAmt(cur, sumOfVotes - cp.points, <font style="color:#569cd6;">true</font>);
                    } <font style="color:#569cd6;">else</font> {
                        repo.chain.increaseAmt(cur, cp.points - sumOfVotes, <font style="color:#569cd6;">false</font>);
                    }

                    <font style="color:#4ec9b0;">uint64</font> amt = _basedOnPar ? cp.par : cp.paid;

                    cp.rate = <font style="color:#4ec9b0;">uint16</font>(sumOfVotes * <font style="color:#b5cea8;">100</font> / amt);
                    cp.points = <font style="color:#4ec9b0;">uint64</font>(sumOfVotes);
                    m.votesInHand.push(cp.rate, cp.paid, cp.par, cp.points);

                    cp.rate = <font style="color:#4ec9b0;">uint16</font>(sumOfDistrs * <font style="color:#b5cea8;">100</font> / amt);
                    cp.points = <font style="color:#4ec9b0;">uint64</font>(sumOfDistrs);
                    m.votesInHand.updateDistrPoints(cp.rate, cp.paid, cp.par, cp.points);
                }

                len--;
            }

            repo.chain.setVoteBase(_basedOnPar);

            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#569cd6;">function</font> _sortWeights(
        Member <font style="color:#569cd6;">storage</font> m,
        IRegisterOfShares ros,
        <font style="color:#4ec9b0;">bool</font> basedOnPar
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> sumOfVotes, <font style="color:#4ec9b0;">uint</font> sumOfDistrs) {

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = m.sharesOfClass[<font style="color:#b5cea8;">0</font>].values();
        <font style="color:#4ec9b0;">uint</font> len = ls.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            SharesRepo.Share <font style="color:#569cd6;">memory</font> share = ros.getShare(ls[len-<font style="color:#b5cea8;">1</font>]);

            <font style="color:#4ec9b0;">uint</font> amt = basedOnPar ? share.body.par : share.body.paid;

            sumOfVotes += amt * share.head.votingWeight / <font style="color:#b5cea8;">100</font>;
            sumOfDistrs += amt * share.body.distrWeight / <font style="color:#b5cea8;">100</font>;

            len--;
        }
    }

    <font style="color:#6a9955;">// ==== Member ====</font>

    <font style="color:#6a9955;">/// @notice Add a member to the repo.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> addMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (repo.membersOfClass[<font style="color:#b5cea8;">0</font>].add(acct)) {
            repo.chain.addNode(acct);
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Remove a member and clear storage.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> delMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (repo.membersOfClass[<font style="color:#b5cea8;">0</font>].remove(acct)) {
            repo.chain.delNode(acct);
            <font style="color:#569cd6;">delete</font> repo.members[acct];
        }
    }

    <font style="color:#6a9955;">/// @notice Link a share to its member owner.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param head Share head.</font>
    <font style="color:#569cd6;">function</font> addShareToMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        SharesRepo.Head <font style="color:#569cd6;">memory</font> head
    ) <font style="color:#569cd6;">public</font> {

        Member <font style="color:#569cd6;">storage</font> member = repo.members[head.shareholder];

        <font style="color:#569cd6;">if</font> (member.sharesOfClass[<font style="color:#b5cea8;">0</font>].add(head.seqOfShare)
            && member.sharesOfClass[head.class].add(head.seqOfShare)
            && member.classesBelonged.add(head.class))
                repo.membersOfClass[head.class].add(head.shareholder);
    }

    <font style="color:#6a9955;">/// @notice Remove a share from its member owner.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param head Share head.</font>
    <font style="color:#569cd6;">function</font> removeShareFromMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        SharesRepo.Head <font style="color:#569cd6;">memory</font> head
    ) <font style="color:#569cd6;">public</font> {

        Member <font style="color:#569cd6;">storage</font> member =
            repo.members[head.shareholder];

        <font style="color:#569cd6;">if</font> (member.sharesOfClass[head.class].remove(head.seqOfShare)
            && member.sharesOfClass[<font style="color:#b5cea8;">0</font>].remove(head.seqOfShare)) {

            <font style="color:#569cd6;">if</font>(member.sharesOfClass[head.class].length() == <font style="color:#b5cea8;">0</font>) {
                repo.membersOfClass[head.class].remove(head.shareholder);
                member.classesBelonged.remove(head.class);
            }
        }

    }

    <font style="color:#6a9955;">/// @notice Update member vote and distribution points.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param votingWeight Voting weight in percent.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight in percent.</font>
    <font style="color:#6a9955;">/// @param deltaPaid Change in paid amount.</font>
    <font style="color:#6a9955;">/// @param deltaPar Change in par amount.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#569cd6;">function</font> increaseAmtOfMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">public</font> {
        _increaseAmtOfMember(repo, acct, votingWeight, distrWeight, deltaPaid, deltaPar, isIncrease);
    }

    <font style="color:#569cd6;">function</font> _increaseAmtOfMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">private</font> {

        Member <font style="color:#569cd6;">storage</font> m = repo.members[acct];
        <font style="color:#4ec9b0;">bool</font> basedOnPar = repo.chain.basedOnPar();
        <font style="color:#4ec9b0;">uint64</font> deltaAmt =  basedOnPar ? <font style="color:#4ec9b0;">uint64</font>(deltaPar) : <font style="color:#4ec9b0;">uint64</font>(deltaPaid);

        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> delta = Checkpoints.Checkpoint({
            timestamp: <font style="color:#b5cea8;">0</font>,
            rate: <font style="color:#b5cea8;">0</font>,
            paid: <font style="color:#4ec9b0;">uint64</font>(deltaPaid),
            par: <font style="color:#4ec9b0;">uint64</font>(deltaPar),
            points: <font style="color:#4ec9b0;">uint64</font>(deltaAmt * votingWeight / <font style="color:#b5cea8;">100</font>)
        });

        <font style="color:#569cd6;">if</font> (acct > <font style="color:#b5cea8;">0</font> && deltaAmt > <font style="color:#b5cea8;">0</font>) {
            repo.chain.increaseAmt(
                acct,
                delta.points,
                isIncrease
            );
        }

        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> cp =
            m.votesInHand.latest();

        cp = _adjustCheckpoint(cp, delta, basedOnPar, isIncrease);

        m.votesInHand.push(cp.rate, cp.paid, cp.par, cp.points);

        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> dp =
            m.votesInHand.getDistrPoints();

        delta.points = deltaAmt * <font style="color:#4ec9b0;">uint16</font>(distrWeight) / <font style="color:#b5cea8;">100</font>;

        dp = _adjustCheckpoint(dp, delta, basedOnPar, isIncrease);

        m.votesInHand.updateDistrPoints(dp.rate, dp.paid, dp.par, dp.points);
    }

    <font style="color:#569cd6;">function</font> _adjustCheckpoint(
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> cp,
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> delta,
        <font style="color:#4ec9b0;">bool</font> basedOnPar,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> output) {

        <font style="color:#569cd6;">if</font> (isIncrease) {
            output.paid = cp.paid + delta.paid;
            output.par = cp.par + delta.par;
            output.points = cp.points + delta.points;
        } <font style="color:#569cd6;">else</font> {
            output.paid = cp.paid - delta.paid;
            output.par = cp.par - delta.par;
            output.points = cp.points - delta.points;
        }

        output.rate = basedOnPar
            ?  output.par > <font style="color:#b5cea8;">0</font> ? <font style="color:#4ec9b0;">uint16</font>(output.points * <font style="color:#b5cea8;">100</font> / output.par) : <font style="color:#b5cea8;">0</font>
            :  output.paid > <font style="color:#b5cea8;">0</font> ? <font style="color:#4ec9b0;">uint16</font>(output.points * <font style="color:#b5cea8;">100</font> / output.paid) : <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">// function _calWeight(</font>
    <font style="color:#6a9955;">//     Checkpoints.Checkpoint memory cp,</font>
    <font style="color:#6a9955;">//     bool basedOnPar,</font>
    <font style="color:#6a9955;">//     Checkpoints.Checkpoint memory delta,</font>
    <font style="color:#6a9955;">//     bool isIncrease</font>
    <font style="color:#6a9955;">// ) private pure returns(uint16 output) {</font>

    <font style="color:#6a9955;">//     if (isIncrease) {</font>
    <font style="color:#6a9955;">//         output = basedOnPar</font>
    <font style="color:#6a9955;">//             ? uint16(((cp.votingWeight * cp.par + delta.votingWeight * delta.par) * 100 / (cp.par + delta.par) + 50) / 100)</font>
    <font style="color:#6a9955;">//             : uint16(((cp.votingWeight * cp.paid + delta.votingWeight * delta.paid) * 100 / (cp.paid + delta.paid) + 50) / 100);</font>
    <font style="color:#6a9955;">//     } else {</font>
    <font style="color:#6a9955;">//         output = basedOnPar</font>
    <font style="color:#6a9955;">//             ? uint16(((cp.votingWeight * cp.par - delta.votingWeight * delta.par) * 100 / (cp.par - delta.par) + 50) / 100)</font>
    <font style="color:#6a9955;">//             : uint16(((cp.votingWeight * cp.paid - delta.votingWeight * delta.paid) * 100 / (cp.paid - delta.paid) + 50) / 100);</font>
    <font style="color:#6a9955;">//     }</font>
    <font style="color:#6a9955;">// }</font>

    <font style="color:#6a9955;">/// @notice Update total capital votes and checkpoints.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param votingWeight Voting weight in percent.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight in percent.</font>
    <font style="color:#6a9955;">/// @param deltaPaid Change in paid amount.</font>
    <font style="color:#6a9955;">/// @param deltaPar Change in par amount.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#569cd6;">function</font> increaseAmtOfCap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> votingWeight,
        <font style="color:#4ec9b0;">uint</font> distrWeight,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">public</font> {

        _increaseAmtOfMember(repo, <font style="color:#b5cea8;">0</font>, votingWeight, distrWeight, deltaPaid, deltaPar, isIncrease);

        <font style="color:#4ec9b0;">bool</font> basedOnPar = repo.chain.basedOnPar();

        <font style="color:#569cd6;">if</font> (basedOnPar && deltaPar > <font style="color:#b5cea8;">0</font>) {
            repo.chain.increaseTotalVotes(deltaPar * votingWeight / <font style="color:#b5cea8;">100</font>, isIncrease);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (!basedOnPar && deltaPaid > <font style="color:#b5cea8;">0</font>) {
            repo.chain.increaseTotalVotes(deltaPaid * votingWeight / <font style="color:#b5cea8;">100</font>, isIncrease);
        }
    }

    <font style="color:#6a9955;">// ==== Restore ====</font>

    <font style="color:#6a9955;">/// @notice Restore member/share relations from snapshots.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param shares Share list.</font>
    <font style="color:#569cd6;">function</font> restoreSharesInRepo(Repo <font style="color:#569cd6;">storage</font> repo, SharesRepo.Share[] <font style="color:#569cd6;">memory</font> shares) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint</font> len = shares.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            SharesRepo.Share <font style="color:#569cd6;">memory</font> share = shares[len - <font style="color:#b5cea8;">1</font>];

            Member <font style="color:#569cd6;">storage</font> member = repo.members[share.head.shareholder];
            member.sharesOfClass[share.head.class].add(share.head.seqOfShare);
            member.sharesOfClass[<font style="color:#b5cea8;">0</font>].add(share.head.seqOfShare);
            member.classesBelonged.add(share.head.class);

            repo.membersOfClass[share.head.class].add(share.head.shareholder);
            repo.membersOfClass[<font style="color:#b5cea8;">0</font>].add(share.head.shareholder);

            len--;
        }
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##    Read      ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">// ==== member ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a user is a member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> isMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.membersOfClass[<font style="color:#b5cea8;">0</font>].contains(acct);
    }

    <font style="color:#6a9955;">/// @notice Get total member count.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> qtyOfMembers(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.membersOfClass[<font style="color:#b5cea8;">0</font>].length();
    }

    <font style="color:#6a9955;">/// @notice Get all member user numbers.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> membersList(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.membersOfClass[<font style="color:#b5cea8;">0</font>].values();
    }

    <font style="color:#6a9955;">// ---- Votes ----</font>

    <font style="color:#6a9955;">/// @notice Get owners' equity checkpoint.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> ownersEquity(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.members[<font style="color:#b5cea8;">0</font>].votesInHand.latest();
    }

    <font style="color:#6a9955;">/// @notice Get owners' distribution points.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> ownersPoints(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.members[<font style="color:#b5cea8;">0</font>].votesInHand.getDistrPoints();
    }

    <font style="color:#6a9955;">/// @notice Get capital checkpoint at date.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#569cd6;">function</font> capAtDate(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> date
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.members[<font style="color:#b5cea8;">0</font>].votesInHand.getAtDate(date);
    }

    <font style="color:#6a9955;">/// @notice Get owners' equity history.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> ownersEquityHistory(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.members[<font style="color:#b5cea8;">0</font>].votesInHand.pointsOfHistory();
    }

    <font style="color:#6a9955;">/// @notice Get member equity checkpoint.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> equityOfMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>
    ) {
        <font style="color:#569cd6;">return</font> repo.members[acct].votesInHand.latest();
    }

    <font style="color:#6a9955;">/// @notice Get member distribution points.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> pointsOfMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>
    ) {
        <font style="color:#569cd6;">return</font> repo.members[acct].votesInHand.getDistrPoints();
    }

    <font style="color:#6a9955;">/// @notice Get member equity at date.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#569cd6;">function</font> equityAtDate(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> date
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(
        Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>
    ) {
        <font style="color:#569cd6;">return</font> repo.members[acct].votesInHand.getAtDate(date);
    }

    <font style="color:#6a9955;">/// @notice Get member votes at date.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param date Timestamp.</font>
    <font style="color:#569cd6;">function</font> votesAtDate(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> date
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">return</font> repo.members[acct].votesInHand.getAtDate(date).points;
    }

    <font style="color:#6a9955;">/// @notice Get member vote history.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> votesHistory(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct)
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.members[acct].votesInHand.pointsOfHistory();
    }

    <font style="color:#6a9955;">// ---- Class ----</font>

    <font style="color:#6a9955;">/// @notice Check if member belongs to class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> isClassMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">return</font> repo.members[acct].classesBelonged.contains(class);
    }

    <font style="color:#6a9955;">/// @notice Get classes a member belongs to.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> classesBelonged(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.members[acct].classesBelonged.values();
    }

    <font style="color:#6a9955;">/// @notice Get member count for a class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> qtyOfClassMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> repo.membersOfClass[class].length();
    }

    <font style="color:#6a9955;">/// @notice Get members of a class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getMembersOfClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.membersOfClass[class].values();
    }

    <font style="color:#6a9955;">// ---- Share ----</font>

    <font style="color:#6a9955;">/// @notice Get count of shares held by member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> qtyOfSharesInHand(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.members[acct].sharesOfClass[<font style="color:#b5cea8;">0</font>].length();
    }

    <font style="color:#6a9955;">/// @notice Get share list held by member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> sharesInHand(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.members[acct].sharesOfClass[<font style="color:#b5cea8;">0</font>].values();
    }

    <font style="color:#6a9955;">/// @notice Get count of shares in class held by member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> qtyOfSharesInClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">if</font> (!isClassMember(repo, acct, class)) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotClassMember"</font>));
        }
        <font style="color:#569cd6;">return</font> repo.members[acct].sharesOfClass[class].length();
    }

    <font style="color:#6a9955;">/// @notice Get share list in class held by member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> sharesInClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> memberExist(repo, acct) <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (!isClassMember(repo, acct, class)) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotClassMember"</font>));
        }
        <font style="color:#569cd6;">return</font> repo.members[acct].sharesOfClass[class].values();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## MockFeedRegistry.sol

---

| |
|:---|
| **contracts/lib/books/MockFeedRegistry.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"@chainlink/contracts/src/v0.8/Denominations.sol"</font>;

<font style="color:#6a9955;">/// @title MockFeedRegistry</font>
<font style="color:#6a9955;">/// @notice Mock Chainlink Feed Registry for testing.</font>
<font style="color:#569cd6;">contract</font> MockFeedRegistry {

    <font style="color:#6a9955;">/**
     * Network: Ethereum Mainnet
     * Feed Registry: 0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf
     */</font>

    <font style="color:#6a9955;">/// @notice Return fixed decimals for mock feed.</font>
    <font style="color:#569cd6;">function</font> decimals() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {
        <font style="color:#6a9955;">// require(base == Denominations.ETH, "not based on ETH");</font>
        <font style="color:#6a9955;">// require(quote != address(0), "zero quote");</font>
        <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">8</font>;
    }

    <font style="color:#6a9955;">/// @notice Return mocked round data.</font>
    <font style="color:#569cd6;">function</font> latestRoundData() <font style="color:#569cd6;">external</font>
        <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (
            <font style="color:#4ec9b0;">uint80</font> roundID,
            <font style="color:#4ec9b0;">int</font>    price,
            <font style="color:#4ec9b0;">uint</font>   startedAt,
            <font style="color:#4ec9b0;">uint</font>   timeStamp,
            <font style="color:#4ec9b0;">uint80</font> answeredInRound
        )
    {
        roundID = <font style="color:#b5cea8;">770919</font>;
        startedAt = <font style="color:#b5cea8;">1567958400</font>;
        timeStamp = block.timestamp;
        answeredInRound = <font style="color:#b5cea8;">190909</font>;
        price = <font style="color:#b5cea8;">225880000000</font>;

        <font style="color:#6a9955;">// int[6] memory rates = [int(0), 166680000000, 130907250548, 153193742107, 24234983023517, 1212778000143];</font>

        <font style="color:#6a9955;">// price = base != Denominations.ETH</font>
        <font style="color:#6a9955;">//     ? rates[0]</font>
        <font style="color:#6a9955;">//     : quote == Denominations.USD</font>
        <font style="color:#6a9955;">//         ?  rates[1]</font>
        <font style="color:#6a9955;">//         : quote == Denominations.GBP</font>
        <font style="color:#6a9955;">//             ?  rates[2]</font>
        <font style="color:#6a9955;">//             : quote == Denominations.EUR</font>
        <font style="color:#6a9955;">//                 ? rates[3]</font>
        <font style="color:#6a9955;">//                 : quote == Denominations.JPY</font>
        <font style="color:#6a9955;">//                     ? rates[4]</font>
        <font style="color:#6a9955;">//                     : quote == Denominations.CNY</font>
        <font style="color:#6a9955;">//                         ? rates[5]</font>
        <font style="color:#6a9955;">//                         : rates[0];</font>
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## MotionsRepo.sol

---

| |
|:---|
| **contracts/lib/books/MotionsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * v0.2.4
 *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./BallotsBox.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./DelegateMap.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./RulesParser.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/roc/IShareholdersAgreement.sol"</font>;

<font style="color:#6a9955;">/// @title MotionsRepo</font>
<font style="color:#6a9955;">/// @notice Repository for motions, voting, and delegate maps.</font>
<font style="color:#569cd6;">library</font> MotionsRepo {
    <font style="color:#569cd6;">using</font> BallotsBox <font style="color:#569cd6;">for</font> BallotsBox.Box;
    <font style="color:#569cd6;">using</font> DelegateMap <font style="color:#569cd6;">for</font> DelegateMap.Map;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> RulesParser <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;

    <font style="color:#6a9955;">/// @notice Motion types.</font>
    <font style="color:#569cd6;">enum</font> TypeOfMotion {
        ZeroPoint,
        ElectOfficer,
        RemoveOfficer,
        ApproveDoc,
        ApproveAction,
        TransferFund,
        DistributeProfits,
        DecreaseCapital
    }

    <font style="color:#6a9955;">/// @notice Motion lifecycle states.</font>
    <font style="color:#569cd6;">enum</font> StateOfMotion {
        ZeroPoint,          <font style="color:#6a9955;">// 0</font>
        Created,            <font style="color:#6a9955;">// 1</font>
        Proposed,           <font style="color:#6a9955;">// 2</font>
        Passed,             <font style="color:#6a9955;">// 3</font>
        Rejected,           <font style="color:#6a9955;">// 4</font>
        Rejected_NotToBuy,  <font style="color:#6a9955;">// 5</font>
        Rejected_ToBuy,     <font style="color:#6a9955;">// 6</font>
        Executed            <font style="color:#6a9955;">// 7</font>
    }

    <font style="color:#6a9955;">/// @notice Motion head fields.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint16</font> typeOfMotion;
        <font style="color:#4ec9b0;">uint64</font> seqOfMotion;
        <font style="color:#4ec9b0;">uint16</font> seqOfVR;
        <font style="color:#4ec9b0;">uint40</font> creator;
        <font style="color:#4ec9b0;">uint40</font> executor;
        <font style="color:#4ec9b0;">uint48</font> createDate;
        <font style="color:#4ec9b0;">uint32</font> data;
    }

    <font style="color:#6a9955;">/// @notice Motion body fields.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">uint40</font> proposer;
        <font style="color:#4ec9b0;">uint48</font> proposeDate;
        <font style="color:#4ec9b0;">uint48</font> shareRegDate;
        <font style="color:#4ec9b0;">uint48</font> voteStartDate;
        <font style="color:#4ec9b0;">uint48</font> voteEndDate;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint8</font> state;
    }

    <font style="color:#6a9955;">/// @notice Full motion record.</font>
    <font style="color:#569cd6;">struct</font> Motion {
        Head head;
        Body body;
        RulesParser.VotingRule votingRule;
        <font style="color:#4ec9b0;">uint</font> contents;
    }

    <font style="color:#6a9955;">/// @notice Vote record: delegates and ballots.</font>
    <font style="color:#569cd6;">struct</font> Record {
        DelegateMap.Map map;
        BallotsBox.Box box;
    }

    <font style="color:#6a9955;">/// @notice Vote calculation base inputs.</font>
    <font style="color:#569cd6;">struct</font> VoteCalBase {
        <font style="color:#4ec9b0;">uint32</font> totalHead;
        <font style="color:#4ec9b0;">uint64</font> totalWeight;
        <font style="color:#4ec9b0;">uint32</font> supportHead;
        <font style="color:#4ec9b0;">uint64</font> supportWeight;
        <font style="color:#4ec9b0;">uint16</font> attendHeadRatio;
        <font style="color:#4ec9b0;">uint16</font> attendWeightRatio;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">bool</font> unaniConsent;
    }

    <font style="color:#6a9955;">/// @notice Repository of motions and vote records.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Motion) motions;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Record) records;
        EnumerableSet.UintSet seqList;
    }

    <font style="color:#6a9955;">//#############</font>
    <font style="color:#6a9955;">//##  Error  ##</font>
    <font style="color:#6a9955;">//#############</font>

    <font style="color:#569cd6;">error</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== snParser ====</font>

    <font style="color:#6a9955;">/// @notice Parse motion head from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed motion head.</font>
    <font style="color:#569cd6;">function</font> snParser (<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head = Head({
            typeOfMotion: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            seqOfMotion: <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">176</font>),
            seqOfVR: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">160</font>),
            creator: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">120</font>),
            executor: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">80</font>),
            createDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">32</font>),
            data: <font style="color:#4ec9b0;">uint32</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Pack motion head into bytes32.</font>
    <font style="color:#6a9955;">/// @param head Motion head.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.typeOfMotion,
                            head.seqOfMotion,
                            head.seqOfVR,
                            head.creator,
                            head.executor,
                            head.createDate,
                            head.data);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== addMotion ====</font>

    <font style="color:#6a9955;">/// @notice Create or update a motion.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param head Motion head.</font>
    <font style="color:#6a9955;">/// @param contents Motion contents.</font>
    <font style="color:#569cd6;">function</font> addMotion(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Head <font style="color:#569cd6;">memory</font> head,
        <font style="color:#4ec9b0;">uint256</font> contents
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font>) {

        <font style="color:#569cd6;">if</font> (head.typeOfMotion == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_ZeroTypeOfMotion"</font>));
        }
        <font style="color:#569cd6;">if</font> (head.seqOfVR == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_ZeroSeqOfVR"</font>));
        }
        <font style="color:#569cd6;">if</font> (head.creator == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_ZeroCaller"</font>));
        }

        <font style="color:#569cd6;">if</font> (!repo.seqList.contains(head.seqOfMotion)) {
            head.seqOfMotion = _increaseCounterOfMotion(repo);
            head.createDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
            repo.seqList.add(head.seqOfMotion);
        }

        Motion <font style="color:#569cd6;">storage</font> m = repo.motions[head.seqOfMotion];

        m.head = head;
        m.contents = contents;
        m.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Created);

        <font style="color:#569cd6;">return</font> head;
    }

    <font style="color:#569cd6;">function</font> _increaseCounterOfMotion (Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font> seq) {
        repo.motions[<font style="color:#b5cea8;">0</font>].head.seqOfMotion++;
        seq = repo.motions[<font style="color:#b5cea8;">0</font>].head.seqOfMotion;
    }

    <font style="color:#6a9955;">// ==== entrustDelegate ====</font>

    <font style="color:#6a9955;">/// @notice Entrust delegate for a motion.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param delegate Delegate user number.</font>
    <font style="color:#6a9955;">/// @param principal Principal user number.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#6a9955;">/// @param _rod Register of directors.</font>
    <font style="color:#569cd6;">function</font> entrustDelegate(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> delegate,
        <font style="color:#4ec9b0;">uint</font> principal,
        IRegisterOfMembers _rom,
        IRegisterOfDirectors _rod
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        Motion <font style="color:#569cd6;">storage</font> m = repo.motions[seqOfMotion];

        <font style="color:#569cd6;">if</font> (m.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Created) &&
            m.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Proposed)) {
            <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_MotionNotInVoting"</font>));
        }

        <font style="color:#569cd6;">if</font> (m.head.seqOfVR < <font style="color:#b5cea8;">11</font> && _rom.isMember(delegate) && _rom.isMember(principal)) {
            <font style="color:#4ec9b0;">uint64</font> weight;
            <font style="color:#569cd6;">if</font> (m.body.shareRegDate > <font style="color:#b5cea8;">0</font> && block.timestamp >= m.body.shareRegDate)
                weight = _rom.votesAtDate(principal, m.body.shareRegDate);
            <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].map.entrustDelegate(principal, delegate, weight);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_rod.isDirector(delegate) && _rod.isDirector(principal)) {
            <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].map.entrustDelegate(principal, delegate, <font style="color:#b5cea8;">0</font>);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotBothMembersOrDirectors"</font>));
    }

    <font style="color:#6a9955;">// ==== propose ====</font>

    <font style="color:#6a9955;">/// @notice Propose motion to general meeting.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param _sha Shareholders agreement.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#6a9955;">/// @param _rod Register of directors.</font>
    <font style="color:#6a9955;">/// @param caller Proposer user number.</font>
    <font style="color:#569cd6;">function</font> proposeMotionToGeneralMeeting(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        IShareholdersAgreement _sha,
        IRegisterOfMembers _rom,
        IRegisterOfDirectors _rod,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> {

        RulesParser.GovernanceRule <font style="color:#569cd6;">memory</font> gr =
            _sha.getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser();

        <font style="color:#569cd6;">if</font> ( !_memberProposalRightCheck(repo, seqOfMotion, gr, caller, _rom) &&
             !_directorProposalRightCheck(repo, seqOfMotion, caller, gr.proposeHeadRatioOfDirectorsInGM, _rod)
        ) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NoProposalRight"</font>));
        }

        _proposeMotion(repo, seqOfMotion, _sha, caller, _rom.qtyOfMembers() == <font style="color:#b5cea8;">1</font>);
    }

    <font style="color:#569cd6;">function</font> _proposeMotion(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        IShareholdersAgreement _sha,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">bool</font> soleMember
    ) <font style="color:#569cd6;">private</font> {

        <font style="color:#569cd6;">if</font> (caller == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_ZeroCaller"</font>));
        }

        <font style="color:#569cd6;">if</font> (repo.records[seqOfMotion].map.voters[caller].delegate != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_EntrustedDelegate"</font>));
        }

        Motion <font style="color:#569cd6;">storage</font> m = repo.motions[seqOfMotion];
        <font style="color:#569cd6;">if</font> (m.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Created)) {
            <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_MotionNotInCreatedState"</font>));
        }

        RulesParser.VotingRule <font style="color:#569cd6;">memory</font> vr =
            _sha.getRule(m.head.seqOfVR).votingRuleParser();

        <font style="color:#4ec9b0;">uint48</font> timestamp = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

        Body <font style="color:#569cd6;">memory</font> body = Body({
            proposer: <font style="color:#4ec9b0;">uint40</font>(caller),
            proposeDate: timestamp,
            shareRegDate: soleMember ? timestamp : timestamp + <font style="color:#4ec9b0;">uint48</font>(vr.invExitDays) * <font style="color:#b5cea8;">86400</font>,
            voteStartDate: soleMember ? timestamp : timestamp + <font style="color:#4ec9b0;">uint48</font>(vr.invExitDays + vr.votePrepareDays) * <font style="color:#b5cea8;">86400</font>,
            voteEndDate: soleMember ? timestamp + <font style="color:#b5cea8;">86400</font> : timestamp + <font style="color:#4ec9b0;">uint48</font>(vr.invExitDays + vr.votePrepareDays + vr.votingDays) * <font style="color:#b5cea8;">86400</font>,
            para: <font style="color:#b5cea8;">0</font>,
            state: <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Proposed)
        });

        m.body = body;
        m.votingRule = vr;
    }

    <font style="color:#569cd6;">function</font> _memberProposalRightCheck(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        RulesParser.GovernanceRule <font style="color:#569cd6;">memory</font> gr,
        <font style="color:#4ec9b0;">uint</font> caller,
        IRegisterOfMembers _rom
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font> (!_rom.isMember(caller)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        Motion <font style="color:#569cd6;">memory</font> motion = repo.motions[seqOfMotion];
        <font style="color:#569cd6;">if</font> (motion.head.typeOfMotion == <font style="color:#4ec9b0;">uint8</font>(TypeOfMotion.ApproveDoc) ||
            motion.head.typeOfMotion == <font style="color:#4ec9b0;">uint8</font>(TypeOfMotion.ElectOfficer))
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#4ec9b0;">uint</font> totalVotes = _rom.totalVotes();

        <font style="color:#569cd6;">if</font> (gr.proposeWeightRatioOfGM > <font style="color:#b5cea8;">0</font> &&
            _rom.votesInHand(caller) * <font style="color:#b5cea8;">10000</font> / totalVotes >= gr.proposeWeightRatioOfGM)
                <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        Record <font style="color:#569cd6;">storage</font> r = repo.records[seqOfMotion];
        r.map.updateLeavesWeightAtDate(caller, <font style="color:#4ec9b0;">uint48</font>(block.timestamp), _rom);

        DelegateMap.Voter <font style="color:#569cd6;">memory</font> voter = r.map.voters[caller];

        <font style="color:#569cd6;">if</font> (gr.proposeWeightRatioOfGM > <font style="color:#b5cea8;">0</font> &&
            (voter.weight + voter.repWeight) * <font style="color:#b5cea8;">10000</font> / totalVotes >= gr.proposeWeightRatioOfGM)
                <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">if</font> (gr.proposeHeadRatioOfMembers > <font style="color:#b5cea8;">0</font> &&
            (voter.repHead + <font style="color:#b5cea8;">1</font>) * <font style="color:#b5cea8;">10000</font> / _rom.qtyOfMembers() >=
                gr.proposeHeadRatioOfMembers)
                    <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#569cd6;">function</font> _directorProposalRightCheck(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint16</font> proposalThreshold,
        IRegisterOfDirectors _rod
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font> (!_rod.isDirector(caller)) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;

        <font style="color:#4ec9b0;">uint</font> totalHead = _rod.getNumOfDirectors();
        repo.records[seqOfMotion].map.updateLeavesHeadcountOfDirectors(caller, _rod);

        <font style="color:#569cd6;">if</font> (proposalThreshold > <font style="color:#b5cea8;">0</font> &&
            (repo.records[seqOfMotion].map.voters[caller].repHead + <font style="color:#b5cea8;">1</font>) * <font style="color:#b5cea8;">10000</font> / totalHead >=
                proposalThreshold)
                    <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#6a9955;">/// @notice Propose motion to board meeting.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param _sha Shareholders agreement.</font>
    <font style="color:#6a9955;">/// @param _rod Register of directors.</font>
    <font style="color:#6a9955;">/// @param caller Proposer user number.</font>
    <font style="color:#569cd6;">function</font> proposeMotionToBoard(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        IShareholdersAgreement _sha,
        IRegisterOfDirectors _rod,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> {

        RulesParser.GovernanceRule <font style="color:#569cd6;">memory</font> gr =
            _sha.getRule(<font style="color:#b5cea8;">0</font>).governanceRuleParser();

        <font style="color:#569cd6;">if</font> (
            !_directorProposalRightCheck(
                repo, seqOfMotion, caller,
                gr.proposeHeadRatioOfDirectorsInBoard,
                _rod
            )
        ) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NoProposalRight"</font>));
        }

        _proposeMotion(repo, seqOfMotion, _sha, caller, _rod.getNumOfDirectors() == <font style="color:#b5cea8;">1</font>);
    }

    <font style="color:#6a9955;">// ==== vote ====</font>

    <font style="color:#6a9955;">/// @notice Cast vote in general meeting.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#6a9955;">/// @param attitude Vote attitude.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> castVoteInGeneralMeeting(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        IRegisterOfMembers _rom
    ) <font style="color:#569cd6;">public</font> {

        <font style="color:#569cd6;">if</font> (!_rom.isMember(acct)) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotMember"</font>));
        }

        Motion <font style="color:#569cd6;">storage</font> m = repo.motions[seqOfMotion];
        Record <font style="color:#569cd6;">storage</font> r = repo.records[seqOfMotion];
        DelegateMap.Voter <font style="color:#569cd6;">storage</font> voter = r.map.voters[acct];

        r.map.updateLeavesWeightAtDate(acct, m.body.shareRegDate, _rom);

        _castVote(repo, seqOfMotion, acct, attitude, voter.repHead + <font style="color:#b5cea8;">1</font>, voter.weight + voter.repWeight, sigHash);
    }

    <font style="color:#6a9955;">/// @notice Cast vote in board meeting.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#6a9955;">/// @param attitude Vote attitude.</font>
    <font style="color:#6a9955;">/// @param sigHash Signature hash.</font>
    <font style="color:#6a9955;">/// @param _rod Register of directors.</font>
    <font style="color:#569cd6;">function</font> castVoteInBoardMeeting(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">bytes32</font> sigHash,
        IRegisterOfDirectors _rod
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (!_rod.isDirector(acct)) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotDirector"</font>));
        }

        Record <font style="color:#569cd6;">storage</font> r = repo.records[seqOfMotion];

        DelegateMap.Voter <font style="color:#569cd6;">storage</font> voter = r.map.voters[acct];

        r.map.updateLeavesHeadcountOfDirectors(acct, _rod);

        _castVote(repo, seqOfMotion, acct, attitude, voter.repHead + <font style="color:#b5cea8;">1</font>, <font style="color:#b5cea8;">0</font>, sigHash);
    }

    <font style="color:#569cd6;">function</font> _castVote(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> attitude,
        <font style="color:#4ec9b0;">uint</font> headcount,
        <font style="color:#4ec9b0;">uint</font> weight,
        <font style="color:#4ec9b0;">bytes32</font> sigHash
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (seqOfMotion == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_ZeroSeqOfMotion"</font>));
        }
        <font style="color:#569cd6;">if</font> (!voteStarted(repo, seqOfMotion)) {
            <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_VoteNotStarted"</font>));
        }
        <font style="color:#569cd6;">if</font> (voteEnded(repo, seqOfMotion)) {
            <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_VoteEnded"</font>));
        }

        Record <font style="color:#569cd6;">storage</font> r = repo.records[seqOfMotion];
        DelegateMap.Voter <font style="color:#569cd6;">storage</font> voter = r.map.voters[acct];

        <font style="color:#569cd6;">if</font> (voter.delegate != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_EntrustedDelegate"</font>));
        }

        r.box.castVote(acct, attitude, headcount, weight, sigHash, voter.principals);
    }

    <font style="color:#6a9955;">// ==== counting ====</font>

    <font style="color:#6a9955;">/// @notice Count votes and update motion state.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param flag0 Pass base condition.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param base Vote calculation base.</font>
    <font style="color:#569cd6;">function</font> voteCounting(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> flag0,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        VoteCalBase <font style="color:#569cd6;">memory</font> base
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {

        Motion <font style="color:#569cd6;">storage</font> m = repo.motions[seqOfMotion];
        Record <font style="color:#569cd6;">storage</font> r = repo.records[seqOfMotion];

        <font style="color:#569cd6;">if</font> (m.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Proposed)) {
            <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_MotionNotInVoting"</font>));
        }

        <font style="color:#569cd6;">if</font> (base.unaniConsent) {
            m.body.state = <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Passed);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (!voteEnded(repo, seqOfMotion)) {
                <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_VoteNotEnded"</font>));
            }

            <font style="color:#4ec9b0;">bool</font> flag1 = m.votingRule.headRatio == <font style="color:#b5cea8;">0</font>;
            <font style="color:#4ec9b0;">bool</font> flag2 = m.votingRule.amountRatio == <font style="color:#b5cea8;">0</font>;

            <font style="color:#4ec9b0;">bool</font> flag = (flag1 && flag2);

            <font style="color:#569cd6;">if</font> (!flag && flag0 && !_isVetoed(r, m.votingRule.vetoers[<font style="color:#b5cea8;">0</font>]) &&
                !_isVetoed(r, m.votingRule.vetoers[<font style="color:#b5cea8;">1</font>])) {
                flag1 = flag1 ? <font style="color:#569cd6;">true</font> : base.totalHead > <font style="color:#b5cea8;">0</font>
                    ? ((r.box.cases[<font style="color:#4ec9b0;">uint8</font>(BallotsBox.AttitudeOfVote.Support)]
                        .sumOfHead + base.supportHead) * <font style="color:#b5cea8;">10000</font>) /
                        base.totalHead >
                        m.votingRule.headRatio
                    : <font style="color:#569cd6;">false</font>;

                flag2 = flag2 ? <font style="color:#569cd6;">true</font> : base.totalWeight > <font style="color:#b5cea8;">0</font>
                    ? ((r.box.cases[<font style="color:#4ec9b0;">uint8</font>(BallotsBox.AttitudeOfVote.Support)]
                        .sumOfWeight + base.supportWeight) * <font style="color:#b5cea8;">10000</font>) /
                        base.totalWeight >
                        m.votingRule.amountRatio
                    : <font style="color:#569cd6;">false</font>;
            }

            m.body.state =  flag || (flag0 && flag1 && flag2)
                    ? <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Passed)
                    : m.votingRule.againstShallBuy
                        ? <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Rejected_ToBuy)
                        : <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Rejected_NotToBuy);
        }

        <font style="color:#569cd6;">return</font> m.body.state;
    }

    <font style="color:#569cd6;">function</font> _isVetoed(Record <font style="color:#569cd6;">storage</font> r, <font style="color:#4ec9b0;">uint256</font> vetoer)
        <font style="color:#569cd6;">private</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> vetoer > <font style="color:#b5cea8;">0</font> && (r.box.ballots[vetoer].sigDate == <font style="color:#b5cea8;">0</font> ||
            r.box.ballots[vetoer].attitude != <font style="color:#4ec9b0;">uint8</font>(BallotsBox.AttitudeOfVote.Support));
    }

    <font style="color:#6a9955;">// ==== ExecResolution ====</font>

    <font style="color:#6a9955;">/// @notice Execute a passed resolution.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param contents Motion contents.</font>
    <font style="color:#6a9955;">/// @param executor Executor user number.</font>
    <font style="color:#569cd6;">function</font> execResolution(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> contents,
        <font style="color:#4ec9b0;">uint</font> executor
    ) <font style="color:#569cd6;">public</font> {
        Motion <font style="color:#569cd6;">storage</font> m = repo.motions[seqOfMotion];
        <font style="color:#569cd6;">if</font> (m.contents != contents) {
            <font style="color:#569cd6;">revert</font> MR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_WrongContents"</font>));
        }
        <font style="color:#569cd6;">if</font> (m.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Passed)) {
            <font style="color:#569cd6;">revert</font> MR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_MotionNotPassed"</font>));
        }
        <font style="color:#569cd6;">if</font> (m.head.executor != <font style="color:#4ec9b0;">uint40</font>(executor)) {
            <font style="color:#569cd6;">revert</font> MR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"MR_NotExecutor"</font>));
        }

        m.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Executed);
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Read     ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== VoteState ====</font>

    <font style="color:#6a9955;">/// @notice Check if motion is proposed.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> isProposed(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.motions[seqOfMotion].body.state == <font style="color:#4ec9b0;">uint8</font>(StateOfMotion.Proposed);
    }

    <font style="color:#6a9955;">/// @notice Check if voting has started.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> voteStarted(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> isProposed(repo, seqOfMotion) &&
            repo.motions[seqOfMotion].body.voteStartDate <= block.timestamp;
    }

    <font style="color:#6a9955;">/// @notice Check if voting has ended.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> voteEnded(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> isProposed(repo, seqOfMotion) &&
            repo.motions[seqOfMotion].body.voteEndDate <= block.timestamp;
    }

    <font style="color:#6a9955;">// ==== Delegate ====</font>

    <font style="color:#6a9955;">/// @notice Get delegate map voter data.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#569cd6;">function</font> getVoterOfDelegateMap(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (DelegateMap.Voter <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].map.voters[acct];
    }

    <font style="color:#6a9955;">/// @notice Get delegate of an account.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#569cd6;">function</font> getDelegateOf(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].map.getDelegateOf(acct);
    }

    <font style="color:#6a9955;">// ==== motion ====</font>

    <font style="color:#6a9955;">/// @notice Get motion by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> getMotion(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Motion <font style="color:#569cd6;">memory</font> motion)
    {
        motion = repo.motions[seqOfMotion];
    }

    <font style="color:#6a9955;">// ==== voting ====</font>

    <font style="color:#6a9955;">/// @notice Check if account has voted.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#569cd6;">function</font> isVoted(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].box.isVoted(acct);
    }

    <font style="color:#6a9955;">/// @notice Check if account voted for an attitude.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#6a9955;">/// @param atti Attitude value.</font>
    <font style="color:#569cd6;">function</font> isVotedFor(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfMotion,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint256</font> atti
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].box.isVotedFor(acct, atti);
    }

    <font style="color:#6a9955;">/// @notice Get aggregate case for attitude.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param atti Attitude value.</font>
    <font style="color:#569cd6;">function</font> getCaseOfAttitude(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> atti)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (BallotsBox.Case <font style="color:#569cd6;">memory</font> )
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].box.getCaseOfAttitude(atti);
    }

    <font style="color:#6a9955;">/// @notice Get ballot for account.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#6a9955;">/// @param acct Voter user number.</font>
    <font style="color:#569cd6;">function</font> getBallot(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (BallotsBox.Ballot <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfMotion].box.getBallot(acct);
    }

    <font style="color:#6a9955;">/// @notice Check if motion passed.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfMotion Motion sequence.</font>
    <font style="color:#569cd6;">function</font> isPassed(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfMotion) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.motions[seqOfMotion].body.state == <font style="color:#4ec9b0;">uint8</font>(MotionsRepo.StateOfMotion.Passed);
    }

    <font style="color:#6a9955;">// ==== snList ====</font>

    <font style="color:#6a9955;">/// @notice Get motion sequence list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getSeqList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.seqList.values();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## OfficersRepo.sol

---

| |
|:---|
| **contracts/lib/books/OfficersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rom/IRegisterOfMembers.sol"</font>;

<font style="color:#6a9955;">/// @title OfficersRepo</font>
<font style="color:#6a9955;">/// @notice Library for managing officer/director positions and memberships.</font>
<font style="color:#6a9955;">/// @dev Stores positions, holders, and nomination rules.</font>
<font style="color:#569cd6;">library</font> OfficersRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.Bytes32Set;
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice Officer title identifiers.</font>
    <font style="color:#569cd6;">enum</font> TitleOfOfficers {
        ZeroPoint,
        Shareholder,
        Chairman,
        ViceChairman,
        ManagingDirector,
        Director,
        CEO,
        CFO,
        COO,
        CTO,
        President,
        VicePresident,
        Supervisor,
        SeniorManager,
        Manager,
        ViceManager
    }

    <font style="color:#6a9955;">/// @notice Position record.</font>
    <font style="color:#569cd6;">struct</font> Position {
        <font style="color:#4ec9b0;">uint16</font> title;
        <font style="color:#4ec9b0;">uint16</font> seqOfPos;
        <font style="color:#4ec9b0;">uint40</font> acct;
        <font style="color:#4ec9b0;">uint40</font> nominator;
        <font style="color:#4ec9b0;">uint48</font> startDate;
        <font style="color:#4ec9b0;">uint48</font> endDate;
        <font style="color:#4ec9b0;">uint16</font> seqOfVR;
        <font style="color:#4ec9b0;">uint16</font> titleOfNominator;
        <font style="color:#4ec9b0;">uint16</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Group of positions and accounts.</font>
    <font style="color:#569cd6;">struct</font> Group {
        <font style="color:#6a9955;">// seqList</font>
        EnumerableSet.UintSet posList;
        <font style="color:#6a9955;">// acctList</font>
        EnumerableSet.UintSet acctList;
    }

    <font style="color:#6a9955;">/// @notice Repository storage for officer positions.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">//seqOfPos => Position</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Position)  positions;
        <font style="color:#6a9955;">// acct => seqOfPos</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => EnumerableSet.UintSet) posInHand;
        Group directors;
        Group managers;
    }

    <font style="color:#6a9955;">//##############</font>
    <font style="color:#6a9955;">//##   Error  ##</font>
    <font style="color:#6a9955;">//##############</font>

    <font style="color:#569cd6;">error</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> OFR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> OFR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##   Modifier  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @dev Reverts if the position is occupied.</font>
    <font style="color:#569cd6;">modifier</font> isVacant(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfPos) {
        <font style="color:#569cd6;">if</font> (isOccupied(repo, seqOfPos)) {
            <font style="color:#569cd6;">revert</font> OFR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_PositionOccupied"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Write    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== snParser ====</font>

    <font style="color:#6a9955;">/// @notice Parse encoded position data.</font>
    <font style="color:#6a9955;">/// @param sn Encoded position head.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Position <font style="color:#569cd6;">memory</font> position) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        position = Position({
            title: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            seqOfPos: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            acct: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">184</font>),
            nominator: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">144</font>),
            startDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">96</font>),
            endDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">48</font>),
            seqOfVR: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">32</font>),
            titleOfNominator: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>),
            argu: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Encode position fields into bytes32.</font>
    <font style="color:#569cd6;">function</font> codifyPosition(Position <font style="color:#569cd6;">memory</font> position) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            position.title,
                            position.seqOfPos,
                            position.acct,
                            position.nominator,
                            position.startDate,
                            position.endDate,
                            position.seqOfVR,
                            position.titleOfNominator,
                            position.argu);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ======== Setting ========</font>

    <font style="color:#6a9955;">/// @notice Create a position from encoded data.</font>
    <font style="color:#6a9955;">/// @param snOfPos Encoded position head (non-zero, valid fields).</font>
    <font style="color:#569cd6;">function</font> createPosition (Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> snOfPos)
        <font style="color:#569cd6;">public</font>
    {
        Position <font style="color:#569cd6;">memory</font> pos = snParser(snOfPos);
        addPosition(repo, pos);
    }

    <font style="color:#6a9955;">/// @notice Add or update a position.</font>
    <font style="color:#6a9955;">/// @param pos Position struct (seqOfPos > 0, title > Shareholder, endDate > startDate).</font>
    <font style="color:#569cd6;">function</font> addPosition(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Position <font style="color:#569cd6;">memory</font> pos
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (pos.title <= <font style="color:#4ec9b0;">uint8</font>(TitleOfOfficers.Shareholder)) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_ZeroPosition"</font>));
        }
        <font style="color:#569cd6;">if</font> (pos.seqOfPos == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_ZeroSeqOfPos"</font>));
        }
        <font style="color:#569cd6;">if</font> (pos.titleOfNominator == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_ZeroTitleOfNominator"</font>));
        }
        <font style="color:#569cd6;">if</font> (pos.endDate <= pos.startDate) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_EndDateNotLaterStart"</font>));
        }
        <font style="color:#569cd6;">if</font> (pos.endDate <= block.timestamp) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_EndDateNotFuture"</font>));
        }

        Position <font style="color:#569cd6;">storage</font> p = repo.positions[pos.seqOfPos];

        <font style="color:#569cd6;">if</font> (p.seqOfPos == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (pos.title <= <font style="color:#4ec9b0;">uint8</font>(TitleOfOfficers.Director))
                repo.directors.posList.add(pos.seqOfPos);
            <font style="color:#569cd6;">else</font> repo.managers.posList.add(pos.seqOfPos);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (p.seqOfPos != pos.seqOfPos || p.title != pos.title)
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_RemovePosFirst"</font>));

        repo.positions[pos.seqOfPos] = pos;
    }

    <font style="color:#6a9955;">/// @notice Remove a vacant position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> removePosition(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfPos)
        <font style="color:#569cd6;">public</font> isVacant(repo, seqOfPos) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#569cd6;">if</font> (repo.directors.posList.remove(seqOfPos) ||
            repo.managers.posList.remove(seqOfPos))
        {
            <font style="color:#569cd6;">delete</font> repo.positions[seqOfPos];
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">/// @notice Assign a position to an account.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> takePosition (
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        <font style="color:#569cd6;">if</font> (seqOfPos == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_ZeroSeqOfPos"</font>));
        }
        <font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_ZeroAcct"</font>));
        }

        Position <font style="color:#569cd6;">storage</font> pos = repo.positions[seqOfPos];

        <font style="color:#569cd6;">if</font> (repo.directors.posList.contains(seqOfPos))
            repo.directors.acctList.add(acct);
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (repo.managers.posList.contains(seqOfPos))
            repo.managers.acctList.add(acct);
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_PosNotExist"</font>));

        pos.acct = <font style="color:#4ec9b0;">uint40</font>(acct);
        pos.startDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

        repo.posInHand[acct].add(seqOfPos);

        flag = <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @notice Quit a position held by an account.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> quitPosition(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfPos,
        <font style="color:#4ec9b0;">uint</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        Position <font style="color:#569cd6;">memory</font> pos = repo.positions[seqOfPos];
        <font style="color:#569cd6;">if</font> (acct != pos.acct) {
            <font style="color:#569cd6;">revert</font> OFR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_NotTheOfficer"</font>));
        }
        flag = vacatePosition(repo, seqOfPos);
    }

    <font style="color:#6a9955;">/// @notice Vacate a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> vacatePosition (
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfPos
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        Position <font style="color:#569cd6;">storage</font> pos = repo.positions[seqOfPos];

        <font style="color:#4ec9b0;">uint</font> acct = pos.acct;
        <font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OFR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OFR_EmptyPos"</font>));
        }

        <font style="color:#569cd6;">if</font> (repo.posInHand[acct].remove(seqOfPos)) {
            pos.acct = <font style="color:#b5cea8;">0</font>;

            <font style="color:#569cd6;">if</font> (pos.title <= <font style="color:#4ec9b0;">uint8</font>(TitleOfOfficers.Director))
                repo.directors.acctList.remove(acct);
            <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (repo.posInHand[acct].length() == <font style="color:#b5cea8;">0</font>) {
                repo.managers.acctList.remove(acct);
            }

            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">// ==== Positions ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a position exists and is active.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> posExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = repo.positions[seqOfPos].endDate > block.timestamp;
    }

    <font style="color:#6a9955;">/// @notice Check whether a position is occupied.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> isOccupied(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = repo.positions[seqOfPos].acct > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get position details.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> getPosition(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfPos) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Position <font style="color:#569cd6;">memory</font> pos) {
        pos = repo.positions[seqOfPos];
    }

    <font style="color:#6a9955;">/// @notice Get full position info for a list of positions.</font>
    <font style="color:#6a9955;">/// @param pl Position sequence list.</font>
    <font style="color:#569cd6;">function</font> getFullPosInfo(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> pl)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Position[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> len = pl.length;
        Position[] <font style="color:#569cd6;">memory</font> ls = <font style="color:#569cd6;">new</font> Position[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            ls[len-<font style="color:#b5cea8;">1</font>] = repo.positions[pl[len-<font style="color:#b5cea8;">1</font>]];
            len--;
        }

        <font style="color:#569cd6;">return</font> ls;
    }

    <font style="color:#6a9955;">// ==== Managers ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is a manager.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> isManager(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {
        flag = repo.managers.acctList.contains(acct);
    }

    <font style="color:#6a9955;">/// @notice Get number of managers.</font>
    <font style="color:#569cd6;">function</font> getNumOfManagers(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> num) {
        num = repo.managers.acctList.length();
    }

    <font style="color:#6a9955;">/// @notice Get manager account list.</font>
    <font style="color:#569cd6;">function</font> getManagersList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> ls) {
        ls = repo.managers.acctList.values();
    }

    <font style="color:#6a9955;">/// @notice Get manager position list.</font>
    <font style="color:#569cd6;">function</font> getManagersPosList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        list = repo.managers.posList.values();
    }

    <font style="color:#6a9955;">/// @notice Get full manager position info.</font>
    <font style="color:#569cd6;">function</font> getManagersFullPosInfo(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(Position[] <font style="color:#569cd6;">memory</font> output)
    {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> pl = repo.managers.posList.values();
        output = getFullPosInfo(repo, pl);
    }

    <font style="color:#6a9955;">// ==== Directors ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account is a director.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> isDirector(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = repo.directors.acctList.contains(acct);
    }

    <font style="color:#6a9955;">/// @notice Get number of directors.</font>
    <font style="color:#569cd6;">function</font> getNumOfDirectors(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> num)
    {
        num = repo.directors.acctList.length();
    }

    <font style="color:#6a9955;">/// @notice Get director account list.</font>
    <font style="color:#569cd6;">function</font> getDirectorsList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> ls)
    {
        ls = repo.directors.acctList.values();
    }

    <font style="color:#6a9955;">/// @notice Get director position list.</font>
    <font style="color:#569cd6;">function</font> getDirectorsPosList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> ls)
    {
        ls = repo.directors.posList.values();
    }

    <font style="color:#6a9955;">/// @notice Get full director position info.</font>
    <font style="color:#569cd6;">function</font> getDirectorsFullPosInfo(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(Position[] <font style="color:#569cd6;">memory</font> output)
    {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> pl = repo.directors.posList.values();
        output = getFullPosInfo(repo, pl);
    }

    <font style="color:#6a9955;">// ==== Executives ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an account holds a position.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#569cd6;">function</font> hasPosition(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint256</font> seqOfPos)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        flag = repo.posInHand[acct].contains(seqOfPos);
    }

    <font style="color:#6a9955;">/// @notice Get positions held by an account.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getPosInHand(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> ls)
    {
        ls = repo.posInHand[acct].values();
    }

    <font style="color:#6a9955;">/// @notice Get full position info held by an account.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getFullPosInfoInHand(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Position[] <font style="color:#569cd6;">memory</font> output)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> pl = repo.posInHand[acct].values();
        output = getFullPosInfo(repo, pl);
    }

    <font style="color:#6a9955;">/// @notice Check whether an account holds a title.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param title Title id (see TitleOfOfficers).</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> hasTitle(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> acct, <font style="color:#4ec9b0;">uint</font> title, IRegisterOfMembers _rom)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">if</font> (title == <font style="color:#4ec9b0;">uint8</font>(TitleOfOfficers.Shareholder))
            <font style="color:#569cd6;">return</font> _rom.isMember(acct);

        <font style="color:#569cd6;">if</font> (title == <font style="color:#4ec9b0;">uint8</font>(TitleOfOfficers.Director))
            <font style="color:#569cd6;">return</font> isDirector(repo, acct);

        Position[] <font style="color:#569cd6;">memory</font> list = getFullPosInfoInHand(repo, acct);
        <font style="color:#4ec9b0;">uint</font> len = list.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (list[len-<font style="color:#b5cea8;">1</font>].title == <font style="color:#4ec9b0;">uint16</font>(title))
                <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
            len --;
        }
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

    <font style="color:#6a9955;">/// @notice Check whether an account has nomination rights for a position.</font>
    <font style="color:#6a9955;">/// @param seqOfPos Position sequence number (> 0).</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#569cd6;">function</font> hasNominationRight(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfPos, <font style="color:#4ec9b0;">uint</font> acct, IRegisterOfMembers _rom)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        Position <font style="color:#569cd6;">memory</font> pos = repo.positions[seqOfPos];
        <font style="color:#569cd6;">if</font> (pos.endDate <= block.timestamp) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (pos.nominator == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">return</font> hasTitle(repo, acct, pos.titleOfNominator, _rom);
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">return</font> (pos.nominator == acct);
    }

    <font style="color:#6a9955;">// ==== seatsCalculator ====</font>

    <font style="color:#6a9955;">/// @notice Get board seats quota nominated by an account.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getBoardSeatsQuota(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> quota)
    {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> pl = repo.directors.posList.values();
        <font style="color:#4ec9b0;">uint256</font> len = pl.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            Position <font style="color:#569cd6;">memory</font> pos = repo.positions[pl[len-<font style="color:#b5cea8;">1</font>]];
            <font style="color:#569cd6;">if</font> (pos.nominator == acct) quota++;
            len--;
        }
    }

    <font style="color:#6a9955;">/// @notice Get number of occupied board seats under an account's nomination.</font>
    <font style="color:#6a9955;">/// @param acct Account id (> 0).</font>
    <font style="color:#569cd6;">function</font> getBoardSeatsOccupied(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> num)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> dl = repo.directors.acctList.values();
        <font style="color:#4ec9b0;">uint256</font> lenOfDL = dl.length;

        <font style="color:#569cd6;">while</font> (lenOfDL > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> pl = repo.posInHand[dl[lenOfDL-<font style="color:#b5cea8;">1</font>]].values();
            <font style="color:#4ec9b0;">uint256</font> lenOfPL = pl.length;

            <font style="color:#569cd6;">while</font>(lenOfPL > <font style="color:#b5cea8;">0</font>) {
                Position <font style="color:#569cd6;">memory</font> pos = repo.positions[pl[lenOfPL-<font style="color:#b5cea8;">1</font>]];
                <font style="color:#569cd6;">if</font> ( pos.title <= <font style="color:#4ec9b0;">uint8</font>(TitleOfOfficers.Director)) {
                    <font style="color:#569cd6;">if</font> (pos.nominator == acct) num++;
                    <font style="color:#569cd6;">break</font>;
                }
                lenOfPL--;
            }

            lenOfDL--;
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## OptionsRepo.sol

---

| |
|:---|
| **contracts/lib/books/OptionsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./Checkpoints.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./CondsRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./SharesRepo.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./SwapsRepo.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/ros/IRegisterOfShares.sol"</font>;

<font style="color:#6a9955;">/// @title OptionsRepo</font>
<font style="color:#6a9955;">/// @notice Library for creating, executing, and settling option records.</font>
<font style="color:#6a9955;">/// @dev Stores options, obligors, swaps, and oracle checkpoints.</font>
<font style="color:#569cd6;">library</font> OptionsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;
    <font style="color:#569cd6;">using</font> Checkpoints <font style="color:#569cd6;">for</font> Checkpoints.History;
    <font style="color:#569cd6;">using</font> CondsRepo <font style="color:#569cd6;">for</font> CondsRepo.Cond;
    <font style="color:#569cd6;">using</font> CondsRepo <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">bytes32</font>;
    <font style="color:#569cd6;">using</font> SwapsRepo <font style="color:#569cd6;">for</font> SwapsRepo.Repo;

    <font style="color:#6a9955;">/// @notice Option types.</font>
    <font style="color:#569cd6;">enum</font> TypeOfOpt {
        CallPrice,
        PutPrice,
        CallRoe,
        PutRoe,
        CallPriceWithCnds,
        PutPriceWithCnds,
        CallRoeWithCnds,
        PutRoeWithCnds
    }

    <font style="color:#6a9955;">/// @notice Option lifecycle states.</font>
    <font style="color:#569cd6;">enum</font> StateOfOpt {
        Pending,
        Issued,
        Executed,
        Closed
    }

    <font style="color:#6a9955;">/// @notice Core option parameters encoded in snOfOpt.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint32</font> seqOfOpt;
        <font style="color:#4ec9b0;">uint8</font> typeOfOpt;
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> rate;
        <font style="color:#4ec9b0;">uint48</font> issueDate;
        <font style="color:#4ec9b0;">uint48</font> triggerDate;
        <font style="color:#4ec9b0;">uint16</font> execDays;
        <font style="color:#4ec9b0;">uint16</font> closingDays;
        <font style="color:#4ec9b0;">uint40</font> obligor;
    }

    <font style="color:#6a9955;">/// @notice Runtime fields of an option.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">uint48</font> closingDeadline;
        <font style="color:#4ec9b0;">uint40</font> rightholder;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Full option record.</font>
    <font style="color:#569cd6;">struct</font> Option {
        Head head;
        CondsRepo.Cond cond;
        Body body;
    }

    <font style="color:#6a9955;">/// @notice Per-option auxiliary data.</font>
    <font style="color:#569cd6;">struct</font> Record {
        EnumerableSet.UintSet obligors;
        SwapsRepo.Repo swaps;
        Checkpoints.History oracles;
    }

    <font style="color:#6a9955;">/// @notice Repository storage for options.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Option) options;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Record) records;
        EnumerableSet.UintSet seqList;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##    Error  ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#569cd6;">error</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> OPR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> OPR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##  Modifier ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">/// @dev Reverts if the option does not exist.</font>
    <font style="color:#569cd6;">modifier</font> optExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfOpt) {
        <font style="color:#569cd6;">if</font> (!isOption(repo, seqOfOpt)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotExist"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">/// @dev Reverts if caller is not the option rightholder.</font>
    <font style="color:#569cd6;">modifier</font> onlyRightholder(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfOpt, <font style="color:#4ec9b0;">uint</font> caller) {
        <font style="color:#569cd6;">if</font> (!isRightholder(repo, seqOfOpt, caller)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_NotTheRightholder"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">// ==== cofify / parser ====</font>

    <font style="color:#6a9955;">/// @notice Parse an option serial number into its head.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head = Head({
            seqOfOpt: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            typeOfOpt: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            classOfShare: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">200</font>),
            rate: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">168</font>),
            issueDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">120</font>),
            triggerDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">72</font>),
            execDays: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">56</font>),
            closingDays: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">40</font>),
            obligor: <font style="color:#4ec9b0;">uint40</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Encode a head into an option serial number.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.seqOfOpt,
                            head.typeOfOpt,
                            head.classOfShare,
                            head.rate,
                            head.issueDate,
                            head.triggerDate,
                            head.execDays,
                            head.closingDays,
                            head.obligor);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== Option ====</font>

    <font style="color:#6a9955;">/// @notice Create and register an option from encoded inputs.</font>
    <font style="color:#569cd6;">function</font> createOption(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> snOfOpt,
        <font style="color:#4ec9b0;">bytes32</font> snOfCond,
        <font style="color:#4ec9b0;">uint</font> rightholder,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head)
    {
        Option <font style="color:#569cd6;">memory</font> opt;

        opt.head = snParser(snOfOpt);
        opt.cond = snOfCond.snParser();

        opt.body.closingDeadline = opt.head.triggerDate + (<font style="color:#4ec9b0;">uint48</font>(opt.head.execDays) + <font style="color:#4ec9b0;">uint48</font>(opt.head.closingDays)) * <font style="color:#b5cea8;">86400</font>;
        opt.body.rightholder = <font style="color:#4ec9b0;">uint40</font>(rightholder);
        opt.body.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        opt.body.par = <font style="color:#4ec9b0;">uint64</font>(par);

        head = regOption(repo, opt);
    }

    <font style="color:#6a9955;">/// @notice Mark an option as issued.</font>
    <font style="color:#569cd6;">function</font> issueOption(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Option <font style="color:#569cd6;">memory</font> opt
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        Option <font style="color:#569cd6;">storage</font> o = repo.options[opt.head.seqOfOpt];

        o.head.issueDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        o.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Issued);

        <font style="color:#569cd6;">return</font> o.head.issueDate;
    }

    <font style="color:#6a9955;">/// @notice Register an option with validation and sequence assignment.</font>
    <font style="color:#569cd6;">function</font> regOption(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Option <font style="color:#569cd6;">memory</font> opt
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font>) {

        <font style="color:#569cd6;">if</font> (opt.head.rate == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_ZeroRate"</font>));
        }
        <font style="color:#569cd6;">if</font> (opt.head.triggerDate <= block.timestamp) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_TriggerDateNotFuture"</font>));
        }
        <font style="color:#569cd6;">if</font> (opt.head.execDays == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_ZeroExecDays"</font>));
        }
        <font style="color:#569cd6;">if</font> (opt.head.closingDays == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_ZeroClosingDays"</font>));
        }
        <font style="color:#569cd6;">if</font> (opt.head.obligor == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_ZeroObligor"</font>)) ;
        }
        <font style="color:#569cd6;">if</font> (opt.body.rightholder == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_ZeroRightholder"</font>));
        }
        <font style="color:#569cd6;">if</font> (opt.body.paid == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_ZeroPaid"</font>));
        }
        <font style="color:#569cd6;">if</font> (opt.body.par < opt.body.paid) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_PaidExceedsPar"</font>));
        }

        opt.head.seqOfOpt = _increaseCounter(repo);

        repo.seqList.add(opt.head.seqOfOpt);

        repo.options[opt.head.seqOfOpt] = opt;
        repo.records[opt.head.seqOfOpt].obligors.add(opt.head.obligor);

        <font style="color:#569cd6;">return</font> opt.head;
    }

    <font style="color:#6a9955;">/// @notice Remove a pending option.</font>
    <font style="color:#569cd6;">function</font> removeOption(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfOpt
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag) {

        <font style="color:#569cd6;">if</font> (repo.options[seqOfOpt].body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Pending)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotInPending"</font>));
        }

        <font style="color:#569cd6;">if</font> (repo.seqList.remove(seqOfOpt)) {
            <font style="color:#569cd6;">delete</font> repo.options[seqOfOpt];
            flag = <font style="color:#569cd6;">true</font>;
        }
    }

    <font style="color:#6a9955;">// ==== Record ====</font>

    <font style="color:#6a9955;">/// @notice Add an obligor to an option.</font>
    <font style="color:#569cd6;">function</font> addObligorIntoOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> obligor)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">if</font> (obligor == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OR.ZeroObligor"</font>));
        }
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].obligors.add(<font style="color:#4ec9b0;">uint40</font>(obligor));
    }

    <font style="color:#6a9955;">/// @notice Remove an obligor from an option.</font>
    <font style="color:#569cd6;">function</font> removeObligorFromOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> obligor)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">if</font> (obligor == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OR.ZeroObligor"</font>));
        }
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].obligors.remove(obligor);
    }

    <font style="color:#6a9955;">/// @notice Add multiple obligors to an option.</font>
    <font style="color:#569cd6;">function</font> addObligorsIntoOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> obligors)
        <font style="color:#569cd6;">public</font>
    {
        Record <font style="color:#569cd6;">storage</font> rcd = repo.records[seqOfOpt];
        <font style="color:#4ec9b0;">uint256</font> len = obligors.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            rcd.obligors.add(<font style="color:#4ec9b0;">uint40</font>(obligors[len-<font style="color:#b5cea8;">1</font>]));
            len--;
        }
    }

    <font style="color:#6a9955;">// ==== ExecOption ====</font>

    <font style="color:#6a9955;">/// @notice Append an oracle checkpoint.</font>
    <font style="color:#569cd6;">function</font> updateOracle(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> d1,
        <font style="color:#4ec9b0;">uint</font> d2,
        <font style="color:#4ec9b0;">uint</font> d3
    ) <font style="color:#569cd6;">public</font> optExist(repo, seqOfOpt) {
        repo.records[seqOfOpt].oracles.push(<font style="color:#b5cea8;">100</font>, d1, d2, d3);
    }

    <font style="color:#6a9955;">/// @notice Execute an issued option within its exercise window.</font>
    <font style="color:#569cd6;">function</font> execOption(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> onlyRightholder(repo, seqOfOpt, caller) {
        Option <font style="color:#569cd6;">storage</font> opt = repo.options[seqOfOpt];
        Record <font style="color:#569cd6;">storage</font> rcd = repo.records[seqOfOpt];

        <font style="color:#569cd6;">if</font> (opt.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Issued)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotInIssuedState"</font>));
        }
        <font style="color:#569cd6;">if</font> (block.timestamp < opt.head.triggerDate) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_NotReachedTriggerDate"</font>));
        }

        <font style="color:#569cd6;">if</font> (block.timestamp >= opt.head.triggerDate + <font style="color:#4ec9b0;">uint48</font>(opt.head.execDays) * <font style="color:#b5cea8;">86400</font>) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_NotInExercisePeriod"</font>));
        }

        <font style="color:#569cd6;">if</font> (opt.head.typeOfOpt > <font style="color:#4ec9b0;">uint8</font>(TypeOfOpt.PutRoe)) {
            Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font> cp = rcd.oracles.latest();

            <font style="color:#569cd6;">if</font> (opt.cond.logicOpr == <font style="color:#4ec9b0;">uint8</font>(CondsRepo.LogOps.ZeroPoint)) {
                <font style="color:#569cd6;">if</font> (!opt.cond.checkSoleCond(cp.paid)) {
                    <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_CondsNotSatisfied"</font>));
                }
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (opt.cond.logicOpr <= <font style="color:#4ec9b0;">uint8</font>(CondsRepo.LogOps.NotEqual)) {
                <font style="color:#569cd6;">if</font> (!opt.cond.checkCondsOfTwo(cp.paid, cp.par)) {
                    <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_CondsNotSatisfied"</font>));
                }
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (opt.cond.logicOpr <= <font style="color:#4ec9b0;">uint8</font>(CondsRepo.LogOps.NeOr)) {
                <font style="color:#569cd6;">if</font> (!opt.cond.checkCondsOfThree(cp.paid, cp.par, cp.points)) {
                    <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_CondsNotSatisfied"</font>));
                }
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> OPR_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_LogOperatorOverflow"</font>));
        }

        opt.body.closingDeadline = <font style="color:#4ec9b0;">uint48</font>(block.timestamp) + <font style="color:#4ec9b0;">uint48</font>(opt.head.closingDays) * <font style="color:#b5cea8;">86400</font>;
        opt.body.state = <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Executed);
    }

    <font style="color:#6a9955;">// ==== Brief ====</font>

    <font style="color:#6a9955;">/// @notice Create a swap order for an executed option.</font>
    <font style="color:#569cd6;">function</font> createSwap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfTarget,
        <font style="color:#4ec9b0;">uint</font> paidOfTarget,
        <font style="color:#4ec9b0;">uint</font> seqOfPledge,
        <font style="color:#4ec9b0;">uint</font> caller,
        IRegisterOfShares _ros
    ) <font style="color:#569cd6;">public</font> onlyRightholder(repo, seqOfOpt, caller) <font style="color:#569cd6;">returns</font>(SwapsRepo.Swap <font style="color:#569cd6;">memory</font> swap) {

        Option <font style="color:#569cd6;">storage</font> opt = repo.options[seqOfOpt];

        <font style="color:#569cd6;">if</font> (opt.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Executed)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotInExecutedState"</font>));
        }
        <font style="color:#569cd6;">if</font> (block.timestamp >= opt.body.closingDeadline) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptExpired"</font>));
        }

        swap.seqOfTarget = <font style="color:#4ec9b0;">uint32</font>(seqOfTarget);
        swap.paidOfTarget = <font style="color:#4ec9b0;">uint64</font>(paidOfTarget);
        swap.seqOfPledge = <font style="color:#4ec9b0;">uint32</font>(seqOfPledge);
        swap.state = <font style="color:#4ec9b0;">uint8</font>(SwapsRepo.StateOfSwap.Issued);

        Record <font style="color:#569cd6;">storage</font> rcd = repo.records[opt.head.seqOfOpt];

        SharesRepo.Head <font style="color:#569cd6;">memory</font> headOfTarget = _ros.getShare(swap.seqOfTarget).head;
        SharesRepo.Head <font style="color:#569cd6;">memory</font> headOfPledge = _ros.getShare(swap.seqOfPledge).head;

        <font style="color:#569cd6;">if</font> (opt.head.classOfShare != headOfTarget.class) {
            <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_WrongTargetClass"</font>));
        }

        <font style="color:#569cd6;">if</font> (opt.body.paid < rcd.swaps.sumPaidOfTarget() + swap.paidOfTarget) {
            <font style="color:#569cd6;">revert</font> OPR_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_PaidOfTargetOverflow"</font>));
        }

        <font style="color:#569cd6;">if</font> (opt.head.typeOfOpt % <font style="color:#b5cea8;">2</font> == <font style="color:#b5cea8;">1</font>) { <font style="color:#6a9955;">// Put Option</font>

            <font style="color:#569cd6;">if</font> (opt.body.rightholder != headOfTarget.shareholder) {
                <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_RightholderNotTargetholder"</font>));
            }
            <font style="color:#569cd6;">if</font> (!rcd.obligors.contains(headOfPledge.shareholder)) {
                <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_PledgeShareholderNotObligor"</font>));
            }

            swap.isPutOpt = <font style="color:#569cd6;">true</font>;

        } <font style="color:#569cd6;">else</font> { <font style="color:#6a9955;">// Call Opt</font>
            <font style="color:#569cd6;">if</font> (opt.body.rightholder != headOfPledge.shareholder) {
                <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_PldShareholderHasNoRight"</font>));
            }

            <font style="color:#569cd6;">if</font> (!rcd.obligors.contains(headOfTarget.shareholder)) {
                <font style="color:#569cd6;">revert</font> OPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_TgtShareholderNotObligor"</font>));
            }
        }

        <font style="color:#569cd6;">if</font> (opt.head.typeOfOpt % <font style="color:#b5cea8;">4</font> < <font style="color:#b5cea8;">2</font>)
            swap.priceOfDeal = opt.head.rate;
        <font style="color:#569cd6;">else</font> {
            <font style="color:#4ec9b0;">uint32</font> ds = <font style="color:#4ec9b0;">uint32</font>(((block.timestamp - headOfTarget.issueDate) + <font style="color:#b5cea8;">43200</font>) / <font style="color:#b5cea8;">86400</font>);
            swap.priceOfDeal = <font style="color:#4ec9b0;">uint32</font>(<font style="color:#4ec9b0;">uint</font>(headOfTarget.priceOfPaid) * (opt.head.rate * ds + <font style="color:#b5cea8;">3650000</font>) / <font style="color:#b5cea8;">3650000</font>);
        }

        <font style="color:#569cd6;">if</font> (opt.head.typeOfOpt % <font style="color:#b5cea8;">2</font> == <font style="color:#b5cea8;">1</font>) {
            swap.paidOfPledge = (swap.priceOfDeal - headOfTarget.priceOfPaid) * <font style="color:#b5cea8;">10000</font>
                * swap.paidOfTarget / headOfPledge.priceOfPaid / <font style="color:#b5cea8;">10000</font>;
        }

        <font style="color:#569cd6;">return</font> rcd.swaps.regSwap(swap);

    }

    <font style="color:#6a9955;">/// @notice Pay off a swap order.</font>
    <font style="color:#569cd6;">function</font> payOffSwap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
        <font style="color:#6a9955;">// uint msgValue,</font>
        <font style="color:#6a9955;">// uint centPrice</font>
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font> ) {

        Option <font style="color:#569cd6;">storage</font> opt = repo.options[seqOfOpt];

        <font style="color:#569cd6;">if</font> (opt.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Executed)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotInExecutedState"</font>));
        }
        <font style="color:#569cd6;">if</font> (block.timestamp >= opt.body.closingDeadline) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptExpired"</font>));
        }

        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.payOffSwap(seqOfSwap);
    }

    <font style="color:#6a9955;">/// @notice Terminate an expired swap order.</font>
    <font style="color:#569cd6;">function</font> terminateSwap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font>){

        Option <font style="color:#569cd6;">storage</font> opt = repo.options[seqOfOpt];

        <font style="color:#569cd6;">if</font> (opt.body.state != <font style="color:#4ec9b0;">uint8</font>(StateOfOpt.Executed)) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotInExecutedState"</font>));
        }
        <font style="color:#569cd6;">if</font> (block.timestamp < opt.body.closingDeadline) {
            <font style="color:#569cd6;">revert</font> OPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"OPR_OptNotExpired"</font>));
        }

        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.terminateSwap(seqOfSwap);
    }

    <font style="color:#6a9955;">// ==== Counter ====</font>

    <font style="color:#6a9955;">/// @dev Increment and return the option sequence counter.</font>
    <font style="color:#569cd6;">function</font> _increaseCounter(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font> seqOfOpt) {
        repo.options[<font style="color:#b5cea8;">0</font>].head.seqOfOpt++;
        seqOfOpt = repo.options[<font style="color:#b5cea8;">0</font>].head.seqOfOpt;
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">// ==== Repo ====</font>

    <font style="color:#6a9955;">/// @notice Get the option counter.</font>
    <font style="color:#569cd6;">function</font> counterOfOptions(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>)
    {
        <font style="color:#569cd6;">return</font> repo.options[<font style="color:#b5cea8;">0</font>].head.seqOfOpt;
    }

    <font style="color:#6a9955;">/// @notice Get number of options.</font>
    <font style="color:#569cd6;">function</font> qtyOfOptions(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>)
    {
        <font style="color:#569cd6;">return</font> repo.seqList.length();
    }

    <font style="color:#6a9955;">/// @notice Check whether an option exists.</font>
    <font style="color:#569cd6;">function</font> isOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.seqList.contains(seqOfOpt);
    }

    <font style="color:#6a9955;">/// @notice Get an option by sequence number.</font>
    <font style="color:#569cd6;">function</font> getOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        optExist(repo, seqOfOpt) <font style="color:#569cd6;">returns</font> (OptionsRepo.Option <font style="color:#569cd6;">memory</font> option)
    {
        option = repo.options[seqOfOpt];
    }

    <font style="color:#6a9955;">/// @notice Get all options.</font>
    <font style="color:#569cd6;">function</font> getAllOptions(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Option[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = repo.seqList.values();
        <font style="color:#4ec9b0;">uint256</font> len = ls.length;
        Option[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> Option[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            output[len-<font style="color:#b5cea8;">1</font>] = repo.options[ls[len-<font style="color:#b5cea8;">1</font>]];
            len--;
        }
        <font style="color:#569cd6;">return</font> output;
    }

    <font style="color:#6a9955;">/// @notice Check whether an account is the rightholder.</font>
    <font style="color:#569cd6;">function</font> isRightholder(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> optExist(repo, seqOfOpt) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.options[seqOfOpt].body.rightholder == acct;
    }

    <font style="color:#6a9955;">/// @notice Check whether an account is an obligor.</font>
    <font style="color:#569cd6;">function</font> isObligor(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font> optExist(repo, seqOfOpt) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].obligors.contains(acct);
    }

    <font style="color:#6a9955;">/// @notice Get obligors of an option.</font>
    <font style="color:#569cd6;">function</font> getObligorsOfOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt) <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font> optExist(repo, seqOfOpt) <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].obligors.values();
    }

    <font style="color:#6a9955;">/// @notice Get list of option sequence numbers.</font>
    <font style="color:#569cd6;">function</font> getSeqList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.seqList.values();
    }

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#6a9955;">/// @notice Get swap counter for an option.</font>
    <font style="color:#569cd6;">function</font> counterOfSwaps(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.counterOfSwaps();
    }

    <font style="color:#6a9955;">/// @notice Sum paid amount of targets for an option.</font>
    <font style="color:#569cd6;">function</font> sumPaidOfTarget(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.sumPaidOfTarget();
    }

    <font style="color:#6a9955;">/// @notice Check whether a swap exists.</font>
    <font style="color:#569cd6;">function</font> isSwap(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfOrder)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.isSwap(seqOfOrder);
    }

    <font style="color:#6a9955;">/// @notice Get a swap by sequence number.</font>
    <font style="color:#569cd6;">function</font> getSwap(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.getSwap(seqOfSwap);
    }

    <font style="color:#6a9955;">/// @notice Get all swaps of an option.</font>
    <font style="color:#569cd6;">function</font> getAllSwapsOfOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (SwapsRepo.Swap[] <font style="color:#569cd6;">memory</font> )
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.getAllSwaps();
    }

    <font style="color:#6a9955;">/// @notice Check whether all swaps are closed.</font>
    <font style="color:#569cd6;">function</font> allSwapsClosed(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].swaps.allSwapsClosed();
    }

    <font style="color:#6a9955;">// ==== Oracles ====</font>

    <font style="color:#6a9955;">/// @notice Get oracle checkpoint at a date.</font>
    <font style="color:#569cd6;">function</font> getOracleAtDate(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfOpt,
        <font style="color:#4ec9b0;">uint</font> date
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> optExist(repo, seqOfOpt)
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].oracles.getAtDate(date);
    }

    <font style="color:#6a9955;">/// @notice Get latest oracle checkpoint.</font>
    <font style="color:#569cd6;">function</font> getLatestOracle(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> optExist(repo, seqOfOpt)
        <font style="color:#569cd6;">returns</font>(Checkpoints.Checkpoint <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].oracles.latest();
    }

    <font style="color:#6a9955;">/// @notice Get all oracle checkpoints of an option.</font>
    <font style="color:#569cd6;">function</font> getAllOraclesOfOption(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfOpt)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> optExist(repo, seqOfOpt)
        <font style="color:#569cd6;">returns</font> (Checkpoints.Checkpoint[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.records[seqOfOpt].oracles.pointsOfHistory();
    }

    <font style="color:#6a9955;">// function checkValueOfSwap(</font>
    <font style="color:#6a9955;">//     Repo storage repo, </font>
    <font style="color:#6a9955;">//     uint seqOfOpt, </font>
    <font style="color:#6a9955;">//     uint seqOfSwap, </font>
    <font style="color:#6a9955;">//     uint centPrice</font>
    <font style="color:#6a9955;">// ) public view optExist(repo, seqOfOpt) returns (uint) {</font>
    <font style="color:#6a9955;">//     return repo.records[seqOfOpt].swaps.checkValueOfSwap(seqOfSwap, centPrice);</font>
    <font style="color:#6a9955;">// }</font>

}</code></pre>
```
 |
| [Contents](#toc) |

---

## OrdersRepo.sol

---

| |
|:---|
| **contracts/lib/books/OrdersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./GoldChain.sol"</font>;

<font style="color:#6a9955;">/// @title OrdersRepo</font>
<font style="color:#6a9955;">/// @notice Order book utilities for matching offers and bids.</font>
<font style="color:#569cd6;">library</font> OrdersRepo {
    <font style="color:#569cd6;">using</font> GoldChain <font style="color:#569cd6;">for</font> GoldChain.Chain;

    <font style="color:#6a9955;">/// @notice Compact brief for on-chain encoding.</font>
    <font style="color:#569cd6;">struct</font> Brief {
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint40</font> buyer;
        <font style="color:#4ec9b0;">uint40</font> seller;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint32</font> price;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
    }

    <font style="color:#6a9955;">/// @notice Order/deal model used by matching engine.</font>
    <font style="color:#569cd6;">struct</font> Deal {
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>;
        <font style="color:#4ec9b0;">uint40</font> buyer;
        <font style="color:#4ec9b0;">uint40</font> groupRep;
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">address</font> to;
        <font style="color:#4ec9b0;">uint40</font> seller;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">bool</font> inEth;
        <font style="color:#4ec9b0;">bool</font> isOffer;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint32</font> price;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
        <font style="color:#4ec9b0;">uint128</font> consideration;
    }

    <font style="color:#6a9955;">/// @notice Two-sided order book storage.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        GoldChain.Chain offers;
        GoldChain.Chain bids;
    }

    <font style="color:#6a9955;">//##############</font>
    <font style="color:#6a9955;">//##  Error   ##</font>
    <font style="color:#6a9955;">//##############</font>

    <font style="color:#569cd6;">error</font> ODR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Codify & Parse ====</font>

    <font style="color:#6a9955;">/// @notice Parse brief from packed bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed brief.</font>
    <font style="color:#569cd6;">function</font> parseBrief(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(
        Brief <font style="color:#569cd6;">memory</font> brief
    ) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        brief.classOfShare = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>);
        brief.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">208</font>);
        brief.buyer = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">168</font>);
        brief.seller = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">128</font>);
        brief.paid = <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">64</font>);
        brief.price = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">32</font>);
        brief.votingWeight = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>);
        brief.distrWeight = <font style="color:#4ec9b0;">uint16</font>(_sn);
    }

    <font style="color:#6a9955;">/// @notice Pack deal fields into brief.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#569cd6;">function</font> codifyBrief(
        Deal <font style="color:#569cd6;">memory</font> deal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn =
            abi.encodePacked(
                deal.classOfShare,
                deal.seqOfShare,
                deal.buyer,
                deal.seller,
                deal.paid,
                deal.price,
                deal.votingWeight,
                deal.distrWeight
            );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">/// @notice Parse a deal from packed segments.</font>
    <font style="color:#6a9955;">/// @param fromSn Packed from-part.</font>
    <font style="color:#6a9955;">/// @param toSn Packed to-part.</font>
    <font style="color:#6a9955;">/// @param qtySn Packed qty-part.</font>
    <font style="color:#569cd6;">function</font> parseDeal(
        <font style="color:#4ec9b0;">bytes32</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(
        Deal <font style="color:#569cd6;">memory</font> deal
    ) {
        <font style="color:#4ec9b0;">uint</font> _fromSn = <font style="color:#4ec9b0;">uint</font>(fromSn);

        deal.<font style="color:#569cd6;">from</font> = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(_fromSn >> <font style="color:#b5cea8;">96</font>));
        deal.buyer = <font style="color:#4ec9b0;">uint40</font>(_fromSn >> <font style="color:#b5cea8;">56</font>);
        deal.groupRep = <font style="color:#4ec9b0;">uint40</font>(_fromSn >> <font style="color:#b5cea8;">16</font>);
        deal.classOfShare = <font style="color:#4ec9b0;">uint16</font>(_fromSn);

        <font style="color:#4ec9b0;">uint</font> _toSn = <font style="color:#4ec9b0;">uint</font>(toSn);

        deal.to = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(_toSn >> <font style="color:#b5cea8;">96</font>));
        deal.seller = <font style="color:#4ec9b0;">uint40</font>(_toSn >> <font style="color:#b5cea8;">56</font>);
        deal.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(_toSn >> <font style="color:#b5cea8;">24</font>);
        deal.state = <font style="color:#4ec9b0;">uint8</font>(_toSn >> <font style="color:#b5cea8;">16</font>);
        deal.inEth = <font style="color:#4ec9b0;">uint8</font>(_toSn >> <font style="color:#b5cea8;">8</font>) == <font style="color:#b5cea8;">1</font>;
        deal.isOffer = <font style="color:#4ec9b0;">uint8</font>(_toSn) == <font style="color:#b5cea8;">1</font>;

        <font style="color:#4ec9b0;">uint</font> _qtySn = <font style="color:#4ec9b0;">uint</font>(qtySn);

        deal.paid = <font style="color:#4ec9b0;">uint64</font>(_qtySn >> <font style="color:#b5cea8;">192</font>);
        deal.price = <font style="color:#4ec9b0;">uint32</font>(_qtySn >> <font style="color:#b5cea8;">160</font>);
        deal.votingWeight = <font style="color:#4ec9b0;">uint16</font>(_qtySn >> <font style="color:#b5cea8;">144</font>);
        deal.distrWeight = <font style="color:#4ec9b0;">uint16</font>(_qtySn >> <font style="color:#b5cea8;">128</font>);
        deal.consideration = <font style="color:#4ec9b0;">uint128</font>(_qtySn);
    }

    <font style="color:#6a9955;">/// @notice Pack a deal into 3 words.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#569cd6;">function</font> codifyDeal(Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(
        <font style="color:#4ec9b0;">bytes32</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn
    ) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _fromSn =
            abi.encodePacked(
                deal.<font style="color:#569cd6;">from</font>,
                deal.buyer,
                deal.groupRep,
                deal.classOfShare
            );

        <font style="color:#569cd6;">assembly</font> {
            fromSn := mload(add(_fromSn, 0x20))
        }

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _toSn =
            abi.encodePacked(
                deal.to,
                deal.seller,
                deal.seqOfShare,
                deal.state,
                deal.inEth,
                deal.isOffer
            );

        <font style="color:#569cd6;">assembly</font> {
            toSn := mload(add(_toSn, 0x20))
        }

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _qtySn =
            abi.encodePacked(
                deal.paid,
                deal.price,
                deal.votingWeight,
                deal.distrWeight,
                deal.consideration
            );

        <font style="color:#569cd6;">assembly</font> {
            qtySn := mload(add(_qtySn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#6a9955;">/// @notice Convert deal to GoldChain order data.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#569cd6;">function</font> dealToData(Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (GoldChain.Data <font style="color:#569cd6;">memory</font> data) {
        <font style="color:#569cd6;">return</font> GoldChain.Data({
            classOfShare : deal.classOfShare,
            seqOfShare : deal.seqOfShare,
            groupRep: deal.groupRep,
            votingWeight : deal.votingWeight,
            distrWeight : deal.distrWeight,
            margin: deal.consideration,
            inEth : deal.inEth,
            pubKey : deal.isOffer ? deal.to : deal.<font style="color:#569cd6;">from</font>,
            date: <font style="color:#b5cea8;">0</font>,
            issueDate : <font style="color:#4ec9b0;">uint48</font>(block.timestamp)
        });
    }

    <font style="color:#6a9955;">/// @notice Match and/or place a sell offer.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param input Offer data.</font>
    <font style="color:#6a9955;">/// @param execHours Expiration in hours.</font>
    <font style="color:#6a9955;">/// @param centPriceInWei Cent price in wei.</font>
    <font style="color:#569cd6;">function</font> placeSellOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> centPriceInWei
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (
        Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        Deal <font style="color:#569cd6;">memory</font> offer
    ) {

        offer = input;

        GoldChain.Chain <font style="color:#569cd6;">storage</font> bids = repo.bids;
        <font style="color:#4ec9b0;">uint</font> len = bids.length();

        deals = <font style="color:#569cd6;">new</font> Deal[](len);
        expired = <font style="color:#569cd6;">new</font> GoldChain.Order[](len);

        <font style="color:#569cd6;">if</font> (offer.price > <font style="color:#b5cea8;">0</font>) {
            (lenOfDeals, lenOfExpired) = _matchOfferToBid(bids, offer, centPriceInWei, deals, expired);
        } <font style="color:#569cd6;">else</font> {
            (lenOfDeals, lenOfExpired) = _matchMarketToBid(bids, offer, centPriceInWei, deals, expired);
        }

        <font style="color:#569cd6;">if</font> (offer.paid > <font style="color:#b5cea8;">0</font> && offer.price > <font style="color:#b5cea8;">0</font>) {

            GoldChain.Data <font style="color:#569cd6;">memory</font> data = dealToData(offer);

            repo.offers.createNode(
                offer.seller,
                offer.paid,
                offer.price,
                execHours,
                <font style="color:#569cd6;">true</font>,
                data
            );
        }
    }

    <font style="color:#6a9955;">/// @notice Compute consideration value in wei.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param price Price in cents.</font>
    <font style="color:#6a9955;">/// @param centPrice Cent price in wei.</font>
    <font style="color:#569cd6;">function</font> getDealValue(
        <font style="color:#4ec9b0;">uint</font> paid, <font style="color:#4ec9b0;">uint</font> price, <font style="color:#4ec9b0;">uint</font> centPrice
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint128</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">uint128</font>(paid * price * centPrice / <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">6</font>);
    }

    <font style="color:#6a9955;">/// @notice Match and/or place a buy bid.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param input Bid data.</font>
    <font style="color:#6a9955;">/// @param execHours Expiration in hours.</font>
    <font style="color:#6a9955;">/// @param centPriceInWei Cent price in wei.</font>
    <font style="color:#569cd6;">function</font> placeBuyOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours,
        <font style="color:#4ec9b0;">uint</font> centPriceInWei
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (
        Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        Deal <font style="color:#569cd6;">memory</font> bid
    ) {

        bid = input;

        <font style="color:#569cd6;">if</font> (getDealValue(bid.paid, bid.price, centPriceInWei) >
            bid.consideration) {
            <font style="color:#569cd6;">revert</font> ODR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ODR_ShortOfMargin"</font>));
        }

        GoldChain.Chain <font style="color:#569cd6;">storage</font> offers = repo.offers;
        <font style="color:#4ec9b0;">uint</font> len = offers.length();

        deals = <font style="color:#569cd6;">new</font> Deal[](len);
        expired = <font style="color:#569cd6;">new</font> GoldChain.Order[](len);

        <font style="color:#569cd6;">if</font> (bid.price > <font style="color:#b5cea8;">0</font>) {
            (lenOfDeals, lenOfExpired) = _matchBidToOffer(offers, bid, centPriceInWei, deals, expired);
        } <font style="color:#569cd6;">else</font> {
            (lenOfDeals, lenOfExpired) = _matchMarketToOffer(offers, bid, centPriceInWei, deals, expired);
        }

        <font style="color:#569cd6;">if</font> (bid.paid > <font style="color:#b5cea8;">0</font> && bid.price > <font style="color:#b5cea8;">0</font>) {

            GoldChain.Data <font style="color:#569cd6;">memory</font> data = dealToData(bid);

            repo.bids.createNode(
                bid.buyer,
                bid.paid,
                bid.price,
                execHours,
                <font style="color:#569cd6;">false</font>,
                data
            );
        }
    }

    <font style="color:#6a9955;">/// @notice Withdraw an order by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> withdrawOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order <font style="color:#569cd6;">memory</font> removed)
    {
        removed = isOffer
            ? repo.offers.offChain(seqOfOrder)
            : repo.bids.offChain(seqOfOrder);
    }

    <font style="color:#569cd6;">function</font> _matchOfferToBid(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> bids, Deal <font style="color:#569cd6;">memory</font> offer, <font style="color:#4ec9b0;">uint</font> centPriceInWei,
        Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = bids.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && offer.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(bids, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = bids.orders[seqOfNode];

            <font style="color:#569cd6;">if</font> (n.node.price >= offer.price) {

                Deal <font style="color:#569cd6;">memory</font> deal =
                    _createDeal(offer, offer.price, n.node.paid, centPriceInWei);

                <font style="color:#569cd6;">if</font> (deal.consideration >= n.data.margin) {
                    deal.consideration = n.data.margin;
                    deal.paid =
                        <font style="color:#4ec9b0;">uint64</font>(<font style="color:#4ec9b0;">uint</font>(deal.consideration) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">6</font> / centPriceInWei / deal.price);

                    n.data.margin = <font style="color:#b5cea8;">0</font>;
                    n.node.paid = <font style="color:#b5cea8;">0</font>;
                    deal.state = <font style="color:#b5cea8;">1</font>;
                } <font style="color:#569cd6;">else</font> {
                    n.data.margin -= deal.consideration;
                    n.node.paid -= deal.paid;
                }

                offer.paid -= deal.paid;

                _fillInOfferDeal(deal, offer, n);

                <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                    GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = bids.offChain(seqOfNode);
                    seqOfNode = delistedOrder.node.next;
                    expired[lenOfExpired] = delistedOrder;
                    lenOfExpired++;
                }

                deals[lenOfDeals] = deal;
                lenOfDeals++;

            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
        }
    }

    <font style="color:#569cd6;">function</font> _matchBidToOffer(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> offers, Deal <font style="color:#569cd6;">memory</font> bid, <font style="color:#4ec9b0;">uint</font> centPriceInWei,
        Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = offers.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && bid.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(offers, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = offers.orders[seqOfNode];

            <font style="color:#569cd6;">if</font> (n.node.price <= bid.price) {

                Deal <font style="color:#569cd6;">memory</font> deal = _createDeal(bid, n.node.price, n.node.paid, centPriceInWei);

                <font style="color:#569cd6;">if</font> (deal.consideration >= bid.consideration) {
                    deal.consideration = bid.consideration;
                    deal.paid =
                        <font style="color:#4ec9b0;">uint64</font>(<font style="color:#4ec9b0;">uint</font>(deal.consideration) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">6</font> / centPriceInWei / deal.price);

                    bid.paid = deal.paid;

                    <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                        deal.state = <font style="color:#b5cea8;">0</font>;
                    }
                }

                n.node.paid -= deal.paid;
                bid.consideration -= deal.consideration;
                bid.paid -= deal.paid;

                _fillInBidDeal(deal, bid, n);

                <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                    GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = offers.offChain(seqOfNode);
                    seqOfNode = delistedOrder.node.next;
                }

                deals[lenOfDeals] = deal;
                lenOfDeals++;

            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
        }
    }

    <font style="color:#569cd6;">function</font> _matchMarketToBid(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> bids, Deal <font style="color:#569cd6;">memory</font> offer, <font style="color:#4ec9b0;">uint</font> centPriceInWei,
        Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = bids.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && offer.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(bids, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = bids.orders[seqOfNode];

            Deal <font style="color:#569cd6;">memory</font> deal = _createDeal(offer, n.node.price, n.node.paid, centPriceInWei);

            <font style="color:#569cd6;">if</font> (deal.consideration >= n.data.margin) {
                deal.consideration = n.data.margin;
                deal.paid = <font style="color:#4ec9b0;">uint64</font>(<font style="color:#4ec9b0;">uint</font>(deal.consideration) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">6</font> / centPriceInWei / deal.price);

                n.data.margin = <font style="color:#b5cea8;">0</font>;
                n.node.paid = <font style="color:#b5cea8;">0</font>;
                n.data.date = <font style="color:#b5cea8;">1</font>;
            } <font style="color:#569cd6;">else</font> {
                n.data.margin -= deal.consideration;
                n.node.paid -= deal.paid;
            }

            offer.paid -= deal.paid;

            _fillInOfferDeal(deal, offer, n);

            <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = bids.offChain(seqOfNode);
                seqOfNode = delistedOrder.node.next;
                expired[lenOfExpired] = delistedOrder;
                lenOfExpired++;
            }

            deals[lenOfDeals] = deal;
            lenOfDeals++;
        }
    }

    <font style="color:#569cd6;">function</font> _matchMarketToOffer(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> offers, Deal <font style="color:#569cd6;">memory</font> bid, <font style="color:#4ec9b0;">uint</font> centPriceInWei,
        Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = offers.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && bid.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(offers, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = offers.orders[seqOfNode];

            Deal <font style="color:#569cd6;">memory</font> deal = _createDeal(bid, n.node.price, n.node.paid, centPriceInWei);

            <font style="color:#569cd6;">if</font> (deal.consideration >= bid.consideration) {
                deal.consideration = bid.consideration;
                deal.paid =
                    <font style="color:#4ec9b0;">uint64</font>(<font style="color:#4ec9b0;">uint</font>(deal.consideration) * <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">6</font> / centPriceInWei / deal.price);

                bid.paid = deal.paid;

                <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                    deal.state = <font style="color:#b5cea8;">0</font>;
                }
            }

            n.node.paid -= deal.paid;
            bid.consideration -= deal.consideration;
            bid.paid -= deal.paid;

            _fillInBidDeal(deal, bid, n);

            <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = offers.offChain(seqOfNode);
                seqOfNode = delistedOrder.node.next;
            }

            deals[lenOfDeals] = deal;
            lenOfDeals++;

        }
    }

    <font style="color:#569cd6;">function</font> _checkExpired(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint32</font> seqOfNode, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired, <font style="color:#4ec9b0;">uint</font> lenOfExpired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>, <font style="color:#4ec9b0;">uint</font>) {

        <font style="color:#569cd6;">while</font> (seqOfNode > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (chain.orders[seqOfNode].node.expireDate <= block.timestamp) {
                GoldChain.Order <font style="color:#569cd6;">memory</font> removedNode = chain.offChain(seqOfNode);
                expired[lenOfExpired] = (removedNode);
                lenOfExpired++;
                seqOfNode = removedNode.node.next;
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
        }

        <font style="color:#569cd6;">return</font> (seqOfNode, lenOfExpired);
    }

    <font style="color:#569cd6;">function</font> _createDeal(
        Deal <font style="color:#569cd6;">memory</font> order, <font style="color:#4ec9b0;">uint32</font> offerPrice, <font style="color:#4ec9b0;">uint64</font> nodePaid, <font style="color:#4ec9b0;">uint</font> centPriceInWei
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Deal <font style="color:#569cd6;">memory</font> deal) {
        deal.price = offerPrice;

        <font style="color:#569cd6;">if</font> (order.paid >= nodePaid) {
            deal.paid = nodePaid;
            deal.state = <font style="color:#b5cea8;">1</font>;
        } <font style="color:#569cd6;">else</font> {
            deal.paid = order.paid;
        }
        deal.inEth = <font style="color:#569cd6;">true</font>;

        deal.consideration =
            getDealValue(deal.paid, deal.price, centPriceInWei);
    }

    <font style="color:#569cd6;">function</font> _fillInOfferDeal(
        Deal <font style="color:#569cd6;">memory</font> deal, Deal <font style="color:#569cd6;">memory</font> offer, GoldChain.Order <font style="color:#569cd6;">memory</font> n
    )<font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font>{
        deal.<font style="color:#569cd6;">from</font> = n.data.pubKey;
        deal.to = offer.to;
        deal.seller = offer.seller;

        deal.classOfShare = offer.classOfShare;
        deal.seqOfShare = offer.seqOfShare;
        deal.buyer = n.node.issuer;
        deal.groupRep = n.data.groupRep;
        deal.votingWeight = offer.votingWeight;
        deal.distrWeight = offer.distrWeight;
    }

    <font style="color:#569cd6;">function</font> _fillInBidDeal(
        Deal <font style="color:#569cd6;">memory</font> deal, Deal <font style="color:#569cd6;">memory</font> bid, GoldChain.Order <font style="color:#569cd6;">memory</font> n
    )<font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font>{

        deal.<font style="color:#569cd6;">from</font> = bid.<font style="color:#569cd6;">from</font>;
        deal.to = n.data.pubKey;
        deal.seller = n.node.issuer;

        deal.classOfShare = n.data.classOfShare;
        deal.seqOfShare = n.data.seqOfShare;
        deal.buyer = bid.buyer;
        deal.groupRep = bid.groupRep;
        deal.votingWeight = n.data.votingWeight;
        deal.distrWeight = n.data.distrWeight;

    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Get order counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> counterOfOrders(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.counter()
            : repo.bids.counter();
    }

    <font style="color:#6a9955;">/// @notice Get head node id.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> headOfList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.head()
            : repo.bids.head();
    }

    <font style="color:#6a9955;">/// @notice Get tail node id.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> tailOfList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.tail()
            : repo.bids.tail();
    }

    <font style="color:#6a9955;">/// @notice Get list length.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> lengthOfList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.length()
            : repo.bids.length();
    }

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an order exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number.</font>
    <font style="color:#569cd6;">function</font> isOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.isNode(seqOfOrder)
            : repo.bids.isNode(seqOfOrder);
    }

    <font style="color:#6a9955;">/// @notice Get order by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number.</font>
    <font style="color:#569cd6;">function</font> getOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order <font style="color:#569cd6;">memory</font> order) {
        order = isOffer
            ? repo.offers.getOrder(seqOfOrder)
            : repo.bids.getOrder(seqOfOrder);
    }

    <font style="color:#6a9955;">/// @notice Get order sequence list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> getSeqList(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> orders) {
        orders = isOffer
            ? repo.offers.getSeqList()
            : repo.bids.getSeqList();
    }

    <font style="color:#6a9955;">/// @notice Get full order chain.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> getOrders(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order[] <font style="color:#569cd6;">memory</font> orders) {
        orders = isOffer
            ? repo.offers.getChain()
            : repo.bids.getChain();
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## PledgesRepo.sol

---

| |
|:---|
| **contracts/lib/books/PledgesRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title PledgesRepo</font>
<font style="color:#6a9955;">/// @notice Repository for share pledge records and lifecycle.</font>
<font style="color:#569cd6;">library</font> PledgesRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.Bytes32Set;

    <font style="color:#6a9955;">/// @notice Pledge lifecycle state.</font>
    <font style="color:#569cd6;">enum</font> StateOfPld {
        Pending,
        Issued,
        Locked,
        Released,
        Executed,
        Revoked
    }

    <font style="color:#6a9955;">/// @notice Pledge header fields.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint16</font> seqOfPld;
        <font style="color:#4ec9b0;">uint48</font> createDate;
        <font style="color:#4ec9b0;">uint16</font> daysToMaturity;
        <font style="color:#4ec9b0;">uint16</font> guaranteeDays;
        <font style="color:#4ec9b0;">uint40</font> creditor;
        <font style="color:#4ec9b0;">uint40</font> debtor;
        <font style="color:#4ec9b0;">uint40</font> pledgor;
        <font style="color:#4ec9b0;">uint8</font> state;
    }

    <font style="color:#6a9955;">/// @notice Pledge body fields.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint64</font> guaranteedAmt;
        <font style="color:#4ec9b0;">uint16</font> preSeq;
        <font style="color:#4ec9b0;">uint16</font> execDays;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Full pledge record.</font>
    <font style="color:#569cd6;">struct</font> Pledge {
        Head head;
        Body body;
        <font style="color:#4ec9b0;">bytes32</font> hashLock;
    }

    <font style="color:#6a9955;">/// @notice Repository of pledges by share and sequence.</font>
    <font style="color:#569cd6;">struct</font> Repo{
        <font style="color:#6a9955;">// seqOfShare => seqOfPld => Pledge</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Pledge)) pledges;
        EnumerableSet.Bytes32Set snList;
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##   Error    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#569cd6;">error</font> PLDR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> PLDR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> PLDR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> PLDR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Parse pledge head from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed pledge head.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head = Head({
            seqOfShare: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            seqOfPld: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">208</font>),
            createDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">160</font>),
            daysToMaturity: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">144</font>),
            guaranteeDays: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">128</font>),
            creditor: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">88</font>),
            debtor: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">48</font>),
            pledgor: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">8</font>),
            state: <font style="color:#4ec9b0;">uint8</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Pack pledge head into bytes32.</font>
    <font style="color:#6a9955;">/// @param head Pledge head.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            head.seqOfShare,
                            head.seqOfPld,
                            head.createDate,
                            head.daysToMaturity,
                            head.guaranteeDays,
                            head.creditor,
                            head.pledgor,
                            head.debtor,
                            head.state);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }

    }

        <font style="color:#6a9955;">/// @notice Create and issue a pledge from packed head.</font>
        <font style="color:#6a9955;">/// @param repo Storage repo.</font>
        <font style="color:#6a9955;">/// @param snOfPld Packed pledge head.</font>
        <font style="color:#6a9955;">/// @param paid Paid amount.</font>
        <font style="color:#6a9955;">/// @param par Par amount.</font>
        <font style="color:#6a9955;">/// @param guaranteedAmt Guaranteed amount.</font>
        <font style="color:#6a9955;">/// @param execDays Execution days.</font>
        <font style="color:#569cd6;">function</font> createPledge(
            Repo <font style="color:#569cd6;">storage</font> repo,
            <font style="color:#4ec9b0;">bytes32</font> snOfPld,
            <font style="color:#4ec9b0;">uint</font> paid,
            <font style="color:#4ec9b0;">uint</font> par,
            <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
            <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head)
    {
        head = snParser(snOfPld);
        head = issuePledge(repo, head, paid, par, guaranteedAmt, execDays);
    }

    <font style="color:#6a9955;">/// @notice Issue a pledge with provided head/body.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param head Pledge head.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @param guaranteedAmt Guaranteed amount.</font>
    <font style="color:#6a9955;">/// @param execDays Execution days.</font>
    <font style="color:#569cd6;">function</font> issuePledge(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Head <font style="color:#569cd6;">memory</font> head,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> guaranteedAmt,
        <font style="color:#4ec9b0;">uint</font> execDays
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> regHead) {

        <font style="color:#569cd6;">if</font> (guaranteedAmt == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_ZeroGuaranteedAmt"</font>);
        <font style="color:#569cd6;">if</font> (par == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_ZeroPar"</font>);
        <font style="color:#569cd6;">if</font> (par < paid) <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_PaidExceedsPar"</font>);

        Pledge <font style="color:#569cd6;">memory</font> pld;

        pld.head = head;

        pld.head.createDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        pld.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Issued);

        pld.body = Body({
            paid: <font style="color:#4ec9b0;">uint64</font>(paid),
            par: <font style="color:#4ec9b0;">uint64</font>(par),
            guaranteedAmt: <font style="color:#4ec9b0;">uint64</font>(guaranteedAmt),
            preSeq:<font style="color:#b5cea8;">0</font>,
            execDays: <font style="color:#4ec9b0;">uint16</font>(execDays),
            para:<font style="color:#b5cea8;">0</font>,
            argu:<font style="color:#b5cea8;">0</font>
        });

        regHead = regPledge(repo, pld);
    }

    <font style="color:#6a9955;">/// @notice Register pledge into storage.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#569cd6;">function</font> regPledge(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Pledge <font style="color:#569cd6;">memory</font> pld
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font>){

        <font style="color:#569cd6;">if</font> (pld.head.seqOfShare == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_ZeroSeqOfShare"</font>);

        pld.head.seqOfPld = _increaseCounterOfPld(repo, pld.head.seqOfShare);

        repo.pledges[pld.head.seqOfShare][pld.head.seqOfPld] = pld;
        repo.snList.add(codifyHead(pld.head));

        <font style="color:#569cd6;">return</font> pld.head;
    }

    <font style="color:#6a9955;">// ==== Update Pledge ====</font>

    <font style="color:#6a9955;">/// @notice Split a pledge and optionally transfer to buyer.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#6a9955;">/// @param buyer Buyer user number.</font>
    <font style="color:#6a9955;">/// @param amt Split amount.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> splitPledge(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint256</font> seqOfShare,
        <font style="color:#4ec9b0;">uint256</font> seqOfPld,
        <font style="color:#4ec9b0;">uint</font> buyer,
        <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Pledge <font style="color:#569cd6;">memory</font> newPld) {

        Pledge <font style="color:#569cd6;">storage</font> pld = repo.pledges[seqOfShare][seqOfPld];

        <font style="color:#569cd6;">if</font> (caller != pld.head.creditor)
            <font style="color:#569cd6;">revert</font> PLDR_WrongParty(<font style="color:#ce9178;">"PLDR_NotCreditor"</font>);

        <font style="color:#569cd6;">if</font> (isExpired(pld))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PledgeExpired"</font>);

        <font style="color:#569cd6;">if</font> (pld.head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Issued) &&
            pld.head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Locked)
        ) {
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotIssuedOrLocked"</font>);
        }

        <font style="color:#569cd6;">if</font> (amt == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_ZeroAmt"</font>);

        newPld = pld;

        <font style="color:#569cd6;">if</font> (amt < pld.body.guaranteedAmt) {
            <font style="color:#6a9955;">// uint64 ratio = uint64(amt) * 10000 / newPld.body.guaranteedAmt;</font>

            newPld.body.paid = <font style="color:#4ec9b0;">uint64</font>(pld.body.paid * amt / newPld.body.guaranteedAmt);
            newPld.body.par = <font style="color:#4ec9b0;">uint64</font>(pld.body.par * amt / newPld.body.guaranteedAmt);
            newPld.body.guaranteedAmt = <font style="color:#4ec9b0;">uint64</font>(amt);

            pld.body.paid -= newPld.body.paid;
            pld.body.par -= newPld.body.par;
            pld.body.guaranteedAmt -= newPld.body.guaranteedAmt;

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (amt == pld.body.guaranteedAmt) {

            pld.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Released);

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font>(<font style="color:#ce9178;">"PR.splitPld: amt overflow"</font>);

        <font style="color:#569cd6;">if</font> (buyer > <font style="color:#b5cea8;">0</font>) {
            newPld.body.preSeq = pld.head.seqOfPld;

            newPld.head.creditor = <font style="color:#4ec9b0;">uint40</font>(buyer);
            newPld.head = regPledge(repo, newPld);
        }
    }

    <font style="color:#6a9955;">/// @notice Extend guarantee days.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#6a9955;">/// @param extDays Extra days.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> extendPledge(
        Pledge <font style="color:#569cd6;">storage</font> pld,
        <font style="color:#4ec9b0;">uint</font> extDays,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (caller != pld.head.pledgor)
            <font style="color:#569cd6;">revert</font> PLDR_WrongParty(<font style="color:#ce9178;">"PLDR_NotPledgor"</font>);

        <font style="color:#569cd6;">if</font> (pld.head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Issued) &&
            pld.head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Locked))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotIssuedOrLocked"</font>);

        <font style="color:#569cd6;">if</font> (isExpired(pld))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldExpired"</font>);

        pld.head.guaranteeDays += <font style="color:#4ec9b0;">uint16</font>(extDays);
    }

    <font style="color:#6a9955;">// ==== Lock & Release ====</font>

    <font style="color:#6a9955;">/// @notice Lock pledge with hash lock.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#6a9955;">/// @param hashLock Hash lock key.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> lockPledge(
        Pledge <font style="color:#569cd6;">storage</font> pld,
        <font style="color:#4ec9b0;">bytes32</font> hashLock,
        <font style="color:#4ec9b0;">uint</font> caller
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (caller != pld.head.creditor)
            <font style="color:#569cd6;">revert</font> PLDR_WrongParty(<font style="color:#ce9178;">"PLDR_NotCreditor"</font>);

        <font style="color:#569cd6;">if</font> (isExpired(pld))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldExpired"</font>);

        <font style="color:#569cd6;">if</font> (hashLock == <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_ZeroHashLock"</font>);

        <font style="color:#569cd6;">if</font> (pld.head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Issued)){
            pld.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Locked);
            pld.hashLock = hashLock;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotIssued"</font>);
    }

    <font style="color:#6a9955;">/// @notice Release pledge with hash key.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#6a9955;">/// @param hashKey Preimage string.</font>
    <font style="color:#569cd6;">function</font> releasePledge(
        Pledge <font style="color:#569cd6;">storage</font> pld,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (pld.head.state != <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Locked))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotLocked"</font>);

        <font style="color:#569cd6;">if</font> (pld.hashLock == keccak256(<font style="color:#4ec9b0;">bytes</font>(hashKey))) {
            pld.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Released);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> PLDR_WrongInput(<font style="color:#ce9178;">"PLDR_WrongKey"</font>);
    }

    <font style="color:#6a9955;">/// @notice Execute a triggered pledge.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> execPledge(Pledge <font style="color:#569cd6;">storage</font> pld, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">public</font> {

        <font style="color:#569cd6;">if</font> (caller != pld.head.creditor)
            <font style="color:#569cd6;">revert</font> PLDR_WrongParty(<font style="color:#ce9178;">"PLDR_NotCreditor"</font>);

        <font style="color:#569cd6;">if</font> (!isTriggerd(pld))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotTriggered"</font>);

        <font style="color:#569cd6;">if</font> (isExpired(pld))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldExpired"</font>);

        <font style="color:#569cd6;">if</font> (pld.head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Issued) ||
            pld.head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Locked))
        {
            pld.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Executed);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotIssuedOrLocked"</font>);
    }

    <font style="color:#6a9955;">/// @notice Revoke an expired pledge.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#6a9955;">/// @param caller Caller user number.</font>
    <font style="color:#569cd6;">function</font> revokePledge(Pledge <font style="color:#569cd6;">storage</font> pld, <font style="color:#4ec9b0;">uint</font> caller) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (caller != pld.head.pledgor)
            <font style="color:#569cd6;">revert</font> PLDR_WrongParty(<font style="color:#ce9178;">"PLDR_NotPledgor"</font>);

        <font style="color:#569cd6;">if</font> (!isExpired(pld))
            <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotExpired"</font>);

        <font style="color:#569cd6;">if</font> (pld.head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Issued) ||
            pld.head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Locked))
        {
            pld.head.state = <font style="color:#4ec9b0;">uint8</font>(StateOfPld.Revoked);
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> PLDR_WrongState(<font style="color:#ce9178;">"PLDR_PldNotIssuedOrLocked"</font>);
    }

    <font style="color:#6a9955;">// ==== Counter ====</font>

    <font style="color:#569cd6;">function</font> _increaseCounterOfPld(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font> seqOfPld)
    {
        repo.pledges[seqOfShare][<font style="color:#b5cea8;">0</font>].head.seqOfPld++;
        seqOfPld = repo.pledges[seqOfShare][<font style="color:#b5cea8;">0</font>].head.seqOfPld;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Read     ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Check if pledge is triggered by maturity.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#569cd6;">function</font> isTriggerd(Pledge <font style="color:#569cd6;">storage</font> pld) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint64</font> triggerDate = pld.head.createDate + <font style="color:#4ec9b0;">uint48</font>(pld.head.daysToMaturity) * <font style="color:#b5cea8;">86400</font>;
        <font style="color:#569cd6;">return</font> block.timestamp >= triggerDate;
    }

    <font style="color:#6a9955;">/// @notice Check if pledge is expired after guarantee days.</font>
    <font style="color:#6a9955;">/// @param pld Pledge record.</font>
    <font style="color:#569cd6;">function</font> isExpired(Pledge <font style="color:#569cd6;">storage</font> pld) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint64</font> expireDate = pld.head.createDate + <font style="color:#4ec9b0;">uint48</font>(pld.head.daysToMaturity + pld.head.guaranteeDays) * <font style="color:#b5cea8;">86400</font>;
        <font style="color:#569cd6;">return</font> block.timestamp >= expireDate;
    }

    <font style="color:#6a9955;">/// @notice Get pledge counter for share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> counterOfPld(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>)
    {
        <font style="color:#569cd6;">return</font> repo.pledges[seqOfShare][<font style="color:#b5cea8;">0</font>].head.seqOfPld;
    }

    <font style="color:#6a9955;">/// @notice Check if pledge exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPledge Pledge sequence.</font>
    <font style="color:#569cd6;">function</font> isPledge(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> seqOfPledge)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> repo.pledges[seqOfShare][seqOfPledge].head.createDate > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get list of pledge head hashes.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getSNList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> list)
    {
        list = repo.snList.values();
    }

    <font style="color:#6a9955;">/// @notice Get pledge by share and sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfPld Pledge sequence.</font>
    <font style="color:#569cd6;">function</font> getPledge(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> seqOfPld)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Pledge <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.pledges[seqOfShare][seqOfPld];
    }

    <font style="color:#6a9955;">/// @notice Get all pledges for a share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> getPledgesOfShare(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfShare)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Pledge[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> len = counterOfPld(repo, seqOfShare);

        Pledge[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> Pledge[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            output[len - <font style="color:#b5cea8;">1</font>] = repo.pledges[seqOfShare][len];
            len--;
        }

        <font style="color:#569cd6;">return</font> output;
    }

    <font style="color:#6a9955;">/// @notice Get all pledges across shares.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getAllPledges(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Pledge[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> snList = getSNList(repo);
        <font style="color:#4ec9b0;">uint</font> len = snList.length;
        Pledge[] <font style="color:#569cd6;">memory</font> ls = <font style="color:#569cd6;">new</font> Pledge[](len);

        <font style="color:#569cd6;">while</font>( len > <font style="color:#b5cea8;">0</font> ) {
            Head <font style="color:#569cd6;">memory</font> head = snParser(snList[len - <font style="color:#b5cea8;">1</font>]);
            ls[len - <font style="color:#b5cea8;">1</font>] = repo.pledges[head.seqOfShare][head.seqOfPld];
            len--;
        }

        <font style="color:#569cd6;">return</font> ls;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RedemptionsRepo.sol

---

| |
|:---|
| **contracts/lib/books/RedemptionsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rom/IRegisterOfMembers.sol"</font>;

<font style="color:#6a9955;">/// @title RedemptionsRepo</font>
<font style="color:#6a9955;">/// @notice Repository for redemption requests grouped by class and pack.</font>
<font style="color:#569cd6;">library</font> RedemptionsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice Redemption request record.</font>
    <font style="color:#569cd6;">struct</font> Request {
        <font style="color:#4ec9b0;">uint16</font> class;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint32</font> navPrice;
        <font style="color:#4ec9b0;">uint40</font> shareholder;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> value;
        <font style="color:#4ec9b0;">uint8</font> seqOfPack;
    }

    <font style="color:#6a9955;">/// @notice Pack of requests grouped by day.</font>
    <font style="color:#569cd6;">struct</font> Pack {
        Request info;
        <font style="color:#569cd6;">mapping</font> (<font style="color:#4ec9b0;">uint</font> => Request) requests;
        EnumerableSet.UintSet sharesList;
    }

    <font style="color:#6a9955;">/// @notice Redemption data for a share class.</font>
    <font style="color:#569cd6;">struct</font> Class {
        Request info;
        <font style="color:#569cd6;">mapping</font> (<font style="color:#4ec9b0;">uint</font> => Pack) packs;
        EnumerableSet.UintSet packsList;
    }

    <font style="color:#6a9955;">/// @notice Repository of redeemable classes.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Class) classes;
        EnumerableSet.UintSet classesList;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Error    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#569cd6;">error</font> PDPR_WrongState(<font style="color:#4ec9b0;">bytes32</font> message);

    <font style="color:#569cd6;">error</font> PDPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> message);

    <font style="color:#569cd6;">error</font> PDPR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> message);

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##    Modifier    ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">/// @notice Ensure class is redeemable.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">modifier</font> redeemableClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> class
    ) {
        <font style="color:#569cd6;">if</font> (!isRedeemable(repo, class))
            <font style="color:#569cd6;">revert</font> PDPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"PDPR_NotRedeemableClass"</font>));
        _;
    }

    <font style="color:#6a9955;">/// @notice Ensure pack exists under class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#569cd6;">modifier</font> redeemablePack(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack
    ) {
        <font style="color:#569cd6;">if</font> (!repo.classes[class].packsList.contains(seqOfPack))
            <font style="color:#569cd6;">revert</font> PDPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"PDPR_NotRedeemablePack"</font>));
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Write    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Pack request info into bytes32.</font>
    <font style="color:#6a9955;">/// @param request Request record.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Request <font style="color:#569cd6;">memory</font> request) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> sn)
    {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn =
            abi.encodePacked(
                request.class,
                request.seqOfShare,
                request.navPrice,
                request.shareholder,
                request.paid,
                request.value,
                request.seqOfPack
            );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }

    }

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#6a9955;">/// @notice Add a redeemable share class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> addRedeemableClass(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> {
        repo.classesList.add(class);
    }

    <font style="color:#6a9955;">/// @notice Remove a redeemable share class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> removeRedeemableClass(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) {
        repo.classesList.remove(class);
    }

    <font style="color:#6a9955;">/// @notice Update NAV price for a class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param price NAV price.</font>
    <font style="color:#569cd6;">function</font> updateNavPrice(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> price
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) {
        repo.classes[class].info.navPrice = <font style="color:#4ec9b0;">uint32</font>(price);
    }

    <font style="color:#6a9955;">// ==== Reqeust ====</font>

    <font style="color:#6a9955;">/// @notice Create a redemption request.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param caller Shareholder user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount of shares.</font>
    <font style="color:#569cd6;">function</font> requestForRedemption(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> caller, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfShare, <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) <font style="color:#569cd6;">returns</font>(
        Request <font style="color:#569cd6;">memory</font> request
    ) {
        Class <font style="color:#569cd6;">storage</font> cls = repo.classes[class];

        request.seqOfPack = <font style="color:#4ec9b0;">uint8</font>(block.timestamp / <font style="color:#b5cea8;">86400</font> % <font style="color:#b5cea8;">256</font>);

        cls.packsList.add(request.seqOfPack);

        Pack <font style="color:#569cd6;">storage</font> pack = cls.packs[request.seqOfPack];

        pack.sharesList.add(seqOfShare);

        request.class = <font style="color:#4ec9b0;">uint16</font>(class);
        request.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(seqOfShare);
        request.navPrice = <font style="color:#4ec9b0;">uint32</font>(cls.info.navPrice);
        request.shareholder = <font style="color:#4ec9b0;">uint40</font>(caller);
        request.paid = <font style="color:#4ec9b0;">uint64</font>(paid);
        request.value = <font style="color:#4ec9b0;">uint64</font>(paid * cls.info.navPrice / <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">4</font>);

        pack.requests[request.seqOfShare] = request;

        pack.info.paid += request.paid;
        pack.info.value += request.value;

        cls.info.paid += request.paid;
        cls.info.value += request.value;
    }

    <font style="color:#6a9955;">// ==== Redeem ====</font>

    <font style="color:#6a9955;">/// @notice Redeem a pack and return request list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#569cd6;">function</font> redeem(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) redeemablePack(repo, class, seqOfPack) <font style="color:#569cd6;">returns</font>(
        Request[] <font style="color:#569cd6;">memory</font> list, Request <font style="color:#569cd6;">memory</font> info
    ) {
        Class <font style="color:#569cd6;">storage</font> cls = repo.classes[class];
        Pack <font style="color:#569cd6;">storage</font> pack = cls.packs[seqOfPack];

        info = pack.info;

        <font style="color:#569cd6;">if</font> (info.value == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> PDPR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"PDPR_ZeroValue"</font>));

        cls.info.value -= pack.info.value;
        cls.info.paid -= pack.info.paid;

        <font style="color:#569cd6;">delete</font> pack.info;

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqs = pack.sharesList.values();
        <font style="color:#4ec9b0;">uint</font> len = seqs.length;

        list = <font style="color:#569cd6;">new</font> Request[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint</font> seq = seqs[len-<font style="color:#b5cea8;">1</font>];
            list[len-<font style="color:#b5cea8;">1</font>] = pack.requests[seq];
            <font style="color:#569cd6;">delete</font> pack.requests[seq];
            pack.sharesList.remove(seq);
            len--;
        }

        cls.packsList.remove(seqOfPack);
        <font style="color:#569cd6;">delete</font> cls.packs[seqOfPack];

    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Read     ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Check whether a class is redeemable.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> isRedeemable(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>){
        <font style="color:#569cd6;">return</font> repo.classesList.contains(class);
    }

    <font style="color:#6a9955;">/// @notice Get list of redeemable classes.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getClassesList(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        list = repo.classesList.values();
    }

    <font style="color:#6a9955;">// ==== Class ====</font>

    <font style="color:#6a9955;">/// @notice Get class redemption info.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getInfoOfClass(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        Request <font style="color:#569cd6;">memory</font> info
    ) {
        info = repo.classes[class].info;
    }

    <font style="color:#6a9955;">/// @notice Get pack list under class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getPacksList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list
    ) {
        list = repo.classes[class].packsList.values();
    }

    <font style="color:#6a9955;">// ==== Pack ====</font>

    <font style="color:#6a9955;">/// @notice Get pack summary info.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#569cd6;">function</font> getInfoOfPack(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) redeemablePack(repo, class, seqOfPack) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        Request <font style="color:#569cd6;">memory</font> info
    ) {
        info = repo.classes[class].packs[seqOfPack].info;
    }

    <font style="color:#6a9955;">/// @notice Get share list in pack.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#569cd6;">function</font> getSharesList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) redeemablePack(repo, class, seqOfPack) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list
    ) {
        list = repo.classes[class].packs[seqOfPack].sharesList.values();
    }

    <font style="color:#6a9955;">/// @notice Get request by share sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> getRequest(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack, <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) redeemablePack(repo, class, seqOfPack) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        Request <font style="color:#569cd6;">memory</font> request
    ) {
        <font style="color:#569cd6;">if</font> (!repo.classes[class].packs[seqOfPack].sharesList.contains(seqOfShare)) {
            <font style="color:#569cd6;">revert</font> PDPR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"PDPR_WrongSeqOfShare"</font>));
        }
        request = repo.classes[class].packs[seqOfPack].requests[seqOfShare];
    }

    <font style="color:#6a9955;">/// @notice Get all requests in pack.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfPack Pack sequence.</font>
    <font style="color:#569cd6;">function</font> getRequests(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfPack
    ) <font style="color:#569cd6;">public</font> redeemableClass(repo, class) redeemablePack(repo, class, seqOfPack) <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        Request[] <font style="color:#569cd6;">memory</font> requests
    ) {
        Pack <font style="color:#569cd6;">storage</font> pack = repo.classes[class].packs[seqOfPack];

        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqs = pack.sharesList.values();
        <font style="color:#4ec9b0;">uint</font> len = seqs.length;
        requests = <font style="color:#569cd6;">new</font> Request[](len);
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            requests[len-<font style="color:#b5cea8;">1</font>] = pack.requests[seqs[len-<font style="color:#b5cea8;">1</font>]];
            len--;
        }
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RulesParser.sol

---

| |
|:---|
| **contracts/lib/books/RulesParser.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title RulesParser</font>
<font style="color:#6a9955;">/// @notice Decode rule snapshots packed into bytes32.</font>
<font style="color:#569cd6;">library</font> RulesParser {

    <font style="color:#6a9955;">// ======== GovernanceRule ========</font>

    <font style="color:#6a9955;">// bytes32 public constant SHA_INIT_GR = </font>
    <font style="color:#6a9955;">//     bytes32(uint(0x0000000000000000010000000000000000000000000000000000000000000000));</font>

    <font style="color:#6a9955;">/// @notice Governance rule parameters.</font>
    <font style="color:#569cd6;">struct</font> GovernanceRule {
        <font style="color:#4ec9b0;">uint32</font> fundApprovalThreshold;
        <font style="color:#4ec9b0;">bool</font> basedOnPar;
        <font style="color:#4ec9b0;">uint16</font> proposeWeightRatioOfGM;
        <font style="color:#4ec9b0;">uint16</font> proposeHeadRatioOfMembers;
        <font style="color:#4ec9b0;">uint16</font> proposeHeadRatioOfDirectorsInGM;
        <font style="color:#4ec9b0;">uint16</font> proposeHeadRatioOfDirectorsInBoard;
        <font style="color:#4ec9b0;">uint16</font> maxQtyOfMembers;
        <font style="color:#4ec9b0;">uint16</font> quorumOfGM;
        <font style="color:#4ec9b0;">uint8</font> maxNumOfDirectors;
        <font style="color:#4ec9b0;">uint16</font> tenureMonOfBoard;
        <font style="color:#4ec9b0;">uint16</font> quorumOfBoardMeeting;
        <font style="color:#4ec9b0;">uint48</font> establishedDate;
        <font style="color:#4ec9b0;">uint8</font> businessTermInYears;
        <font style="color:#4ec9b0;">uint8</font> typeOfComp;
        <font style="color:#4ec9b0;">uint16</font> minVoteRatioOnChain;
    }

    <font style="color:#6a9955;">/// @notice Parse governance rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> governanceRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (GovernanceRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = GovernanceRule({
            fundApprovalThreshold: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            basedOnPar: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>) == <font style="color:#b5cea8;">1</font>,
            proposeWeightRatioOfGM: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">200</font>),
            proposeHeadRatioOfMembers: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">184</font>),
            proposeHeadRatioOfDirectorsInGM: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">168</font>),
            proposeHeadRatioOfDirectorsInBoard: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">152</font>),
            maxQtyOfMembers: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">136</font>),
            quorumOfGM: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">120</font>),
            maxNumOfDirectors: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">112</font>),
            tenureMonOfBoard: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">96</font>),
            quorumOfBoardMeeting: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">80</font>),
            establishedDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">32</font>),
            businessTermInYears: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">24</font>),
            typeOfComp: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">16</font>),
            minVoteRatioOnChain: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">// ---- VotingRule ----</font>

    <font style="color:#6a9955;">// bytes32 public constant SHA_INIT_VR = </font>
    <font style="color:#6a9955;">//     bytes32(uint(0x00080c080100001a0b0000010000000000000100000000000000000000000000));</font>

    <font style="color:#6a9955;">/// @notice Voting rule parameters.</font>
    <font style="color:#569cd6;">struct</font> VotingRule{
        <font style="color:#4ec9b0;">uint16</font> seqOfRule;
        <font style="color:#4ec9b0;">uint8</font> qtyOfSubRule;
        <font style="color:#4ec9b0;">uint8</font> seqOfSubRule;
        <font style="color:#4ec9b0;">uint8</font> authority;
        <font style="color:#4ec9b0;">uint16</font> headRatio;
        <font style="color:#4ec9b0;">uint16</font> amountRatio;
        <font style="color:#4ec9b0;">bool</font> onlyAttendance;
        <font style="color:#4ec9b0;">bool</font> impliedConsent;
        <font style="color:#4ec9b0;">bool</font> partyAsConsent;
        <font style="color:#4ec9b0;">bool</font> againstShallBuy;
        <font style="color:#4ec9b0;">uint8</font> frExecDays;
        <font style="color:#4ec9b0;">uint8</font> dtExecDays;
        <font style="color:#4ec9b0;">uint8</font> dtConfirmDays;
        <font style="color:#4ec9b0;">uint8</font> invExitDays;
        <font style="color:#4ec9b0;">uint8</font> votePrepareDays;
        <font style="color:#4ec9b0;">uint8</font> votingDays;
        <font style="color:#4ec9b0;">uint8</font> execDaysForPutOpt;
        <font style="color:#4ec9b0;">uint40</font>[<font style="color:#b5cea8;">2</font>] vetoers;
        <font style="color:#4ec9b0;">uint16</font> class;
    }

    <font style="color:#6a9955;">/// @notice Parse voting rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> votingRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (VotingRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = VotingRule({
            seqOfRule: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            qtyOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">232</font>),
            seqOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            authority: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            headRatio: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">200</font>),
            amountRatio: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">184</font>),
            onlyAttendance: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">176</font>) == <font style="color:#b5cea8;">1</font>,
            impliedConsent: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">168</font>) == <font style="color:#b5cea8;">1</font>,
            partyAsConsent: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">160</font>) == <font style="color:#b5cea8;">1</font>,
            againstShallBuy: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">152</font>) == <font style="color:#b5cea8;">1</font>,
            frExecDays: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">144</font>),
            dtExecDays: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">136</font>),
            dtConfirmDays: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">128</font>),
            invExitDays: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">120</font>),
            votePrepareDays: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">112</font>),
            votingDays: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">104</font>),
            execDaysForPutOpt: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">96</font>),
            vetoers: [<font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">56</font>), <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">16</font>)],
            class: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">// ---- BoardSeatsRule ----</font>

<font style="color:#6a9955;">/*
    1: Chairman;
    2: ViceChairman;
    3: Director;
    ...
*/</font>

    <font style="color:#6a9955;">/// @notice Board seat allocation rule.</font>
    <font style="color:#569cd6;">struct</font> PositionAllocateRule {
        <font style="color:#4ec9b0;">uint16</font> seqOfRule;
        <font style="color:#4ec9b0;">uint8</font> qtyOfSubRule;
        <font style="color:#4ec9b0;">uint8</font> seqOfSubRule;
        <font style="color:#4ec9b0;">bool</font> removePos;
        <font style="color:#4ec9b0;">uint16</font> seqOfPos;
        <font style="color:#4ec9b0;">uint16</font> titleOfPos;
        <font style="color:#4ec9b0;">uint40</font> nominator;
        <font style="color:#4ec9b0;">uint16</font> titleOfNominator;
        <font style="color:#4ec9b0;">uint16</font> seqOfVR;
        <font style="color:#4ec9b0;">uint48</font> endDate;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
        <font style="color:#4ec9b0;">uint32</font> data;
    }

    <font style="color:#6a9955;">/// @notice Parse position allocation rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> positionAllocateRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(PositionAllocateRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = PositionAllocateRule({
            seqOfRule: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            qtyOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">232</font>),
            seqOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            removePos: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>) == <font style="color:#b5cea8;">1</font>,
            seqOfPos: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">200</font>),
            titleOfPos: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">184</font>),
            nominator: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">144</font>),
            titleOfNominator: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">128</font>),
            seqOfVR: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">112</font>),
            endDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">64</font>),
            para: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">48</font>),
            argu: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">32</font>),
            data: <font style="color:#4ec9b0;">uint32</font>(_sn)
        });

    }

    <font style="color:#6a9955;">// ---- FirstRefusal Rule ----</font>

    <font style="color:#6a9955;">/// @notice First refusal rule parameters.</font>
    <font style="color:#569cd6;">struct</font> FirstRefusalRule {
        <font style="color:#4ec9b0;">uint16</font> seqOfRule;
        <font style="color:#4ec9b0;">uint8</font> qtyOfSubRule;
        <font style="color:#4ec9b0;">uint8</font> seqOfSubRule;
        <font style="color:#4ec9b0;">uint8</font> typeOfDeal;
        <font style="color:#4ec9b0;">bool</font> membersEqual;
        <font style="color:#4ec9b0;">bool</font> proRata;
        <font style="color:#4ec9b0;">bool</font> basedOnPar;
        <font style="color:#4ec9b0;">uint40</font>[<font style="color:#b5cea8;">4</font>] rightholders;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Parse first refusal rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> firstRefusalRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(FirstRefusalRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = FirstRefusalRule({
            seqOfRule: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            qtyOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">232</font>),
            seqOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            typeOfDeal: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            membersEqual: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">208</font>) == <font style="color:#b5cea8;">1</font>,
            proRata: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">200</font>) == <font style="color:#b5cea8;">1</font>,
            basedOnPar: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">192</font>) == <font style="color:#b5cea8;">1</font>,
            rightholders: [<font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">152</font>), <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">112</font>), <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">72</font>), <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">32</font>)],
            para: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>),
            argu: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">// ---- GroupUpdateOrder ----</font>

    <font style="color:#6a9955;">/// @notice Group membership update order.</font>
    <font style="color:#569cd6;">struct</font> GroupUpdateOrder {
        <font style="color:#4ec9b0;">uint16</font> seqOfRule;
        <font style="color:#4ec9b0;">uint8</font> qtyOfSubRule;
        <font style="color:#4ec9b0;">uint8</font> seqOfSubRule;
        <font style="color:#4ec9b0;">bool</font> addMember;
        <font style="color:#4ec9b0;">uint40</font> groupRep;
        <font style="color:#4ec9b0;">uint40</font>[<font style="color:#b5cea8;">4</font>] members;
        <font style="color:#4ec9b0;">uint16</font> para;
    }

    <font style="color:#6a9955;">/// @notice Parse group update order from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed order bytes32.</font>
    <font style="color:#569cd6;">function</font> groupUpdateOrderParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(GroupUpdateOrder <font style="color:#569cd6;">memory</font> order) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        order = GroupUpdateOrder({
            seqOfRule: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            qtyOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">232</font>),
            seqOfSubRule: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            addMember: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">216</font>) == <font style="color:#b5cea8;">1</font>,
            groupRep: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">176</font>),
            members: [
                <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">136</font>),
                <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">96</font>),
                <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">56</font>),
                <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">16</font>)
            ],
            para: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">// ---- ListingRule ----</font>

    <font style="color:#6a9955;">/// @notice Listing rule parameters for LOO.</font>
    <font style="color:#569cd6;">struct</font> ListingRule {
        <font style="color:#4ec9b0;">uint16</font> seqOfRule;
        <font style="color:#4ec9b0;">uint16</font> titleOfIssuer;
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> maxTotalPar;
        <font style="color:#4ec9b0;">uint16</font> titleOfVerifier;
        <font style="color:#4ec9b0;">uint16</font> maxQtyOfInvestors;
        <font style="color:#4ec9b0;">uint32</font> ceilingPrice;
        <font style="color:#4ec9b0;">uint32</font> floorPrice;
        <font style="color:#4ec9b0;">uint16</font> lockupDays;
        <font style="color:#4ec9b0;">uint16</font> offPrice;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
        <font style="color:#4ec9b0;">uint16</font> para;
    }

    <font style="color:#6a9955;">/// @notice Parse listing rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> listingRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(ListingRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = ListingRule({
            seqOfRule: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            titleOfIssuer: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">224</font>),
            classOfShare: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">208</font>),
            maxTotalPar: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">176</font>),
            titleOfVerifier: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">160</font>),
            maxQtyOfInvestors: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">144</font>),
            ceilingPrice: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">112</font>),
            floorPrice: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">80</font>),
            lockupDays: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">64</font>),
            offPrice: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">48</font>),
            votingWeight: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">32</font>),
            distrWeight: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>),
            para: <font style="color:#4ec9b0;">uint16</font>(_sn)
        });
    }

    <font style="color:#6a9955;">// ======== LinkRule ========</font>

    <font style="color:#6a9955;">/// @notice Link rule parameters.</font>
    <font style="color:#569cd6;">struct</font> LinkRule {
        <font style="color:#4ec9b0;">uint48</font> triggerDate;
        <font style="color:#4ec9b0;">uint16</font> effectiveDays;
        <font style="color:#4ec9b0;">uint8</font> triggerType;
        <font style="color:#4ec9b0;">uint16</font> shareRatioThreshold;
        <font style="color:#4ec9b0;">uint32</font> rate;
        <font style="color:#4ec9b0;">bool</font> proRata;
        <font style="color:#4ec9b0;">uint16</font> seq;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
        <font style="color:#4ec9b0;">uint16</font> ref;
        <font style="color:#4ec9b0;">uint64</font> data;
    }

    <font style="color:#6a9955;">/// @notice Parse link rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> linkRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (LinkRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = LinkRule({
            triggerDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">208</font>),
            effectiveDays: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">192</font>),
            triggerType: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">184</font>),
            shareRatioThreshold: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">168</font>),
            rate: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">136</font>),
            proRata: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">128</font>) == <font style="color:#b5cea8;">1</font>,
            seq: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">112</font>),
            para: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">96</font>),
            argu: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">80</font>),
            ref: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">64</font>),
            data: <font style="color:#4ec9b0;">uint64</font>(_sn)
        });
    }

    <font style="color:#6a9955;">// ======== DistributionRule ========</font>

    <font style="color:#6a9955;">/// @notice Distribution types.</font>
    <font style="color:#569cd6;">enum</font> TypeOfDistr {
        ProRata,
        IntFront,
        PrinFront,
        HuddleCarry
    }

    <font style="color:#6a9955;">// rule: 1280</font>
    <font style="color:#6a9955;">/// @notice Distribution rule parameters.</font>
    <font style="color:#569cd6;">struct</font> DistrRule {
        <font style="color:#4ec9b0;">uint8</font> typeOfDistr;
        <font style="color:#4ec9b0;">uint8</font> numOfTiers;
        <font style="color:#4ec9b0;">bool</font> isCumulative;
        <font style="color:#4ec9b0;">bool</font> refundPrincipal;
        <font style="color:#4ec9b0;">uint16</font>[<font style="color:#b5cea8;">7</font>] tiers;
        <font style="color:#4ec9b0;">uint16</font>[<font style="color:#b5cea8;">7</font>] rates;
    }

    <font style="color:#6a9955;">/// @notice Parse distribution rule from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes32.</font>
    <font style="color:#569cd6;">function</font> DistrRuleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (DistrRule <font style="color:#569cd6;">memory</font> rule) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = DistrRule({
            typeOfDistr: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">248</font>),
            numOfTiers: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            isCumulative: <font style="color:#4ec9b0;">uint8</font>(_sn >> <font style="color:#b5cea8;">232</font>) == <font style="color:#b5cea8;">1</font>,
            refundPrincipal: <font style="color:#4ec9b0;">uint8</font>(_sn>><font style="color:#b5cea8;">224</font>) == <font style="color:#b5cea8;">1</font>,
            tiers: [
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">208</font>), <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">192</font>),
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">176</font>), <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">160</font>),
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">144</font>), <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">128</font>),
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">112</font>)
            ],
            rates: [
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">96</font>),
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">80</font>), <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">64</font>),
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">48</font>), <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">32</font>),
                <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>), <font style="color:#4ec9b0;">uint16</font>(_sn)
            ]
        });
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## SharesRepo.sol

---

| |
|:---|
| **contracts/lib/books/SharesRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title SharesRepo</font>
<font style="color:#6a9955;">/// @notice Repository for share classes and share records.</font>
<font style="color:#569cd6;">library</font> SharesRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice Share header fields.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">uint16</font> class;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint32</font> preSeq;
        <font style="color:#4ec9b0;">uint48</font> issueDate;
        <font style="color:#4ec9b0;">uint40</font> shareholder;
        <font style="color:#4ec9b0;">uint32</font> priceOfPaid;
        <font style="color:#4ec9b0;">uint32</font> priceOfPar;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint8</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Share body fields.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">uint48</font> payInDeadline;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint64</font> par;
        <font style="color:#4ec9b0;">uint64</font> cleanPaid;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
    }

    <font style="color:#6a9955;">/// @notice Full share record.</font>
    <font style="color:#569cd6;">struct</font> Share {
        Head head;
        Body body;
    }

    <font style="color:#6a9955;">/// @notice Share class with info and share list.</font>
    <font style="color:#569cd6;">struct</font> Class{
        Share info;
        EnumerableSet.UintSet seqList;
    }

    <font style="color:#6a9955;">/// @notice Repository of classes and shares.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// seqOfClass => Class</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Class) classes;
        <font style="color:#6a9955;">// seqOfShare => Share</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Share) shares;
    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##     Error      ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#569cd6;">error</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SHR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SHR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SHR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##    Modifier    ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">/// @notice Ensure share exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">modifier</font> shareExist(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) {
        <font style="color:#569cd6;">if</font> (!isShare(repo, seqOfShare)) {
            <font style="color:#569cd6;">revert</font> SHR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ShareNotExist"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##    Write    ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">/// @notice Parse share head from bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed share head.</font>
    <font style="color:#569cd6;">function</font> snParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font> head)
    {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        head = Head({
            class: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>),
            seqOfShare: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">208</font>),
            preSeq: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">176</font>),
            issueDate: <font style="color:#4ec9b0;">uint48</font>(_sn >> <font style="color:#b5cea8;">128</font>),
            shareholder: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">88</font>),
            priceOfPaid: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">56</font>),
            priceOfPar: <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">24</font>),
            votingWeight: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">8</font>),
            argu: <font style="color:#4ec9b0;">uint8</font>(_sn)
        });
    }

    <font style="color:#6a9955;">/// @notice Pack share head into bytes32.</font>
    <font style="color:#6a9955;">/// @param head Share head.</font>
    <font style="color:#569cd6;">function</font> codifyHead(Head <font style="color:#569cd6;">memory</font> head) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> sn)
    {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn =
            abi.encodePacked(
                head.class,
                head.seqOfShare,
                head.preSeq,
                head.issueDate,
                head.shareholder,
                head.priceOfPaid,
                head.priceOfPar,
                head.votingWeight,
                head.argu
            );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }

    }

    <font style="color:#6a9955;">// ==== issue/regist share ====</font>

    <font style="color:#6a9955;">/// @notice Build a share from packed head and body values.</font>
    <font style="color:#6a9955;">/// @param sharenumber Packed share head.</font>
    <font style="color:#6a9955;">/// @param payInDeadline Pay-in deadline timestamp.</font>
    <font style="color:#6a9955;">/// @param paid Paid amount.</font>
    <font style="color:#6a9955;">/// @param par Par amount.</font>
    <font style="color:#6a9955;">/// @param distrWeight Distribution weight.</font>
    <font style="color:#569cd6;">function</font> createShare(
        <font style="color:#4ec9b0;">bytes32</font> sharenumber,
        <font style="color:#4ec9b0;">uint</font> payInDeadline,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par,
        <font style="color:#4ec9b0;">uint</font> distrWeight
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Share <font style="color:#569cd6;">memory</font> share) {

        share.head = snParser(sharenumber);

        share.body = Body({
            payInDeadline: <font style="color:#4ec9b0;">uint48</font>(payInDeadline),
            paid: <font style="color:#4ec9b0;">uint64</font>(paid),
            par: <font style="color:#4ec9b0;">uint64</font>(par),
            cleanPaid: <font style="color:#4ec9b0;">uint64</font>(paid),
            distrWeight: <font style="color:#4ec9b0;">uint16</font>(distrWeight)
        });
    }

    <font style="color:#6a9955;">/// @notice Decode premium snapshot to share body.</font>
    <font style="color:#6a9955;">/// @param premium Encoded premium value.</font>
    <font style="color:#569cd6;">function</font> codifyPremium(<font style="color:#4ec9b0;">uint</font> premium) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Body <font style="color:#569cd6;">memory</font> body) {
        body = Body({
            payInDeadline: <font style="color:#4ec9b0;">uint48</font>(premium >> <font style="color:#b5cea8;">208</font>),
            paid: <font style="color:#4ec9b0;">uint64</font>(premium >> <font style="color:#b5cea8;">144</font>),
            par: <font style="color:#4ec9b0;">uint64</font>(premium >> <font style="color:#b5cea8;">80</font>),
            cleanPaid: <font style="color:#4ec9b0;">uint64</font>(premium >> <font style="color:#b5cea8;">16</font>),
            distrWeight: <font style="color:#4ec9b0;">uint16</font>(premium)
        });
    }

    <font style="color:#569cd6;">function</font> _addPremium(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> priceOfPaid,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">private</font> {

        <font style="color:#569cd6;">if</font> (priceOfPaid > <font style="color:#b5cea8;">10000</font> && paid > <font style="color:#b5cea8;">0</font>) {

            <font style="color:#4ec9b0;">uint</font> premium = getPremium(repo);

            premium += ((priceOfPaid - <font style="color:#b5cea8;">10000</font>) * paid / <font style="color:#b5cea8;">10000</font>);

            repo.shares[<font style="color:#b5cea8;">0</font>].body = codifyPremium(premium);
        }

    }

    <font style="color:#6a9955;">/// @notice Add a share and update class equity.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param share Share record.</font>
    <font style="color:#569cd6;">function</font> addShare(Repo <font style="color:#569cd6;">storage</font> repo, Share <font style="color:#569cd6;">memory</font> share)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Share <font style="color:#569cd6;">memory</font> newShare)
    {
        newShare = regShare(repo, share);

        _addPremium(repo, newShare.head.priceOfPaid, newShare.body.paid);

        Share <font style="color:#569cd6;">storage</font> info = repo.classes[newShare.head.class].info;

        <font style="color:#569cd6;">if</font> (info.head.issueDate == <font style="color:#b5cea8;">0</font>) {
            info.head = newShare.head;
            info.body.distrWeight = newShare.body.distrWeight;
        }

        increaseEquityOfClass(repo, <font style="color:#569cd6;">true</font>, share.head.class,
            share.body.paid, share.body.par, <font style="color:#b5cea8;">0</font>);
    }

    <font style="color:#6a9955;">/// @notice Register share in storage.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param share Share record.</font>
    <font style="color:#569cd6;">function</font> regShare(Repo <font style="color:#569cd6;">storage</font> repo, Share <font style="color:#569cd6;">memory</font> share)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Share <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">if</font> (share.head.class == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroClass"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.body.par == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroPar"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.body.par < share.body.paid) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_PaidExceedPar"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.head.issueDate > block.timestamp) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_FutureIssueDate"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.head.issueDate > share.body.payInDeadline) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_IssueDateLaterPayInDeadline"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.head.shareholder == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroShareholder"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.head.votingWeight == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroVotingWeight"</font>));
        }

        <font style="color:#569cd6;">if</font> (share.head.class > counterOfClasses(repo))
            share.head.class = _increaseCounterOfClasses(repo);

        Class <font style="color:#569cd6;">storage</font> class = repo.classes[share.head.class];

        <font style="color:#569cd6;">if</font> (!class.seqList.contains(share.head.seqOfShare)) {
            share.head.seqOfShare = _increaseCounterOfShares(repo);

            <font style="color:#569cd6;">if</font> (share.head.issueDate == <font style="color:#b5cea8;">0</font>)
                share.head.issueDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);

            class.seqList.add(share.head.seqOfShare);
            repo.classes[<font style="color:#b5cea8;">0</font>].seqList.add(share.head.seqOfShare);
        }

        repo.shares[share.head.seqOfShare] = share;

        <font style="color:#569cd6;">return</font> share;
    }

    <font style="color:#6a9955;">// ==== counters ====</font>

    <font style="color:#569cd6;">function</font> _increaseCounterOfShares(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {

        Head <font style="color:#569cd6;">storage</font> h = repo.shares[<font style="color:#b5cea8;">0</font>].head;

        <font style="color:#569cd6;">do</font> {
            <font style="color:#569cd6;">unchecked</font> {
                h.seqOfShare++;
            }
        } <font style="color:#569cd6;">while</font> (isShare(repo, h.seqOfShare) ||
            h.seqOfShare == <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">return</font> h.seqOfShare;
    }

    <font style="color:#569cd6;">function</font> _increaseCounterOfClasses(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>)
    {
        repo.shares[<font style="color:#b5cea8;">0</font>].head.class++;
        <font style="color:#569cd6;">return</font> repo.shares[<font style="color:#b5cea8;">0</font>].head.class;
    }

    <font style="color:#6a9955;">// ==== amountChange ====</font>

    <font style="color:#6a9955;">/// @notice Increase paid-in capital for a share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param amt Paid amount.</font>
    <font style="color:#569cd6;">function</font> payInCapital(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">public</font> shareExist(repo, seqOfShare) {

        Share <font style="color:#569cd6;">storage</font> share = repo.shares[seqOfShare];

        <font style="color:#4ec9b0;">uint64</font> deltaPaid = <font style="color:#4ec9b0;">uint64</font>(amt);

        <font style="color:#569cd6;">if</font> (deltaPaid == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroAmt"</font>));
        }

        <font style="color:#569cd6;">if</font> (block.timestamp > share.body.payInDeadline) {
            <font style="color:#569cd6;">revert</font> SHR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_MissedDeadline"</font>));
        }

        <font style="color:#569cd6;">if</font> (share.body.paid + deltaPaid > share.body.par) {
            <font style="color:#569cd6;">revert</font> SHR_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_PaidExceedPar"</font>));
        }

        share.body.paid += deltaPaid;
        share.body.cleanPaid += deltaPaid;

        _addPremium(repo, share.head.priceOfPaid, share.body.paid);

        increaseEquityOfClass(repo, <font style="color:#569cd6;">true</font>, share.head.class, deltaPaid, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>);
    }

    <font style="color:#6a9955;">/// @notice Decrease share amounts or delete share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Paid delta.</font>
    <font style="color:#6a9955;">/// @param par Par delta.</font>
    <font style="color:#569cd6;">function</font> subAmtFromShare(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid,
        <font style="color:#4ec9b0;">uint</font> par
    ) <font style="color:#569cd6;">public</font> shareExist(repo, seqOfShare) {

        Share <font style="color:#569cd6;">storage</font> share = repo.shares[seqOfShare];
        Class <font style="color:#569cd6;">storage</font> class = repo.classes[share.head.class];

        <font style="color:#4ec9b0;">uint64</font> deltaPaid = <font style="color:#4ec9b0;">uint64</font>(paid);
        <font style="color:#4ec9b0;">uint64</font> deltaPar = <font style="color:#4ec9b0;">uint64</font>(par);

        <font style="color:#569cd6;">if</font> (deltaPar == <font style="color:#b5cea8;">0</font> && deltaPaid == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroDeltaAmt"</font>));
        }
        <font style="color:#569cd6;">if</font> (share.body.cleanPaid < deltaPaid) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_DeltaPaidExceedCleanPaid"</font>));
        }

        <font style="color:#569cd6;">if</font> (deltaPar == share.body.par) {
            class.seqList.remove(seqOfShare);
            repo.classes[<font style="color:#b5cea8;">0</font>].seqList.remove(seqOfShare);
            <font style="color:#569cd6;">delete</font> repo.shares[seqOfShare];
        } <font style="color:#569cd6;">else</font> {
            share.body.paid -= deltaPaid;
            share.body.par -= deltaPar;
            share.body.cleanPaid -= deltaPaid;

            <font style="color:#569cd6;">if</font> (share.body.par < share.body.paid) {
                <font style="color:#569cd6;">revert</font> SHR_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_PaidExceedPar"</font>));
            }
        }
    }

    <font style="color:#6a9955;">/// @notice Adjust clean paid amount.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param paid Delta amount.</font>
    <font style="color:#569cd6;">function</font> increaseCleanPaid(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isIncrease,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> paid
    ) <font style="color:#569cd6;">public</font> shareExist(repo, seqOfShare) {

        Share <font style="color:#569cd6;">storage</font> share = repo.shares[seqOfShare];

        <font style="color:#4ec9b0;">uint64</font> deltaClean = <font style="color:#4ec9b0;">uint64</font>(paid);

        <font style="color:#569cd6;">if</font> (deltaClean == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_ZeroDeltaCleanPaid"</font>));
        }

        <font style="color:#569cd6;">if</font> (isIncrease && share.body.cleanPaid + deltaClean <= share.body.paid)
            share.body.cleanPaid += deltaClean;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font>(!isIncrease && share.body.cleanPaid >= deltaClean)
            share.body.cleanPaid -= deltaClean;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> SHR_Overflow(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_CleanPaidOverflow"</font>));
    }

    <font style="color:#6a9955;">// ---- EquityOfClass ----</font>

    <font style="color:#6a9955;">/// @notice Update equity totals for a class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class.</font>
    <font style="color:#6a9955;">/// @param deltaPaid Paid delta.</font>
    <font style="color:#6a9955;">/// @param deltaPar Par delta.</font>
    <font style="color:#6a9955;">/// @param deltaCleanPaid Clean paid delta.</font>
    <font style="color:#569cd6;">function</font> increaseEquityOfClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isIncrease,
        <font style="color:#4ec9b0;">uint</font> classOfShare,
        <font style="color:#4ec9b0;">uint</font> deltaPaid,
        <font style="color:#4ec9b0;">uint</font> deltaPar,
        <font style="color:#4ec9b0;">uint</font> deltaCleanPaid
    ) <font style="color:#569cd6;">public</font> {

        Body <font style="color:#569cd6;">storage</font> equity = repo.classes[classOfShare].info.body;

        <font style="color:#569cd6;">if</font> (isIncrease) {
            equity.paid += <font style="color:#4ec9b0;">uint64</font>(deltaPaid);
            equity.par += <font style="color:#4ec9b0;">uint64</font>(deltaPar);
            equity.cleanPaid += <font style="color:#4ec9b0;">uint64</font>(deltaCleanPaid);
        } <font style="color:#569cd6;">else</font> {
            equity.paid -= <font style="color:#4ec9b0;">uint64</font>(deltaPaid);
            equity.par -= <font style="color:#4ec9b0;">uint64</font>(deltaPar);
            equity.cleanPaid -= <font style="color:#4ec9b0;">uint64</font>(deltaCleanPaid);
        }
    }

    <font style="color:#6a9955;">/// @notice Update paid price for a share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param newPrice New price.</font>
    <font style="color:#569cd6;">function</font> updatePriceOfPaid(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> newPrice
    ) <font style="color:#569cd6;">public</font> shareExist(repo, seqOfShare) {
        Share <font style="color:#569cd6;">storage</font> share = repo.shares[seqOfShare];
        share.head.priceOfPaid = <font style="color:#4ec9b0;">uint32</font>(newPrice);
    }

    <font style="color:#6a9955;">/// @notice Update pay-in deadline for a share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#6a9955;">/// @param deadline New deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> updatePayInDeadline(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare,
        <font style="color:#4ec9b0;">uint</font> deadline
    ) <font style="color:#569cd6;">public</font> shareExist(repo, seqOfShare) {

        Share <font style="color:#569cd6;">storage</font> share = repo.shares[seqOfShare];

        <font style="color:#4ec9b0;">uint48</font> newLine = <font style="color:#4ec9b0;">uint48</font>(deadline);

        <font style="color:#569cd6;">if</font> (block.timestamp >= newLine) {
            <font style="color:#569cd6;">revert</font> SHR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SHR_UpdatePayInDeadlineNotFuture"</font>));
        }

        share.body.payInDeadline = newLine;
    }

    <font style="color:#6a9955;">/// @notice Restore repo from snapshots.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param shares Share list.</font>
    <font style="color:#6a9955;">/// @param classInfos Class info list.</font>
    <font style="color:#569cd6;">function</font> restoreRepo(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Share[] <font style="color:#569cd6;">memory</font> shares,
        Share[] <font style="color:#569cd6;">memory</font> classInfos
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint</font> len = shares.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">1</font>) {
            Share <font style="color:#569cd6;">memory</font> share = shares[len - <font style="color:#b5cea8;">1</font>];
            repo.shares[share.head.seqOfShare] = share;

            repo.classes[share.head.class].seqList.add(share.head.seqOfShare);
            repo.classes[<font style="color:#b5cea8;">0</font>].seqList.add(share.head.seqOfShare);

            len --;
        }

        repo.shares[<font style="color:#b5cea8;">0</font>] = shares[<font style="color:#b5cea8;">0</font>];

        len = classInfos.length;
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            Share <font style="color:#569cd6;">memory</font> info = classInfos[len - <font style="color:#b5cea8;">1</font>];
            repo.classes[info.head.class].info = info;

            len--;
        }
    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##    Read I/O    ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">// ---- Counter ----</font>

    <font style="color:#6a9955;">/// @notice Get share counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> counterOfShares(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> repo.shares[<font style="color:#b5cea8;">0</font>].head.seqOfShare;
    }

    <font style="color:#6a9955;">/// @notice Get class counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> counterOfClasses(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> repo.shares[<font style="color:#b5cea8;">0</font>].head.class;
    }

    <font style="color:#6a9955;">// ---- Share ----</font>

    <font style="color:#6a9955;">/// @notice Check whether share exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> isShare(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.shares[seqOfShare].head.issueDate > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get share by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> getShare(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> shareExist(repo, seqOfShare) <font style="color:#569cd6;">returns</font> (
        Share <font style="color:#569cd6;">memory</font>
    ) {
        <font style="color:#569cd6;">return</font> repo.shares[seqOfShare];
    }

    <font style="color:#6a9955;">/// @notice Get total share count.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getQtyOfShares(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.classes[<font style="color:#b5cea8;">0</font>].seqList.length();
    }

    <font style="color:#6a9955;">/// @notice Get share sequence list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getSeqListOfShares(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.classes[<font style="color:#b5cea8;">0</font>].seqList.values();
    }

    <font style="color:#6a9955;">/// @notice Get list of all shares.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getSharesList(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Share[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList = repo.classes[<font style="color:#b5cea8;">0</font>].seqList.values();
        <font style="color:#569cd6;">return</font> _getShares(repo, seqList);
    }

    <font style="color:#6a9955;">/// @notice Get zero share record.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getShareZero(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Share <font style="color:#569cd6;">memory</font> share) {
            share = repo.shares[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">// ---- Class ----    </font>

    <font style="color:#6a9955;">/// @notice Get share count in class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class.</font>
    <font style="color:#569cd6;">function</font> getQtyOfSharesInClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.classes[classOfShare].seqList.length();
    }

    <font style="color:#6a9955;">/// @notice Get share sequence list in class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class.</font>
    <font style="color:#569cd6;">function</font> getSeqListOfClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.classes[classOfShare].seqList.values();
    }

    <font style="color:#6a9955;">/// @notice Get class info share.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class.</font>
    <font style="color:#569cd6;">function</font> getInfoOfClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Share <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.classes[classOfShare].info;
    }

    <font style="color:#6a9955;">/// @notice Get shares of a class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param classOfShare Share class.</font>
    <font style="color:#569cd6;">function</font> getSharesOfClass(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> classOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Share[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList =
            repo.classes[classOfShare].seqList.values();
        <font style="color:#569cd6;">return</font> _getShares(repo, seqList);
    }

    <font style="color:#569cd6;">function</font> _getShares(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Share[] <font style="color:#569cd6;">memory</font> list) {

        <font style="color:#4ec9b0;">uint</font> len = seqList.length;
        list = <font style="color:#569cd6;">new</font> Share[](len);

        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            list[len - <font style="color:#b5cea8;">1</font>] = repo.shares[seqList[len - <font style="color:#b5cea8;">1</font>]];
            len--;
        }
    }

    <font style="color:#6a9955;">/// @notice Get encoded premium snapshot.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getPremium(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> premium) {
        Body <font style="color:#569cd6;">memory</font> body = repo.shares[<font style="color:#b5cea8;">0</font>].body;

        premium =   (<font style="color:#4ec9b0;">uint</font>(body.payInDeadline) << <font style="color:#b5cea8;">208</font>) +
                    (<font style="color:#4ec9b0;">uint</font>(body.paid) << <font style="color:#b5cea8;">144</font>) +
                    (<font style="color:#4ec9b0;">uint</font>(body.par) << <font style="color:#b5cea8;">80</font>) +
                    (<font style="color:#4ec9b0;">uint</font>(body.cleanPaid) << <font style="color:#b5cea8;">16</font>) +
                    body.distrWeight;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## SigsRepo.sol

---

| |
|:---|
| **contracts/lib/books/SigsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title SigsRepo</font>
<font style="color:#6a9955;">/// @notice Library for managing signature pages and signer metadata.</font>
<font style="color:#569cd6;">library</font> SigsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice Signature metadata for a party.</font>
    <font style="color:#569cd6;">struct</font> Signature {
        <font style="color:#4ec9b0;">uint40</font> signer;
        <font style="color:#4ec9b0;">uint48</font> sigDate;
        <font style="color:#4ec9b0;">uint64</font> blocknumber;
        <font style="color:#4ec9b0;">bool</font> flag;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> arg;
        <font style="color:#4ec9b0;">uint16</font> seq;
        <font style="color:#4ec9b0;">uint16</font> attr;
        <font style="color:#4ec9b0;">uint32</font> data;
    }

    <font style="color:#6a9955;">/// @notice Party-specific blank containing deal list and signature data.</font>
    <font style="color:#569cd6;">struct</font> Blank{
        EnumerableSet.UintSet seqOfDeals;
        Signature sig;
        <font style="color:#4ec9b0;">bytes32</font> sigHash;
    }

    <font style="color:#6a9955;">// blanks[0].sig {</font>
    <font style="color:#6a9955;">//     sigDate: circulateDate;</font>
    <font style="color:#6a9955;">//     flag: established;</font>
    <font style="color:#6a9955;">//     para: counterOfBlanks;</font>
    <font style="color:#6a9955;">//     arg: counterOfSigs;</font>
    <font style="color:#6a9955;">//     seq: signingDays;</font>
    <font style="color:#6a9955;">//     attr: closingDays;</font>
    <font style="color:#6a9955;">// }</font>

    <font style="color:#6a9955;">/// @notice Signature page with buyers and sellers.</font>
    <font style="color:#569cd6;">struct</font> Page {
        <font style="color:#6a9955;">// party => Blank</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Blank) blanks;
        EnumerableSet.UintSet buyers;
        EnumerableSet.UintSet sellers;
    }

    <font style="color:#6a9955;">//###################</font>
    <font style="color:#6a9955;">//##    Error      ##</font>
    <font style="color:#6a9955;">//###################</font>

    <font style="color:#569cd6;">error</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SIGR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SIGR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> SIGR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//###################</font>
    <font style="color:#6a9955;">//##    Config    ##</font>
    <font style="color:#6a9955;">//###################</font>

    <font style="color:#6a9955;">/// @notice Set circulate date for the page.</font>
    <font style="color:#569cd6;">function</font> circulateDoc(
        Page <font style="color:#569cd6;">storage</font> p
    ) <font style="color:#569cd6;">public</font> {
        p.blanks[<font style="color:#b5cea8;">0</font>].sig.sigDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
    }

    <font style="color:#6a9955;">/// @notice Set signing and closing windows (in days).</font>
    <font style="color:#569cd6;">function</font> setTiming(
        Page <font style="color:#569cd6;">storage</font> p,
        <font style="color:#4ec9b0;">uint</font> signingDays,
        <font style="color:#4ec9b0;">uint</font> closingDays
    ) <font style="color:#569cd6;">public</font> {
        p.blanks[<font style="color:#b5cea8;">0</font>].sig.seq = <font style="color:#4ec9b0;">uint16</font>(signingDays);
        p.blanks[<font style="color:#b5cea8;">0</font>].sig.attr = <font style="color:#4ec9b0;">uint16</font>(closingDays);
    }

    <font style="color:#6a9955;">/// @notice Add a party and its deal sequence to the page.</font>
    <font style="color:#569cd6;">function</font> addBlank(
        Page <font style="color:#569cd6;">storage</font> p,
        <font style="color:#4ec9b0;">bool</font> beBuyer,
        <font style="color:#4ec9b0;">uint256</font> seq,
        <font style="color:#4ec9b0;">uint256</font> acct
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (seq == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_ZeroSeqOfDeal"</font>));
        }
        <font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_ZeroAcct"</font>));
        }

        <font style="color:#569cd6;">if</font> (beBuyer) {
            <font style="color:#569cd6;">if</font> (p.sellers.contains(acct)) {
                <font style="color:#569cd6;">revert</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_SellerIntendsToBuy"</font>));
            }
            p.buyers.add(acct);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (p.buyers.contains(acct)) {
                <font style="color:#569cd6;">revert</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_BuyerIntendsToSell"</font>));
            }
            p.sellers.add(acct);
        }

        <font style="color:#569cd6;">if</font> (p.blanks[<font style="color:#4ec9b0;">uint40</font>(acct)].seqOfDeals.add(<font style="color:#4ec9b0;">uint16</font>(seq)))
            _increaseCounterOfBlanks(p);
    }

    <font style="color:#6a9955;">/// @notice Remove a deal sequence for a party and cleanup if empty.</font>
    <font style="color:#569cd6;">function</font> removeBlank(
        Page <font style="color:#569cd6;">storage</font> p,
        <font style="color:#4ec9b0;">uint256</font> seq,
        <font style="color:#4ec9b0;">uint256</font> acct
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (p.buyers.contains(acct) || p.sellers.contains(acct)) {
            <font style="color:#569cd6;">if</font> (p.blanks[acct].seqOfDeals.remove(seq))
                _decreaseCounterOfBlanks(p);

            <font style="color:#569cd6;">if</font> (p.blanks[acct].seqOfDeals.length() == <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">delete</font> p.blanks[acct];
                p.buyers.remove(acct) || p.sellers.remove(acct);
            }
        }
    }

    <font style="color:#6a9955;">/// @notice Record a party signature for a page.</font>
    <font style="color:#569cd6;">function</font> signDoc(Page <font style="color:#569cd6;">storage</font> p, <font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">bytes32</font> sigHash)
        <font style="color:#569cd6;">public</font>
    {
        <font style="color:#569cd6;">if</font> (block.timestamp >= getSigDeadline(p) &&
            getSigningDays(p) != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_MissedSigDeadline"</font>));
        }

        <font style="color:#569cd6;">if</font> (established(p)) {
            <font style="color:#569cd6;">revert</font> SIGR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_DocAlreadyEstablished"</font>));
        }

        <font style="color:#569cd6;">if</font> ((p.buyers.contains(acct) || p.sellers.contains(acct)) &&
            p.blanks[acct].sig.sigDate == <font style="color:#b5cea8;">0</font>) {

            Signature <font style="color:#569cd6;">storage</font> sig = p.blanks[acct].sig;

            sig.signer = <font style="color:#4ec9b0;">uint40</font>(acct);
            sig.sigDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
            sig.blocknumber = <font style="color:#4ec9b0;">uint64</font>(block.number);

            p.blanks[acct].sigHash = sigHash;

            _increaseCounterOfSigs(p, p.blanks[acct].seqOfDeals.length());
        }
    }

    <font style="color:#6a9955;">/// @notice Register a signature with a provided date.</font>
    <font style="color:#569cd6;">function</font> regSig(Page <font style="color:#569cd6;">storage</font> p, <font style="color:#4ec9b0;">uint256</font> acct, <font style="color:#4ec9b0;">uint</font> sigDate, <font style="color:#4ec9b0;">bytes32</font> sigHash)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font> flag)
    {
        <font style="color:#569cd6;">if</font> (block.timestamp >= getSigDeadline(p) &&
            getSigningDays(p) != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SIGR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_MissedSigDeadline"</font>));
        }

        <font style="color:#569cd6;">if</font> (established(p)) {
            <font style="color:#569cd6;">revert</font> SIGR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SIGR_DocAlreadyEstablished"</font>));
        }

        <font style="color:#569cd6;">if</font> (p.buyers.contains(acct) || p.sellers.contains(acct)) {

            Signature <font style="color:#569cd6;">storage</font> sig = p.blanks[acct].sig;

            sig.signer = <font style="color:#4ec9b0;">uint40</font>(acct);
            sig.sigDate = <font style="color:#4ec9b0;">uint48</font>(sigDate);
            sig.blocknumber = <font style="color:#4ec9b0;">uint64</font>(block.number);

            p.blanks[acct].sigHash = sigHash;

            _increaseCounterOfSigs(p, <font style="color:#b5cea8;">1</font>);

            flag = <font style="color:#569cd6;">true</font>;
        }

    }

    <font style="color:#6a9955;">/// @dev Increment blank counter.</font>
    <font style="color:#569cd6;">function</font> _increaseCounterOfBlanks(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">private</font> {
        p.blanks[<font style="color:#b5cea8;">0</font>].sig.para++;
    }

    <font style="color:#6a9955;">/// @dev Decrement blank counter.</font>
    <font style="color:#569cd6;">function</font> _decreaseCounterOfBlanks(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">private</font> {
        p.blanks[<font style="color:#b5cea8;">0</font>].sig.para--;
    }

    <font style="color:#6a9955;">/// @dev Increase signature counter by deal count.</font>
    <font style="color:#569cd6;">function</font> _increaseCounterOfSigs(Page <font style="color:#569cd6;">storage</font> p, <font style="color:#4ec9b0;">uint</font> qtyOfDeals) <font style="color:#569cd6;">private</font> {
        p.blanks[<font style="color:#b5cea8;">0</font>].sig.arg += <font style="color:#4ec9b0;">uint16</font>(qtyOfDeals);
    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##    Read I/O    ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">/// @notice Check whether the page is circulated.</font>
    <font style="color:#569cd6;">function</font> circulated(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.sigDate > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Check whether all required signatures are collected.</font>
    <font style="color:#569cd6;">function</font> established(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> counterOfBlanks(p) > <font style="color:#b5cea8;">0</font>
            && counterOfBlanks(p) == counterOfSigs(p);
    }

    <font style="color:#6a9955;">/// @notice Get number of blanks.</font>
    <font style="color:#569cd6;">function</font> counterOfBlanks(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.para;
    }

    <font style="color:#6a9955;">/// @notice Get number of collected signatures.</font>
    <font style="color:#569cd6;">function</font> counterOfSigs(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.arg;
    }

    <font style="color:#6a9955;">/// @notice Get circulate date.</font>
    <font style="color:#569cd6;">function</font> getCirculateDate(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.sigDate;
    }

    <font style="color:#6a9955;">/// @notice Get signing window in days.</font>
    <font style="color:#569cd6;">function</font> getSigningDays(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.seq;
    }

    <font style="color:#6a9955;">/// @notice Get closing window in days.</font>
    <font style="color:#569cd6;">function</font> getClosingDays(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.attr;
    }

    <font style="color:#6a9955;">/// @notice Get signature deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> getSigDeadline(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.sigDate + <font style="color:#4ec9b0;">uint48</font>(p.blanks[<font style="color:#b5cea8;">0</font>].sig.seq) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Get closing deadline timestamp.</font>
    <font style="color:#569cd6;">function</font> getClosingDeadline(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint48</font>) {
        <font style="color:#569cd6;">return</font> p.blanks[<font style="color:#b5cea8;">0</font>].sig.sigDate + <font style="color:#4ec9b0;">uint48</font>(p.blanks[<font style="color:#b5cea8;">0</font>].sig.attr) * <font style="color:#b5cea8;">86400</font>;
    }

    <font style="color:#6a9955;">/// @notice Check whether a party has signed.</font>
    <font style="color:#569cd6;">function</font> isSigner(Page <font style="color:#569cd6;">storage</font> p, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> p.blanks[acct].sig.signer > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Get signature data of a party.</font>
    <font style="color:#569cd6;">function</font> sigOfParty(Page <font style="color:#569cd6;">storage</font> p, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (
            <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> seqOfDeals,
            Signature <font style="color:#569cd6;">memory</font> sig,
            <font style="color:#4ec9b0;">bytes32</font> sigHash
        )
    {
        seqOfDeals = p.blanks[acct].seqOfDeals.values();
        sig = p.blanks[acct].sig;
        sigHash = p.blanks[acct].sigHash;
    }

    <font style="color:#6a9955;">/// @notice Get signatures of buyers and sellers.</font>
    <font style="color:#569cd6;">function</font> sigsOfPage(Page <font style="color:#569cd6;">storage</font> p) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (
            Signature[] <font style="color:#569cd6;">memory</font> sigsOfBuyer,
            Signature[]<font style="color:#569cd6;">memory</font> sigsOfSeller
        )
    {
        sigsOfBuyer = sigsOfSide(p, p.buyers);
        sigsOfSeller = sigsOfSide(p, p.sellers);
    }

    <font style="color:#6a9955;">/// @notice Get signatures of a side (buyers or sellers).</font>
    <font style="color:#569cd6;">function</font> sigsOfSide(Page <font style="color:#569cd6;">storage</font> p, EnumerableSet.UintSet <font style="color:#569cd6;">storage</font> partiesOfSide)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Signature[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> parties = partiesOfSide.values();
        <font style="color:#4ec9b0;">uint256</font> len = parties.length;

        Signature[] <font style="color:#569cd6;">memory</font> sigs = <font style="color:#569cd6;">new</font> Signature[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            sigs[len-<font style="color:#b5cea8;">1</font>] = p.blanks[parties[len-<font style="color:#b5cea8;">1</font>]].sig;
            len--;
        }

        <font style="color:#569cd6;">return</font> sigs;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## SwapsRepo.sol

---

| |
|:---|
| **contracts/lib/books/SwapsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title SwapsRepo</font>
<font style="color:#6a9955;">/// @notice Repository of swap records for pledge/target exchanges.</font>
<font style="color:#569cd6;">library</font> SwapsRepo {

    <font style="color:#6a9955;">/// @notice Swap lifecycle state.</font>
    <font style="color:#569cd6;">enum</font> StateOfSwap {
        Pending,
        Issued,
        Closed,
        Terminated
    }

    <font style="color:#6a9955;">/// @notice Swap record.</font>
    <font style="color:#569cd6;">struct</font> Swap {
        <font style="color:#4ec9b0;">uint16</font> seqOfSwap;
        <font style="color:#4ec9b0;">uint32</font> seqOfPledge;
        <font style="color:#4ec9b0;">uint64</font> paidOfPledge;
        <font style="color:#4ec9b0;">uint32</font> seqOfTarget;
        <font style="color:#4ec9b0;">uint64</font> paidOfTarget;
        <font style="color:#4ec9b0;">uint32</font> priceOfDeal;
        <font style="color:#4ec9b0;">bool</font> isPutOpt;
        <font style="color:#4ec9b0;">uint8</font> state;
    }

    <font style="color:#6a9955;">/// @notice Repository of swaps by sequence.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// seqOfSwap => Swap</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Swap) swaps;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##    Error  ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#569cd6;">error</font> SWR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> SWR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> SWR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> SWR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##  Modifier ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">/// @notice Ensure swap exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">modifier</font> swapExist(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfSwap) {
        <font style="color:#569cd6;">if</font> (!isSwap(repo, seqOfSwap)) {
            <font style="color:#569cd6;">revert</font> SWR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SWR_SwapNotExist"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ## Write I/O ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">// ==== cofify / parser ====</font>

    <font style="color:#6a9955;">/// @notice Pack swap into bytes32.</font>
    <font style="color:#6a9955;">/// @param swap Swap record.</font>
    <font style="color:#569cd6;">function</font> codifySwap(Swap <font style="color:#569cd6;">memory</font> swap) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn = abi.encodePacked(
                            swap.seqOfSwap,
                            swap.seqOfPledge,
                            swap.paidOfPledge,
                            swap.seqOfTarget,
                            swap.paidOfTarget,
                            swap.priceOfDeal,
                            swap.isPutOpt,
                            swap.state);
        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">/// @notice Register a new swap.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param swap Swap record.</font>
    <font style="color:#569cd6;">function</font> regSwap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Swap <font style="color:#569cd6;">memory</font> swap
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Swap <font style="color:#569cd6;">memory</font>) {

        <font style="color:#569cd6;">if</font> (swap.seqOfTarget * swap.paidOfTarget * swap.seqOfPledge == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> SWR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SR_ZeroParaOfSwap"</font>));
        }

        swap.seqOfSwap = _increaseCounter(repo);

        repo.swaps[swap.seqOfSwap] = swap;
        repo.swaps[<font style="color:#b5cea8;">0</font>].paidOfTarget += swap.paidOfTarget;

        <font style="color:#569cd6;">return</font> swap;
    }

    <font style="color:#6a9955;">/// @notice Mark a swap as paid off.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">function</font> payOffSwap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
        <font style="color:#6a9955;">// uint msgValue,</font>
        <font style="color:#6a9955;">// uint centPrice</font>
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Swap <font style="color:#569cd6;">memory</font> ) {

        Swap <font style="color:#569cd6;">storage</font> swap = repo.swaps[seqOfSwap];

        <font style="color:#569cd6;">if</font> (swap.state != <font style="color:#4ec9b0;">uint8</font>(StateOfSwap.Issued)) {
            <font style="color:#569cd6;">revert</font> SWR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SWR_SwapNotIssued"</font>));
        }

        swap.state = <font style="color:#4ec9b0;">uint8</font>(StateOfSwap.Closed);

        <font style="color:#569cd6;">return</font> swap;
    }

    <font style="color:#6a9955;">/// @notice Terminate an issued swap.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">function</font> terminateSwap(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfSwap
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (Swap <font style="color:#569cd6;">memory</font>){

        Swap <font style="color:#569cd6;">storage</font> swap = repo.swaps[seqOfSwap];

        <font style="color:#569cd6;">if</font> (swap.state != <font style="color:#4ec9b0;">uint8</font>(StateOfSwap.Issued)) {
            <font style="color:#569cd6;">revert</font> SWR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"SWR_SwapNotIssued"</font>));
        }

        swap.state = <font style="color:#4ec9b0;">uint8</font>(StateOfSwap.Terminated);

        <font style="color:#569cd6;">return</font> swap;
    }

    <font style="color:#6a9955;">// ==== Counter ====</font>

    <font style="color:#569cd6;">function</font> _increaseCounter(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint16</font>) {
        repo.swaps[<font style="color:#b5cea8;">0</font>].seqOfSwap++;
        <font style="color:#569cd6;">return</font> repo.swaps[<font style="color:#b5cea8;">0</font>].seqOfSwap;
    }

    <font style="color:#6a9955;">// ################</font>
    <font style="color:#6a9955;">// ##  Read I/O  ##</font>
    <font style="color:#6a9955;">// ################</font>

    <font style="color:#6a9955;">/// @notice Get total swap counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> counterOfSwaps(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>)
    {
        <font style="color:#569cd6;">return</font> repo.swaps[<font style="color:#b5cea8;">0</font>].seqOfSwap;
    }

    <font style="color:#6a9955;">/// @notice Get sum of paid target amounts.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> sumPaidOfTarget(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>)
    {
        <font style="color:#569cd6;">return</font> repo.swaps[<font style="color:#b5cea8;">0</font>].paidOfTarget;
    }

    <font style="color:#6a9955;">/// @notice Check whether a swap exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">function</font> isSwap(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> seqOfSwap <= counterOfSwaps(repo);
    }

    <font style="color:#6a9955;">/// @notice Get swap by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfSwap Swap sequence.</font>
    <font style="color:#569cd6;">function</font> getSwap(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint256</font> seqOfSwap)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> swapExist(repo, seqOfSwap) <font style="color:#569cd6;">returns</font> (Swap <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.swaps[seqOfSwap];
    }

    <font style="color:#6a9955;">// function checkValueOfSwap(</font>
    <font style="color:#6a9955;">//     Repo storage repo,</font>
    <font style="color:#6a9955;">//     uint seqOfSwap,</font>
    <font style="color:#6a9955;">//     uint centPrice</font>
    <font style="color:#6a9955;">// ) public view returns (uint) {</font>
    <font style="color:#6a9955;">//     Swap memory swap = getSwap(repo, seqOfSwap);</font>
    <font style="color:#6a9955;">//     return centPrice * swap.paidOfTarget * swap.priceOfDeal / 10 ** 6;</font>
    <font style="color:#6a9955;">// }</font>

    <font style="color:#6a9955;">/// @notice Get all swaps.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getAllSwaps(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Swap[] <font style="color:#569cd6;">memory</font> )
    {
        <font style="color:#4ec9b0;">uint256</font> len = counterOfSwaps(repo);
        Swap[] <font style="color:#569cd6;">memory</font> swaps = <font style="color:#569cd6;">new</font> Swap[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            swaps[len-<font style="color:#b5cea8;">1</font>] = repo.swaps[len];
            len--;
        }
        <font style="color:#569cd6;">return</font> swaps;
    }

    <font style="color:#6a9955;">/// @notice Check whether all swaps are closed.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> allSwapsClosed(Repo <font style="color:#569cd6;">storage</font> repo)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> len = counterOfSwaps(repo);
        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (repo.swaps[len].state < <font style="color:#4ec9b0;">uint8</font>(StateOfSwap.Closed))
                <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
            len--;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## TeamsRepo.sol

---

| |
|:---|
| **contracts/lib/books/TeamsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title TeamsRepo</font>
<font style="color:#6a9955;">/// @notice Repository for project teams, members, and payroll flows.</font>
<font style="color:#569cd6;">library</font> TeamsRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

	<font style="color:#6a9955;">/// @notice Member or team/project info record.</font>
	<font style="color:#569cd6;">struct</font> Member {
        <font style="color:#4ec9b0;">uint16</font> seqOfTeam;
        <font style="color:#4ec9b0;">uint40</font> userNo;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">uint32</font> rate;
				<font style="color:#4ec9b0;">uint32</font> workHours; <font style="color:#6a9955;">// appliedAmt for Team / Project</font>
        <font style="color:#4ec9b0;">uint32</font> budgetAmt;
        <font style="color:#4ec9b0;">uint32</font> approvedAmt;
        <font style="color:#4ec9b0;">uint32</font> receivableAmt;
        <font style="color:#4ec9b0;">uint32</font> paidAmt;
    }

	<font style="color:#6a9955;">/// @notice Team with member list and records.</font>
	<font style="color:#569cd6;">struct</font> Team {
        EnumerableSet.UintSet membersList;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Member) members;
    }

	<font style="color:#6a9955;">/// @notice Repository of teams and payroll balances.</font>
	<font style="color:#569cd6;">struct</font> Repo {
        EnumerableSet.UintSet teamsList;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Team) teams;
        EnumerableSet.UintSet payroll;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => <font style="color:#4ec9b0;">uint256</font>) cashBox;
    }

	<font style="color:#6a9955;">/// @notice Ensure caller is project manager.</font>
	<font style="color:#569cd6;">modifier</font> onlyManager(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> caller) {
        <font style="color:#569cd6;">if</font> (!isManager(repo, caller)) {
            <font style="color:#569cd6;">revert</font> TR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotManager"</font>));
        }
        _;
    }

	<font style="color:#6a9955;">/// @notice Ensure team exists in list.</font>
	<font style="color:#569cd6;">modifier</font> onlyListedTeam(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam
    ) {
        <font style="color:#569cd6;">if</font> (!teamIsListed(repo, seqOfTeam)) {
            <font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotListedTeam"</font>));
        }
        _;
    }

	<font style="color:#6a9955;">/// @notice Ensure caller is team leader.</font>
	<font style="color:#569cd6;">modifier</font> onlyTeamLeader(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam
    ) {
        <font style="color:#569cd6;">if</font> (!isTeamLeader(repo, caller, seqOfTeam)) {
            <font style="color:#569cd6;">revert</font> TR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotTeamLeader"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">///////////////////</font>
    <font style="color:#6a9955;">//     Error    //</font>
    <font style="color:#6a9955;">//////////////////</font>

	<font style="color:#569cd6;">error</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);
	<font style="color:#569cd6;">error</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);
	<font style="color:#569cd6;">error</font> TR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);
	<font style="color:#569cd6;">error</font> TR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">///////////////////</font>
    <font style="color:#6a9955;">//   Write I/O   //</font>
    <font style="color:#6a9955;">///////////////////</font>

	<font style="color:#6a9955;">/// @notice Set initial project manager.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param acct Manager user number.</font>
	<font style="color:#569cd6;">function</font> setManager(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> {
        repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>].userNo = <font style="color:#4ec9b0;">uint40</font>(acct);
    }

	<font style="color:#6a9955;">/// @notice Transfer project manager role.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Current manager user number.</font>
	<font style="color:#6a9955;">/// @param newManager New manager user number.</font>
	<font style="color:#569cd6;">function</font> transferProject(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> newManager
    ) <font style="color:#569cd6;">public</font> onlyManager(repo, caller) {
        repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>].userNo = <font style="color:#4ec9b0;">uint40</font>(newManager);
    }

    <font style="color:#6a9955;">// ---- Project ----</font>

	<font style="color:#6a9955;">/// @notice Set initial project budget.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Manager user number.</font>
	<font style="color:#6a9955;">/// @param budget Budget amount.</font>
	<font style="color:#569cd6;">function</font> setBudget(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> budget
    ) <font style="color:#569cd6;">public</font> onlyManager(repo, caller) {
        Member <font style="color:#569cd6;">storage</font> info = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];
        <font style="color:#569cd6;">if</font> (info.state != <font style="color:#b5cea8;">0</font>) {
			<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_BudgetAlreadySet"</font>));
		}
        info.budgetAmt = <font style="color:#4ec9b0;">uint32</font>(budget);
    }

	<font style="color:#6a9955;">/// @notice Fix project budget (lock initial state).</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Manager user number.</font>
	<font style="color:#569cd6;">function</font> fixBudget(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> caller)
			<font style="color:#569cd6;">public</font> onlyManager(repo, caller)
		{
        Member <font style="color:#569cd6;">storage</font> info = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];
        <font style="color:#569cd6;">if</font> (info.state != <font style="color:#b5cea8;">0</font>) {
			<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_BudgetAlreadyFixed"</font>));
		}
        info.state = <font style="color:#b5cea8;">1</font>;
    }

		<font style="color:#6a9955;">/// @notice Increase project budget after fixation.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Manager user number.</font>
		<font style="color:#6a9955;">/// @param deltaAmt Increase amount.</font>
		<font style="color:#569cd6;">function</font> increaseBudget(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> deltaAmt
    ) <font style="color:#569cd6;">public</font> onlyManager(repo, caller) {
        Member <font style="color:#569cd6;">storage</font> info = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];
        <font style="color:#569cd6;">if</font> (info.state == <font style="color:#b5cea8;">0</font>) {
			<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_BudgetStillPending"</font>));
		}
				info.budgetAmt += <font style="color:#4ec9b0;">uint32</font>(deltaAmt);
    }

    <font style="color:#6a9955;">// ---- Team ----</font>

	<font style="color:#6a9955;">/// @notice Create a new team with leader and budget.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
	<font style="color:#6a9955;">/// @param budget Team budget.</font>
	<font style="color:#569cd6;">function</font> createTeam(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> budget
    ) <font style="color:#569cd6;">public</font> {
				<font style="color:#4ec9b0;">uint40</font> acct = <font style="color:#4ec9b0;">uint40</font>(caller);

        <font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_AddTeamZeroLeader"</font>));
        }

        Member <font style="color:#569cd6;">storage</font> projInfo =
            repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];

        projInfo.seqOfTeam++;

        Member <font style="color:#569cd6;">storage</font> teamInfo =
						repo.teams[projInfo.seqOfTeam].members[<font style="color:#b5cea8;">0</font>];

				teamInfo.seqOfTeam = projInfo.seqOfTeam;
				teamInfo.userNo = acct;
				teamInfo.budgetAmt = <font style="color:#4ec9b0;">uint32</font>(budget);

				repo.teamsList.add(projInfo.seqOfTeam);
    }

	<font style="color:#6a9955;">/// @notice Update team budget before approval.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
	<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
	<font style="color:#6a9955;">/// @param budget New budget.</font>
	<font style="color:#569cd6;">function</font> updateTeam(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam,
        <font style="color:#4ec9b0;">uint</font> budget
    ) <font style="color:#569cd6;">public</font> onlyTeamLeader(repo, caller, seqOfTeam){

        Member <font style="color:#569cd6;">storage</font> teamInfo =
            repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>];

        <font style="color:#569cd6;">if</font> (teamInfo.state != <font style="color:#b5cea8;">0</font>) {
			<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_TeamAlreadyApproved"</font>));
		}

				teamInfo.budgetAmt = <font style="color:#4ec9b0;">uint32</font>(budget);
    }

	<font style="color:#6a9955;">/// @notice Approve and enroll a listed team.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Manager user number.</font>
	<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
	<font style="color:#569cd6;">function</font> enrollTeam(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam
    ) <font style="color:#569cd6;">public</font> onlyManager(repo, caller)
			onlyListedTeam(repo, seqOfTeam)
		{
        Member <font style="color:#569cd6;">storage</font> projInfo =
            repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];

        Member <font style="color:#569cd6;">storage</font> teamInfo =
            repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>];

				_enrollMember(projInfo, teamInfo);
    }

		<font style="color:#569cd6;">function</font> _enrollMember(
			Member <font style="color:#569cd6;">storage</font> teamInfo,
			Member <font style="color:#569cd6;">storage</font> member
		) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (member.state != <font style="color:#b5cea8;">0</font>) {
			<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_AlreadyEnrolled"</font>));
		}

        <font style="color:#569cd6;">if</font> (teamInfo.budgetAmt < (teamInfo.approvedAmt + member.budgetAmt)) {
			<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_BudgetOverflow"</font>));
		}

        member.state = <font style="color:#b5cea8;">1</font>;
        teamInfo.approvedAmt += member.budgetAmt;
		}

	<font style="color:#6a9955;">/// @notice Replace team leader.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Manager user number.</font>
	<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
	<font style="color:#6a9955;">/// @param leader New leader user number.</font>
	<font style="color:#569cd6;">function</font> replaceLeader(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam,
        <font style="color:#4ec9b0;">uint</font> leader
    ) <font style="color:#569cd6;">public</font> onlyManager(repo, caller)
			onlyListedTeam(repo, seqOfTeam)
    {
				<font style="color:#4ec9b0;">uint40</font> acct = <font style="color:#4ec9b0;">uint40</font>(leader);
				<font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_ZeroAcct"</font>));
				}
				repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>].userNo = acct;
    }

	<font style="color:#6a9955;">/// @notice Increase team budget by delta.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Manager user number.</font>
	<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
	<font style="color:#6a9955;">/// @param delta Increase amount.</font>
	<font style="color:#569cd6;">function</font> increaseTeamBudget(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> delta
    ) <font style="color:#569cd6;">public</font> onlyManager(repo, caller)
        onlyListedTeam(repo, seqOfTeam)
    {
        Member <font style="color:#569cd6;">storage</font> projInfo = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];
        Member <font style="color:#569cd6;">storage</font> teamInfo = repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>];

				_increaseBudget(projInfo, teamInfo, delta);
    }

		<font style="color:#569cd6;">function</font> _increaseBudget(
			Member <font style="color:#569cd6;">storage</font> teamInfo,
			Member <font style="color:#569cd6;">storage</font> member,
			<font style="color:#4ec9b0;">uint</font> delta
		)	<font style="color:#569cd6;">private</font> {

			<font style="color:#4ec9b0;">uint32</font> amt = <font style="color:#4ec9b0;">uint32</font>(delta);

			 <font style="color:#569cd6;">if</font> (amt == <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_ZeroAmt"</font>));
				}

			<font style="color:#569cd6;">if</font> (teamInfo.budgetAmt < teamInfo.approvedAmt + amt) {
				<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_BudgetOverflow"</font>));
			}

			member.budgetAmt += amt;
			teamInfo.approvedAmt += amt;
		}

    <font style="color:#6a9955;">// ---- Member ----</font>

	<font style="color:#6a9955;">/// @notice Enroll a member into a team.</font>
	<font style="color:#6a9955;">/// @param repo Storage repo.</font>
	<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
	<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
	<font style="color:#6a9955;">/// @param userNo Member user number.</font>
	<font style="color:#6a9955;">/// @param rate Pay rate.</font>
	<font style="color:#6a9955;">/// @param budgetAmt Member budget.</font>
	<font style="color:#569cd6;">function</font> enrollMember(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> caller,
        <font style="color:#4ec9b0;">uint</font> seqOfTeam,
        <font style="color:#4ec9b0;">uint</font> userNo,
        <font style="color:#4ec9b0;">uint</font> rate,
        <font style="color:#4ec9b0;">uint</font> budgetAmt
    ) <font style="color:#569cd6;">public</font> onlyTeamLeader(repo, caller, seqOfTeam) {
        Team <font style="color:#569cd6;">storage</font> t = repo.teams[seqOfTeam];
        Member <font style="color:#569cd6;">storage</font> teamInfo = t.members[<font style="color:#b5cea8;">0</font>];

				<font style="color:#4ec9b0;">uint40</font> acct = <font style="color:#4ec9b0;">uint40</font>(userNo);
        <font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_ZeroAcct"</font>));
        }

        <font style="color:#569cd6;">if</font> (t.membersList.contains(acct)) {
            <font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_AlreadyEnrolled"</font>));
        }

        Member <font style="color:#569cd6;">storage</font> member = t.members[acct];

				member.seqOfTeam = teamInfo.seqOfTeam;
        member.userNo = acct;
				member.rate = <font style="color:#4ec9b0;">uint32</font>(rate);
				member.budgetAmt = <font style="color:#4ec9b0;">uint32</font>(budgetAmt);

				_enrollMember(teamInfo, member);

        t.membersList.add(acct);
        repo.payroll.add(acct);
    }

		<font style="color:#6a9955;">/// @notice Remove a member from team.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param userNo Member user number.</font>
		<font style="color:#569cd6;">function</font> removeMember(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo
		) <font style="color:#569cd6;">public</font> {

				(Member <font style="color:#569cd6;">storage</font> teamInfo, Member <font style="color:#569cd6;">storage</font> member) =
						_getTeamInfoAndMember(repo, caller, seqOfTeam, userNo);

				<font style="color:#569cd6;">if</font> (member.state == <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotEnrolled"</font>));
				}

				member.state = <font style="color:#b5cea8;">0</font>;

				teamInfo.approvedAmt -= (member.budgetAmt - member.receivableAmt);
				teamInfo.workHours -= (member.approvedAmt);
		}

		<font style="color:#569cd6;">function</font> _getTeamInfoAndMember(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo
		) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
				Member <font style="color:#569cd6;">storage</font> teamInfo,
				Member <font style="color:#569cd6;">storage</font> member
		) {
				(teamInfo, member) = _getInfoAndMember(repo, seqOfTeam, userNo);
				<font style="color:#569cd6;">if</font> (teamInfo.userNo != caller) {
					<font style="color:#569cd6;">revert</font> TR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotTeamLeader"</font>));
				}
		}

		<font style="color:#569cd6;">function</font> _getInfoAndMember(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo
		) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> onlyListedTeam(repo, seqOfTeam) <font style="color:#569cd6;">returns</font>(
				Member <font style="color:#569cd6;">storage</font> teamInfo,
				Member <font style="color:#569cd6;">storage</font> member
		) {
				Team <font style="color:#569cd6;">storage</font> t = repo.teams[seqOfTeam];
				teamInfo = t.members[<font style="color:#b5cea8;">0</font>];

				<font style="color:#569cd6;">if</font> (!t.membersList.contains(userNo)) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotListed"</font>));
				}

				member = t.members[userNo];
		}

		<font style="color:#6a9955;">/// @notice Restore a previously removed member.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param userNo Member user number.</font>
		<font style="color:#569cd6;">function</font> restoreMember(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo
		) <font style="color:#569cd6;">public</font> {

				(Member <font style="color:#569cd6;">storage</font> teamInfo, Member <font style="color:#569cd6;">storage</font> member) =
					_getTeamInfoAndMember(repo, caller, seqOfTeam, userNo);

				<font style="color:#569cd6;">if</font> (member.state != <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_AlreadyEnrolled"</font>));
				}

				<font style="color:#4ec9b0;">uint32</font> balance = (member.budgetAmt - member.receivableAmt);
				<font style="color:#569cd6;">if</font> (teamInfo.budgetAmt < teamInfo.approvedAmt + balance) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_BudgetOverflow"</font>));
				}
				teamInfo.budgetAmt += balance;

				<font style="color:#569cd6;">if</font> (member.approvedAmt > <font style="color:#b5cea8;">0</font>) {
					member.state = <font style="color:#b5cea8;">2</font>;
					teamInfo.workHours += member.approvedAmt;
				} <font style="color:#569cd6;">else</font> {
					member.state = <font style="color:#b5cea8;">1</font>;
				}
		}

		<font style="color:#6a9955;">/// @notice Increase a member's budget within team.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param userNo Member user number.</font>
		<font style="color:#6a9955;">/// @param delta Increase amount.</font>
		<font style="color:#569cd6;">function</font> increaseMemberBudget(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo,
				<font style="color:#4ec9b0;">uint</font> delta
		) <font style="color:#569cd6;">public</font> {

				(Member <font style="color:#569cd6;">storage</font> teamInfo, Member <font style="color:#569cd6;">storage</font> member) =
						_getTeamInfoAndMember(repo, caller, seqOfTeam, userNo);

				<font style="color:#569cd6;">if</font> (member.state == <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotEnrolled"</font>));
				}

				_increaseBudget(teamInfo, member, delta);
		}

		<font style="color:#6a9955;">/// @notice Adjust a member's rate.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param userNo Member user number.</font>
		<font style="color:#6a9955;">/// @param increase True to increase, false to decrease.</font>
		<font style="color:#6a9955;">/// @param delta Rate delta.</font>
		<font style="color:#569cd6;">function</font> adjustSalary(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo,
				<font style="color:#4ec9b0;">bool</font> increase,
				<font style="color:#4ec9b0;">uint</font> delta
		) <font style="color:#569cd6;">public</font> {

				( , Member <font style="color:#569cd6;">storage</font> member) =
						_getTeamInfoAndMember(repo, caller, seqOfTeam, userNo);

				<font style="color:#569cd6;">if</font> (member.state == <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotEnrolled"</font>));
				}

				<font style="color:#4ec9b0;">uint32</font> amt = <font style="color:#4ec9b0;">uint32</font>(delta);

				<font style="color:#569cd6;">if</font> (increase) {
					member.rate += amt;
				} <font style="color:#569cd6;">else</font> {
					<font style="color:#569cd6;">if</font> (member.rate < amt) {
						<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_InsufficientAmt"</font>));
					}
					member.rate -= amt;
				}
		}

	  <font style="color:#6a9955;">// ---- Work ----</font>

		<font style="color:#6a9955;">/// @notice Apply working hours for approval.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Member user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param hrs Working hours.</font>
		<font style="color:#569cd6;">function</font> applyWorkingHour(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> hrs
		) <font style="color:#569cd6;">public</font> {

				(, Member <font style="color:#569cd6;">storage</font> member) = _getInfoAndMember(repo, seqOfTeam, caller);

				<font style="color:#569cd6;">if</font> (member.state != <font style="color:#b5cea8;">1</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_WrongState"</font>));
				}

				<font style="color:#4ec9b0;">uint32</font> delta = <font style="color:#4ec9b0;">uint32</font>(member.rate * hrs);

				<font style="color:#569cd6;">if</font> (member.budgetAmt < member.receivableAmt + delta) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_ExceedBudget"</font>));
				}

				member.workHours += <font style="color:#4ec9b0;">uint32</font>(hrs);
				member.approvedAmt = delta;

				member.state = <font style="color:#b5cea8;">2</font>;
		}

		<font style="color:#6a9955;">/// @notice Verify a member's applied work.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Team leader user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param userNo Member user number.</font>
		<font style="color:#6a9955;">/// @param ratio Approve ratio (0-10000).</font>
		<font style="color:#569cd6;">function</font> verifyMemberWork(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> userNo,
				<font style="color:#4ec9b0;">uint</font> ratio
		) <font style="color:#569cd6;">public</font> {
				<font style="color:#569cd6;">if</font> (ratio > <font style="color:#b5cea8;">10000</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_RatioOverflow"</font>));
				}

				(Member <font style="color:#569cd6;">storage</font> teamInfo, Member <font style="color:#569cd6;">storage</font> member) =
					_getTeamInfoAndMember(repo, caller, seqOfTeam, userNo);

				<font style="color:#569cd6;">if</font> (member.state != <font style="color:#b5cea8;">2</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_WrongState"</font>));
				}

				member.approvedAmt = <font style="color:#4ec9b0;">uint32</font>(member.approvedAmt * ratio / <font style="color:#b5cea8;">10000</font>);
				member.state = <font style="color:#b5cea8;">3</font>;

				teamInfo.workHours += member.approvedAmt;
		}

		<font style="color:#6a9955;">/// @notice Verify team work and update receivables.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller Manager user number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#6a9955;">/// @param ratio Approve ratio (0-10000).</font>
		<font style="color:#569cd6;">function</font> verifyTeamWork(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam,
				<font style="color:#4ec9b0;">uint</font> ratio
		) <font style="color:#569cd6;">public</font> onlyManager(repo, caller)
				onlyListedTeam(repo, seqOfTeam)
		{
				<font style="color:#569cd6;">if</font> (ratio > <font style="color:#b5cea8;">10000</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_RatioOverflow"</font>));
				}

				Team <font style="color:#569cd6;">storage</font> t = repo.teams[seqOfTeam];
				Member <font style="color:#569cd6;">storage</font> teamInfo = t.members[<font style="color:#b5cea8;">0</font>];

				<font style="color:#569cd6;">if</font> (teamInfo.workHours == <font style="color:#b5cea8;">0</font>) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_ZeroApplied"</font>));
				}

				<font style="color:#4ec9b0;">uint32</font> deltaAmt = <font style="color:#4ec9b0;">uint32</font>(teamInfo.workHours * ratio / <font style="color:#b5cea8;">10000</font>);
				teamInfo.receivableAmt += deltaAmt;

				Member <font style="color:#569cd6;">storage</font> proInfo = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];
				proInfo.receivableAmt += deltaAmt;

				_confirmTeamWork(t, ratio);

				teamInfo.workHours = <font style="color:#b5cea8;">0</font>;
		}

		<font style="color:#569cd6;">function</font> _confirmTeamWork(
				Team <font style="color:#569cd6;">storage</font> t,
				<font style="color:#4ec9b0;">uint</font> ratio
		) <font style="color:#569cd6;">private</font> {
				<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = t.membersList.values();
				<font style="color:#4ec9b0;">uint</font> len = ls.length;

				<font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
						Member <font style="color:#569cd6;">storage</font> m = t.members[ls[len-<font style="color:#b5cea8;">1</font>]];
						<font style="color:#569cd6;">if</font> (m.state == <font style="color:#b5cea8;">3</font>) {
								m.receivableAmt += <font style="color:#4ec9b0;">uint32</font>(m.approvedAmt * ratio / <font style="color:#b5cea8;">10000</font>);
								m.approvedAmt = <font style="color:#b5cea8;">0</font>;
								m.state = <font style="color:#b5cea8;">1</font>;
						}
						len--;
				}
		}

		<font style="color:#6a9955;">/// @notice Distribute payment to all teams by receivables.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param amtInWei Amount in wei.</font>
		<font style="color:#6a9955;">/// @param centPriceInWei Cent price in wei.</font>
		<font style="color:#569cd6;">function</font> distributePayment(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> amtInWei,
				<font style="color:#4ec9b0;">uint</font> centPriceInWei
		) <font style="color:#569cd6;">public</font> {

				<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = repo.teamsList.values();
				<font style="color:#4ec9b0;">uint</font> len = ls.length;

				Member <font style="color:#569cd6;">storage</font> projInfo = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];

				<font style="color:#4ec9b0;">uint</font> rate = amtInWei * <font style="color:#b5cea8;">10000</font> / (projInfo.receivableAmt - projInfo.paidAmt);
				<font style="color:#4ec9b0;">uint32</font> sum = <font style="color:#b5cea8;">0</font>;

				<font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
						Team <font style="color:#569cd6;">storage</font> t = repo.teams[ls[len-<font style="color:#b5cea8;">1</font>]];
						Member <font style="color:#569cd6;">storage</font> info = t.members[<font style="color:#b5cea8;">0</font>];

						<font style="color:#569cd6;">if</font> (info.receivableAmt > info.paidAmt) {
								<font style="color:#4ec9b0;">uint32</font> amt = _distributePackage(repo, t, rate, centPriceInWei);
								info.paidAmt += amt;
								sum += amt;
						}

						len--;
				}

				projInfo.paidAmt += sum;
				repo.cashBox[<font style="color:#b5cea8;">0</font>] += amtInWei;
		}

		<font style="color:#569cd6;">function</font> _distributePackage(
				Repo <font style="color:#569cd6;">storage</font> repo,
				Team <font style="color:#569cd6;">storage</font> t,
				<font style="color:#4ec9b0;">uint</font> rate,
				<font style="color:#4ec9b0;">uint</font> centPriceInWei
		) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font> sum) {
				<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = t.membersList.values();
				<font style="color:#4ec9b0;">uint</font> len = ls.length;
				sum = <font style="color:#b5cea8;">0</font>;

				<font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
						Member <font style="color:#569cd6;">storage</font> m = t.members[ls[len-<font style="color:#b5cea8;">1</font>]];

						<font style="color:#4ec9b0;">uint</font> outstandingAmt = m.receivableAmt - m.paidAmt;

						<font style="color:#569cd6;">if</font> (outstandingAmt > <font style="color:#b5cea8;">0</font>) {
							repo.cashBox[m.userNo] += rate * outstandingAmt / <font style="color:#b5cea8;">10000</font>;

							<font style="color:#4ec9b0;">uint32</font> amtFiat = <font style="color:#4ec9b0;">uint32</font>(rate * outstandingAmt / centPriceInWei / <font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">4</font>);

							m.paidAmt += amtFiat;
							sum += amtFiat;
						}

						len--;
				}
		}

		<font style="color:#6a9955;">/// @notice Withdraw balance from payroll.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param caller User number.</font>
		<font style="color:#6a9955;">/// @param amt Amount in wei.</font>
		<font style="color:#569cd6;">function</font> pickupDeposit(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> caller,
				<font style="color:#4ec9b0;">uint</font> amt
		) <font style="color:#569cd6;">public</font> {
				<font style="color:#569cd6;">if</font> (!repo.payroll.contains(caller)) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_NotInPayroll"</font>));
				}

				<font style="color:#4ec9b0;">uint</font> balance = repo.cashBox[caller];

				<font style="color:#569cd6;">if</font> (balance < amt) {
					<font style="color:#569cd6;">revert</font> TR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TR_InsufficientBalance"</font>));
				}

				repo.cashBox[caller] -= amt;
				repo.cashBox[<font style="color:#b5cea8;">0</font>] -= amt;
		}

		<font style="color:#6a9955;">///////////////////</font>
		<font style="color:#6a9955;">//   Read I/O    //</font>
		<font style="color:#6a9955;">///////////////////</font>

		<font style="color:#6a9955;">/// @notice Check if user is project manager.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#569cd6;">function</font> isManager(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> acct > <font style="color:#b5cea8;">0</font> &&
						repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>].userNo == acct;
		}

		<font style="color:#6a9955;">/// @notice Get project info record.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#569cd6;">function</font> getProjectInfo(
				Repo <font style="color:#569cd6;">storage</font> repo
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Member <font style="color:#569cd6;">memory</font> info) {
				info = repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>];
		}

		<font style="color:#6a9955;">// ---- Teams ----</font>

		<font style="color:#6a9955;">/// @notice Get number of teams.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#569cd6;">function</font> qtyOfTeams (
				Repo <font style="color:#569cd6;">storage</font> repo
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
				<font style="color:#569cd6;">return</font> repo.teams[<font style="color:#b5cea8;">0</font>].members[<font style="color:#b5cea8;">0</font>].seqOfTeam;
		}

		<font style="color:#6a9955;">/// @notice Get list of team ids.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#569cd6;">function</font> getListOfTeams(
				Repo <font style="color:#569cd6;">storage</font> repo
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
				<font style="color:#569cd6;">return</font> repo.teamsList.values();
		}

		<font style="color:#6a9955;">/// @notice Check if team is listed.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> teamIsListed(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> repo.teamsList.contains(seqOfTeam);
		}

		<font style="color:#6a9955;">/// @notice Check if team is enrolled.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> teamIsEnrolled(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> repo.teamsList.contains(seqOfTeam) &&
						repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>].state == <font style="color:#b5cea8;">1</font>;
		}

		<font style="color:#6a9955;">// ---- TeamInfo ----</font>

		<font style="color:#6a9955;">/// @notice Check if user is team leader.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> isTeamLeader(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> repo.teamsList.contains(seqOfTeam) &&
						repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>].userNo == acct;
		}

		<font style="color:#6a9955;">/// @notice Get team info record.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> getTeamInfo(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Member <font style="color:#569cd6;">memory</font> info) {
				<font style="color:#569cd6;">if</font> (repo.teamsList.contains(seqOfTeam)) {
					info = repo.teams[seqOfTeam].members[<font style="color:#b5cea8;">0</font>];
				}
		}

		<font style="color:#6a9955;">// ---- Member ----</font>

		<font style="color:#6a9955;">/// @notice Check if user is a team member.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> isMember(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>  <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> repo.teamsList.contains(seqOfTeam) &&
						repo.teams[seqOfTeam].membersList.contains(acct);
		}

		<font style="color:#6a9955;">/// @notice Check if member is enrolled.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> isEnrolledMember(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> repo.teamsList.contains(seqOfTeam) &&
					repo.teams[seqOfTeam].membersList.contains(acct) &&
					repo.teams[seqOfTeam].members[acct].state > <font style="color:#b5cea8;">0</font>;
		}

		<font style="color:#6a9955;">/// @notice Get member list of a team.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> getTeamMembersList(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls) {
				<font style="color:#569cd6;">if</font> (repo.teamsList.contains(seqOfTeam)) {
					ls = repo.teams[seqOfTeam].membersList.values();
				}
		}

		<font style="color:#6a9955;">/// @notice Get member info for a team.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> getMemberInfo(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct,
				<font style="color:#4ec9b0;">uint</font> seqOfTeam
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Member <font style="color:#569cd6;">memory</font> m) {

				<font style="color:#569cd6;">if</font> (repo.teamsList.contains(seqOfTeam) &&
						repo.teams[seqOfTeam].membersList.contains(acct)
				) {
					m = repo.teams[seqOfTeam].members[acct];
				}
		}

		<font style="color:#6a9955;">/// @notice Get all members of a team.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param seqOfTeam Team sequence.</font>
		<font style="color:#569cd6;">function</font> getMembersOfTeam(Repo <font style="color:#569cd6;">storage</font> repo,<font style="color:#4ec9b0;">uint</font> seqOfTeam)
				<font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Member[] <font style="color:#569cd6;">memory</font>)
		{
				<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = getTeamMembersList(repo, seqOfTeam);
				<font style="color:#4ec9b0;">uint</font> len = ls.length;
				Member[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> Member[](len);

				Team <font style="color:#569cd6;">storage</font> t = repo.teams[seqOfTeam];

				<font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
						output[len-<font style="color:#b5cea8;">1</font>] = t.members[ls[len-<font style="color:#b5cea8;">1</font>]];
						len--;
				}

				<font style="color:#569cd6;">return</font> output;
		}

		<font style="color:#6a9955;">// ---- Payroll ----</font>

		<font style="color:#6a9955;">/// @notice Get payroll user list.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#569cd6;">function</font> getPayroll(
				Repo <font style="color:#569cd6;">storage</font> repo
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
				<font style="color:#569cd6;">return</font> repo.payroll.values();
		}

		<font style="color:#6a9955;">/// @notice Check if user is in payroll.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#569cd6;">function</font> inPayroll(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
				<font style="color:#569cd6;">return</font> repo.payroll.contains(acct);
		}

		<font style="color:#6a9955;">/// @notice Get payroll balance for user.</font>
		<font style="color:#6a9955;">/// @param repo Storage repo.</font>
		<font style="color:#6a9955;">/// @param acct User number.</font>
		<font style="color:#569cd6;">function</font> getBalanceOf(
				Repo <font style="color:#569cd6;">storage</font> repo,
				<font style="color:#4ec9b0;">uint</font> acct
		) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
				<font style="color:#569cd6;">return</font> repo.cashBox[acct];
		}
}</code></pre>
```
 |
| [Contents](#toc) |

---

## TopChain.sol

---

| |
|:---|
| **contracts/lib/books/TopChain.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/roa/IInvestmentAgreement.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/ros/IRegisterOfShares.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./DealsRepo.sol"</font>;

<font style="color:#6a9955;">/// @title TopChain</font>
<font style="color:#6a9955;">/// @notice Voting power chain for members and groups.</font>
<font style="color:#569cd6;">library</font> TopChain {

    <font style="color:#6a9955;">/// @notice Node categories in chain.</font>
    <font style="color:#569cd6;">enum</font> CatOfNode {
        IndepMemberInQueue, <font style="color:#6a9955;">// 0</font>
        GroupRepInQueue,    <font style="color:#6a9955;">// 1</font>
        GroupMember,        <font style="color:#6a9955;">// 2</font>
        IndepMemberOnChain, <font style="color:#6a9955;">// 3 </font>
        GroupRepOnChain     <font style="color:#6a9955;">// 4</font>
    }

    <font style="color:#6a9955;">/// @notice Chain node for a member or group.</font>
    <font style="color:#569cd6;">struct</font> Node {
        <font style="color:#4ec9b0;">uint40</font> prev;
        <font style="color:#4ec9b0;">uint40</font> next;
        <font style="color:#4ec9b0;">uint40</font> ptr;
        <font style="color:#4ec9b0;">uint64</font> amt;
        <font style="color:#4ec9b0;">uint64</font> sum;
        <font style="color:#4ec9b0;">uint8</font> cat;
    }

    <font style="color:#6a9955;">/// @notice Chain parameters and counters.</font>
    <font style="color:#569cd6;">struct</font> Para {
        <font style="color:#4ec9b0;">uint40</font> tail;
        <font style="color:#4ec9b0;">uint40</font> head;
        <font style="color:#4ec9b0;">uint32</font> maxQtyOfMembers;
        <font style="color:#4ec9b0;">uint16</font> minVoteRatioOnChain;
        <font style="color:#4ec9b0;">uint32</font> qtyOfSticks;
        <font style="color:#4ec9b0;">uint32</font> qtyOfBranches;
        <font style="color:#4ec9b0;">uint32</font> qtyOfMembers;
        <font style="color:#4ec9b0;">uint16</font> para;
        <font style="color:#4ec9b0;">uint16</font> argu;
    }

    <font style="color:#6a9955;">/// @notice Chain storage by user number.</font>
    <font style="color:#569cd6;">struct</font> Chain {
        <font style="color:#6a9955;">// usrNo => Node</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => Node) nodes;
        Para para;
    }

    <font style="color:#6a9955;">/* Node[0] {
        prev: tail;
        next: head;
        ptr: pending;
        amt: pending;
        sum: totalVotes;
        cat: basedOnPar;
    } */</font>

    <font style="color:#6a9955;">//########################</font>
    <font style="color:#6a9955;">//##  Error & Modifier  ##</font>
    <font style="color:#6a9955;">//########################</font>

    <font style="color:#569cd6;">error</font> TopChain_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> TopChain_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#569cd6;">error</font> TopChain_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Ensure member exists in chain.</font>
    <font style="color:#569cd6;">modifier</font> memberExist(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct) {
        <font style="color:#569cd6;">if</font> (!isMember(chain, acct)) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_MemberNotExist"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Options ====</font>

    <font style="color:#6a9955;">/// @notice Set max member count.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param max Max member count.</font>
    <font style="color:#569cd6;">function</font> setMaxQtyOfMembers(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> max) <font style="color:#569cd6;">public</font> {
        chain.para.maxQtyOfMembers = <font style="color:#4ec9b0;">uint32</font>(max);
    }

    <font style="color:#6a9955;">/// @notice Set minimum vote ratio required on chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param min Minimum ratio (0-4999).</font>
    <font style="color:#569cd6;">function</font> setMinVoteRatioOnChain(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> min) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (min >= <font style="color:#b5cea8;">5000</font>) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_InvalidMinVoteRatio"</font>));
        }
        chain.para.minVoteRatioOnChain = <font style="color:#4ec9b0;">uint16</font>(min);
    }

    <font style="color:#6a9955;">/// @notice Set vote base to par or paid.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param _basedOnPar True for par, false for paid.</font>
    <font style="color:#569cd6;">function</font> setVoteBase(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">bool</font> _basedOnPar
    ) <font style="color:#569cd6;">public</font> {
        chain.nodes[<font style="color:#b5cea8;">0</font>].cat = _basedOnPar ? <font style="color:#b5cea8;">1</font> : <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">// ==== Node ====</font>

    <font style="color:#6a9955;">/// @notice Add a member node to chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> addNode(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> {

        <font style="color:#569cd6;">if</font> (acct == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_ZeroAcct"</font>));
        }

        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        <font style="color:#569cd6;">if</font> (n.ptr == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> ( maxQtyOfMembers(chain) != <font style="color:#b5cea8;">0</font> &&
                qtyOfMembers(chain) >= maxQtyOfMembers(chain)
            ) {
                <font style="color:#569cd6;">revert</font> TopChain_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_NoVacanceForMember"</font>));
            }

            n.ptr = <font style="color:#4ec9b0;">uint40</font>(acct);

            _appendToQueue(chain, n, n.ptr);
            _increaseQtyOfMembers(chain);
        }
    }

    <font style="color:#6a9955;">/// @notice Delete a member node from chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> delNode(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> {
        _carveOut(chain, acct);
        <font style="color:#569cd6;">delete</font> chain.nodes[acct];
        _decreaseQtyOfMembers(chain);
    }

    <font style="color:#6a9955;">// ==== ChangeAmt ====</font>

    <font style="color:#6a9955;">/// @notice Update total votes.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param deltaAmt Delta amount.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#569cd6;">function</font> increaseTotalVotes(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint</font> deltaAmt,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint40</font> amt = <font style="color:#4ec9b0;">uint40</font>(deltaAmt);
        <font style="color:#569cd6;">if</font> (isIncrease) _increaseTotalVotes(chain, amt);
        <font style="color:#569cd6;">else</font> _decreaseTotalVotes(chain, amt);
    }

    <font style="color:#6a9955;">/// @notice Update member amount and re-balance chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param deltaAmt Delta amount.</font>
    <font style="color:#6a9955;">/// @param isIncrease True to increase, false to decrease.</font>
    <font style="color:#569cd6;">function</font> increaseAmt(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint</font> deltaAmt,
        <font style="color:#4ec9b0;">bool</font> isIncrease
    ) <font style="color:#569cd6;">public</font> memberExist(chain, acct) {

        <font style="color:#4ec9b0;">uint64</font> amt = <font style="color:#4ec9b0;">uint64</font>(deltaAmt);

        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        <font style="color:#569cd6;">if</font> (isIncrease) {
            n.amt += amt;
            n.sum += amt;
        } <font style="color:#569cd6;">else</font> {
            n.amt -= amt;
            n.sum -= amt;
        }

        <font style="color:#569cd6;">if</font> (n.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupMember)) {

            Node <font style="color:#569cd6;">storage</font> r = chain.nodes[n.ptr];

            <font style="color:#569cd6;">if</font> (isIncrease) {

                r.sum += amt;

                <font style="color:#569cd6;">if</font> (r.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepOnChain))
                    _move(chain, n.ptr, isIncrease);
                <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_onChainTest(chain, r))
                    _upChainAndMove(chain, r, n.ptr);

            } <font style="color:#569cd6;">else</font> {

                r.sum -= amt;

                <font style="color:#569cd6;">if</font> (r.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepOnChain)) {

                    <font style="color:#569cd6;">if</font> (!_onChainTest(chain, r))
                        _offChain(chain, r, n.ptr);
                    <font style="color:#569cd6;">else</font> _move(chain, n.ptr, isIncrease);

                }
            }

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isOnChain(n)) {

            <font style="color:#569cd6;">if</font> (isIncrease) _move(chain, n.ptr, isIncrease);
            <font style="color:#569cd6;">else</font> {
                <font style="color:#569cd6;">if</font> (!_onChainTest(chain, n))
                    _offChain(chain, n, n.ptr);
                <font style="color:#569cd6;">else</font> _move(chain, n.ptr, isIncrease);
            }

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font>(isIncrease && _onChainTest(chain, n))
            _upChainAndMove(chain, n, n.ptr);

    }

    <font style="color:#6a9955;">// ==== Grouping ====</font>

    <font style="color:#6a9955;">/// @notice Move an independent member under a group root.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#6a9955;">/// @param root Group root user number.</font>
    <font style="color:#569cd6;">function</font> top2Sub(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint256</font> acct,
        <font style="color:#4ec9b0;">uint256</font> root
    ) <font style="color:#569cd6;">public</font> memberExist(chain, root) {

        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];
        Node <font style="color:#569cd6;">storage</font> r = chain.nodes[root];

        <font style="color:#569cd6;">if</font> (acct == root) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_SameAcct"</font>));
        }
        <font style="color:#569cd6;">if</font> (!_isIndepMember(n)) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_NotIndepMember"</font>));
        }
        <font style="color:#569cd6;">if</font> (!_notGroupMember(r)) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_LeafAsRoot"</font>));
        }

        _carveOut(chain, n.ptr);
        _vInsert(chain, n.ptr, <font style="color:#4ec9b0;">uint40</font>(root));
    }

    <font style="color:#6a9955;">/// @notice Promote group member to independent member.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> sub2Top(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct) <font style="color:#569cd6;">public</font> {

        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];
        <font style="color:#569cd6;">if</font>(!_isInGroup(n)) {
            <font style="color:#569cd6;">revert</font> TopChain_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"TC_NotInGroup"</font>));
        }

        _carveOut(chain, acct);

        n.sum = n.amt;
        n.ptr = <font style="color:#4ec9b0;">uint40</font>(acct);

        <font style="color:#569cd6;">if</font> (_onChainTest(chain, n)) _upChainAndMove(chain, n, n.ptr);
        <font style="color:#569cd6;">else</font> _appendToQueue(chain, n, n.ptr);
    }

    <font style="color:#6a9955;">// ==== CarveOut ====</font>

    <font style="color:#569cd6;">function</font> _branchOff(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> root) <font style="color:#569cd6;">private</font> {
        Node <font style="color:#569cd6;">storage</font> r = chain.nodes[root];

        <font style="color:#569cd6;">if</font> (_isOnChain(r)) {

            chain.nodes[r.next].prev = r.prev;
            chain.nodes[r.prev].next = r.next;

            _decreaseQtyOfBranches(chain);

        } <font style="color:#569cd6;">else</font> {

            <font style="color:#569cd6;">if</font> (r.prev > <font style="color:#b5cea8;">0</font> && r.next > <font style="color:#b5cea8;">0</font>) {
                chain.nodes[r.next].prev = r.prev;
                chain.nodes[r.prev].next = r.next;
            }<font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (r.prev == <font style="color:#b5cea8;">0</font> && r.next == <font style="color:#b5cea8;">0</font>) {
                chain.para.tail = <font style="color:#b5cea8;">0</font>;
                chain.para.head = <font style="color:#b5cea8;">0</font>;
            }<font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (r.next == <font style="color:#b5cea8;">0</font>) {
                chain.para.tail = r.prev;
                chain.nodes[r.prev].next = <font style="color:#b5cea8;">0</font>;
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (r.prev == <font style="color:#b5cea8;">0</font>) {
                chain.nodes[r.next].prev = <font style="color:#b5cea8;">0</font>;
                chain.para.head = r.next;
            }

            _decreaseQtyOfSticks(chain);

        }
    }

    <font style="color:#569cd6;">function</font> _carveOut(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint</font> acct)
        <font style="color:#569cd6;">private</font>
        memberExist(chain, acct)
    {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        <font style="color:#569cd6;">if</font> (_isIndepMember(n)) {

            _branchOff(chain, acct);

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isGroupRep(n)) {

            <font style="color:#569cd6;">if</font> (n.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepOnChain) || (n.prev > <font style="color:#b5cea8;">0</font> && n.next > <font style="color:#b5cea8;">0</font>)) {

                chain.nodes[n.prev].next = n.ptr;
                chain.nodes[n.next].prev = n.ptr;

            } <font style="color:#569cd6;">else</font> {

                <font style="color:#569cd6;">if</font> (n.prev == <font style="color:#b5cea8;">0</font> && n.next == <font style="color:#b5cea8;">0</font>) {
                    chain.para.tail = n.ptr;
                    chain.para.head = n.ptr;
                } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (n.next == <font style="color:#b5cea8;">0</font>) {
                    chain.para.tail = n.ptr;
                    chain.nodes[n.prev].next = n.ptr;
                } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (n.prev == <font style="color:#b5cea8;">0</font>) {
                    chain.nodes[n.next].prev = n.ptr;
                    chain.para.head = n.ptr;
                }

            }

            Node <font style="color:#569cd6;">storage</font> d = chain.nodes[n.ptr];

            d.ptr = d.next;
            d.prev = n.prev;
            d.next = n.next;

            <font style="color:#569cd6;">if</font> (d.ptr > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#4ec9b0;">uint40</font> cur = d.ptr;
                <font style="color:#569cd6;">while</font> (cur > <font style="color:#b5cea8;">0</font>) {
                    chain.nodes[cur].ptr = n.ptr;
                    cur = chain.nodes[cur].next;
                }
                d.cat = n.cat;
            } <font style="color:#569cd6;">else</font> {
                d.ptr = n.ptr;
                d.cat = n.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepInQueue)
                    ? <font style="color:#4ec9b0;">uint8</font>(CatOfNode.IndepMemberInQueue)
                    : <font style="color:#4ec9b0;">uint8</font>(CatOfNode.IndepMemberOnChain);
            }

            d.sum = n.sum - n.amt;

            _offChainCheck(chain, d, n.ptr);

        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isGroupMember(n)) {

            Node <font style="color:#569cd6;">storage</font> u = chain.nodes[n.prev];

            <font style="color:#569cd6;">if</font> (n.next > <font style="color:#b5cea8;">0</font>) chain.nodes[n.next].prev = n.prev;

            <font style="color:#569cd6;">if</font> (u.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupMember)) u.next = n.next;
            <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (n.next > <font style="color:#b5cea8;">0</font>) {
                u.ptr = n.next;
            } <font style="color:#569cd6;">else</font> {
                u.ptr = n.ptr;
                u.cat = u.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepInQueue)
                    ? <font style="color:#4ec9b0;">uint8</font>(CatOfNode.IndepMemberInQueue)
                    : <font style="color:#4ec9b0;">uint8</font>(CatOfNode.IndepMemberOnChain);
            }

            Node <font style="color:#569cd6;">storage</font> r = chain.nodes[n.ptr];

            r.sum -= n.amt;

            _offChainCheck(chain, r, n.ptr);

        }
    }

    <font style="color:#569cd6;">function</font> _offChainCheck(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node <font style="color:#569cd6;">storage</font> r,
        <font style="color:#4ec9b0;">uint40</font> acct
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (_isOnChain(r)) {
            <font style="color:#569cd6;">if</font> (_onChainTest(chain, r)) _move(chain, acct, <font style="color:#569cd6;">false</font>);
            <font style="color:#569cd6;">else</font> _offChain(chain, r, acct);
        }
    }

    <font style="color:#6a9955;">// ==== Insert ====</font>

    <font style="color:#569cd6;">function</font> _hInsert(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">uint</font> prev,
        <font style="color:#4ec9b0;">uint</font> next
    ) <font style="color:#569cd6;">private</font> {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        chain.nodes[prev].next = <font style="color:#4ec9b0;">uint40</font>(acct);
        n.prev = <font style="color:#4ec9b0;">uint40</font>(prev);

        chain.nodes[next].prev = <font style="color:#4ec9b0;">uint40</font>(acct);
        n.next = <font style="color:#4ec9b0;">uint40</font>(next);

        _increaseQtyOfBranches(chain);
    }

    <font style="color:#569cd6;">function</font> _vInsert(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint40</font> acct,
        <font style="color:#4ec9b0;">uint40</font> root
    ) <font style="color:#569cd6;">private</font> {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];
        Node <font style="color:#569cd6;">storage</font> r = chain.nodes[root];

        <font style="color:#569cd6;">if</font> (_isIndepMember(r)) {
            r.cat = r.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.IndepMemberInQueue)
                ? <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepInQueue)
                : <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupRepOnChain);
            n.next = <font style="color:#b5cea8;">0</font>;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isGroupRep(r)) {
            n.next = r.ptr;
            chain.nodes[n.next].prev = acct;
        }

        n.prev = root;
        n.ptr = root;

        n.cat = <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupMember);

        r.ptr = acct;
        r.sum += n.amt;

        <font style="color:#569cd6;">if</font> (_isOnChain(r)) _move(chain, root, <font style="color:#569cd6;">true</font>);
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_onChainTest(chain, r)) {
            _upChainAndMove(chain, r, root);
        }
    }

    <font style="color:#6a9955;">// ==== Move ====</font>

    <font style="color:#569cd6;">function</font> _move(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint</font> acct,
        <font style="color:#4ec9b0;">bool</font> increase
    ) <font style="color:#569cd6;">private</font> {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        (<font style="color:#4ec9b0;">uint256</font> prev, <font style="color:#4ec9b0;">uint256</font> next) = getPos(
            chain,
            n.sum,
            n.prev,
            n.next,
            increase
        );

        <font style="color:#569cd6;">if</font> (next != n.next || prev != n.prev) {
            _branchOff(chain, acct);
            _hInsert(chain, acct, prev, next);
        }
    }

    <font style="color:#6a9955;">// ==== Chain & Queue ====</font>

    <font style="color:#569cd6;">function</font> _appendToQueue(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node <font style="color:#569cd6;">storage</font> n,
        <font style="color:#4ec9b0;">uint40</font> acct
    ) <font style="color:#569cd6;">private</font> {

        <font style="color:#569cd6;">if</font> (chain.para.qtyOfSticks > <font style="color:#b5cea8;">0</font>) {
            chain.nodes[chain.para.tail].next = acct;
        } <font style="color:#569cd6;">else</font> {
            chain.para.head = acct;
        }

        n.prev = chain.para.tail;
        n.next = <font style="color:#b5cea8;">0</font>;

        chain.para.tail = acct;

        <font style="color:#569cd6;">if</font> (_isOnChain(n)) n.cat -= <font style="color:#b5cea8;">3</font>;

        _increaseQtyOfSticks(chain);
    }

    <font style="color:#569cd6;">function</font> _appendToChain(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node <font style="color:#569cd6;">storage</font> n,
        <font style="color:#4ec9b0;">uint40</font> acct
    ) <font style="color:#569cd6;">private</font> {
        n.prev = chain.nodes[<font style="color:#b5cea8;">0</font>].prev;
        chain.nodes[n.prev].next = acct;
        chain.nodes[<font style="color:#b5cea8;">0</font>].prev = acct;
        n.next = <font style="color:#b5cea8;">0</font>;

        <font style="color:#569cd6;">if</font> (_isInQueue(n)) n.cat += <font style="color:#b5cea8;">3</font>;

        _increaseQtyOfBranches(chain);
    }

    <font style="color:#569cd6;">function</font> _onChainTest(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node <font style="color:#569cd6;">storage</font> r
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">uint</font>(r.sum) * <font style="color:#b5cea8;">10000</font> >= <font style="color:#4ec9b0;">uint</font>(totalVotes(chain)) * minVoteRatioOnChain(chain);
    }

    <font style="color:#569cd6;">function</font> _upChainAndMove(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node <font style="color:#569cd6;">storage</font> n,
        <font style="color:#4ec9b0;">uint40</font> acct
    ) <font style="color:#569cd6;">private</font> {
        _trimChain(chain);
        _branchOff(chain, acct);
        _appendToChain(chain, n, acct);
        _move(chain, acct, <font style="color:#569cd6;">true</font>);

    }

    <font style="color:#569cd6;">function</font> _trimChain(
        Chain <font style="color:#569cd6;">storage</font> chain
    ) <font style="color:#569cd6;">private</font> {

        <font style="color:#4ec9b0;">uint40</font> cur = chain.nodes[<font style="color:#b5cea8;">0</font>].prev;

        <font style="color:#569cd6;">while</font> (cur > <font style="color:#b5cea8;">0</font>) {
            Node <font style="color:#569cd6;">storage</font> t = chain.nodes[cur];
            <font style="color:#4ec9b0;">uint40</font> prev = t.prev;
            <font style="color:#569cd6;">if</font> (!_onChainTest(chain, t))
                _offChain(chain, t, cur);
            <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
            cur = prev;
        }
    }

    <font style="color:#569cd6;">function</font> _offChain(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node <font style="color:#569cd6;">storage</font> n,
        <font style="color:#4ec9b0;">uint40</font> acct
    ) <font style="color:#569cd6;">private</font> {
        _branchOff(chain, acct);
        _appendToQueue(chain, n, acct);
    }

    <font style="color:#6a9955;">// ---- Categories Of Node ----</font>

    <font style="color:#569cd6;">function</font> _isOnChain(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat > <font style="color:#b5cea8;">2</font>;
    }

    <font style="color:#569cd6;">function</font> _isInQueue(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat < <font style="color:#b5cea8;">2</font>;
    }

    <font style="color:#569cd6;">function</font> _isIndepMember(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat % <font style="color:#b5cea8;">3</font> == <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#569cd6;">function</font> _isInGroup(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat % <font style="color:#b5cea8;">3</font> > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#569cd6;">function</font> _isGroupRep(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat % <font style="color:#b5cea8;">3</font> == <font style="color:#b5cea8;">1</font>;
    }

    <font style="color:#569cd6;">function</font> _isGroupMember(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupMember);
    }

    <font style="color:#569cd6;">function</font> _notGroupMember(
        Node <font style="color:#569cd6;">storage</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> n.cat % <font style="color:#b5cea8;">3</font> < <font style="color:#b5cea8;">2</font>;
    }

    <font style="color:#6a9955;">// ==== setting ====</font>

    <font style="color:#569cd6;">function</font> _increaseQtyOfBranches(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">private</font> {
        chain.para.qtyOfBranches++;
    }

    <font style="color:#569cd6;">function</font> _increaseQtyOfMembers(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">private</font> {
        chain.para.qtyOfMembers++;
    }

    <font style="color:#569cd6;">function</font> _increaseQtyOfSticks(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">private</font> {
        chain.para.qtyOfSticks++;
    }

    <font style="color:#569cd6;">function</font> _increaseTotalVotes(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint64</font> deltaAmt) <font style="color:#569cd6;">private</font> {
        chain.nodes[<font style="color:#b5cea8;">0</font>].sum += deltaAmt;
    }

    <font style="color:#569cd6;">function</font> _decreaseQtyOfBranches(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">private</font> {
        chain.para.qtyOfBranches--;
    }

    <font style="color:#569cd6;">function</font> _decreaseQtyOfMembers(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">private</font> {
        chain.para.qtyOfMembers--;
    }

    <font style="color:#569cd6;">function</font> _decreaseQtyOfSticks(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">private</font> {
        chain.para.qtyOfSticks--;
    }

    <font style="color:#569cd6;">function</font> _decreaseTotalVotes(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint64</font> deltaAmt) <font style="color:#569cd6;">private</font> {
        chain.nodes[<font style="color:#b5cea8;">0</font>].sum -= deltaAmt;
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##    Read    ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Check whether a user is a member.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#569cd6;">function</font> isMember(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#569cd6;">return</font> chain.nodes[acct].ptr != <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">// ==== Zero Node ====</font>

    <font style="color:#6a9955;">/// @notice Get tail node id of chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> tail(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> chain.nodes[<font style="color:#b5cea8;">0</font>].prev;
    }

    <font style="color:#6a9955;">/// @notice Get head node id of chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> head(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>) {
        <font style="color:#569cd6;">return</font> chain.nodes[<font style="color:#b5cea8;">0</font>].next;
    }

    <font style="color:#6a9955;">/// @notice Get total votes sum.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> totalVotes(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font>) {
        <font style="color:#569cd6;">return</font> chain.nodes[<font style="color:#b5cea8;">0</font>].sum;
    }

    <font style="color:#6a9955;">/// @notice Check if votes are based on par.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> basedOnPar(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> chain.nodes[<font style="color:#b5cea8;">0</font>].cat == <font style="color:#b5cea8;">1</font>;
    }

    <font style="color:#6a9955;">// ---- Para ----</font>

    <font style="color:#6a9955;">/// @notice Get head of off-chain queue.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> headOfQueue(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>)
    {
        <font style="color:#569cd6;">return</font>  chain.para.head;
    }

    <font style="color:#6a9955;">/// @notice Get tail of off-chain queue.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> tailOfQueue(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font>)
    {
        <font style="color:#569cd6;">return</font>  chain.para.tail;
    }

    <font style="color:#6a9955;">/// @notice Get max member limit.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> maxQtyOfMembers(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>)
    {
        <font style="color:#569cd6;">return</font> chain.para.maxQtyOfMembers;
    }

    <font style="color:#6a9955;">/// @notice Get minimum vote ratio required on chain.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> minVoteRatioOnChain(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint16</font>)
    {
        <font style="color:#4ec9b0;">uint16</font> min = chain.para.minVoteRatioOnChain;
        <font style="color:#569cd6;">return</font> min > <font style="color:#b5cea8;">0</font> ? min : <font style="color:#b5cea8;">500</font>;
    }

    <font style="color:#6a9955;">/// @notice Get number of branch groups.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> qtyOfBranches(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.para.qtyOfBranches;
    }

    <font style="color:#6a9955;">/// @notice Get number of groups (branches + sticks).</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> qtyOfGroups(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.para.qtyOfBranches + chain.para.qtyOfSticks;
    }

    <font style="color:#6a9955;">/// @notice Get count of top-level members.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> qtyOfTopMembers(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> qty)
    {
        <font style="color:#4ec9b0;">uint</font> cur = chain.nodes[<font style="color:#b5cea8;">0</font>].next;

        <font style="color:#569cd6;">while</font>(cur > <font style="color:#b5cea8;">0</font>) {
            qty++;
            cur = nextNode(chain, cur);
        }
    }

    <font style="color:#6a9955;">/// @notice Get total member count.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#569cd6;">function</font> qtyOfMembers(Chain <font style="color:#569cd6;">storage</font> chain) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> chain.para.qtyOfMembers;
    }

    <font style="color:#6a9955;">// ==== locate position ====</font>

    <font style="color:#6a9955;">/// @notice Find insertion position for amount.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param amount Target amount.</font>
    <font style="color:#6a9955;">/// @param prev Previous node id.</font>
    <font style="color:#6a9955;">/// @param next Next node id.</font>
    <font style="color:#6a9955;">/// @param increase True when amount increased.</font>
    <font style="color:#569cd6;">function</font> getPos(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint256</font> amount,
        <font style="color:#4ec9b0;">uint256</font> prev,
        <font style="color:#4ec9b0;">uint256</font> next,
        <font style="color:#4ec9b0;">bool</font> increase
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>, <font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">if</font> (increase)
            <font style="color:#569cd6;">while</font> (prev > <font style="color:#b5cea8;">0</font> && chain.nodes[prev].sum < amount) {
                next = prev;
                prev = chain.nodes[prev].prev;
            }
        <font style="color:#569cd6;">else</font>
            <font style="color:#569cd6;">while</font> (next > <font style="color:#b5cea8;">0</font> && chain.nodes[next].sum > amount) {
                prev = next;
                next = chain.nodes[next].next;
            }

        <font style="color:#569cd6;">return</font> (prev, next);
    }

    <font style="color:#6a9955;">/// @notice Get next node id in traversal order.</font>
    <font style="color:#6a9955;">/// @param chain Storage chain.</font>
    <font style="color:#6a9955;">/// @param acct Member user number.</font>
    <font style="color:#569cd6;">function</font> nextNode(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> next)
    {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        <font style="color:#569cd6;">if</font> (_isIndepMember(n)) {
            next = n.next;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isGroupRep(n)) {
            next = n.ptr;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isGroupMember(n)) {
            next = (n.next > <font style="color:#b5cea8;">0</font>) ? n.next : chain.nodes[n.ptr].next;
        }
    }

    <font style="color:#569cd6;">function</font> getNode(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Node <font style="color:#569cd6;">memory</font> n)
    {
        n = chain.nodes[acct];
    }

    <font style="color:#6a9955;">// ==== group ====</font>

    <font style="color:#569cd6;">function</font> rootOf(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        memberExist(chain, acct)
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint40</font> group)
    {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];
        group = (n.cat == <font style="color:#4ec9b0;">uint8</font>(CatOfNode.GroupMember)) ? n.ptr : <font style="color:#4ec9b0;">uint40</font>(acct) ;
    }

    <font style="color:#569cd6;">function</font> deepOfBranch(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        memberExist(chain, acct)
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> deep)
    {
        Node <font style="color:#569cd6;">storage</font> n = chain.nodes[acct];

        <font style="color:#569cd6;">if</font> (_isIndepMember(n)) deep = <font style="color:#b5cea8;">1</font>;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> (_isGroupRep(n)) deep = _deepOfBranch(chain, acct);
        <font style="color:#569cd6;">else</font> deep = _deepOfBranch(chain, n.ptr);
    }

    <font style="color:#569cd6;">function</font> _deepOfBranch(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> root)
        <font style="color:#569cd6;">private</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font> deep)
    {
        deep = <font style="color:#b5cea8;">1</font>;

        <font style="color:#4ec9b0;">uint40</font> next = chain.nodes[root].ptr;

        <font style="color:#569cd6;">while</font> (next > <font style="color:#b5cea8;">0</font>) {
            deep++;
            next = chain.nodes[next].next;
        }
    }

    <font style="color:#569cd6;">function</font> votesOfGroup(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint64</font> votes)
    {
        <font style="color:#4ec9b0;">uint256</font> group = rootOf(chain, acct);
        votes = chain.nodes[group].sum;
    }

    <font style="color:#569cd6;">function</font> membersOfGroup(Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint256</font> acct)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> list)
    {
        <font style="color:#4ec9b0;">uint256</font> cur = rootOf(chain, acct);
        <font style="color:#4ec9b0;">uint256</font> len = deepOfBranch(chain, acct);

        list = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint256</font>[](len);
        <font style="color:#4ec9b0;">uint256</font> i = <font style="color:#b5cea8;">0</font>;

        <font style="color:#569cd6;">while</font> (i < len) {
            list[i] = cur;
            cur = nextNode(chain, cur);
            i++;
        }
    }

    <font style="color:#569cd6;">function</font> affiliated(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint256</font> acct1,
        <font style="color:#4ec9b0;">uint256</font> acct2
    )
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        memberExist(chain, acct1)
        memberExist(chain, acct2)
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        Node <font style="color:#569cd6;">storage</font> n1 = chain.nodes[acct1];
        Node <font style="color:#569cd6;">storage</font> n2 = chain.nodes[acct2];

        <font style="color:#569cd6;">return</font> n1.ptr == n2.ptr || n1.ptr == acct2 || n2.ptr == acct1;
    }

    <font style="color:#6a9955;">// ==== members ====</font>

    <font style="color:#569cd6;">function</font> topMembersList(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> list)
    {
        <font style="color:#4ec9b0;">uint256</font> len = qtyOfTopMembers(chain);
        list = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint</font>[](len);

        len = <font style="color:#b5cea8;">0</font>;
        <font style="color:#4ec9b0;">uint</font> cur = chain.nodes[<font style="color:#b5cea8;">0</font>].next;

        _seqListOfQueue(chain, list, cur, len);
    }

    <font style="color:#569cd6;">function</font> sortedMembersList(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font>
        <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> list)
    {
        <font style="color:#4ec9b0;">uint256</font> len = qtyOfMembers(chain);
        list = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint</font>[](len);

        <font style="color:#4ec9b0;">uint</font> cur = chain.nodes[<font style="color:#b5cea8;">0</font>].next;
        len = <font style="color:#b5cea8;">0</font>;

        len = _seqListOfQueue(chain, list, cur, len);

        cur = chain.para.head;
        _seqListOfQueue(chain, list, cur, len);
    }

    <font style="color:#569cd6;">function</font> _seqListOfQueue(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list,
        <font style="color:#4ec9b0;">uint</font> cur,
        <font style="color:#4ec9b0;">uint</font> i
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">while</font> (cur > <font style="color:#b5cea8;">0</font>) {
            list[i] = cur;
            cur = nextNode(chain, cur);
            i++;
        }
        <font style="color:#569cd6;">return</font> i;
    }

    <font style="color:#6a9955;">// ==== Backup / Restore ====</font>

    <font style="color:#569cd6;">function</font> getSnapshot(Chain <font style="color:#569cd6;">storage</font> chain)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Node[] <font style="color:#569cd6;">memory</font> list, Para <font style="color:#569cd6;">memory</font> para)
    {
        para = chain.para;

        <font style="color:#4ec9b0;">uint256</font> len = qtyOfMembers(chain);
        list = <font style="color:#569cd6;">new</font> Node[](len + <font style="color:#b5cea8;">1</font>);

        list[<font style="color:#b5cea8;">0</font>] = chain.nodes[<font style="color:#b5cea8;">0</font>];

        <font style="color:#4ec9b0;">uint256</font> cur = chain.nodes[<font style="color:#b5cea8;">0</font>].next;
        len = <font style="color:#b5cea8;">1</font>;
        len = _backupNodes(chain, list, cur, len);

        cur = para.head;
        _backupNodes(chain, list, cur, len);
    }

    <font style="color:#569cd6;">function</font> _backupNodes(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node[] <font style="color:#569cd6;">memory</font> list,
        <font style="color:#4ec9b0;">uint</font> cur,
        <font style="color:#4ec9b0;">uint</font> i
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">while</font> (cur > <font style="color:#b5cea8;">0</font>) {
            list[i] = chain.nodes[cur];
            cur = nextNode(chain, cur);
            i++;
        }
        <font style="color:#569cd6;">return</font> i;
    }

    <font style="color:#569cd6;">function</font> restoreChain(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node[] <font style="color:#569cd6;">memory</font> list,
        Para <font style="color:#569cd6;">memory</font> para
    ) <font style="color:#569cd6;">public</font> {

        chain.nodes[<font style="color:#b5cea8;">0</font>] = list[<font style="color:#b5cea8;">0</font>];
        chain.para = para;

        <font style="color:#4ec9b0;">uint256</font> cur = list[<font style="color:#b5cea8;">0</font>].next;
        <font style="color:#4ec9b0;">uint256</font> i = <font style="color:#b5cea8;">1</font>;
        i = _restoreNodes(chain, list, cur, i);

        cur = para.head;
        _restoreNodes(chain, list, cur, i);
    }

    <font style="color:#569cd6;">function</font> _restoreNodes(
        Chain <font style="color:#569cd6;">storage</font> chain,
        Node[] <font style="color:#569cd6;">memory</font> list,
        <font style="color:#4ec9b0;">uint</font> cur,
        <font style="color:#4ec9b0;">uint</font> i
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">while</font> (cur > <font style="color:#b5cea8;">0</font>) {
            chain.nodes[cur] = list[i];
            cur = nextNode(chain, cur);
            i++;
        }
        <font style="color:#569cd6;">return</font> i;
    }

    <font style="color:#6a9955;">// ==== MockDeals ====</font>

    <font style="color:#569cd6;">function</font> mockDealsOfIA(
        Chain <font style="color:#569cd6;">storage</font> chain,
        IInvestmentAgreement _ia,
        IRegisterOfShares _ros
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqList = _ia.getSeqList();

        <font style="color:#4ec9b0;">uint256</font> len = seqList.length;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            DealsRepo.Deal <font style="color:#569cd6;">memory</font> deal = _ia.getDeal(seqList[len-<font style="color:#b5cea8;">1</font>]);

            <font style="color:#4ec9b0;">uint</font> amount = basedOnPar(chain) ? deal.body.par : deal.body.paid;

            <font style="color:#569cd6;">if</font> (deal.head.seller > <font style="color:#b5cea8;">0</font>) {
                amount = amount * _ros.getShare(deal.head.seqOfShare).head.votingWeight / <font style="color:#b5cea8;">100</font>;
                mockDealOfSell(chain, deal.head.seller, amount);
            } <font style="color:#569cd6;">else</font> {
                amount = amount * deal.head.votingWeight / <font style="color:#b5cea8;">100</font>;
            }

            mockDealOfBuy(chain, deal.body.buyer, deal.body.groupOfBuyer, amount);

            len--;
        }
    }

    <font style="color:#569cd6;">function</font> mockDealOfSell(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint256</font> seller,
        <font style="color:#4ec9b0;">uint</font> amount
    ) <font style="color:#569cd6;">public</font> {
        increaseAmt(chain, seller, amount, <font style="color:#569cd6;">false</font>);

        <font style="color:#569cd6;">if</font> (chain.nodes[seller].amt == <font style="color:#b5cea8;">0</font>)
            delNode(chain, seller);
    }

    <font style="color:#569cd6;">function</font> mockDealOfBuy(
        Chain <font style="color:#569cd6;">storage</font> chain,
        <font style="color:#4ec9b0;">uint256</font> buyer,
        <font style="color:#4ec9b0;">uint256</font> group,
        <font style="color:#4ec9b0;">uint</font> amount
    ) <font style="color:#569cd6;">public</font> {
        addNode(chain, buyer);

        increaseAmt(chain, buyer, amount, <font style="color:#569cd6;">true</font>);

        <font style="color:#569cd6;">if</font> (rootOf(chain, buyer) != group)
            top2Sub(chain, buyer, group);
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## UsdLockersRepo.sol

---

| |
|:---|
| **contracts/lib/books/UsdLockersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#6a9955;">/// @title UsdLockersRepo</font>
<font style="color:#6a9955;">/// @notice Repository for time-locked USDC escrows keyed by hashLock.</font>
<font style="color:#6a9955;">/// @dev Stores locker metadata and optional cross-contract payloads for conditional release.</font>
<font style="color:#569cd6;">library</font> UsdLockersRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.Bytes32Set;

    <font style="color:#6a9955;">/// @notice Locker lifecycle states.</font>
    <font style="color:#569cd6;">enum</font> StateOfLocker {
        empty,
        locked,
        picked,
        withdrawn
    }

    <font style="color:#6a9955;">/// @notice Locker header metadata.</font>
    <font style="color:#6a9955;">/// @dev `expireDate/pickupDate` are unix timestamps; `amt` is USDC in smallest units.</font>
    <font style="color:#569cd6;">struct</font> Head {
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>;
        <font style="color:#4ec9b0;">uint40</font> payer;
        <font style="color:#4ec9b0;">uint48</font> expireDate;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">address</font> to;
        <font style="color:#4ec9b0;">uint40</font> payee;
        <font style="color:#4ec9b0;">uint48</font> pickupDate;
        <font style="color:#4ec9b0;">bool</font> flag;
        <font style="color:#4ec9b0;">uint256</font> amt;
    }

    <font style="color:#6a9955;">/// @notice Optional conditional release payload.</font>
    <font style="color:#6a9955;">/// @dev `counterLocker` is the target contract invoked on release.</font>
    <font style="color:#569cd6;">struct</font> Body {
        <font style="color:#4ec9b0;">address</font> counterLocker;
        <font style="color:#4ec9b0;">bytes</font> payload;
    }

    <font style="color:#6a9955;">/// @notice Full locker record (header + body).</font>
    <font style="color:#569cd6;">struct</font> Locker {
        Head head;
        Body body;
    }

    <font style="color:#6a9955;">/// @notice Repository storage container.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">bytes32</font> => Locker) lockers;
        EnumerableSet.Bytes32Set snList;
    }

    <font style="color:#6a9955;">//###############</font>
    <font style="color:#6a9955;">//##   Error   ##</font>
    <font style="color:#6a9955;">//###############</font>

    <font style="color:#569cd6;">error</font> ULR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> ULR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> ULR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Create a locker header with basic validation.</font>
    <font style="color:#6a9955;">/// @param from Payer address (non-zero).</font>
    <font style="color:#6a9955;">/// @param to Payee address (non-zero).</font>
    <font style="color:#6a9955;">/// @param payer Payer userNo (uint40 in implementation).</font>
    <font style="color:#6a9955;">/// @param payee Payee userNo (uint40 in implementation).</font>
    <font style="color:#6a9955;">/// @param expireDate Unix timestamp (must be in the future).</font>
    <font style="color:#6a9955;">/// @param amt USDC amount (smallest units, must be > 0).</font>
    <font style="color:#6a9955;">/// @return head Newly created header.</font>
    <font style="color:#569cd6;">function</font> _createHead(
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint</font> payer,
        <font style="color:#4ec9b0;">uint</font> payee, <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">uint</font> amt
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Head <font style="color:#569cd6;">memory</font> head){
        <font style="color:#569cd6;">if</font> (<font style="color:#569cd6;">from</font> == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> ULR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_ZeroFrom"</font>));

        <font style="color:#569cd6;">if</font> (to == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> ULR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_ZeroTo"</font>));

        <font style="color:#569cd6;">if</font> (amt == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> ULR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_ZeroAmt"</font>));

        <font style="color:#569cd6;">if</font> (expireDate <= block.timestamp)
            <font style="color:#569cd6;">revert</font> ULR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_NotFuture"</font>));

        head = Head({
            <font style="color:#569cd6;">from</font>: <font style="color:#569cd6;">from</font>,
            payer: <font style="color:#4ec9b0;">uint40</font>(payer),
            expireDate: <font style="color:#4ec9b0;">uint48</font>(expireDate),
            state: <font style="color:#b5cea8;">1</font>,
            to: to,
            payee: <font style="color:#4ec9b0;">uint40</font>(payee),
            pickupDate: <font style="color:#b5cea8;">0</font>,
            flag: <font style="color:#569cd6;">true</font>,
            amt: amt
        });
    }

    <font style="color:#6a9955;">/// @notice Add a locker to storage.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param head Locker header.</font>
    <font style="color:#6a9955;">/// @param body Locker body.</font>
    <font style="color:#6a9955;">/// @param hashLock Unique hash key (must be unused).</font>
    <font style="color:#569cd6;">function</font> _addLocker(
        Repo <font style="color:#569cd6;">storage</font> repo, Head <font style="color:#569cd6;">memory</font> head,
        Body <font style="color:#569cd6;">memory</font> body, <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">if</font> (repo.snList.add(hashLock)) {
            Locker <font style="color:#569cd6;">storage</font> locker = repo.lockers[hashLock];
            locker.head = head;
            locker.body = body;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_Occupied"</font>));
    }

    <font style="color:#6a9955;">/// @notice Lock USDC with an external conditional release hook.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param from Payer address.</font>
    <font style="color:#6a9955;">/// @param to Payee address.</font>
    <font style="color:#6a9955;">/// @param expireDate Unix timestamp when withdrawal is allowed.</font>
    <font style="color:#6a9955;">/// @param amt USDC amount (smallest units).</font>
    <font style="color:#6a9955;">/// @param counterLocker Target contract for conditional release.</font>
    <font style="color:#6a9955;">/// @param payload Calldata payload prefix for target.</font>
    <font style="color:#6a9955;">/// @param hashLock Unique hash key for this locker.</font>
    <font style="color:#569cd6;">function</font> lockConsideration(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">address</font> counterLocker,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">calldata</font> payload, <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">public</font> {
        Head <font style="color:#569cd6;">memory</font> head =
            _createHead(<font style="color:#569cd6;">from</font>, to, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, expireDate, amt);

        Body <font style="color:#569cd6;">memory</font> body = Body({
            counterLocker: counterLocker,
            payload: payload
        });

        _addLocker(repo, head, body, hashLock);
    }

    <font style="color:#6a9955;">/// @notice Lock USDC for later release by hash key.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param from Payer address.</font>
    <font style="color:#6a9955;">/// @param to Payee address.</font>
    <font style="color:#6a9955;">/// @param expireDate Unix timestamp when withdrawal is allowed.</font>
    <font style="color:#6a9955;">/// @param amt USDC amount (smallest units).</font>
    <font style="color:#6a9955;">/// @param hashLock Unique hash key for this locker.</font>
    <font style="color:#569cd6;">function</font> lockUsd(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to,
        <font style="color:#4ec9b0;">uint</font> expireDate, <font style="color:#4ec9b0;">uint</font> amt, <font style="color:#4ec9b0;">bytes32</font> hashLock
    ) <font style="color:#569cd6;">public</font> {
        Head <font style="color:#569cd6;">memory</font> head =
            _createHead(<font style="color:#569cd6;">from</font>, to, <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, expireDate, amt);
        Body <font style="color:#569cd6;">memory</font> body;

        _addLocker(repo, head, body, hashLock);
    }

    <font style="color:#6a9955;">/// @notice Release a locker using the preimage of hashLock.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#6a9955;">/// @param hashKey Preimage string (must hash to `lock`).</font>
    <font style="color:#6a9955;">/// @param msgSender Caller (must be payee for conditional lockers).</font>
    <font style="color:#6a9955;">/// @return head Updated locker header.</font>
    <font style="color:#569cd6;">function</font> releaseUsd(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> lock,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> hashKey, <font style="color:#4ec9b0;">address</font> msgSender
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font>){
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> key = <font style="color:#4ec9b0;">bytes</font>(hashKey);

        <font style="color:#569cd6;">if</font> (!isLocked(repo, lock))
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotExist"</font>));

        <font style="color:#569cd6;">if</font> (lock != keccak256(key))
            <font style="color:#569cd6;">revert</font> ULR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_WrongKey"</font>));

        Locker <font style="color:#569cd6;">storage</font> locker = repo.lockers[lock];

        <font style="color:#569cd6;">if</font> (locker.head.expireDate <= block.timestamp)
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockExpired"</font>));

        <font style="color:#569cd6;">if</font> (locker.head.state != <font style="color:#b5cea8;">1</font>)
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotLocked"</font>));

        locker.head.pickupDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        locker.head.state = <font style="color:#b5cea8;">2</font>;
        locker.head.flag = <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">if</font> (locker.body.counterLocker != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">if</font> (locker.head.to != msgSender)
                <font style="color:#569cd6;">revert</font> ULR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_NotIntendedPayee"</font>));

            <font style="color:#4ec9b0;">uint</font> len = key.length;
            <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> zero = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">bytes</font>(<font style="color:#b5cea8;">32</font> - (len % <font style="color:#b5cea8;">32</font>));

            <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> payload = abi.encodePacked(locker.body.payload, len, key, zero);
            (<font style="color:#4ec9b0;">bool</font> flag, ) = locker.body.counterLocker.call(payload);

            <font style="color:#569cd6;">if</font> (!flag)
                <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_CounterCallFailed"</font>));
        }

        <font style="color:#569cd6;">return</font> locker.head;
    }

    <font style="color:#6a9955;">/// @notice Withdraw a locker after expiry by the creator.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#6a9955;">/// @param msgSender Caller (must be creator).</font>
    <font style="color:#6a9955;">/// @return head Updated locker header.</font>
    <font style="color:#569cd6;">function</font> withdrawUsd(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> lock, <font style="color:#4ec9b0;">address</font> msgSender
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font>){

        <font style="color:#569cd6;">if</font> (!isLocked(repo, lock))
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotExist"</font>));

        Locker <font style="color:#569cd6;">storage</font> locker = repo.lockers[lock];

        <font style="color:#569cd6;">if</font> (locker.head.state != <font style="color:#b5cea8;">1</font>)
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotLocked"</font>));

        <font style="color:#569cd6;">if</font> (locker.head.expireDate > block.timestamp)
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotExpired"</font>));

        <font style="color:#569cd6;">if</font> (locker.head.<font style="color:#569cd6;">from</font> != msgSender)
            <font style="color:#569cd6;">revert</font> ULR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_NotCreator"</font>));

        locker.head.pickupDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        locker.head.state = <font style="color:#b5cea8;">3</font>;
        locker.head.flag = <font style="color:#569cd6;">false</font>;

        <font style="color:#569cd6;">return</font> locker.head;
    }

    <font style="color:#6a9955;">//##################</font>
    <font style="color:#6a9955;">//##   Read I/O   ##</font>
    <font style="color:#6a9955;">//##################</font>

    <font style="color:#6a9955;">/// @notice Check if a locker is currently locked.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#6a9955;">/// @return True if state is `locked`.</font>
    <font style="color:#569cd6;">function</font> isLocked(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>){
        <font style="color:#569cd6;">return</font> repo.lockers[lock].head.state == <font style="color:#4ec9b0;">uint8</font>(StateOfLocker.locked);
    }

    <font style="color:#6a9955;">/// @notice Get total number of lockers.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Count of lockers.</font>
    <font style="color:#569cd6;">function</font> counterOfLockers(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.snList.length();
    }

    <font style="color:#6a9955;">/// @notice Get locker header by hash.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#6a9955;">/// @return Header record.</font>
    <font style="color:#569cd6;">function</font> getHeadOfLocker(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Head <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (!isLocked(repo, lock))
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotExist"</font>));
        <font style="color:#569cd6;">return</font> repo.lockers[lock].head;
    }

    <font style="color:#6a9955;">/// @notice Get full locker by hash.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param lock Hash lock value.</font>
    <font style="color:#6a9955;">/// @return Locker record.</font>
    <font style="color:#569cd6;">function</font> getLocker(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> lock) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Locker <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (!isLocked(repo, lock))
            <font style="color:#569cd6;">revert</font> ULR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"ULR_LockerNotExist"</font>));
        <font style="color:#569cd6;">return</font> repo.lockers[lock];
    }

    <font style="color:#6a9955;">/// @notice Get list of all hash locks.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Array of hash locks.</font>
    <font style="color:#569cd6;">function</font> getSnList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.snList.values();
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## UsdOrdersRepo.sol

---

| |
|:---|
| **contracts/lib/books/UsdOrdersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./GoldChain.sol"</font>;

<font style="color:#6a9955;">/// @title UsdOrdersRepo</font>
<font style="color:#6a9955;">/// @notice Order book utilities for USD-settled offers and bids.</font>
<font style="color:#569cd6;">library</font> UsdOrdersRepo {
    <font style="color:#569cd6;">using</font> GoldChain <font style="color:#569cd6;">for</font> GoldChain.Chain;

    <font style="color:#6a9955;">/// @notice Compact brief for on-chain encoding.</font>
    <font style="color:#569cd6;">struct</font> Brief {
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint40</font> buyer;
        <font style="color:#4ec9b0;">uint40</font> seller;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint32</font> price;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
    }

    <font style="color:#6a9955;">/// @notice Order/deal model used by matching engine.</font>
    <font style="color:#569cd6;">struct</font> Deal {
        <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>;
        <font style="color:#4ec9b0;">uint40</font> buyer;
        <font style="color:#4ec9b0;">uint40</font> groupRep;
        <font style="color:#4ec9b0;">uint16</font> classOfShare;
        <font style="color:#4ec9b0;">address</font> to;
        <font style="color:#4ec9b0;">uint40</font> seller;
        <font style="color:#4ec9b0;">uint32</font> seqOfShare;
        <font style="color:#4ec9b0;">uint8</font> state;
        <font style="color:#4ec9b0;">bool</font> inEth;
        <font style="color:#4ec9b0;">bool</font> isOffer;
        <font style="color:#4ec9b0;">uint64</font> paid;
        <font style="color:#4ec9b0;">uint32</font> price;
        <font style="color:#4ec9b0;">uint16</font> votingWeight;
        <font style="color:#4ec9b0;">uint16</font> distrWeight;
        <font style="color:#4ec9b0;">uint128</font> consideration;
    }

    <font style="color:#6a9955;">/// @notice Two-sided order book storage.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        GoldChain.Chain offers;
        GoldChain.Chain bids;
    }

    <font style="color:#6a9955;">//#################</font>
    <font style="color:#6a9955;">//##  Write I/O  ##</font>
    <font style="color:#6a9955;">//#################</font>

    <font style="color:#6a9955;">// ==== Codify & Parse ====</font>

    <font style="color:#6a9955;">/// @notice Parse brief from packed bytes32.</font>
    <font style="color:#6a9955;">/// @param sn Packed brief.</font>
    <font style="color:#569cd6;">function</font> parseBrief(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(
        Brief <font style="color:#569cd6;">memory</font> brief
    ) {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        brief.classOfShare = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">240</font>);
        brief.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">208</font>);
        brief.buyer = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">168</font>);
        brief.seller = <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">128</font>);
        brief.paid = <font style="color:#4ec9b0;">uint64</font>(_sn >> <font style="color:#b5cea8;">64</font>);
        brief.price = <font style="color:#4ec9b0;">uint32</font>(_sn >> <font style="color:#b5cea8;">32</font>);
        brief.votingWeight = <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">16</font>);
        brief.distrWeight = <font style="color:#4ec9b0;">uint16</font>(_sn);
    }

    <font style="color:#6a9955;">/// @notice Pack deal fields into brief.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#569cd6;">function</font> codifyBrief(
        Deal <font style="color:#569cd6;">memory</font> deal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bytes32</font> sn) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _sn =
            abi.encodePacked(
                deal.classOfShare,
                deal.seqOfShare,
                deal.buyer,
                deal.seller,
                deal.paid,
                deal.price,
                deal.votingWeight,
                deal.distrWeight
            );

        <font style="color:#569cd6;">assembly</font> {
            sn := mload(add(_sn, 0x20))
        }
    }

    <font style="color:#6a9955;">/// @notice Parse a deal from packed segments.</font>
    <font style="color:#6a9955;">/// @param fromSn Packed from-part.</font>
    <font style="color:#6a9955;">/// @param toSn Packed to-part.</font>
    <font style="color:#6a9955;">/// @param qtySn Packed qty-part.</font>
    <font style="color:#569cd6;">function</font> parseDeal(
        <font style="color:#4ec9b0;">bytes32</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(
        Deal <font style="color:#569cd6;">memory</font> deal
    ) {
        <font style="color:#4ec9b0;">uint</font> _fromSn = <font style="color:#4ec9b0;">uint</font>(fromSn);

        deal.<font style="color:#569cd6;">from</font> = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(_fromSn >> <font style="color:#b5cea8;">96</font>));
        deal.buyer = <font style="color:#4ec9b0;">uint40</font>(_fromSn >> <font style="color:#b5cea8;">56</font>);
        deal.groupRep = <font style="color:#4ec9b0;">uint40</font>(_fromSn >> <font style="color:#b5cea8;">16</font>);
        deal.classOfShare = <font style="color:#4ec9b0;">uint16</font>(_fromSn);

        <font style="color:#4ec9b0;">uint</font> _toSn = <font style="color:#4ec9b0;">uint</font>(toSn);

        deal.to = <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(_toSn >> <font style="color:#b5cea8;">96</font>));
        deal.seller = <font style="color:#4ec9b0;">uint40</font>(_toSn >> <font style="color:#b5cea8;">56</font>);
        deal.seqOfShare = <font style="color:#4ec9b0;">uint32</font>(_toSn >> <font style="color:#b5cea8;">24</font>);
        deal.state = <font style="color:#4ec9b0;">uint8</font>(_toSn >> <font style="color:#b5cea8;">16</font>);
        deal.inEth = <font style="color:#4ec9b0;">uint8</font>(_toSn >> <font style="color:#b5cea8;">8</font>) == <font style="color:#b5cea8;">1</font>;
        deal.isOffer = <font style="color:#4ec9b0;">uint8</font>(_toSn) == <font style="color:#b5cea8;">1</font>;

        <font style="color:#4ec9b0;">uint</font> _qtySn = <font style="color:#4ec9b0;">uint</font>(qtySn);

        deal.paid = <font style="color:#4ec9b0;">uint64</font>(_qtySn >> <font style="color:#b5cea8;">192</font>);
        deal.price = <font style="color:#4ec9b0;">uint32</font>(_qtySn >> <font style="color:#b5cea8;">160</font>);
        deal.votingWeight = <font style="color:#4ec9b0;">uint16</font>(_qtySn >> <font style="color:#b5cea8;">144</font>);
        deal.distrWeight = <font style="color:#4ec9b0;">uint16</font>(_qtySn >> <font style="color:#b5cea8;">128</font>);
        deal.consideration = <font style="color:#4ec9b0;">uint128</font>(_qtySn);
    }

    <font style="color:#6a9955;">/// @notice Pack a deal into 3 words.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#569cd6;">function</font> codifyDeal(Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(
        <font style="color:#4ec9b0;">bytes32</font> fromSn, <font style="color:#4ec9b0;">bytes32</font> toSn, <font style="color:#4ec9b0;">bytes32</font> qtySn
    ) {
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _fromSn =
            abi.encodePacked(
                deal.<font style="color:#569cd6;">from</font>,
                deal.buyer,
                deal.groupRep,
                deal.classOfShare
            );

        <font style="color:#569cd6;">assembly</font> {
            fromSn := mload(add(_fromSn, 0x20))
        }

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _toSn =
            abi.encodePacked(
                deal.to,
                deal.seller,
                deal.seqOfShare,
                deal.state,
                deal.inEth,
                deal.isOffer
            );

        <font style="color:#569cd6;">assembly</font> {
            toSn := mload(add(_toSn, 0x20))
        }

        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _qtySn =
            abi.encodePacked(
                deal.paid,
                deal.price,
                deal.votingWeight,
                deal.distrWeight,
                deal.consideration
            );

        <font style="color:#569cd6;">assembly</font> {
            qtySn := mload(add(_qtySn, 0x20))
        }
    }

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#6a9955;">/// @notice Convert deal to GoldChain order data.</font>
    <font style="color:#6a9955;">/// @param deal Deal data.</font>
    <font style="color:#569cd6;">function</font> dealToData(Deal <font style="color:#569cd6;">memory</font> deal) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (GoldChain.Data <font style="color:#569cd6;">memory</font> data) {
        <font style="color:#569cd6;">return</font> GoldChain.Data({
            classOfShare : deal.classOfShare,
            seqOfShare : deal.seqOfShare,
            groupRep: deal.groupRep,
            votingWeight : deal.votingWeight,
            distrWeight : deal.distrWeight,
            margin: deal.consideration,
            inEth : deal.inEth,
            pubKey : deal.isOffer ? deal.to : deal.<font style="color:#569cd6;">from</font>,
            date: <font style="color:#b5cea8;">0</font>,
            issueDate : <font style="color:#4ec9b0;">uint48</font>(block.timestamp)
        });
    }

    <font style="color:#6a9955;">/// @notice Match and/or place a sell offer.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param input Offer data.</font>
    <font style="color:#6a9955;">/// @param execHours Expiration in hours.</font>
    <font style="color:#569cd6;">function</font> placeSellOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (
        Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        Deal <font style="color:#569cd6;">memory</font> offer
    ) {

        offer = input;

        GoldChain.Chain <font style="color:#569cd6;">storage</font> bids = repo.bids;
        <font style="color:#4ec9b0;">uint</font> len = bids.length();

        deals = <font style="color:#569cd6;">new</font> Deal[](len);
        expired = <font style="color:#569cd6;">new</font> GoldChain.Order[](len);

        <font style="color:#569cd6;">if</font> (offer.price > <font style="color:#b5cea8;">0</font>) {
            (lenOfDeals, lenOfExpired) = _matchOfferToBid(bids, offer, deals, expired);
        } <font style="color:#569cd6;">else</font> {
            (lenOfDeals, lenOfExpired) = _matchMarketToBid(bids, offer, deals, expired);
        }

        <font style="color:#569cd6;">if</font> (offer.paid > <font style="color:#b5cea8;">0</font> && offer.price > <font style="color:#b5cea8;">0</font>) {

            GoldChain.Data <font style="color:#569cd6;">memory</font> data = dealToData(offer);

            repo.offers.createNode(
                offer.seller,
                offer.paid,
                offer.price,
                execHours,
                <font style="color:#569cd6;">true</font>,
                data
            );
        }
    }

    <font style="color:#6a9955;">/// @notice Match and/or place a buy bid.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param input Bid data.</font>
    <font style="color:#6a9955;">/// @param execHours Expiration in hours.</font>
    <font style="color:#569cd6;">function</font> placeBuyOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        Deal <font style="color:#569cd6;">memory</font> input,
        <font style="color:#4ec9b0;">uint</font> execHours
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (
        Deal[] <font style="color:#569cd6;">memory</font> deals,
        <font style="color:#4ec9b0;">uint</font> lenOfDeals,
        GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired,
        <font style="color:#4ec9b0;">uint</font> lenOfExpired,
        Deal <font style="color:#569cd6;">memory</font> bid
    ) {

        bid = input;

        GoldChain.Chain <font style="color:#569cd6;">storage</font> offers = repo.offers;
        <font style="color:#4ec9b0;">uint</font> len = offers.length();

        deals = <font style="color:#569cd6;">new</font> Deal[](len);
        expired = <font style="color:#569cd6;">new</font> GoldChain.Order[](len);

        <font style="color:#569cd6;">if</font> (bid.price > <font style="color:#b5cea8;">0</font>) {
            (lenOfDeals, lenOfExpired) = _matchBidToOffer(offers, bid, deals, expired);
        } <font style="color:#569cd6;">else</font> {
            (lenOfDeals, lenOfExpired) = _matchMarketToOffer(offers, bid, deals, expired);
        }

        <font style="color:#569cd6;">if</font> (bid.paid > <font style="color:#b5cea8;">0</font> && bid.price > <font style="color:#b5cea8;">0</font>) {

            GoldChain.Data <font style="color:#569cd6;">memory</font> data = dealToData(bid);

            repo.bids.createNode(
                bid.buyer,
                bid.paid,
                bid.price,
                execHours,
                <font style="color:#569cd6;">false</font>,
                data
            );
        }

    }

    <font style="color:#6a9955;">/// @notice Withdraw an order by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> withdrawOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order <font style="color:#569cd6;">memory</font> removed)
    {
        removed = isOffer
            ? repo.offers.offChain(seqOfOrder)
            : repo.bids.offChain(seqOfOrder);
    }

    <font style="color:#569cd6;">function</font> _matchOfferToBid(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> bids, Deal <font style="color:#569cd6;">memory</font> offer, Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = bids.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && offer.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(bids, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = bids.orders[seqOfNode];

            <font style="color:#569cd6;">if</font> (n.node.price >= offer.price) {

                Deal <font style="color:#569cd6;">memory</font> deal = _createDeal(offer, offer.price, n.node.paid);

                n.data.margin -= deal.consideration;
                n.node.paid -= deal.paid;
                offer.paid -= deal.paid;

                _fillInOfferDeal(deal, offer, n);

                <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                    GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = bids.offChain(seqOfNode);
                    seqOfNode = delistedOrder.node.next;
                    expired[lenOfExpired] = delistedOrder;
                    lenOfExpired++;
                }

                deals[lenOfDeals] = deal;
                lenOfDeals++;

            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
        }
    }

    <font style="color:#569cd6;">function</font> _matchBidToOffer(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> offers, Deal <font style="color:#569cd6;">memory</font> bid, Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = offers.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && bid.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(offers, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = offers.orders[seqOfNode];

            <font style="color:#569cd6;">if</font> (n.node.price <= bid.price) {

                Deal <font style="color:#569cd6;">memory</font> deal =
                    _createDeal(bid, n.node.price, n.node.paid);

                n.node.paid -= deal.paid;
                bid.consideration -= deal.consideration;
                bid.paid -= deal.paid;

                _fillInBidDeal(deal, bid, n);

                <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                    GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = offers.offChain(seqOfNode);
                    seqOfNode = delistedOrder.node.next;
                }

                deals[lenOfDeals] = deal;
                lenOfDeals++;

            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
        }
    }

    <font style="color:#569cd6;">function</font> _matchMarketToBid(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> bids, Deal <font style="color:#569cd6;">memory</font> offer, Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = bids.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && offer.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(bids, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = bids.orders[seqOfNode];

            Deal <font style="color:#569cd6;">memory</font> deal = _createDeal(offer, n.node.price, n.node.paid);

            n.data.margin -= deal.consideration;
            n.node.paid -= deal.paid;
            offer.paid -= deal.paid;

            _fillInOfferDeal(deal, offer, n);

            <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = bids.offChain(seqOfNode);
                seqOfNode = delistedOrder.node.next;
            }

            deals[lenOfDeals] = deal;
            lenOfDeals++;
        }
    }

    <font style="color:#569cd6;">function</font> _matchMarketToOffer(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> offers, Deal <font style="color:#569cd6;">memory</font> bid, Deal[] <font style="color:#569cd6;">memory</font> deals, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> lenOfDeals, <font style="color:#4ec9b0;">uint</font> lenOfExpired){

        <font style="color:#4ec9b0;">uint32</font> seqOfNode = offers.head();

        <font style="color:#569cd6;">while</font>(seqOfNode > <font style="color:#b5cea8;">0</font> && bid.paid > <font style="color:#b5cea8;">0</font>) {

            (seqOfNode, lenOfExpired) = _checkExpired(offers, seqOfNode, expired, lenOfExpired);
            <font style="color:#569cd6;">if</font> (seqOfNode == <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">break</font>;

            GoldChain.Order <font style="color:#569cd6;">storage</font> n = offers.orders[seqOfNode];

            Deal <font style="color:#569cd6;">memory</font> deal = _createDeal(bid, n.node.price, n.node.paid);

            <font style="color:#569cd6;">if</font> (deal.consideration >= bid.consideration) {
                deal.consideration = bid.consideration;
                deal.paid = <font style="color:#4ec9b0;">uint64</font>(<font style="color:#4ec9b0;">uint</font>(deal.consideration) / deal.price);

                bid.paid = deal.paid;

                <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                    deal.state = <font style="color:#b5cea8;">0</font>;
                }
            }

            n.node.paid -= deal.paid;
            bid.consideration -= deal.consideration;
            bid.paid -= deal.paid;

            _fillInBidDeal(deal, bid, n);

            <font style="color:#569cd6;">if</font> (deal.state == <font style="color:#b5cea8;">1</font>) {
                GoldChain.Order <font style="color:#569cd6;">memory</font> delistedOrder = offers.offChain(seqOfNode);
                seqOfNode = delistedOrder.node.next;
            }

            deals[lenOfDeals] = deal;
            lenOfDeals++;
        }
    }

    <font style="color:#569cd6;">function</font> _checkExpired(
        GoldChain.Chain <font style="color:#569cd6;">storage</font> chain, <font style="color:#4ec9b0;">uint32</font> seqOfNode, GoldChain.Order[] <font style="color:#569cd6;">memory</font> expired, <font style="color:#4ec9b0;">uint</font> lenOfExpired
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint32</font>, <font style="color:#4ec9b0;">uint</font>) {

        <font style="color:#569cd6;">while</font> (seqOfNode > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (chain.orders[seqOfNode].node.expireDate <= block.timestamp) {
                GoldChain.Order <font style="color:#569cd6;">memory</font> removedNode = chain.offChain(seqOfNode);
                expired[lenOfExpired] = (removedNode);
                lenOfExpired++;
                seqOfNode = removedNode.node.next;
            } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">break</font>;
        }

        <font style="color:#569cd6;">return</font> (seqOfNode, lenOfExpired);
    }

    <font style="color:#569cd6;">function</font> _createDeal(
        Deal <font style="color:#569cd6;">memory</font> order, <font style="color:#4ec9b0;">uint</font> offerPrice, <font style="color:#4ec9b0;">uint</font> nodePaid
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Deal <font style="color:#569cd6;">memory</font> deal) {
        deal.price = <font style="color:#4ec9b0;">uint32</font>(offerPrice);

        <font style="color:#569cd6;">if</font> (order.paid >= nodePaid) {
            deal.paid = <font style="color:#4ec9b0;">uint64</font>(nodePaid);
            deal.state = <font style="color:#b5cea8;">1</font>;
        } <font style="color:#569cd6;">else</font> {
            deal.paid = order.paid;
        }

        deal.consideration = deal.paid * deal.price;
    }

    <font style="color:#569cd6;">function</font> _fillInBidDeal(
        Deal <font style="color:#569cd6;">memory</font> deal, Deal <font style="color:#569cd6;">memory</font> bid, GoldChain.Order <font style="color:#569cd6;">memory</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> {
        deal.<font style="color:#569cd6;">from</font> = bid.<font style="color:#569cd6;">from</font>;
        deal.to = n.data.pubKey;
        deal.seller = n.node.issuer;

        deal.classOfShare = n.data.classOfShare;
        deal.seqOfShare = n.data.seqOfShare;
        deal.buyer = bid.buyer;
        deal.groupRep = bid.groupRep;
        deal.votingWeight = n.data.votingWeight;
        deal.distrWeight = n.data.distrWeight;
    }

    <font style="color:#569cd6;">function</font> _fillInOfferDeal(
        Deal <font style="color:#569cd6;">memory</font> deal, Deal <font style="color:#569cd6;">memory</font> offer, GoldChain.Order <font style="color:#569cd6;">memory</font> n
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> {
        deal.<font style="color:#569cd6;">from</font> = n.data.pubKey;
        deal.to = offer.to;
        deal.seller = offer.seller;

        deal.classOfShare = offer.classOfShare;
        deal.seqOfShare = offer.seqOfShare;
        deal.buyer = n.node.issuer;
        deal.groupRep = n.data.groupRep;
        deal.votingWeight = offer.votingWeight;
        deal.distrWeight = offer.distrWeight;
    }

    <font style="color:#6a9955;">//################</font>
    <font style="color:#6a9955;">//##  Read I/O  ##</font>
    <font style="color:#6a9955;">//################</font>

    <font style="color:#6a9955;">/// @notice Get order counter.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> counterOfOrders(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.counter()
            : repo.bids.counter();
    }

    <font style="color:#6a9955;">/// @notice Get head node id.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> headOfList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.head()
            : repo.bids.head();
    }

    <font style="color:#6a9955;">/// @notice Get tail node id.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> tailOfList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.tail()
            : repo.bids.tail();
    }

    <font style="color:#6a9955;">/// @notice Get list length.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> lengthOfList(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint32</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.length()
            : repo.bids.length();
    }

    <font style="color:#6a9955;">// ==== Order ====</font>

    <font style="color:#6a9955;">/// @notice Check whether an order exists.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number.</font>
    <font style="color:#569cd6;">function</font> isOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> isOffer
            ? repo.offers.isNode(seqOfOrder)
            : repo.bids.isNode(seqOfOrder);
    }

    <font style="color:#6a9955;">/// @notice Get order by sequence.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#6a9955;">/// @param seqOfOrder Order sequence number.</font>
    <font style="color:#569cd6;">function</font> getOrder(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer,
        <font style="color:#4ec9b0;">uint</font> seqOfOrder
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order <font style="color:#569cd6;">memory</font> order) {
        order = isOffer
            ? repo.offers.getOrder(seqOfOrder)
            : repo.bids.getOrder(seqOfOrder);
    }

    <font style="color:#6a9955;">/// @notice Get order sequence list.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> getSeqList(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> orders) {
        orders = isOffer
            ? repo.offers.getSeqList()
            : repo.bids.getSeqList();
    }

    <font style="color:#6a9955;">/// @notice Get full order chain.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param isOffer True for offer book, false for bid book.</font>
    <font style="color:#569cd6;">function</font> getOrders(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bool</font> isOffer
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (GoldChain.Order[] <font style="color:#569cd6;">memory</font> orders) {
        orders = isOffer
            ? repo.offers.getChain()
            : repo.bids.getChain();
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## UsersRepo.sol

---

| |
|:---|
| **contracts/lib/books/UsersRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title UsersRepo</font>
<font style="color:#6a9955;">/// @notice User registry and platform rules repository for ownership, keeper, and user key management.</font>
<font style="color:#6a9955;">/// @dev Stores user metadata keyed by userNo and maps addresses to userNo. Provides</font>
<font style="color:#6a9955;">///      registration, rule configuration, and coupon accounting helpers.</font>

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../openzeppelin/utils/structs/EnumerableSet.sol"</font>;

<font style="color:#569cd6;">library</font> UsersRepo {
    <font style="color:#569cd6;">using</font> EnumerableSet <font style="color:#569cd6;">for</font> EnumerableSet.UintSet;

    <font style="color:#6a9955;">/// @notice User key metadata.</font>
    <font style="color:#6a9955;">/// @dev `discount/gift/coupon` are short fixed-width counters/values used in pricing rules.</font>
    <font style="color:#569cd6;">struct</font> Key {
        <font style="color:#4ec9b0;">address</font> pubKey;
        <font style="color:#4ec9b0;">uint16</font> discount;
        <font style="color:#4ec9b0;">uint40</font> gift;
        <font style="color:#4ec9b0;">uint40</font> coupon;
    }

    <font style="color:#6a9955;">/// @notice User record with prime and backup keys.</font>
    <font style="color:#569cd6;">struct</font> User {
        Key primeKey;
        Key backupKey;
    }

    <font style="color:#6a9955;">/// @notice Platform rule configuration.</font>
    <font style="color:#6a9955;">/// @dev Values are decoded from a packed bytes32 rule descriptor.</font>
    <font style="color:#569cd6;">struct</font> Rule {
        <font style="color:#4ec9b0;">uint40</font> eoaRewards;
        <font style="color:#4ec9b0;">uint40</font> coaRewards;
        <font style="color:#4ec9b0;">uint40</font> floor;
        <font style="color:#4ec9b0;">uint16</font> rate;
        <font style="color:#4ec9b0;">uint16</font> para;
    }

    <font style="color:#6a9955;">/// @notice Repository storage container.</font>
    <font style="color:#6a9955;">/// @dev `users[0]` is reserved for platform config and admin keys.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// userNo => User</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint256</font> => User) users;
        <font style="color:#6a9955;">// key => userNo</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint</font>) userNo;
        <font style="color:#6a9955;">// userNo set        </font>
        EnumerableSet.UintSet usersList;
    }

    <font style="color:#6a9955;">// platformRule: Rule({</font>
    <font style="color:#6a9955;">//     eoaRewards: users[0].primeKey.gift,</font>
    <font style="color:#6a9955;">//     coaRewards: users[0].backupKey.gift,</font>
    <font style="color:#6a9955;">//     floor: users[0].backupKey.coupon,</font>
    <font style="color:#6a9955;">//     rate: users[0].primeKey.discount,</font>
    <font style="color:#6a9955;">//     para: users[0].backupKey.discount</font>
    <font style="color:#6a9955;">// });</font>

    <font style="color:#6a9955;">// counterOfUers: users[0].primeKey.coupon;</font>

    <font style="color:#6a9955;">// owner: users[0].primeKey.pubKey;</font>
    <font style="color:#6a9955;">// bookeeper: users[0].backupKey.pubKey;</font>

    <font style="color:#6a9955;">// ########################</font>
    <font style="color:#6a9955;">// ##  Error & Modifer   ##</font>
    <font style="color:#6a9955;">// ########################</font>

    <font style="color:#569cd6;">error</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> USRR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> USRR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> USRR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">/// @notice Restrict to platform owner (users[0].primeKey.pubKey).</font>
    <font style="color:#569cd6;">modifier</font> onlyOwner(Repo <font style="color:#569cd6;">storage</font> repo) {
        <font style="color:#569cd6;">if</font> (msg.sender != repo.users[<font style="color:#b5cea8;">0</font>].primeKey.pubKey)
            <font style="color:#569cd6;">revert</font> USRR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UR_NotOwner"</font>));
        _;
    }

    <font style="color:#6a9955;">/// @notice Restrict to platform keeper (users[0].backupKey.pubKey).</font>
    <font style="color:#569cd6;">modifier</font> onlyKeeper(Repo <font style="color:#569cd6;">storage</font> repo) {
        <font style="color:#569cd6;">if</font> (msg.sender != repo.users[<font style="color:#b5cea8;">0</font>].backupKey.pubKey)
            <font style="color:#569cd6;">revert</font> USRR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UR_NotKeeper"</font>));
        _;
    }

    <font style="color:#6a9955;">// ########################</font>
    <font style="color:#6a9955;">// ##  Config Setting    ##</font>
    <font style="color:#6a9955;">// ########################</font>

    <font style="color:#6a9955;">// ==== Platform  ====</font>

    <font style="color:#6a9955;">/// @notice Parse a packed platform rule into a {Rule} struct.</font>
    <font style="color:#6a9955;">/// @param sn Packed rule bytes.</font>
    <font style="color:#6a9955;">/// @return rule Decoded rule.</font>
    <font style="color:#569cd6;">function</font> ruleParser(<font style="color:#4ec9b0;">bytes32</font> sn) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font>
        <font style="color:#569cd6;">returns</font>(Rule <font style="color:#569cd6;">memory</font> rule)
    {
        <font style="color:#4ec9b0;">uint</font> _sn = <font style="color:#4ec9b0;">uint</font>(sn);

        rule = Rule({
            eoaRewards: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">216</font>),
            coaRewards: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">176</font>),
            floor: <font style="color:#4ec9b0;">uint40</font>(_sn >> <font style="color:#b5cea8;">136</font>),
            rate: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">120</font>),
            para: <font style="color:#4ec9b0;">uint16</font>(_sn >> <font style="color:#b5cea8;">96</font>)
        });
    }

    <font style="color:#6a9955;">/// @notice Update platform owner address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param newOwner New owner address (non-zero).</font>
    <font style="color:#569cd6;">function</font> transferOwnership(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> newOwner) <font style="color:#569cd6;">public</font> onlyOwner(repo) {
        <font style="color:#569cd6;">if</font> (newOwner == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UR_TO: zero address"</font>));
        repo.users[<font style="color:#b5cea8;">0</font>].primeKey.pubKey = newOwner;
    }

    <font style="color:#6a9955;">/// @notice Update platform keeper address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param newKeeper New keeper address (non-zero).</font>
    <font style="color:#569cd6;">function</font> handoverCenterKey(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> newKeeper) <font style="color:#569cd6;">public</font> onlyKeeper(repo) {
        <font style="color:#569cd6;">if</font> (newKeeper == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"UR_HCK: zero address"</font>));
        repo.users[<font style="color:#b5cea8;">0</font>].backupKey.pubKey = newKeeper;
    }

    <font style="color:#6a9955;">// ==== Coupon ====</font>

    <font style="color:#6a9955;">/// @notice Parse a packed royalty rule into a {Key} struct.</font>
    <font style="color:#6a9955;">/// @param info Packed rule bytes.</font>
    <font style="color:#6a9955;">/// @return out Decoded key values (pubKey zeroed).</font>
    <font style="color:#569cd6;">function</font> infoParser(<font style="color:#4ec9b0;">bytes32</font> info) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(Key <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint</font> _info = <font style="color:#4ec9b0;">uint</font>(info);

        Key <font style="color:#569cd6;">memory</font> out = Key({
            pubKey: <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>),
            discount: <font style="color:#4ec9b0;">uint16</font>(_info >> <font style="color:#b5cea8;">80</font>),
            gift: <font style="color:#4ec9b0;">uint40</font>(_info >> <font style="color:#b5cea8;">40</font>),
            coupon: <font style="color:#4ec9b0;">uint40</font>(_info)
        });

        <font style="color:#569cd6;">return</font> out;
    }

    <font style="color:#6a9955;">/// @notice Set platform rule values.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param snOfRule Packed rule bytes.</font>
    <font style="color:#569cd6;">function</font> setPlatformRule(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> snOfRule) <font style="color:#569cd6;">public</font> onlyOwner(repo) {

        Rule <font style="color:#569cd6;">memory</font> rule = ruleParser(snOfRule);

        User <font style="color:#569cd6;">storage</font> opt = repo.users[<font style="color:#b5cea8;">0</font>];

        opt.primeKey.discount = rule.rate;
        opt.primeKey.gift = rule.eoaRewards;

        opt.backupKey.discount = rule.para;
        opt.backupKey.gift = rule.coaRewards;
        opt.backupKey.coupon = rule.floor;
    }

    <font style="color:#6a9955;">/// @notice Set per-author royalty rule for msgSender.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param snOfRoyalty Packed rule bytes.</font>
    <font style="color:#6a9955;">/// @param msgSender Author address (must be registered).</font>
    <font style="color:#569cd6;">function</font> setRoyaltyRule(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> snOfRoyalty,
        <font style="color:#4ec9b0;">address</font> msgSender
    ) <font style="color:#569cd6;">public</font> {

        Key <font style="color:#569cd6;">memory</font> rule = infoParser(snOfRoyalty);

        <font style="color:#4ec9b0;">uint</font> author = getUserNo(repo, msgSender);
        User <font style="color:#569cd6;">storage</font> a = repo.users[author];

        a.backupKey.discount = rule.discount;
        a.backupKey.gift = rule.gift;
        a.backupKey.coupon = rule.coupon;

    }

    <font style="color:#6a9955;">/// @notice Increment coupon counter for a user once, wrapping to 1 on overflow.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param targetAddr User address (must be registered).</font>
    <font style="color:#569cd6;">function</font> addCouponOnce(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> targetAddr) <font style="color:#569cd6;">public</font> {
        User <font style="color:#569cd6;">storage</font> user = repo.users[getUserNo(repo, targetAddr)];
        <font style="color:#569cd6;">unchecked</font> {
            user.primeKey.coupon =
                (user.primeKey.coupon == type(<font style="color:#4ec9b0;">uint40</font>).max)
                    ? <font style="color:#b5cea8;">1</font>
                    : user.primeKey.coupon + <font style="color:#b5cea8;">1</font>;
        }
    }

    <font style="color:#6a9955;">// ==== Reg User ====</font>

    <font style="color:#6a9955;">/// @notice Register a new user and assign a unique userNo.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param msgSender User address (non-zero, not used).</font>
    <font style="color:#6a9955;">/// @return user Newly created user record.</font>
    <font style="color:#569cd6;">function</font> regUser(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> msgSender
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (User <font style="color:#569cd6;">memory</font> ) {
        <font style="color:#569cd6;">if</font> (msgSender == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"USRR_ZeroAddress"</font>));
        <font style="color:#569cd6;">if</font> (usedKey(repo, msgSender))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"USRR_UsedKey"</font>));
        <font style="color:#4ec9b0;">uint</font> userNo = block.timestamp;
        <font style="color:#569cd6;">do</font> {
            userNo = <font style="color:#4ec9b0;">uint40</font>(<font style="color:#4ec9b0;">uint</font>(keccak256(abi.encodePacked(
                userNo, msgSender
            ))));
        } <font style="color:#569cd6;">while</font> (userNo == <font style="color:#b5cea8;">0</font> || !repo.usersList.add(userNo));

        repo.userNo[msgSender] = userNo;

        User <font style="color:#569cd6;">memory</font> user;

        user.primeKey.pubKey = msgSender;

        Rule <font style="color:#569cd6;">memory</font> rule = getPlatformRule(repo);

        <font style="color:#569cd6;">if</font> (_isContract(msgSender)) {
            user.primeKey.discount = <font style="color:#b5cea8;">1</font>;
            user.primeKey.gift = rule.coaRewards;
        } <font style="color:#569cd6;">else</font> user.primeKey.gift = rule.eoaRewards;

        repo.users[userNo] = user;

        <font style="color:#569cd6;">return</font> user;
    }

    <font style="color:#6a9955;">/// @notice Check whether an address is a contract.</font>
    <font style="color:#6a9955;">/// @param acct Address to check.</font>
    <font style="color:#6a9955;">/// @return True if code size > 0.</font>
    <font style="color:#569cd6;">function</font> _isContract(<font style="color:#4ec9b0;">address</font> acct) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint32</font> size;
        <font style="color:#569cd6;">assembly</font> {
            size := extcodesize(acct)
        }
        <font style="color:#569cd6;">return</font> size != <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Set a backup key for a user.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param bKey Backup key address (non-zero, unused).</font>
    <font style="color:#6a9955;">/// @param msgSender User address (must be registered).</font>
    <font style="color:#569cd6;">function</font> setBackupKey(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> bKey,
        <font style="color:#4ec9b0;">address</font> msgSender
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (msgSender == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URSBK_ZeroCallerAddress"</font>));
        <font style="color:#569cd6;">if</font> (bKey == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URSBK_ZeroBKeyAddress"</font>));
        <font style="color:#569cd6;">if</font> (usedKey(repo, bKey))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URSBK_UsedKey"</font>));

        <font style="color:#4ec9b0;">uint</font> caller = getUserNo(repo, msgSender);

        User <font style="color:#569cd6;">storage</font> user = repo.users[caller];

        <font style="color:#569cd6;">if</font> (user.backupKey.pubKey != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URSBK_AlreadySetBackupKey"</font>));

        user.backupKey.pubKey = bKey;

        repo.userNo[bKey] = caller;
    }

    <font style="color:#6a9955;">/// @notice Swap backup key to become prime key for a user.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param msgSender User address (must be registered, backup key set).</font>
    <font style="color:#569cd6;">function</font> upgradeBackupToPrime(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">address</font> msgSender
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">if</font> (!usedKey(repo, msgSender))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URUBP_CallerNotRegistered"</font>));

        User <font style="color:#569cd6;">storage</font> user = repo.users[getUserNo(repo, msgSender)];

        <font style="color:#569cd6;">if</font> (user.backupKey.pubKey == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>))
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URUBP_ZeroBackupKey"</font>));

        (user.primeKey.pubKey, user.backupKey.pubKey) =
            (user.backupKey.pubKey, user.primeKey.pubKey);
    }

    <font style="color:#6a9955;">// ##############</font>
    <font style="color:#6a9955;">// ## Read I/O ##</font>
    <font style="color:#6a9955;">// ##############</font>

    <font style="color:#6a9955;">// ==== Config ====</font>

    <font style="color:#6a9955;">/// @notice Get platform owner address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Owner address.</font>
    <font style="color:#569cd6;">function</font> getOwner(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> repo.users[<font style="color:#b5cea8;">0</font>].primeKey.pubKey;
    }

    <font style="color:#6a9955;">/// @notice Get platform keeper address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Keeper address.</font>
    <font style="color:#569cd6;">function</font> getBookeeper(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> repo.users[<font style="color:#b5cea8;">0</font>].backupKey.pubKey;
    }

    <font style="color:#6a9955;">/// @notice Get current platform rule values.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return rule Current rule.</font>
    <font style="color:#569cd6;">function</font> getPlatformRule(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font>
        <font style="color:#569cd6;">returns</font> (Rule <font style="color:#569cd6;">memory</font> rule)
    {
        User <font style="color:#569cd6;">storage</font> opt = repo.users[<font style="color:#b5cea8;">0</font>];

        rule = Rule({
            eoaRewards: opt.primeKey.gift,
            coaRewards: opt.backupKey.gift,
            floor: opt.backupKey.coupon,
            rate: opt.primeKey.discount,
            para: opt.backupKey.discount
        });
    }

    <font style="color:#6a9955;">// ==== User & No ====</font>

    <font style="color:#6a9955;">/// @notice Check whether a userNo exists.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param acct User number.</font>
    <font style="color:#6a9955;">/// @return True if exists.</font>
    <font style="color:#569cd6;">function</font> isUserNo(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> acct) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.usersList.contains(acct);
    }

    <font style="color:#6a9955;">/// @notice Resolve userNo by address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param targetAddr User address.</font>
    <font style="color:#6a9955;">/// @return userNo Registered user number.</font>
    <font style="color:#569cd6;">function</font> getUserNo(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> targetAddr)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font>)
    {
        <font style="color:#4ec9b0;">uint40</font> user = <font style="color:#4ec9b0;">uint40</font>(repo.userNo[targetAddr]);

        <font style="color:#569cd6;">if</font> (user > <font style="color:#b5cea8;">0</font>) <font style="color:#569cd6;">return</font> user;
        <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font> (<font style="color:#ce9178;">"UR.getUserNo: not registered"</font>);
    }

    <font style="color:#6a9955;">/// @notice Get total number of registered users.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Count of users.</font>
    <font style="color:#569cd6;">function</font> counterOfUsers(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>) {
        <font style="color:#569cd6;">return</font> repo.usersList.length();
    }

    <font style="color:#6a9955;">/// @notice Get list of all user numbers.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @return Array of user numbers.</font>
    <font style="color:#569cd6;">function</font> getUserNoList(Repo <font style="color:#569cd6;">storage</font> repo) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> repo.usersList.values();
    }

    <font style="color:#6a9955;">/// @notice Get user record by address.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param targetAddr User address.</font>
    <font style="color:#6a9955;">/// @return User record.</font>
    <font style="color:#569cd6;">function</font> getUser(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> targetAddr)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (User <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">return</font> repo.users[getUserNo(repo, targetAddr)];
    }

    <font style="color:#6a9955;">/// @notice Get royalty rule for an author.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param author Author userNo (must be > 0).</font>
    <font style="color:#6a9955;">/// @return rule Royalty rule with pubKey cleared.</font>
    <font style="color:#569cd6;">function</font> getRoyaltyRule(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> author)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (Key <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#569cd6;">if</font> (author == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> USRR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"URGR_ZeroAuthor"</font>));

        Key <font style="color:#569cd6;">memory</font> rule = repo.users[author].backupKey;
        <font style="color:#569cd6;">delete</font> rule.pubKey;

        <font style="color:#569cd6;">return</font> rule;
    }

    <font style="color:#6a9955;">// ==== Key ====</font>

    <font style="color:#6a9955;">/// @notice Check if an address is already registered as a key.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param key Address to check.</font>
    <font style="color:#6a9955;">/// @return True if used.</font>
    <font style="color:#569cd6;">function</font> usedKey(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> key) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.userNo[key] > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/// @notice Check if an address is a user's prime key.</font>
    <font style="color:#6a9955;">/// @param repo Repository storage.</font>
    <font style="color:#6a9955;">/// @param key Address to check.</font>
    <font style="color:#6a9955;">/// @return True if prime key.</font>
    <font style="color:#569cd6;">function</font> isPrimeKey(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">address</font> key) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font> (usedKey(repo, key)) {
            <font style="color:#569cd6;">return</font> key == repo.users[repo.userNo[key]].primeKey.pubKey;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## WaterfallsRepo.sol

---

| |
|:---|
| **contracts/lib/books/WaterfallsRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./RulesParser.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../comps/books/rom/IRegisterOfMembers.sol"</font>;

<font style="color:#6a9955;">/// @title WaterfallsRepo</font>
<font style="color:#6a9955;">/// @notice Waterfall distribution repository for funds and members.</font>
<font style="color:#569cd6;">library</font> WaterfallsRepo {

    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TWO_TO_40 = <font style="color:#b5cea8;">1</font> << <font style="color:#b5cea8;">40</font> - <font style="color:#b5cea8;">1</font>;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TWO_TO_16 = <font style="color:#b5cea8;">1</font> << <font style="color:#b5cea8;">16</font> - <font style="color:#b5cea8;">1</font>;
    <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">constant</font> TWO_TO_32 = <font style="color:#b5cea8;">1</font> << <font style="color:#b5cea8;">32</font> - <font style="color:#b5cea8;">1</font>;

    <font style="color:#6a9955;">/// @notice Distribution drop record.</font>
    <font style="color:#569cd6;">struct</font> Drop {
        <font style="color:#4ec9b0;">uint24</font> seqOfDistr;
        <font style="color:#4ec9b0;">uint40</font> member;
        <font style="color:#4ec9b0;">uint16</font> class;
        <font style="color:#4ec9b0;">uint48</font> distrDate;
        <font style="color:#4ec9b0;">uint64</font> principal;
        <font style="color:#4ec9b0;">uint64</font> income;
    }

    <font style="color:#6a9955;">/// @notice Flow of drops for shares.</font>
    <font style="color:#569cd6;">struct</font> Flow {
        <font style="color:#6a9955;">// seqOfShare => drop</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Drop) drops;
        <font style="color:#4ec9b0;">uint</font>[] shares;
    }

    <font style="color:#6a9955;">/// @notice Creek of flows per class.</font>
    <font style="color:#569cd6;">struct</font> Creek {
        <font style="color:#6a9955;">// class => Flow</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Flow) flows;
        <font style="color:#4ec9b0;">uint</font>[] classes;
    }

    <font style="color:#6a9955;">/// @notice Stream of creeks per member.</font>
    <font style="color:#569cd6;">struct</font> Stream {
        <font style="color:#6a9955;">// member => Creek</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Creek) creeks;
        <font style="color:#4ec9b0;">uint</font>[] members;
    }

    <font style="color:#6a9955;">/// @notice Repository of distribution streams.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#6a9955;">// seqOfDistr => Stream</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">uint</font> => Stream) streams;
    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##     Error      ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#569cd6;">error</font> WR_WrongInput(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> WR_WrongState(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> WR_Overflow(<font style="color:#4ec9b0;">bytes32</font> reason);
    <font style="color:#569cd6;">error</font> WR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##     Write      ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">/// @notice Initialize a class with principal.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param principal Principal amount.</font>
    <font style="color:#569cd6;">function</font> initClass(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> principal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>];

        <font style="color:#569cd6;">if</font> (info.distrDate != <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> WR_WrongState(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"WR_ClassAlreadyInitialized"</font>));

        <font style="color:#569cd6;">if</font> (principal == <font style="color:#b5cea8;">0</font>)
            <font style="color:#569cd6;">revert</font> WR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"WR_ZeroPrincipal"</font>));

        info.class = <font style="color:#4ec9b0;">uint16</font>(class);
        info.distrDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
        info.principal = <font style="color:#4ec9b0;">uint64</font>(principal);

        repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>] = info; <font style="color:#6a9955;">// seaInfo</font>
        repo.streams[<font style="color:#b5cea8;">0</font>].creeks[TWO_TO_40].flows[class].drops[<font style="color:#b5cea8;">0</font>] = info; <font style="color:#6a9955;">// initSeaInfo</font>
        repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">1</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>].distrDate = info.distrDate; <font style="color:#6a9955;">// gulfInfo</font>

        Creek <font style="color:#569cd6;">storage</font> counter = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>]; <font style="color:#6a9955;">// counterOfClasses</font>
        counter.classes.push(info.class);
    }

    <font style="color:#6a9955;">/// @notice Redeem principal for a class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param principal Principal amount.</font>
    <font style="color:#569cd6;">function</font> redeemClass(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> principal
    ) <font style="color:#569cd6;">public</font> {
        Drop <font style="color:#569cd6;">memory</font> info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>];

        <font style="color:#569cd6;">if</font> (info.distrDate > <font style="color:#b5cea8;">0</font>) {

            <font style="color:#569cd6;">if</font> (principal == <font style="color:#b5cea8;">0</font>)
                <font style="color:#569cd6;">revert</font> WR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"WR_ZeroPrincipal"</font>));

            <font style="color:#569cd6;">if</font> (info.principal <= principal)
                <font style="color:#569cd6;">revert</font> WR_WrongInput(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"WR_RedeemPrincipalExceeds"</font>));

            info.principal = <font style="color:#4ec9b0;">uint64</font>(principal);

            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>].principal -= info.principal; <font style="color:#6a9955;">// seaInfo</font>
            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[TWO_TO_40].flows[class].drops[<font style="color:#b5cea8;">0</font>].principal -= info.principal; <font style="color:#6a9955;">// initSeaInfo</font>
        }
    }

    <font style="color:#6a9955;">// ==== Distribution ====</font>

    <font style="color:#6a9955;">// ---- ProRata ----</font>

    <font style="color:#6a9955;">/// @notice Distribute pro-rata by member points or shares.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param _rom Register of members.</font>
    <font style="color:#6a9955;">/// @param _ros Register of shares.</font>
    <font style="color:#6a9955;">/// @param refundPrincipal True to refund principal.</font>
    <font style="color:#569cd6;">function</font> proRataDistr(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> amt, IRegisterOfMembers _rom,
        IRegisterOfShares _ros, <font style="color:#4ec9b0;">bool</font> refundPrincipal
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(
        Drop <font style="color:#569cd6;">memory</font> drop,
        Drop[] <font style="color:#569cd6;">memory</font> mList,
        Drop[] <font style="color:#569cd6;">memory</font> sList
    ){

        <font style="color:#4ec9b0;">uint</font> totalPoints = _rom.ownersPoints().points;
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members = _rom.membersList();

        drop = _createDrop(repo);

        drop.class = <font style="color:#4ec9b0;">uint16</font>(TWO_TO_16);
        drop.principal = <font style="color:#b5cea8;">0</font>;

        <font style="color:#569cd6;">if</font> (refundPrincipal) {
            _allocateAmongShares(repo, members, drop, _rom, _ros, amt, totalPoints);
            sList = getDropsOfStream(repo, drop.seqOfDistr);
        } <font style="color:#569cd6;">else</font> {
            _allocateAmongMembers(repo, members, drop, _rom, amt, totalPoints);
        }

        mList = getCreeksOfStream(repo, drop.seqOfDistr);
    }

    <font style="color:#569cd6;">function</font> _allocateAmongShares(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members, Drop <font style="color:#569cd6;">memory</font> drop,
        IRegisterOfMembers _rom, IRegisterOfShares _ros, <font style="color:#4ec9b0;">uint</font> amt,
        <font style="color:#4ec9b0;">uint</font> totalPoints
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">uint</font> len = members.length;
        <font style="color:#4ec9b0;">uint</font> sum = <font style="color:#b5cea8;">0</font>;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            drop.member = <font style="color:#4ec9b0;">uint40</font>(members[len-<font style="color:#b5cea8;">1</font>]);

            <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> seqs = _rom.sharesInHand(drop.member);
            <font style="color:#4ec9b0;">uint</font> qty = seqs.length;

            SharesRepo.Share <font style="color:#569cd6;">memory</font> share;

            <font style="color:#569cd6;">while</font>((len > <font style="color:#b5cea8;">1</font> && qty > <font style="color:#b5cea8;">0</font>) || (len == <font style="color:#b5cea8;">1</font> && qty > <font style="color:#b5cea8;">1</font>)) {
                share = _ros.getShare(seqs[qty-<font style="color:#b5cea8;">1</font>]);
                drop.class = share.head.class;
                drop.income =
                    <font style="color:#4ec9b0;">uint64</font>(amt * share.body.paid * share.body.distrWeight / <font style="color:#b5cea8;">100</font> / totalPoints);
                drop.principal = share.body.paid * <font style="color:#b5cea8;">100</font>;
                <font style="color:#569cd6;">if</font> (drop.income >= drop.principal) {
                    drop.income -= drop.principal;
                }<font style="color:#569cd6;">else</font> {
                    drop.principal = drop.income;
                    drop.income = <font style="color:#b5cea8;">0</font>;
                }
                _addDrop(repo, drop, seqs[qty-<font style="color:#b5cea8;">1</font>]);

                sum += drop.income + drop.principal;

                qty--;
            }

            <font style="color:#569cd6;">if</font> (len == <font style="color:#b5cea8;">1</font> && qty == <font style="color:#b5cea8;">1</font>) {
                share = _ros.getShare(seqs[<font style="color:#b5cea8;">0</font>]);
                drop.class = share.head.class;
                drop.income = <font style="color:#4ec9b0;">uint64</font>(amt - sum);
                drop.principal = share.body.paid * <font style="color:#b5cea8;">100</font>;
                <font style="color:#569cd6;">if</font> (drop.income >= drop.principal) {
                    drop.income -= drop.principal;
                }<font style="color:#569cd6;">else</font> {
                    drop.principal = drop.income;
                    drop.income = <font style="color:#b5cea8;">0</font>;
                }
                _addDrop(repo, drop, seqs[<font style="color:#b5cea8;">0</font>]);
            }

            len--;
        }

    }

    <font style="color:#569cd6;">function</font> _allocateAmongMembers(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> members, Drop <font style="color:#569cd6;">memory</font> drop,
        IRegisterOfMembers _rom, <font style="color:#4ec9b0;">uint</font> amt,<font style="color:#4ec9b0;">uint</font> totalPoints
    ) <font style="color:#569cd6;">private</font> {
        <font style="color:#4ec9b0;">uint</font> len = members.length;
        <font style="color:#4ec9b0;">uint</font> sum = <font style="color:#b5cea8;">0</font>;

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">1</font>) {
            drop.member = <font style="color:#4ec9b0;">uint40</font>(members[len-<font style="color:#b5cea8;">1</font>]);
            drop.income =
                <font style="color:#4ec9b0;">uint64</font>(amt * _rom.pointsOfMember(drop.member).points / totalPoints);

            sum += drop.income;

            _addDrop(repo, drop, TWO_TO_32);

            len--;
        }

        drop.member = <font style="color:#4ec9b0;">uint40</font>(members[<font style="color:#b5cea8;">0</font>]);
        drop.income = <font style="color:#4ec9b0;">uint64</font>(amt - sum);
        _addDrop(repo, drop, TWO_TO_32);
    }

    <font style="color:#6a9955;">// ---- IntFrontDistr ----</font>

    <font style="color:#6a9955;">/// @notice Distribute interest-first by tiers.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param _ros Register of shares.</font>
    <font style="color:#6a9955;">/// @param rule Distribution rule.</font>
    <font style="color:#569cd6;">function</font> intFrontDistr(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> amt, IRegisterOfShares _ros,
        RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(
        Drop <font style="color:#569cd6;">memory</font> drop,
        Drop[] <font style="color:#569cd6;">memory</font> mList,
        Drop[] <font style="color:#569cd6;">memory</font> sList
    ) {
        drop = _createDrop(repo);

        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">while</font> (amt > <font style="color:#b5cea8;">0</font> && i < rule.numOfTiers) {
            drop.class = rule.tiers[i];
            amt = _intFrontDistr(repo, rule, rule.rates[i], amt, _ros, drop);
            i++;
        }

        mList = getCreeksOfStream(repo, drop.seqOfDistr);
        sList = getDropsOfStream(repo, drop.seqOfDistr);
    }

    <font style="color:#569cd6;">function</font> _updateGulfInfo (
        Drop <font style="color:#569cd6;">storage</font> gulfInfo,
        <font style="color:#4ec9b0;">uint</font> interests,
        <font style="color:#4ec9b0;">uint</font> interestsBalance,
        <font style="color:#4ec9b0;">uint</font> principal,
        <font style="color:#4ec9b0;">uint</font> distrDate
    ) <font style="color:#569cd6;">private</font> {
        gulfInfo.income += <font style="color:#4ec9b0;">uint64</font>(interests + interestsBalance);
        gulfInfo.principal += <font style="color:#4ec9b0;">uint64</font>(principal);
        gulfInfo.distrDate = <font style="color:#4ec9b0;">uint48</font>(distrDate);
    }

    <font style="color:#569cd6;">function</font> _intFrontDistr(
        Repo <font style="color:#569cd6;">storage</font> repo, RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule, <font style="color:#4ec9b0;">uint</font> rate, <font style="color:#4ec9b0;">uint</font> amt,
        IRegisterOfShares _ros, Drop <font style="color:#569cd6;">memory</font> drop
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> balance) {

        Drop <font style="color:#569cd6;">memory</font> seaInfo = getSeaInfo(repo, drop.class);
        Drop <font style="color:#569cd6;">storage</font> gulfInfo =
            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">1</font>].flows[drop.class].drops[<font style="color:#b5cea8;">0</font>];

        <font style="color:#4ec9b0;">uint</font> principal = seaInfo.principal;

        <font style="color:#4ec9b0;">uint</font> secs = rule.isCumulative
            ? drop.distrDate - gulfInfo.distrDate
            : drop.distrDate - (drop.seqOfDistr > <font style="color:#b5cea8;">1</font>
                ? getStreamInfo(repo, drop.seqOfDistr - <font style="color:#b5cea8;">1</font>).distrDate
                : gulfInfo.distrDate) ;

        <font style="color:#4ec9b0;">uint</font> interests = rate * principal * secs / (<font style="color:#b5cea8;">365</font> * <font style="color:#b5cea8;">10000</font> * <font style="color:#b5cea8;">86400</font>);
        <font style="color:#4ec9b0;">uint</font> interestsBalance = (seaInfo.income - gulfInfo.income);

        <font style="color:#569cd6;">if</font> (rule.isCumulative) interests -= interestsBalance;

        <font style="color:#569cd6;">if</font> (rate == <font style="color:#b5cea8;">0</font>) {
            <font style="color:#569cd6;">if</font> (rule.refundPrincipal) {
                <font style="color:#569cd6;">if</font> (amt >= principal) {
                    interests = amt - principal;
                } <font style="color:#569cd6;">else</font> principal = amt;
            } <font style="color:#569cd6;">else</font> {
                interests = amt;
                principal = <font style="color:#b5cea8;">0</font>;
            }
            _updateGulfInfo(gulfInfo, interests, interestsBalance, principal, drop.distrDate);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (rule.refundPrincipal) {
                <font style="color:#569cd6;">if</font> (amt < interests) {
                    interests = amt;
                    principal = <font style="color:#b5cea8;">0</font>;
                } <font style="color:#569cd6;">else</font> {
                    <font style="color:#569cd6;">if</font> (amt < interests + principal){
                        principal = amt - interests;
                    } <font style="color:#569cd6;">else</font> {
                        balance = amt - (principal + interests);
                    }
                    _updateGulfInfo(gulfInfo, interests, interestsBalance, principal, drop.distrDate);
                }
            } <font style="color:#569cd6;">else</font> {
                principal = <font style="color:#b5cea8;">0</font>;
                <font style="color:#569cd6;">if</font> (amt < interests) {
                    interests = amt;
                } <font style="color:#569cd6;">else</font> {
                    _updateGulfInfo(gulfInfo, interests, interestsBalance, principal, drop.distrDate);
                    balance = amt - interests;
                }
            }
        }

        _distrAmongShares(repo, _ros, drop, principal, interests);
    }

    <font style="color:#6a9955;">// ---- PrinFrontDistr ----</font>

    <font style="color:#6a9955;">/// @notice Distribute principal-first by tiers.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param _ros Register of shares.</font>
    <font style="color:#6a9955;">/// @param rule Distribution rule.</font>
    <font style="color:#569cd6;">function</font> prinFrontDistr(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> amt, IRegisterOfShares _ros,
        RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(
        Drop <font style="color:#569cd6;">memory</font> drop,
        Drop[] <font style="color:#569cd6;">memory</font> mList,
        Drop[] <font style="color:#569cd6;">memory</font> sList
    ) {
        drop = _createDrop(repo);

        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">while</font> (amt > <font style="color:#b5cea8;">0</font> && i < rule.numOfTiers) {
            drop.class = rule.tiers[i];
            amt= _prinFrontDistr(repo, rule.rates[i], amt, drop);
            _distrAmongShares(repo, _ros, drop, drop.principal, drop.income);
            i++;
        }

        mList = getCreeksOfStream(repo, drop.seqOfDistr);
        sList = getDropsOfStream(repo, drop.seqOfDistr);
    }

    <font style="color:#569cd6;">function</font> _getInterestsPayable(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> rate
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> interests) {
        Drop <font style="color:#569cd6;">memory</font> initSeaInfo = getInitSeaInfo(repo, class);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> distrList = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[class].shares;
        <font style="color:#4ec9b0;">uint</font> len = distrList.length;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font> && rate > <font style="color:#b5cea8;">0</font>) {
            Drop <font style="color:#569cd6;">memory</font> drop =
                repo.streams[distrList[len-<font style="color:#b5cea8;">1</font>]].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>];
            <font style="color:#569cd6;">if</font> (drop.principal > <font style="color:#b5cea8;">0</font>) {
                interests += (drop.principal * rate * (drop.distrDate - initSeaInfo.distrDate) / (<font style="color:#b5cea8;">365</font> * <font style="color:#b5cea8;">10000</font> * <font style="color:#b5cea8;">86400</font>) - drop.income);
            }
            len--;
        }
    }

    <font style="color:#569cd6;">function</font> _updateIsland(
        Repo <font style="color:#569cd6;">storage</font> repo, Drop <font style="color:#569cd6;">memory</font> drop
    ) <font style="color:#569cd6;">private</font> {
        Flow <font style="color:#569cd6;">storage</font> island = repo.streams[drop.seqOfDistr].creeks[<font style="color:#b5cea8;">0</font>].flows[drop.class];

        <font style="color:#569cd6;">if</font> (island.drops[<font style="color:#b5cea8;">0</font>].seqOfDistr == <font style="color:#b5cea8;">0</font>) {
            island.drops[<font style="color:#b5cea8;">0</font>].seqOfDistr = drop.seqOfDistr;
            island.drops[<font style="color:#b5cea8;">0</font>].class = drop.class;
            island.drops[<font style="color:#b5cea8;">0</font>].distrDate = drop.distrDate;
            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[drop.class].shares.push(drop.seqOfDistr);
        }

        island.drops[<font style="color:#b5cea8;">0</font>].principal += drop.principal;
        island.drops[<font style="color:#b5cea8;">0</font>].income += drop.income;
    }

    <font style="color:#569cd6;">function</font> _prinFrontDistr(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> rate, <font style="color:#4ec9b0;">uint</font> amt, Drop <font style="color:#569cd6;">memory</font> drop
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font> balance) {

        Drop <font style="color:#569cd6;">memory</font> initSeaInfo = getInitSeaInfo(repo, drop.class);
        Drop <font style="color:#569cd6;">memory</font> seaInfo = getSeaInfo(repo, drop.class);
        Drop <font style="color:#569cd6;">memory</font> islandInfo = getIslandInfo(repo, drop.class, drop.seqOfDistr);

        drop.principal = seaInfo.principal - islandInfo.principal;
        drop.income = <font style="color:#4ec9b0;">uint64</font>(_getInterestsPayable(repo, drop.class, rate));

        <font style="color:#569cd6;">if</font> (drop.principal > <font style="color:#b5cea8;">0</font> && rate > <font style="color:#b5cea8;">0</font>) {
            drop.income += <font style="color:#4ec9b0;">uint64</font>(drop.principal * rate * (drop.distrDate - initSeaInfo.distrDate) / (<font style="color:#b5cea8;">365</font> * <font style="color:#b5cea8;">10000</font> * <font style="color:#b5cea8;">86400</font>));
        }

        <font style="color:#569cd6;">if</font> (amt < drop.principal) {
            drop.principal = <font style="color:#4ec9b0;">uint64</font>(amt);
            drop.income = <font style="color:#b5cea8;">0</font>;
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">if</font> (amt < drop.principal + drop.income || rate == <font style="color:#b5cea8;">0</font>){
                drop.income = <font style="color:#4ec9b0;">uint64</font>(amt - drop.principal);
            } <font style="color:#569cd6;">else</font> {
                balance = amt - (drop.principal + drop.income);
            }
        }

        _updateIsland(repo, drop);
    }

    <font style="color:#6a9955;">// ---- HurdleCarry ----</font>

    <font style="color:#6a9955;">/// @notice Distribute with hurdle carry to fund manager.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param amt Amount to distribute.</font>
    <font style="color:#6a9955;">/// @param _ros Register of shares.</font>
    <font style="color:#6a9955;">/// @param rule Distribution rule.</font>
    <font style="color:#6a9955;">/// @param fundManager Manager user number.</font>
    <font style="color:#569cd6;">function</font> hurdleCarryDistr(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> amt, IRegisterOfShares _ros,
        RulesParser.DistrRule <font style="color:#569cd6;">memory</font> rule, <font style="color:#4ec9b0;">uint</font> fundManager
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font>(
        Drop <font style="color:#569cd6;">memory</font> drop,
        Drop[] <font style="color:#569cd6;">memory</font> mList,
        Drop[] <font style="color:#569cd6;">memory</font> sList
    ) {

        drop = _createDrop(repo);

        drop.class = rule.tiers[<font style="color:#b5cea8;">0</font>];
        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">0</font>;

        <font style="color:#4ec9b0;">uint</font> principal;
        <font style="color:#4ec9b0;">uint</font> interests;
        <font style="color:#4ec9b0;">uint</font> bonus;

        <font style="color:#4ec9b0;">uint</font> balance;

        <font style="color:#569cd6;">while</font>(amt > <font style="color:#b5cea8;">0</font> && i <= rule.numOfTiers) {

            <font style="color:#4ec9b0;">uint</font> ratio = rule.tiers[i+<font style="color:#b5cea8;">1</font>];
            <font style="color:#4ec9b0;">uint</font> dvd = amt * ratio / <font style="color:#b5cea8;">10000</font>;

            balance = _prinFrontDistr(repo, rule.rates[i], dvd, drop);

            <font style="color:#4ec9b0;">uint</font> carry = balance > <font style="color:#b5cea8;">0</font>
                ? (dvd - balance) * (<font style="color:#b5cea8;">10000</font> - ratio) / ratio
                : amt - dvd;

            amt -= (dvd - balance + carry);

            principal += drop.principal;
            interests += drop.income;
            bonus += carry;

            i++;
        }

        _distrAmongShares(repo, _ros, drop, principal, interests);
        _assignCarryToManager(repo, drop, fundManager, bonus);

        mList = getCreeksOfStream(repo, drop.seqOfDistr);
        sList = getDropsOfStream(repo, drop.seqOfDistr);
    }

    <font style="color:#6a9955;">// ---- Private Funcs ----</font>

    <font style="color:#569cd6;">function</font> _createDrop(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(
        Drop <font style="color:#569cd6;">memory</font> drop
    ) {
        drop.seqOfDistr = getOceanInfo(repo).seqOfDistr + <font style="color:#b5cea8;">1</font>;
        drop.distrDate = <font style="color:#4ec9b0;">uint48</font>(block.timestamp);
    }

    <font style="color:#569cd6;">function</font> _removeTail(Drop <font style="color:#569cd6;">memory</font> drop, SharesRepo.Share <font style="color:#569cd6;">memory</font> share)<font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> {
        <font style="color:#569cd6;">if</font> (drop.principal/<font style="color:#b5cea8;">100</font> > share.body.paid) {
            drop.principal = share.body.paid * <font style="color:#b5cea8;">100</font>;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">if</font> ((drop.principal / <font style="color:#b5cea8;">100</font> < share.body.paid) &&
            (share.body.paid * <font style="color:#b5cea8;">100</font> - drop.principal <= <font style="color:#b5cea8;">100</font>)) {
            drop.principal = share.body.paid * <font style="color:#b5cea8;">100</font>;
        }
    }

    <font style="color:#569cd6;">function</font> _distrAmongShares(
        Repo <font style="color:#569cd6;">storage</font> repo, IRegisterOfShares _ros, Drop <font style="color:#569cd6;">memory</font> drop,
        <font style="color:#4ec9b0;">uint</font> principal, <font style="color:#4ec9b0;">uint</font> interests
    ) <font style="color:#569cd6;">private</font> {

        SharesRepo.Share[] <font style="color:#569cd6;">memory</font> shares =
            _ros.getSharesOfClass(drop.class);

        <font style="color:#4ec9b0;">uint</font> sum = _ros.getInfoOfClass(drop.class).body.par;

        <font style="color:#4ec9b0;">uint</font> len = shares.length;
        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">1</font>;
        <font style="color:#4ec9b0;">uint</font> totalPrincipal = <font style="color:#b5cea8;">0</font>;
        <font style="color:#4ec9b0;">uint</font> totalInterests = <font style="color:#b5cea8;">0</font>;
        SharesRepo.Share <font style="color:#569cd6;">memory</font> share;

        <font style="color:#569cd6;">while</font> (i < len) {
            share = shares[i];
            drop.member = share.head.shareholder;
            drop.income = <font style="color:#4ec9b0;">uint64</font>(interests * share.body.par / sum);
            drop.principal = <font style="color:#4ec9b0;">uint64</font>(principal * share.body.par / sum);

            _removeTail(drop, share);

            totalPrincipal += drop.principal;
            totalInterests += drop.income;

            _addDrop(repo, drop, share.head.seqOfShare);

            i++;
        }
        share = shares[<font style="color:#b5cea8;">0</font>];
        drop.member = share.head.shareholder;
        drop.income = <font style="color:#4ec9b0;">uint64</font>(interests - totalInterests);
        drop.principal = <font style="color:#4ec9b0;">uint64</font>(principal - totalPrincipal);

        _removeTail(drop, share);

        _addDrop(repo, drop, share.head.seqOfShare);
    }

    <font style="color:#569cd6;">function</font> _assignCarryToManager(
        Repo <font style="color:#569cd6;">storage</font> repo, Drop <font style="color:#569cd6;">memory</font> drop, <font style="color:#4ec9b0;">uint</font> fundManager, <font style="color:#4ec9b0;">uint</font> carry
    ) <font style="color:#569cd6;">private</font> {
        drop.member = <font style="color:#4ec9b0;">uint40</font>(fundManager);
        drop.principal = <font style="color:#b5cea8;">0</font>;
        drop.income = <font style="color:#4ec9b0;">uint64</font>(carry);

        _addDrop(repo, drop, TWO_TO_32);
    }

    <font style="color:#6a9955;">// ---- Update Water Fall ----</font>

    <font style="color:#569cd6;">function</font> _addDrop(Repo <font style="color:#569cd6;">storage</font> repo, Drop <font style="color:#569cd6;">memory</font> drop, <font style="color:#4ec9b0;">uint</font> seqOfShare) <font style="color:#569cd6;">private</font> {

        <font style="color:#6a9955;">// ==== Sum Info ====</font>

        Drop <font style="color:#569cd6;">storage</font> ocean =
            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>];

        <font style="color:#569cd6;">if</font> (ocean.seqOfDistr < drop.seqOfDistr) {
            ocean.seqOfDistr = drop.seqOfDistr;
            ocean.distrDate = drop.distrDate;
        }

        ocean.principal += drop.principal;
        ocean.income += drop.income;

        <font style="color:#6a9955;">// ==== Class Centered ====</font>

        Drop <font style="color:#569cd6;">storage</font> sea =
            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[drop.class].drops[<font style="color:#b5cea8;">0</font>];

        <font style="color:#569cd6;">if</font> (sea.seqOfDistr < drop.seqOfDistr) {
            sea.seqOfDistr = drop.seqOfDistr;
            sea.distrDate = drop.distrDate;
        }

        <font style="color:#569cd6;">if</font> (sea.principal >= drop.principal) {
            sea.principal -= drop.principal;
        } <font style="color:#569cd6;">else</font> <font style="color:#569cd6;">revert</font>(<font style="color:#ce9178;">"WR.addDrop: principal overflow"</font>);

        sea.income += drop.income;

        <font style="color:#6a9955;">// ==== Distribution Centered ====</font>

        Stream <font style="color:#569cd6;">storage</font> stream =
            repo.streams[drop.seqOfDistr];

        Creek <font style="color:#569cd6;">storage</font> creek =
            stream.creeks[drop.member];

        Flow <font style="color:#569cd6;">storage</font> flow =
            creek.flows[drop.class];

        Drop <font style="color:#569cd6;">storage</font> d =
            flow.drops[seqOfShare];

        <font style="color:#569cd6;">if</font> (d.distrDate == <font style="color:#b5cea8;">0</font>) {
            flow.drops[seqOfShare] = drop;
            d.distrDate = <font style="color:#4ec9b0;">uint32</font>(seqOfShare);
            flow.shares.push(d.distrDate);
        } <font style="color:#569cd6;">else</font> {
            d.principal += drop.principal;
            d.income += drop.income;
        }

        <font style="color:#569cd6;">if</font> (flow.drops[<font style="color:#b5cea8;">0</font>].distrDate == <font style="color:#b5cea8;">0</font>) {
            flow.drops[<font style="color:#b5cea8;">0</font>] = drop;
            creek.classes.push(drop.class);
        } <font style="color:#569cd6;">else</font> {
            flow.drops[<font style="color:#b5cea8;">0</font>].principal += drop.principal;
            flow.drops[<font style="color:#b5cea8;">0</font>].income += drop.income;
        }

        <font style="color:#569cd6;">if</font> (creek.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].distrDate == <font style="color:#b5cea8;">0</font>) {
            creek.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>] = drop;
            stream.members.push(drop.member);
            creek.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].seqOfDistr = <font style="color:#b5cea8;">1</font>;
        } <font style="color:#569cd6;">else</font> {
            creek.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].seqOfDistr ++;
            creek.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].principal += drop.principal;
            creek.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].income += drop.income;
        }

        <font style="color:#569cd6;">if</font> (stream.creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].distrDate == <font style="color:#b5cea8;">0</font>) {
            stream.creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>] = drop;
            stream.creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].seqOfDistr = <font style="color:#b5cea8;">1</font>;
        } <font style="color:#569cd6;">else</font> {
            stream.creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].seqOfDistr ++;
            stream.creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].principal += drop.principal;
            stream.creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].income += drop.income;
        }

        <font style="color:#6a9955;">// ==== Member Centered ====</font>

        Creek <font style="color:#569cd6;">storage</font> lake =
            repo.streams[<font style="color:#b5cea8;">0</font>].creeks[drop.member];

        Drop <font style="color:#569cd6;">storage</font> pool =
            lake.flows[drop.class].drops[<font style="color:#b5cea8;">0</font>];

        <font style="color:#569cd6;">if</font> (pool.distrDate == <font style="color:#b5cea8;">0</font>) {
            lake.flows[drop.class].drops[<font style="color:#b5cea8;">0</font>] = drop;
            lake.classes.push(drop.class);
        } <font style="color:#569cd6;">else</font> {
            pool.principal += drop.principal;
            pool.income += drop.income;
        }

        <font style="color:#569cd6;">if</font> (lake.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].distrDate == <font style="color:#b5cea8;">0</font>) {
            lake.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>] = drop;
            repo.streams[<font style="color:#b5cea8;">0</font>].members.push(drop.member);
        } <font style="color:#569cd6;">else</font> {
            lake.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].principal += drop.principal;
            lake.flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>].income += drop.income;
        }

    }

    <font style="color:#6a9955;">//####################</font>
    <font style="color:#6a9955;">//##     Read       ##</font>
    <font style="color:#6a9955;">//####################</font>

    <font style="color:#6a9955;">// ==== Distribution ====</font>

    <font style="color:#6a9955;">// ---- Drop ----</font>

    <font style="color:#6a9955;">/// @notice Get a specific drop by path.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfShare Share sequence.</font>
    <font style="color:#569cd6;">function</font> getDrop(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfShare
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> drop) {
        drop = repo.streams[seqOfDistr].creeks[member].flows[class].drops[seqOfShare];
    }

    <font style="color:#6a9955;">// ---- Flow ----</font>

    <font style="color:#6a9955;">/// @notice Get flow summary info.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getFlowInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[seqOfDistr].creeks[member].flows[class].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get drops in a flow.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getDropsOfFlow(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop[] <font style="color:#569cd6;">memory</font> drops) {
        Flow <font style="color:#569cd6;">storage</font> flow = repo.streams[seqOfDistr].creeks[member].flows[class];
        <font style="color:#4ec9b0;">uint</font> len = flow.shares.length;
        drops = <font style="color:#569cd6;">new</font> Drop[](len);
        <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">0</font>;
        <font style="color:#569cd6;">while</font> (i < len) {
            drops[i] = flow.drops[flow.shares[i]];
            i++;
        }
    }

    <font style="color:#6a9955;">// ---- Creek ----</font>

    <font style="color:#6a9955;">/// @notice Get creek summary info.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#569cd6;">function</font> getCreekInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[seqOfDistr].creeks[member].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get all drops in a creek.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#569cd6;">function</font> getDropsOfCreek(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop[] <font style="color:#569cd6;">memory</font> list) {
        Creek <font style="color:#569cd6;">storage</font> creek = repo.streams[seqOfDistr].creeks[member];
        Drop <font style="color:#569cd6;">memory</font> info = getCreekInfo(repo, seqOfDistr, member);
        list = <font style="color:#569cd6;">new</font> Drop[](info.seqOfDistr);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = creek.classes;
        <font style="color:#4ec9b0;">uint</font> len = ls.length;
        <font style="color:#4ec9b0;">uint</font> i;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            Drop[] <font style="color:#569cd6;">memory</font> lsOfFlow =
                getDropsOfFlow(repo, seqOfDistr, member, ls[len-<font style="color:#b5cea8;">1</font>]);
            <font style="color:#4ec9b0;">uint</font> lenOfFlow = lsOfFlow.length;

            <font style="color:#569cd6;">while</font>(lenOfFlow > <font style="color:#b5cea8;">0</font>) {
                list[i] = lsOfFlow[lenOfFlow - <font style="color:#b5cea8;">1</font>];
                lenOfFlow--;
                i++;
            }

            len--;
        }
    }

    <font style="color:#6a9955;">// ---- Stream ----</font>

    <font style="color:#6a9955;">/// @notice Get stream summary info.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#569cd6;">function</font> getStreamInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[seqOfDistr].creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get creeks in a stream.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#569cd6;">function</font> getCreeksOfStream(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop[] <font style="color:#569cd6;">memory</font> list) {
        Stream <font style="color:#569cd6;">storage</font> stream = repo.streams[seqOfDistr];
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = stream.members;
        <font style="color:#4ec9b0;">uint</font> len = ls.length;
        list = <font style="color:#569cd6;">new</font> Drop[](len);
        <font style="color:#4ec9b0;">uint</font> i;
        <font style="color:#569cd6;">while</font>(i < len) {
            Drop <font style="color:#569cd6;">memory</font> info =
                getCreekInfo(repo, seqOfDistr, ls[i]);
            list[i] = info;
            i++;
        }
    }

    <font style="color:#6a9955;">/// @notice Get all drops in a stream.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#569cd6;">function</font> getDropsOfStream(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop[] <font style="color:#569cd6;">memory</font> list) {
        Stream <font style="color:#569cd6;">storage</font> stream = repo.streams[seqOfDistr];
        Drop <font style="color:#569cd6;">memory</font> info = getStreamInfo(repo, seqOfDistr);
        list = <font style="color:#569cd6;">new</font> Drop[](info.seqOfDistr);
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = stream.members;
        <font style="color:#4ec9b0;">uint</font> len = ls.length;
        <font style="color:#4ec9b0;">uint</font> i;
        <font style="color:#569cd6;">while</font>(len > <font style="color:#b5cea8;">0</font>) {
            Drop[] <font style="color:#569cd6;">memory</font> lsOfCreek =
                getDropsOfCreek(repo, seqOfDistr, ls[len-<font style="color:#b5cea8;">1</font>]);
            <font style="color:#4ec9b0;">uint</font> lenOfCreek = lsOfCreek.length;

            <font style="color:#569cd6;">while</font>(lenOfCreek > <font style="color:#b5cea8;">0</font>) {
                list[i] = lsOfCreek[lenOfCreek - <font style="color:#b5cea8;">1</font>];
                lenOfCreek--;
                i++;
            }

            len--;
        }
    }

    <font style="color:#6a9955;">// ==== Member ====</font>

    <font style="color:#6a9955;">/// @notice Get pool info for member/class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getPoolInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> member, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[member].flows[class].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get lake info for member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param member Member user number.</font>
    <font style="color:#569cd6;">function</font> getLakeInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> member
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[member].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">// ==== Class ====</font>

    <font style="color:#6a9955;">/// @notice Get initial sea info for class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getInitSeaInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[TWO_TO_40].flows[class].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get sea info for class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getSeaInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get gulf info for class.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#569cd6;">function</font> getGulfInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">1</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get island info for class and distribution.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param class Share class.</font>
    <font style="color:#6a9955;">/// @param seqOfDistr Distribution sequence.</font>
    <font style="color:#569cd6;">function</font> getIslandInfo(
        Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">uint</font> class, <font style="color:#4ec9b0;">uint</font> seqOfDistr
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[seqOfDistr].creeks[<font style="color:#b5cea8;">0</font>].flows[class].drops[<font style="color:#b5cea8;">0</font>];
    }

    <font style="color:#6a9955;">/// @notice Get list of classes in sea.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getListOfClasses(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> list) {
        list = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].classes;
    }

    <font style="color:#6a9955;">/// @notice Get sea info list for all classes.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getAllSeasInfo(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop[] <font style="color:#569cd6;">memory</font> list) {
        <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> ls = getListOfClasses(repo);
        <font style="color:#4ec9b0;">uint</font> len = ls.length;
        list = <font style="color:#569cd6;">new</font> Drop[](len);
        <font style="color:#4ec9b0;">uint</font> i=<font style="color:#b5cea8;">0</font>;

        <font style="color:#569cd6;">while</font> (i<len) {
            <font style="color:#4ec9b0;">uint</font> class = ls[i];
            list[i] = getSeaInfo(repo, class);
            i++;
        }
    }

    <font style="color:#6a9955;">// ==== Sum ====</font>

    <font style="color:#6a9955;">/// @notice Get ocean info summary.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#569cd6;">function</font> getOceanInfo(
        Repo <font style="color:#569cd6;">storage</font> repo
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font>(Drop <font style="color:#569cd6;">memory</font> info) {
        info = repo.streams[<font style="color:#b5cea8;">0</font>].creeks[<font style="color:#b5cea8;">0</font>].flows[<font style="color:#b5cea8;">0</font>].drops[<font style="color:#b5cea8;">0</font>];
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## InterfacesHub.sol

---

| |
|:---|
| **contracts/lib/InterfacesHub.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../center/IRegCenter.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/IGeneralKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IKeepersRouter.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roa/IRegisterOfAgreements.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roc/IRegisterOfConstitution.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roc/IShareholdersAgreement.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/rod/IRegisterOfDirectors.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/common/components/IMeetingMinutes.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/rom/IRegisterOfMembers.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/ros/IRegisterOfShares.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/loo/IListOfOrders.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roo/IRegisterOfOptions.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/rop/IRegisterOfPledges.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roi/IRegisterOfInvestors.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../center/utils/MockUSDC/IUSDC.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/cashier/ICashier.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/ror/IRegisterOfRedemptions.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roc/IShareholdersAgreement.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roc/terms/IAntiDilution.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roc/terms/IAlongs.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/books/roa/IInvestmentAgreement.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/common/components/IFilesFolder.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/common/components/ISigPage.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IROCKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IRODKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IBMMKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IROMKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IGMMKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IROAKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IROOKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IROPKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/ISHAKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/ILOOKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IROIKeeper.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IAccountant.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/keepers/IRORKeeper.sol"</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/common/access/IDraftControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/common/access/IAccessControl.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../comps/common/access/IOwnable.sol"</font>;

<font style="color:#569cd6;">library</font> InterfacesHub {

    <font style="color:#6a9955;">/// @notice Keeper type identifiers.</font>
    <font style="color:#569cd6;">enum</font> Keepers {
        ZeroPoint,
        ROCK,       <font style="color:#6a9955;">//1</font>
        RODK,
        BMMK,
        ROMK,
        GMMK,       <font style="color:#6a9955;">//5 </font>
        ROAK,
        ROOK,
        ROPK,
        SHAK,
        LOOK,       <font style="color:#6a9955;">//10</font>
        ROIK,
        Accountant,
        Blank_1,
        Blank_2,
        Blank_3,    <font style="color:#6a9955;">//15</font>
        RORK
    }

    <font style="color:#6a9955;">/// @notice Book type identifiers.</font>
    <font style="color:#569cd6;">enum</font> Books {
        ZeroPoint,
        ROC,        <font style="color:#6a9955;">//1</font>
        ROD,
        BMM,
        ROM,
        GMM,        <font style="color:#6a9955;">//5</font>
        ROA,
        ROO,
        ROP,
        ROS,
        LOO,        <font style="color:#6a9955;">//10</font>
        ROI,
        Bank,
        Blank_1,
        Blank_2,
        Cashier,    <font style="color:#6a9955;">//15</font>
        ROR
    }

    <font style="color:#6a9955;">// ==== RegCenter ====</font>

    <font style="color:#6a9955;">/// @notice Cast address to RegCenter interface.</font>
    <font style="color:#6a9955;">/// @param rc RegCenter address (non-zero).</font>
    <font style="color:#569cd6;">function</font> getRC(<font style="color:#4ec9b0;">address</font> rc) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(IRegCenter) {
        <font style="color:#569cd6;">return</font> IRegCenter(rc);
    }

    <font style="color:#6a9955;">/// @notice Cast address to GeneralKeeper interface.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address (non-zero).</font>
    <font style="color:#569cd6;">function</font> getRCByGK(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegCenter) {
        <font style="color:#569cd6;">return</font> IRegCenter(IOwnable(gk).getRegCenter());
    }

    <font style="color:#6a9955;">// ==== GeneralKeeper ====</font>

    <font style="color:#6a9955;">/// @notice Cast address to GeneralKeeper interface.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address (non-zero).</font>
    <font style="color:#569cd6;">function</font> getGK(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (IGeneralKeeper) {
        <font style="color:#569cd6;">return</font> IGeneralKeeper(gk);
    }

    <font style="color:#569cd6;">function</font> getRouter(<font style="color:#4ec9b0;">address</font> router) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (IKeepersRouter) {
        <font style="color:#569cd6;">return</font> IKeepersRouter(router);
    }

    <font style="color:#6a9955;">// ==== Books ====</font>
    <font style="color:#6a9955;">/// @notice Get ROC (Register of Constitution).</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROC(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfConstitution) {
        <font style="color:#569cd6;">return</font> IRegisterOfConstitution(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROC)));
    }

    <font style="color:#6a9955;">/// @notice Get Shareholders Agreement (current pointer).</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getSHA(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IShareholdersAgreement) {
        <font style="color:#569cd6;">return</font> IShareholdersAgreement(getROC(gk).pointer());
    }

    <font style="color:#6a9955;">/// @notice Get Register of Directors.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROD(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfDirectors) {
        <font style="color:#569cd6;">return</font> IRegisterOfDirectors(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROD)));
    }

    <font style="color:#6a9955;">/// @notice Get Board Meeting Minutes.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getBMM(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IMeetingMinutes) {
        <font style="color:#569cd6;">return</font> IMeetingMinutes(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.BMM)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Members.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROM(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfMembers) {
        <font style="color:#569cd6;">return</font> IRegisterOfMembers(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROM)));
    }

    <font style="color:#6a9955;">/// @notice Get General Meeting Minutes.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getGMM(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IMeetingMinutes) {
        <font style="color:#569cd6;">return</font> IMeetingMinutes(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.GMM)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Agreements.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROA(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfAgreements) {
        <font style="color:#569cd6;">return</font> IRegisterOfAgreements(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROA)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Options.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROO(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfOptions) {
        <font style="color:#569cd6;">return</font> IRegisterOfOptions(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROO)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Pledges.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROP(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfPledges) {
        <font style="color:#569cd6;">return</font> IRegisterOfPledges(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROP)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Shares.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROS(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfShares) {
        <font style="color:#569cd6;">return</font> IRegisterOfShares(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROS)));
    }

    <font style="color:#6a9955;">/// @notice Get List of Orders.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getLOO(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IListOfOrders) {
        <font style="color:#569cd6;">return</font> IListOfOrders(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.LOO)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Investors.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROI(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfInvestors) {
        <font style="color:#569cd6;">return</font> IRegisterOfInvestors(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROI)));
    }

    <font style="color:#6a9955;">/// @notice Get USDC bank contract.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getBank(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IUSDC) {
        <font style="color:#569cd6;">return</font> IUSDC(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.Bank)));
    }

    <font style="color:#6a9955;">/// @notice Get Cashier contract.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getCashier(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (ICashier) {
        <font style="color:#569cd6;">return</font> ICashier(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.Cashier)));
    }

    <font style="color:#6a9955;">/// @notice Get Register of Redemptions.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROR(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRegisterOfRedemptions) {
        <font style="color:#569cd6;">return</font> IRegisterOfRedemptions(IGeneralKeeper(gk).getBook(<font style="color:#4ec9b0;">uint8</font>(Books.ROR)));
    }

    <font style="color:#6a9955;">// ==== Keepers ====</font>

    <font style="color:#6a9955;">/// @notice Get ROC Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROCKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IROCKeeper) {
        <font style="color:#569cd6;">return</font> IROCKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.ROCK)));
    }

    <font style="color:#6a9955;">/// @notice Get ROD Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getRODKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRODKeeper) {
        <font style="color:#569cd6;">return</font> IRODKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.RODK)));
    }

    <font style="color:#6a9955;">/// @notice Get BMM Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getBMMKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IBMMKeeper) {
        <font style="color:#569cd6;">return</font> IBMMKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.BMMK)));
    }

    <font style="color:#6a9955;">/// @notice Get ROM Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROMKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IROMKeeper) {
        <font style="color:#569cd6;">return</font> IROMKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.ROMK)));
    }

    <font style="color:#6a9955;">/// @notice Get GMM Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getGMMKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IGMMKeeper) {
        <font style="color:#569cd6;">return</font> IGMMKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.GMMK)));
    }

    <font style="color:#6a9955;">/// @notice Get ROA Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROAKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IROAKeeper) {
        <font style="color:#569cd6;">return</font> IROAKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.ROAK)));
    }

    <font style="color:#6a9955;">/// @notice Get ROO Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROOKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IROOKeeper) {
        <font style="color:#569cd6;">return</font> IROOKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.ROOK)));
    }

    <font style="color:#6a9955;">/// @notice Get ROP Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROPKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IROPKeeper) {
        <font style="color:#569cd6;">return</font> IROPKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.ROPK)));
    }

    <font style="color:#6a9955;">/// @notice Get SHA Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getSHAKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (ISHAKeeper) {
        <font style="color:#569cd6;">return</font> ISHAKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.SHAK)));
    }

    <font style="color:#6a9955;">/// @notice Get LOO Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getLOOKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (ILOOKeeper) {
        <font style="color:#569cd6;">return</font> ILOOKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.LOOK)));
    }

    <font style="color:#6a9955;">/// @notice Get ROI Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getROIKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IROIKeeper) {
        <font style="color:#569cd6;">return</font> IROIKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.ROIK)));
    }

    <font style="color:#6a9955;">/// @notice Get Accountant Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getAccountant(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IAccountant) {
        <font style="color:#569cd6;">return</font> IAccountant(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.Accountant)));
    }

    <font style="color:#6a9955;">/// @notice Get ROR Keeper.</font>
    <font style="color:#6a9955;">/// @param gk GeneralKeeper address.</font>
    <font style="color:#569cd6;">function</font> getRORKeeper(<font style="color:#4ec9b0;">address</font> gk) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (IRORKeeper) {
        <font style="color:#569cd6;">return</font> IRORKeeper(IGeneralKeeper(gk).getKeeper(<font style="color:#4ec9b0;">uint8</font>(Keepers.RORK)));
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## ArrayUtils.sol

---

| |
|:---|
| **contracts/lib/utils/ArrayUtils.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title ArrayUtils</font>
<font style="color:#6a9955;">/// @notice Utility functions for uint256 array operations.</font>
<font style="color:#569cd6;">library</font> ArrayUtils {

    <font style="color:#6a9955;">/// @notice Merge two arrays into a unique list (no duplicates).</font>
    <font style="color:#6a9955;">/// @param arrA First array.</font>
    <font style="color:#6a9955;">/// @param arrB Second array.</font>
    <font style="color:#569cd6;">function</font> merge(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrB)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrC = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint256</font>[](arrA.length + arrB.length);
        <font style="color:#4ec9b0;">uint256</font> lenC;

        (arrC, lenC) = filter(arrA, arrC, <font style="color:#b5cea8;">0</font>);
        (arrC, lenC) = filter(arrB, arrC, lenC);

        <font style="color:#569cd6;">return</font> resize(arrC, lenC);
    }

    <font style="color:#6a9955;">/// @notice Append unique elements from arrA into arrC.</font>
    <font style="color:#6a9955;">/// @param arrA Source array.</font>
    <font style="color:#6a9955;">/// @param arrC Target array buffer.</font>
    <font style="color:#6a9955;">/// @param lenC Current length used in arrC.</font>
    <font style="color:#569cd6;">function</font> filter(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrC, <font style="color:#4ec9b0;">uint256</font> lenC)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>, <font style="color:#4ec9b0;">uint256</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> lenA = arrA.length;
        <font style="color:#4ec9b0;">uint256</font> i;

        <font style="color:#569cd6;">while</font> (i < lenA) {

            <font style="color:#4ec9b0;">uint256</font> j;
            <font style="color:#569cd6;">while</font> (j < lenC){
                <font style="color:#569cd6;">if</font> (arrA[i] == arrC[j]) <font style="color:#569cd6;">break</font>;
                j++;
            }

            <font style="color:#569cd6;">if</font> (j == lenC) {
                arrC[lenC] = arrA[i];
                lenC++;
            }

            i++;
        }

        <font style="color:#569cd6;">return</font> (arrC, lenC);
    }

    <font style="color:#6a9955;">/// @notice Remove duplicates from an array.</font>
    <font style="color:#6a9955;">/// @param arrA Source array.</font>
    <font style="color:#569cd6;">function</font> refine(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrB = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint256</font>[](arrA.length);
        <font style="color:#4ec9b0;">uint256</font> lenB;
        (arrB, lenB) = filter(arrA, arrB, <font style="color:#b5cea8;">0</font>);

        <font style="color:#569cd6;">return</font> resize(arrB, lenB);
    }

    <font style="color:#6a9955;">/// @notice Resize an array to a specific length (truncate).</font>
    <font style="color:#6a9955;">/// @param arrA Source array.</font>
    <font style="color:#6a9955;">/// @param len New length (<= arrA.length).</font>
    <font style="color:#569cd6;">function</font> resize(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint256</font> len)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> output = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint256</font>[](len);

        <font style="color:#569cd6;">while</font> (len > <font style="color:#b5cea8;">0</font>) {
            output[len - <font style="color:#b5cea8;">1</font>] = arrA[len - <font style="color:#b5cea8;">1</font>];
            len--;
        }

        <font style="color:#569cd6;">return</font> output;
    }

    <font style="color:#6a9955;">/// @notice Concatenate two arrays (keeps duplicates).</font>
    <font style="color:#6a9955;">/// @param arrA First array.</font>
    <font style="color:#6a9955;">/// @param arrB Second array.</font>
    <font style="color:#569cd6;">function</font> combine(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrB)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> lenA = arrA.length;
        <font style="color:#4ec9b0;">uint256</font> lenB = arrB.length;
        <font style="color:#4ec9b0;">uint256</font> i;

        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrC = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint256</font>[](lenA + lenB);

        <font style="color:#569cd6;">for</font> (i = <font style="color:#b5cea8;">0</font>; i < lenA; i++) arrC[i] = arrA[i];
        <font style="color:#569cd6;">for</font> (i = <font style="color:#b5cea8;">0</font>; i < lenB; i++) arrC[lenA + i] = arrB[i];

        <font style="color:#569cd6;">return</font> arrC;
    }

    <font style="color:#6a9955;">/// @notice Return elements in arrA that are not in arrB.</font>
    <font style="color:#6a9955;">/// @param arrA Source array.</font>
    <font style="color:#6a9955;">/// @param arrB Exclusion array.</font>
    <font style="color:#569cd6;">function</font> minus(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrB)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>)
    {
        <font style="color:#4ec9b0;">uint256</font> lenA = arrA.length;
        <font style="color:#4ec9b0;">uint256</font> lenB = arrB.length;

        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrC = <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">uint256</font>[](lenA);

        <font style="color:#4ec9b0;">uint256</font> pointer;

        <font style="color:#569cd6;">while</font> (lenA > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">bool</font> flag = <font style="color:#569cd6;">false</font>;
            lenB = arrB.length;

            <font style="color:#569cd6;">while</font> (lenB > <font style="color:#b5cea8;">0</font>) {
                <font style="color:#569cd6;">if</font> (arrB[lenB - <font style="color:#b5cea8;">1</font>] == arrA[lenA - <font style="color:#b5cea8;">1</font>]) {
                    flag = <font style="color:#569cd6;">true</font>;
                    <font style="color:#569cd6;">break</font>;
                }
                lenB--;
            }

            <font style="color:#569cd6;">if</font> (!flag) {
                arrC[pointer] = arrA[lenA - <font style="color:#b5cea8;">1</font>];
                pointer++;
            }

            lenA--;
        }

        <font style="color:#569cd6;">return</font> resize(arrC, pointer);
    }

    <font style="color:#6a9955;">/// @notice Check whether arrA is fully covered by arrB.</font>
    <font style="color:#6a9955;">/// @param arrA Required elements.</font>
    <font style="color:#6a9955;">/// @param arrB Cover elements.</font>
    <font style="color:#569cd6;">function</font> fullyCoveredBy(<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrB)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>)
    {
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrAr = refine(arrA);
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> arrBr = refine(arrB);

        <font style="color:#4ec9b0;">uint256</font> lenA = arrAr.length;
        <font style="color:#4ec9b0;">uint256</font> lenB = arrBr.length;

        <font style="color:#569cd6;">while</font> (lenA > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint256</font> i;
            <font style="color:#569cd6;">while</font> (i < lenB) {
                <font style="color:#569cd6;">if</font> (arrBr[i] == arrAr[lenA-<font style="color:#b5cea8;">1</font>]) <font style="color:#569cd6;">break</font>;
                i++;
            }
            <font style="color:#569cd6;">if</font> (i==lenB) <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
            lenA--;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @notice Check whether two arrays have no overlapping elements.</font>
    <font style="color:#6a9955;">/// @param arrA First array.</font>
    <font style="color:#6a9955;">/// @param arrB Second array.</font>
    <font style="color:#569cd6;">function</font> noOverlapWith(<font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> arrA, <font style="color:#4ec9b0;">uint</font>[] <font style="color:#569cd6;">memory</font> arrB) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">uint</font> lenA = arrA.length;
        <font style="color:#4ec9b0;">uint</font> lenB = arrB.length;

        <font style="color:#569cd6;">while</font> (lenA > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#4ec9b0;">uint</font> i = <font style="color:#b5cea8;">0</font>;
            <font style="color:#569cd6;">while</font> (i < lenB) {
                <font style="color:#569cd6;">if</font> (arrA[lenA-<font style="color:#b5cea8;">1</font>] == arrB[i]) {
                    <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
                }
                i++;
            }
            lenA--;
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

}</code></pre>
```
 |
| [Contents](#toc) |

---

## RolesRepo.sol

---

| |
|:---|
| **contracts/lib/utils/RolesRepo.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/// @title RolesRepo</font>
<font style="color:#6a9955;">/// @notice Library for role membership and admin management.</font>
<font style="color:#569cd6;">library</font> RolesRepo {

    <font style="color:#6a9955;">/// @notice Role with admin and members.</font>
    <font style="color:#569cd6;">struct</font> Role {
        <font style="color:#4ec9b0;">address</font> admin;
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">bool</font>) isMember;
    }

    <font style="color:#6a9955;">/// @notice Repository of roles by id.</font>
    <font style="color:#569cd6;">struct</font> Repo {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">bytes32</font> => Role) roles;
    }

    <font style="color:#569cd6;">error</font> RR_WrongParty(<font style="color:#4ec9b0;">bytes32</font> reason);

    <font style="color:#6a9955;">// ##################</font>
    <font style="color:#6a9955;">// ##    Modifier  ##</font>
    <font style="color:#6a9955;">// ##################</font>

    <font style="color:#6a9955;">/// @dev Reverts if caller is not role admin.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role id.</font>
    <font style="color:#6a9955;">/// @param caller Caller address.</font>
    <font style="color:#569cd6;">modifier</font> onlyAdmin(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> caller
    ) {
        <font style="color:#569cd6;">if</font> (repo.roles[role].admin != caller) {
            <font style="color:#569cd6;">revert</font> RR_WrongParty(<font style="color:#4ec9b0;">bytes32</font>(<font style="color:#ce9178;">"RR_NotAdmin"</font>));
        }
        _;
    }

    <font style="color:#6a9955;">// #################</font>
    <font style="color:#6a9955;">// ##    Write    ##</font>
    <font style="color:#6a9955;">// #################</font>

    <font style="color:#6a9955;">/// @notice Set role admin and add as member.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Admin address (non-zero).</font>
    <font style="color:#569cd6;">function</font> setRoleAdmin(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> acct
    ) <font style="color:#569cd6;">public</font> {
        repo.roles[role].admin = acct;
        repo.roles[role].isMember[acct] = <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @notice Remove role admin and its membership.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param caller Current admin address.</font>
    <font style="color:#569cd6;">function</font> quitRoleAdmin(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> caller
    ) <font style="color:#569cd6;">public</font> onlyAdmin(repo, role, caller) {
        <font style="color:#569cd6;">delete</font> repo.roles[role].admin;
        <font style="color:#569cd6;">delete</font> repo.roles[role].isMember[caller];
    }

    <font style="color:#6a9955;">/// @notice Grant a role to an account.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Account address (non-zero).</font>
    <font style="color:#6a9955;">/// @param caller Admin address.</font>
    <font style="color:#569cd6;">function</font> grantRole(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> acct,
        <font style="color:#4ec9b0;">address</font> caller
    ) <font style="color:#569cd6;">public</font> onlyAdmin(repo, role, caller) {
        repo.roles[role].isMember[acct] = <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @notice Revoke a role from an account.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Account address (non-zero).</font>
    <font style="color:#6a9955;">/// @param caller Admin address.</font>
    <font style="color:#569cd6;">function</font> revokeRole(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> acct,
        <font style="color:#4ec9b0;">address</font> caller
    ) <font style="color:#569cd6;">public</font> onlyAdmin(repo, role, caller) {
        <font style="color:#569cd6;">delete</font> repo.roles[role].isMember[acct];
    }

    <font style="color:#6a9955;">/// @notice Renounce a role held by caller.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param caller Caller address.</font>
    <font style="color:#569cd6;">function</font> renounceRole(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> caller
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">delete</font> repo.roles[role].isMember[caller];
    }

    <font style="color:#6a9955;">/// @notice Abandon a role and all members.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#569cd6;">function</font> abandonRole(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role
    ) <font style="color:#569cd6;">public</font> {
        <font style="color:#569cd6;">delete</font> repo.roles[role];
    }

    <font style="color:#6a9955;">// ###############</font>
    <font style="color:#6a9955;">// ##   Read    ##</font>
    <font style="color:#6a9955;">// ###############</font>

    <font style="color:#6a9955;">/// @notice Get role admin address.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#569cd6;">function</font> getRoleAdmin(Repo <font style="color:#569cd6;">storage</font> repo, <font style="color:#4ec9b0;">bytes32</font> role)
        <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>)
    {
        <font style="color:#569cd6;">return</font> repo.roles[role].admin;
    }

    <font style="color:#6a9955;">/// @notice Check whether an account has a role.</font>
    <font style="color:#6a9955;">/// @param repo Storage repo.</font>
    <font style="color:#6a9955;">/// @param role Role identifier (non-zero bytes32).</font>
    <font style="color:#6a9955;">/// @param acct Account address (non-zero).</font>
    <font style="color:#569cd6;">function</font> hasRole(
        Repo <font style="color:#569cd6;">storage</font> repo,
        <font style="color:#4ec9b0;">bytes32</font> role,
        <font style="color:#4ec9b0;">address</font> acct
    ) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> repo.roles[role].isMember[acct];
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## RoyaltyCharge.sol

---

| |
|:---|
| **contracts/lib/utils/RoyaltyCharge.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: UNLICENSED</font>

<font style="color:#6a9955;">/* *
 * v.0.2.5
 * Copyright (c) 2021-2026 LI LI @ JINGTIAN & GONGCHENG.
 *
 * This WORK is licensed under ComBoox SoftWare License 1.0, a copy of which
 * can be obtained at:
 *         [https://github.com/paul-lee-attorney/comboox]
 *
 * THIS WORK IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. IN NO
 * EVENT SHALL ANY CONTRIBUTOR BE LIABLE TO YOU FOR ANY DAMAGES.
 *
 * YOU ARE PROHIBITED FROM DEPLOYING THE SMART CONTRACTS OF THIS WORK, IN WHOLE
 * OR IN PART, FOR WHATEVER PURPOSE, ON ANY BLOCKCHAIN NETWORK THAT HAS ONE OR
 * MORE NODES THAT ARE OUT OF YOUR CONTROL.
 * */</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../InterfacesHub.sol"</font>;

<font style="color:#6a9955;">/// @title RoyaltyCharge</font>
<font style="color:#6a9955;">/// @notice Internal helper for charging royalty fees via RegCenter.</font>
<font style="color:#569cd6;">library</font> RoyaltyCharge {
    <font style="color:#569cd6;">using</font> InterfacesHub <font style="color:#569cd6;">for</font> <font style="color:#4ec9b0;">address</font>;

    <font style="color:#6a9955;">/// @notice Emitted when a royalty charge is applied.</font>
    <font style="color:#6a9955;">/// @param typeOfDoc Document type identifier.</font>
    <font style="color:#6a9955;">/// @param version Document version.</font>
    <font style="color:#6a9955;">/// @param rate Royalty rate (unit defined by caller).</font>
    <font style="color:#6a9955;">/// @param user User number charged.</font>
    <font style="color:#6a9955;">/// @param author Author user number receiving royalty.</font>
    <font style="color:#569cd6;">event</font> ChargeRoyalty(
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> typeOfDoc, <font style="color:#4ec9b0;">uint</font> version, <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> rate,
        <font style="color:#4ec9b0;">uint</font> <font style="color:#569cd6;">indexed</font> user, <font style="color:#4ec9b0;">uint</font> author
    );

    <font style="color:#6a9955;">/// @notice Resolve sender user number and charge royalty.</font>
    <font style="color:#6a9955;">/// @param target Caller address.</font>
    <font style="color:#6a9955;">/// @param rate Royalty rate (unit defined by caller).</font>
    <font style="color:#6a9955;">/// @return usr User number of the caller.</font>
    <font style="color:#569cd6;">function</font> msgSender(
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">uint</font> typeOfDoc,
        <font style="color:#4ec9b0;">uint</font> version,
        <font style="color:#4ec9b0;">uint</font> rate
    ) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font>(<font style="color:#4ec9b0;">uint40</font> usr) {
        <font style="color:#4ec9b0;">address</font> gk = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);
        <font style="color:#4ec9b0;">uint</font> author =
            gk.getRCByGK().getTemp(
                typeOfDoc,
                version
            ).head.author;

        usr = gk.getRCByGK().getUserNo(
            target, rate * (<font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">10</font>), author
        );

        <font style="color:#569cd6;">emit</font> ChargeRoyalty(
            typeOfDoc,
            version,
            rate * (<font style="color:#b5cea8;">10</font> ** <font style="color:#b5cea8;">10</font>),
            usr,
            author
        );
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## draft-IERC1822.sol

---

| |
|:---|
| **contracts/openzeppelin/interfaces/draft-IERC1822.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#6a9955;">/**
 * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
 * proxy whose upgrades are fully controlled by the current implementation.
 */</font>
<font style="color:#569cd6;">interface</font> IERC1822Proxiable {
    <font style="color:#6a9955;">/**
     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
     * address.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy.
     */</font>
    <font style="color:#569cd6;">function</font> proxiableUUID() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## draft-IERC6093.sol

---

| |
|:---|
| **contracts/openzeppelin/interfaces/draft-IERC6093.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> >=<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">4</font>;

<font style="color:#6a9955;">/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */</font>
<font style="color:#569cd6;">interface</font> IERC20Errors {
    <font style="color:#6a9955;">/**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */</font>
    <font style="color:#569cd6;">error</font> ERC20InsufficientBalance(<font style="color:#4ec9b0;">address</font> sender, <font style="color:#4ec9b0;">uint256</font> balance, <font style="color:#4ec9b0;">uint256</font> needed);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */</font>
    <font style="color:#569cd6;">error</font> ERC20InvalidSender(<font style="color:#4ec9b0;">address</font> sender);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */</font>
    <font style="color:#569cd6;">error</font> ERC20InvalidReceiver(<font style="color:#4ec9b0;">address</font> receiver);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `spender`'s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */</font>
    <font style="color:#569cd6;">error</font> ERC20InsufficientAllowance(<font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> allowance, <font style="color:#4ec9b0;">uint256</font> needed);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */</font>
    <font style="color:#569cd6;">error</font> ERC20InvalidApprover(<font style="color:#4ec9b0;">address</font> approver);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */</font>
    <font style="color:#569cd6;">error</font> ERC20InvalidSpender(<font style="color:#4ec9b0;">address</font> spender);
}

<font style="color:#6a9955;">/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */</font>
<font style="color:#569cd6;">interface</font> IERC721Errors {
    <font style="color:#6a9955;">/**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-721.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721InvalidOwner(<font style="color:#4ec9b0;">address</font> owner);

    <font style="color:#6a9955;">/**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721NonexistentToken(<font style="color:#4ec9b0;">uint256</font> tokenId);

    <font style="color:#6a9955;">/**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721IncorrectOwner(<font style="color:#4ec9b0;">address</font> sender, <font style="color:#4ec9b0;">uint256</font> tokenId, <font style="color:#4ec9b0;">address</font> owner);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721InvalidSender(<font style="color:#4ec9b0;">address</font> sender);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721InvalidReceiver(<font style="color:#4ec9b0;">address</font> receiver);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `operator`'s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721InsufficientApproval(<font style="color:#4ec9b0;">address</font> operator, <font style="color:#4ec9b0;">uint256</font> tokenId);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721InvalidApprover(<font style="color:#4ec9b0;">address</font> approver);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */</font>
    <font style="color:#569cd6;">error</font> ERC721InvalidOperator(<font style="color:#4ec9b0;">address</font> operator);
}

<font style="color:#6a9955;">/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */</font>
<font style="color:#569cd6;">interface</font> IERC1155Errors {
    <font style="color:#6a9955;">/**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155InsufficientBalance(<font style="color:#4ec9b0;">address</font> sender, <font style="color:#4ec9b0;">uint256</font> balance, <font style="color:#4ec9b0;">uint256</font> needed, <font style="color:#4ec9b0;">uint256</font> tokenId);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155InvalidSender(<font style="color:#4ec9b0;">address</font> sender);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155InvalidReceiver(<font style="color:#4ec9b0;">address</font> receiver);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `operator`'s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155MissingApprovalForAll(<font style="color:#4ec9b0;">address</font> operator, <font style="color:#4ec9b0;">address</font> owner);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155InvalidApprover(<font style="color:#4ec9b0;">address</font> approver);

    <font style="color:#6a9955;">/**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155InvalidOperator(<font style="color:#4ec9b0;">address</font> operator);

    <font style="color:#6a9955;">/**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */</font>
    <font style="color:#569cd6;">error</font> ERC1155InvalidArrayLength(<font style="color:#4ec9b0;">uint256</font> idsLength, <font style="color:#4ec9b0;">uint256</font> valuesLength);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IERC1967.sol

---

| |
|:---|
| **contracts/openzeppelin/interfaces/IERC1967.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#6a9955;">/**
 * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
 *
 * _Available since v4.8.3._
 */</font>
<font style="color:#569cd6;">interface</font> IERC1967 {
    <font style="color:#6a9955;">/**
     * @dev Emitted when the implementation is upgraded.
     */</font>
    <font style="color:#569cd6;">event</font> Upgraded(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> implementation);

    <font style="color:#6a9955;">/**
     * @dev Emitted when the admin account has changed.
     */</font>
    <font style="color:#569cd6;">event</font> AdminChanged(<font style="color:#4ec9b0;">address</font> previousAdmin, <font style="color:#4ec9b0;">address</font> newAdmin);

    <font style="color:#6a9955;">/**
     * @dev Emitted when the beacon is changed.
     */</font>
    <font style="color:#569cd6;">event</font> BeaconUpgraded(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> beacon);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IBeacon.sol

---

| |
|:---|
| **contracts/openzeppelin/proxy/beacon/IBeacon.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#6a9955;">/**
 * @dev This is the interface that {BeaconProxy} expects of its beacon.
 */</font>
<font style="color:#569cd6;">interface</font> IBeacon {
    <font style="color:#6a9955;">/**
     * @dev Must return an address that can be used as a delegate call target.
     *
     * {BeaconProxy} will check that this address is a contract.
     */</font>
    <font style="color:#569cd6;">function</font> implementation() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ERC1967Proxy.sol

---

| |
|:---|
| **contracts/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../Proxy.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./ERC1967Upgrade.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
 * implementation address that can be changed. This address is stored in storage in the location specified by
 * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
 * implementation behind the proxy.
 */</font>
<font style="color:#569cd6;">contract</font> ERC1967Proxy <font style="color:#569cd6;">is</font> Proxy, ERC1967Upgrade {
    <font style="color:#6a9955;">/**
     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
     *
     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
     * function call, and allows initializing the storage of the proxy like a Solidity constructor.
     */</font>
    <font style="color:#569cd6;">constructor</font>(<font style="color:#4ec9b0;">address</font> _logic, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> _data) <font style="color:#569cd6;">payable</font> {
        _upgradeToAndCall(_logic, _data, <font style="color:#569cd6;">false</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the current implementation address.
     */</font>
    <font style="color:#569cd6;">function</font> _implementation() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font> impl) {
        <font style="color:#569cd6;">return</font> ERC1967Upgrade._getImplementation();
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ERC1967Upgrade.sol

---

| |
|:---|
| **contracts/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../beacon/IBeacon.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../interfaces/IERC1967.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../interfaces/draft-IERC1822.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../utils/Address.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../utils/StorageSlot.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev This abstract contract provides getters and event emitting update functions for
 * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
 *
 * _Available since v4.1._
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> ERC1967Upgrade <font style="color:#569cd6;">is</font> IERC1967 {
    <font style="color:#6a9955;">// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">constant</font> _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;

    <font style="color:#6a9955;">/**
     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
     */</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">constant</font> _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    <font style="color:#6a9955;">/**
     * @dev Returns the current implementation address.
     */</font>
    <font style="color:#569cd6;">function</font> _getImplementation() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    }

    <font style="color:#6a9955;">/**
     * @dev Stores a new address in the EIP1967 implementation slot.
     */</font>
    <font style="color:#569cd6;">function</font> _setImplementation(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">require</font>(Address.isContract(newImplementation), <font style="color:#ce9178;">"ERC1967: new implementation is not a contract"</font>);
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
    }

    <font style="color:#6a9955;">/**
     * @dev Perform implementation upgrade
     *
     * Emits an {Upgraded} event.
     */</font>
    <font style="color:#569cd6;">function</font> _upgradeTo(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">internal</font> {
        _setImplementation(newImplementation);
        <font style="color:#569cd6;">emit</font> Upgraded(newImplementation);
    }

    <font style="color:#6a9955;">/**
     * @dev Perform implementation upgrade with additional setup call.
     *
     * Emits an {Upgraded} event.
     */</font>
    <font style="color:#569cd6;">function</font> _upgradeToAndCall(<font style="color:#4ec9b0;">address</font> newImplementation, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data, <font style="color:#4ec9b0;">bool</font> forceCall) <font style="color:#569cd6;">internal</font> {
        _upgradeTo(newImplementation);
        <font style="color:#569cd6;">if</font> (data.length > <font style="color:#b5cea8;">0</font> || forceCall) {
            Address.functionDelegateCall(newImplementation, data);
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
     *
     * Emits an {Upgraded} event.
     */</font>
    <font style="color:#569cd6;">function</font> _upgradeToAndCallUUPS(<font style="color:#4ec9b0;">address</font> newImplementation, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data, <font style="color:#4ec9b0;">bool</font> forceCall) <font style="color:#569cd6;">internal</font> {
        <font style="color:#6a9955;">// Upgrades from old implementations will perform a rollback test. This test requires the new</font>
        <font style="color:#6a9955;">// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing</font>
        <font style="color:#6a9955;">// this special case will break upgrade paths from old UUPS implementation to new ones.</font>
        <font style="color:#569cd6;">if</font> (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {
            _setImplementation(newImplementation);
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">try</font> IERC1822Proxiable(newImplementation).proxiableUUID() <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font> slot) {
                <font style="color:#569cd6;">require</font>(slot == _IMPLEMENTATION_SLOT, <font style="color:#ce9178;">"ERC1967Upgrade: unsupported proxiableUUID"</font>);
            } <font style="color:#569cd6;">catch</font> {
                <font style="color:#569cd6;">revert</font>(<font style="color:#ce9178;">"ERC1967Upgrade: new implementation is not UUPS"</font>);
            }
            _upgradeToAndCall(newImplementation, data, forceCall);
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Storage slot with the admin of the contract.
     * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
     * validated in the constructor.
     */</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">constant</font> _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    <font style="color:#6a9955;">/**
     * @dev Returns the current admin.
     */</font>
    <font style="color:#569cd6;">function</font> _getAdmin() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
    }

    <font style="color:#6a9955;">/**
     * @dev Stores a new address in the EIP1967 admin slot.
     */</font>
    <font style="color:#569cd6;">function</font> _setAdmin(<font style="color:#4ec9b0;">address</font> newAdmin) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">require</font>(newAdmin != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC1967: new admin is the zero address"</font>);
        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
    }

    <font style="color:#6a9955;">/**
     * @dev Changes the admin of the proxy.
     *
     * Emits an {AdminChanged} event.
     */</font>
    <font style="color:#569cd6;">function</font> _changeAdmin(<font style="color:#4ec9b0;">address</font> newAdmin) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">emit</font> AdminChanged(_getAdmin(), newAdmin);
        _setAdmin(newAdmin);
    }

    <font style="color:#6a9955;">/**
     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
     */</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">constant</font> _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

    <font style="color:#6a9955;">/**
     * @dev Returns the current beacon.
     */</font>
    <font style="color:#569cd6;">function</font> _getBeacon() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> StorageSlot.getAddressSlot(_BEACON_SLOT).value;
    }

    <font style="color:#6a9955;">/**
     * @dev Stores a new beacon in the EIP1967 beacon slot.
     */</font>
    <font style="color:#569cd6;">function</font> _setBeacon(<font style="color:#4ec9b0;">address</font> newBeacon) <font style="color:#569cd6;">private</font> {
        <font style="color:#569cd6;">require</font>(Address.isContract(newBeacon), <font style="color:#ce9178;">"ERC1967: new beacon is not a contract"</font>);
        <font style="color:#569cd6;">require</font>(
            Address.isContract(IBeacon(newBeacon).implementation()),
            <font style="color:#ce9178;">"ERC1967: beacon implementation is not a contract"</font>
        );
        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
    }

    <font style="color:#6a9955;">/**
     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
     *
     * Emits a {BeaconUpgraded} event.
     */</font>
    <font style="color:#569cd6;">function</font> _upgradeBeaconToAndCall(<font style="color:#4ec9b0;">address</font> newBeacon, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data, <font style="color:#4ec9b0;">bool</font> forceCall) <font style="color:#569cd6;">internal</font> {
        _setBeacon(newBeacon);
        <font style="color:#569cd6;">emit</font> BeaconUpgraded(newBeacon);
        <font style="color:#569cd6;">if</font> (data.length > <font style="color:#b5cea8;">0</font> || forceCall) {
            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Proxy.sol

---

| |
|:---|
| **contracts/openzeppelin/proxy/Proxy.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#6a9955;">/**
 * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
 * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
 * be specified by overriding the virtual {_implementation} function.
 *
 * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
 * different contract through the {_delegate} function.
 *
 * The success and return data of the delegated call will be returned back to the caller of the proxy.
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> Proxy {
    <font style="color:#6a9955;">/**
     * @dev Delegates the current call to `implementation`.
     *
     * This function does not return to its internal call site, it will return directly to the external caller.
     */</font>
    <font style="color:#569cd6;">function</font> _delegate(<font style="color:#4ec9b0;">address</font> implementation) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">assembly</font> {
            <font style="color:#6a9955;">// Copy msg.data. We take full control of memory in this inline assembly</font>
            <font style="color:#6a9955;">// block because it will not return to Solidity code. We overwrite the</font>
            <font style="color:#6a9955;">// Solidity scratch pad at memory position 0.</font>
            calldatacopy(<font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, calldatasize())

            <font style="color:#6a9955;">// Call the implementation.</font>
            <font style="color:#6a9955;">// out and outsize are 0 because we don't know the size yet.</font>
            let result := delegatecall(gas(), implementation, <font style="color:#b5cea8;">0</font>, calldatasize(), <font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>)

            <font style="color:#6a9955;">// Copy the returned data.</font>
            returndatacopy(<font style="color:#b5cea8;">0</font>, <font style="color:#b5cea8;">0</font>, returndatasize())

            switch result
            <font style="color:#6a9955;">// delegatecall returns 0 on error.</font>
            case <font style="color:#b5cea8;">0</font> {
                <font style="color:#569cd6;">revert</font>(<font style="color:#b5cea8;">0</font>, returndatasize())
            }
            default {
                <font style="color:#569cd6;">return</font>(<font style="color:#b5cea8;">0</font>, returndatasize())
            }
        }
    }

    <font style="color:#6a9955;">/**
     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function
     * and {_fallback} should delegate.
     */</font>
    <font style="color:#569cd6;">function</font> _implementation() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>);

    <font style="color:#6a9955;">/**
     * @dev Delegates the current call to the address returned by `_implementation()`.
     *
     * This function does not return to its internal call site, it will return directly to the external caller.
     */</font>
    <font style="color:#569cd6;">function</font> _fallback() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        _beforeFallback();
        _delegate(_implementation());
    }

    <font style="color:#6a9955;">/**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
     * function in the contract matches the call data.
     */</font>
    <font style="color:#569cd6;">fallback</font>() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">payable</font> <font style="color:#569cd6;">virtual</font> {
        _fallback();
    }

    <font style="color:#6a9955;">/**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
     * is empty.
     */</font>
    <font style="color:#569cd6;">receive</font>() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">payable</font> <font style="color:#569cd6;">virtual</font> {
        _fallback();
    }

    <font style="color:#6a9955;">/**
     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
     * call, or as part of the Solidity `fallback` or `receive` functions.
     *
     * If overridden should call `super._beforeFallback()`.
     */</font>
    <font style="color:#569cd6;">function</font> _beforeFallback() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {}
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Initializable.sol

---

| |
|:---|
| **contracts/openzeppelin/proxy/utils/Initializable.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../utils/Address.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> Initializable {
    <font style="color:#6a9955;">/**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */</font>
    <font style="color:#4ec9b0;">uint8</font> <font style="color:#569cd6;">private</font> _initialized;

    <font style="color:#6a9955;">/**
     * @dev Indicates that the contract is in the process of being initialized.
     */</font>
    <font style="color:#4ec9b0;">bool</font> <font style="color:#569cd6;">private</font> _initializing;

    <font style="color:#6a9955;">/**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */</font>
    <font style="color:#569cd6;">event</font> Initialized(<font style="color:#4ec9b0;">uint8</font> version);

    <font style="color:#6a9955;">/**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */</font>
    <font style="color:#569cd6;">modifier</font> initializer() {
        <font style="color:#4ec9b0;">bool</font> isTopLevelCall = !_initializing;
        <font style="color:#569cd6;">require</font>(
            (isTopLevelCall && _initialized < <font style="color:#b5cea8;">1</font>) || (!Address.isContract(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>)) && _initialized == <font style="color:#b5cea8;">1</font>),
            <font style="color:#ce9178;">"Initializable: contract is already initialized"</font>
        );
        _initialized = <font style="color:#b5cea8;">1</font>;
        <font style="color:#569cd6;">if</font> (isTopLevelCall) {
            _initializing = <font style="color:#569cd6;">true</font>;
        }
        _;
        <font style="color:#569cd6;">if</font> (isTopLevelCall) {
            _initializing = <font style="color:#569cd6;">false</font>;
            <font style="color:#569cd6;">emit</font> Initialized(<font style="color:#b5cea8;">1</font>);
        }
    }

    <font style="color:#6a9955;">/**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: setting the version to 255 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */</font>
    <font style="color:#569cd6;">modifier</font> reinitializer(<font style="color:#4ec9b0;">uint8</font> version) {
        <font style="color:#569cd6;">require</font>(!_initializing && _initialized < version, <font style="color:#ce9178;">"Initializable: contract is already initialized"</font>);
        _initialized = version;
        _initializing = <font style="color:#569cd6;">true</font>;
        _;
        _initializing = <font style="color:#569cd6;">false</font>;
        <font style="color:#569cd6;">emit</font> Initialized(version);
    }

    <font style="color:#6a9955;">/**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */</font>
    <font style="color:#569cd6;">modifier</font> onlyInitializing() {
        <font style="color:#569cd6;">require</font>(_initializing, <font style="color:#ce9178;">"Initializable: contract is not initializing"</font>);
        _;
    }

    <font style="color:#6a9955;">/**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */</font>
    <font style="color:#569cd6;">function</font> _disableInitializers() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">require</font>(!_initializing, <font style="color:#ce9178;">"Initializable: contract is initializing"</font>);
        <font style="color:#569cd6;">if</font> (_initialized != type(<font style="color:#4ec9b0;">uint8</font>).max) {
            _initialized = type(<font style="color:#4ec9b0;">uint8</font>).max;
            <font style="color:#569cd6;">emit</font> Initialized(type(<font style="color:#4ec9b0;">uint8</font>).max);
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */</font>
    <font style="color:#569cd6;">function</font> _getInitializedVersion() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {
        <font style="color:#569cd6;">return</font> _initialized;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */</font>
    <font style="color:#569cd6;">function</font> _isInitializing() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _initializing;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## UUPSUpgradeable.sol

---

| |
|:---|
| **contracts/openzeppelin/proxy/utils/UUPSUpgradeable.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../interfaces/draft-IERC1822.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../ERC1967/ERC1967Upgrade.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
 * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
 *
 * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
 * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
 * `UUPSUpgradeable` with a custom implementation of upgrades.
 *
 * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
 *
 * _Available since v4.1._
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> UUPSUpgradeable <font style="color:#569cd6;">is</font> IERC1822Proxiable, ERC1967Upgrade {
    <font style="color:#6a9955;">/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment</font>
    <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">immutable</font> __self = <font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>);

    <font style="color:#6a9955;">/**
     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
     * fail.
     */</font>
    <font style="color:#569cd6;">modifier</font> onlyProxy() {
        <font style="color:#569cd6;">require</font>(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>) != __self, <font style="color:#ce9178;">"Function must be called through delegatecall"</font>);
        <font style="color:#569cd6;">require</font>(_getImplementation() == __self, <font style="color:#ce9178;">"Function must be called through active proxy"</font>);
        _;
    }

    <font style="color:#6a9955;">/**
     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
     * callable on the implementing contract but not through proxies.
     */</font>
    <font style="color:#569cd6;">modifier</font> notDelegated() {
        <font style="color:#569cd6;">require</font>(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>) == __self, <font style="color:#ce9178;">"UUPSUpgradeable: must not be called through delegatecall"</font>);
        _;
    }

    <font style="color:#6a9955;">/**
     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
     */</font>
    <font style="color:#569cd6;">function</font> proxiableUUID() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> notDelegated <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>) {
        <font style="color:#569cd6;">return</font> _IMPLEMENTATION_SLOT;
    }

    <font style="color:#6a9955;">/**
     * @dev Upgrade the implementation of the proxy to `newImplementation`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     *
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */</font>
    <font style="color:#569cd6;">function</font> upgradeTo(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, <font style="color:#569cd6;">new</font> <font style="color:#4ec9b0;">bytes</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#569cd6;">false</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
     * encoded in `data`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     *
     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
     */</font>
    <font style="color:#569cd6;">function</font> upgradeToAndCall(<font style="color:#4ec9b0;">address</font> newImplementation, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">payable</font> <font style="color:#569cd6;">virtual</font> onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, data, <font style="color:#569cd6;">true</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
     * {upgradeTo} and {upgradeToAndCall}.
     *
     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
     *
     * ```solidity
     * function _authorizeUpgrade(address) internal override onlyOwner {}
     * ```
     */</font>
    <font style="color:#569cd6;">function</font> _authorizeUpgrade(<font style="color:#4ec9b0;">address</font> newImplementation) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font>;
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ERC20.sol

---

| |
|:---|
| **contracts/openzeppelin/token/ERC20/ERC20.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./IERC20.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"./extensions/IERC20Metadata.sol"</font>;
<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../../utils/Context.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */</font>
<font style="color:#569cd6;">contract</font> ERC20 <font style="color:#569cd6;">is</font> Context, IERC20, IERC20Metadata {
    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint256</font>) <font style="color:#569cd6;">private</font> _balances;

    <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint256</font>)) <font style="color:#569cd6;">private</font> _allowances;

    <font style="color:#4ec9b0;">uint256</font> <font style="color:#569cd6;">private</font> _totalSupply;

    <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">private</font> _name;
    <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">private</font> _symbol;

    <font style="color:#6a9955;">/**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */</font>
    <font style="color:#569cd6;">constructor</font>(<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> name_, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the name of the token.
     */</font>
    <font style="color:#569cd6;">function</font> name() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _name;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */</font>
    <font style="color:#569cd6;">function</font> symbol() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> _symbol;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */</font>
    <font style="color:#569cd6;">function</font> decimals() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">18</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-totalSupply}.
     */</font>
    <font style="color:#569cd6;">function</font> totalSupply() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _totalSupply;
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-balanceOf}.
     */</font>
    <font style="color:#569cd6;">function</font> balanceOf(<font style="color:#4ec9b0;">address</font> account) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _balances[account];
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */</font>
    <font style="color:#569cd6;">function</font> transfer(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> owner = _msgSender();
        _transfer(owner, to, amount);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-allowance}.
     */</font>
    <font style="color:#569cd6;">function</font> allowance(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _allowances[owner][spender];
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */</font>
    <font style="color:#569cd6;">function</font> approve(<font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> owner = _msgSender();
        _approve(owner, spender, amount);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */</font>
    <font style="color:#569cd6;">function</font> transferFrom(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">override</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> spender = _msgSender();
        _spendAllowance(<font style="color:#569cd6;">from</font>, spender, amount);
        _transfer(<font style="color:#569cd6;">from</font>, to, amount);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */</font>
    <font style="color:#569cd6;">function</font> increaseAllowance(<font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> addedValue) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */</font>
    <font style="color:#569cd6;">function</font> decreaseAllowance(<font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> subtractedValue) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> owner = _msgSender();
        <font style="color:#4ec9b0;">uint256</font> currentAllowance = allowance(owner, spender);
        <font style="color:#569cd6;">require</font>(currentAllowance >= subtractedValue, <font style="color:#ce9178;">"ERC20: decreased allowance below zero"</font>);
        <font style="color:#569cd6;">unchecked</font> {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */</font>
    <font style="color:#569cd6;">function</font> _transfer(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">require</font>(<font style="color:#569cd6;">from</font> != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC20: transfer from the zero address"</font>);
        <font style="color:#569cd6;">require</font>(to != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC20: transfer to the zero address"</font>);

        _beforeTokenTransfer(<font style="color:#569cd6;">from</font>, to, amount);

        <font style="color:#4ec9b0;">uint256</font> fromBalance = _balances[<font style="color:#569cd6;">from</font>];
        <font style="color:#569cd6;">require</font>(fromBalance >= amount, <font style="color:#ce9178;">"ERC20: transfer amount exceeds balance"</font>);
        <font style="color:#569cd6;">unchecked</font> {
            _balances[<font style="color:#569cd6;">from</font>] = fromBalance - amount;
            <font style="color:#6a9955;">// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by</font>
            <font style="color:#6a9955;">// decrementing then incrementing.</font>
            _balances[to] += amount;
        }

        <font style="color:#569cd6;">emit</font> Transfer(<font style="color:#569cd6;">from</font>, to, amount);

        _afterTokenTransfer(<font style="color:#569cd6;">from</font>, to, amount);
    }

    <font style="color:#6a9955;">/** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */</font>
    <font style="color:#569cd6;">function</font> _mint(<font style="color:#4ec9b0;">address</font> account, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">require</font>(account != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC20: mint to the zero address"</font>);

        _beforeTokenTransfer(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), account, amount);

        _totalSupply += amount;
        <font style="color:#569cd6;">unchecked</font> {
            <font style="color:#6a9955;">// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.</font>
            _balances[account] += amount;
        }
        <font style="color:#569cd6;">emit</font> Transfer(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), account, amount);

        _afterTokenTransfer(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), account, amount);
    }

    <font style="color:#6a9955;">/**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */</font>
    <font style="color:#569cd6;">function</font> _burn(<font style="color:#4ec9b0;">address</font> account, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">require</font>(account != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC20: burn from the zero address"</font>);

        _beforeTokenTransfer(account, <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), amount);

        <font style="color:#4ec9b0;">uint256</font> accountBalance = _balances[account];
        <font style="color:#569cd6;">require</font>(accountBalance >= amount, <font style="color:#ce9178;">"ERC20: burn amount exceeds balance"</font>);
        <font style="color:#569cd6;">unchecked</font> {
            _balances[account] = accountBalance - amount;
            <font style="color:#6a9955;">// Overflow not possible: amount <= accountBalance <= totalSupply.</font>
            _totalSupply -= amount;
        }

        <font style="color:#569cd6;">emit</font> Transfer(account, <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), amount);

        _afterTokenTransfer(account, <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), amount);
    }

    <font style="color:#6a9955;">/**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */</font>
    <font style="color:#569cd6;">function</font> _approve(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#569cd6;">require</font>(owner != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC20: approve from the zero address"</font>);
        <font style="color:#569cd6;">require</font>(spender != <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), <font style="color:#ce9178;">"ERC20: approve to the zero address"</font>);

        _allowances[owner][spender] = amount;
        <font style="color:#569cd6;">emit</font> Approval(owner, spender, amount);
    }

    <font style="color:#6a9955;">/**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */</font>
    <font style="color:#569cd6;">function</font> _spendAllowance(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#4ec9b0;">uint256</font> currentAllowance = allowance(owner, spender);
        <font style="color:#569cd6;">if</font> (currentAllowance != type(<font style="color:#4ec9b0;">uint256</font>).max) {
            <font style="color:#569cd6;">require</font>(currentAllowance >= amount, <font style="color:#ce9178;">"ERC20: insufficient allowance"</font>);
            <font style="color:#569cd6;">unchecked</font> {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */</font>
    <font style="color:#569cd6;">function</font> _beforeTokenTransfer(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {}

    <font style="color:#6a9955;">/**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */</font>
    <font style="color:#569cd6;">function</font> _afterTokenTransfer(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {}
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ERC20Upgradeable.sol

---

| |
|:---|
| **contracts/openzeppelin/token/ERC20/ERC20Upgradeable.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/ERC20.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#569cd6;">import</font> {IERC20} <font style="color:#569cd6;">from</font> <font style="color:#ce9178;">"./IERC20.sol"</font>;
<font style="color:#569cd6;">import</font> {IERC20Metadata} <font style="color:#569cd6;">from</font> <font style="color:#ce9178;">"./extensions/IERC20Metadata.sol"</font>;
<font style="color:#569cd6;">import</font> {ContextUpgradeable} <font style="color:#569cd6;">from</font> <font style="color:#ce9178;">"../../utils/ContextUpgradeable.sol"</font>;
<font style="color:#569cd6;">import</font> {IERC20Errors} <font style="color:#569cd6;">from</font> <font style="color:#ce9178;">"../../interfaces/draft-IERC6093.sol"</font>;
<font style="color:#569cd6;">import</font> {Initializable} <font style="color:#569cd6;">from</font> <font style="color:#ce9178;">"../../proxy/utils/Initializable.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> ERC20Upgradeable <font style="color:#569cd6;">is</font> Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
    <font style="color:#6a9955;">/// @custom:storage-location erc7201:openzeppelin.storage.ERC20</font>
    <font style="color:#569cd6;">struct</font> ERC20Storage {
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint256</font>) _balances;

        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">address</font> => <font style="color:#4ec9b0;">uint256</font>)) _allowances;

        <font style="color:#4ec9b0;">uint256</font> _totalSupply;

        <font style="color:#4ec9b0;">string</font> _name;
        <font style="color:#4ec9b0;">string</font> _symbol;
    }

    <font style="color:#6a9955;">// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))</font>
    <font style="color:#4ec9b0;">bytes32</font> <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">constant</font> ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;

    <font style="color:#569cd6;">function</font> _getERC20Storage() <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (ERC20Storage <font style="color:#569cd6;">storage</font> $) {
        <font style="color:#569cd6;">assembly</font> {
            $.slot := ERC20StorageLocation
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Sets the values for {name} and {symbol}.
     *
     * Both values are immutable: they can only be set once during construction.
     */</font>
    <font style="color:#569cd6;">function</font> __ERC20_init(<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> name_, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> symbol_) <font style="color:#569cd6;">internal</font> onlyInitializing {
        __ERC20_init_unchained(name_, symbol_);
    }

    <font style="color:#569cd6;">function</font> __ERC20_init_unchained(<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> name_, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> symbol_) <font style="color:#569cd6;">internal</font> onlyInitializing {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        $._name = name_;
        $._symbol = symbol_;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the name of the token.
     */</font>
    <font style="color:#569cd6;">function</font> name() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font>) {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">return</font> $._name;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */</font>
    <font style="color:#569cd6;">function</font> symbol() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font>) {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">return</font> $._symbol;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */</font>
    <font style="color:#569cd6;">function</font> decimals() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">18</font>;
    }

    <font style="color:#6a9955;">/// @inheritdoc IERC20</font>
    <font style="color:#569cd6;">function</font> totalSupply() <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">return</font> $._totalSupply;
    }

    <font style="color:#6a9955;">/// @inheritdoc IERC20</font>
    <font style="color:#569cd6;">function</font> balanceOf(<font style="color:#4ec9b0;">address</font> account) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">return</font> $._balances[account];
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */</font>
    <font style="color:#569cd6;">function</font> transfer(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> owner = _msgSender();
        _transfer(owner, to, value);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/// @inheritdoc IERC20</font>
    <font style="color:#569cd6;">function</font> allowance(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">return</font> $._allowances[owner][spender];
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */</font>
    <font style="color:#569cd6;">function</font> approve(<font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> owner = _msgSender();
        _approve(owner, spender, value);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */</font>
    <font style="color:#569cd6;">function</font> transferFrom(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#4ec9b0;">address</font> spender = _msgSender();
        _spendAllowance(<font style="color:#569cd6;">from</font>, spender, value);
        _transfer(<font style="color:#569cd6;">from</font>, to, value);
        <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */</font>
    <font style="color:#569cd6;">function</font> _transfer(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">if</font> (<font style="color:#569cd6;">from</font> == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ERC20InvalidSender(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        }
        <font style="color:#569cd6;">if</font> (to == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ERC20InvalidReceiver(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        }
        _update(<font style="color:#569cd6;">from</font>, to, value);
    }

    <font style="color:#6a9955;">/**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */</font>
    <font style="color:#569cd6;">function</font> _update(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">if</font> (<font style="color:#569cd6;">from</font> == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#6a9955;">// Overflow check required: The rest of the code assumes that totalSupply never overflows</font>
            $._totalSupply += value;
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#4ec9b0;">uint256</font> fromBalance = $._balances[<font style="color:#569cd6;">from</font>];
            <font style="color:#569cd6;">if</font> (fromBalance < value) {
                <font style="color:#569cd6;">revert</font> ERC20InsufficientBalance(<font style="color:#569cd6;">from</font>, fromBalance, value);
            }
            <font style="color:#569cd6;">unchecked</font> {
                <font style="color:#6a9955;">// Overflow not possible: value <= fromBalance <= totalSupply.</font>
                $._balances[<font style="color:#569cd6;">from</font>] = fromBalance - value;
            }
        }

        <font style="color:#569cd6;">if</font> (to == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">unchecked</font> {
                <font style="color:#6a9955;">// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.</font>
                $._totalSupply -= value;
            }
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">unchecked</font> {
                <font style="color:#6a9955;">// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.</font>
                $._balances[to] += value;
            }
        }

        <font style="color:#569cd6;">emit</font> Transfer(<font style="color:#569cd6;">from</font>, to, value);
    }

    <font style="color:#6a9955;">/**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */</font>
    <font style="color:#569cd6;">function</font> _mint(<font style="color:#4ec9b0;">address</font> account, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">if</font> (account == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ERC20InvalidReceiver(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        }
        _update(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), account, value);
    }

    <font style="color:#6a9955;">/**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */</font>
    <font style="color:#569cd6;">function</font> _burn(<font style="color:#4ec9b0;">address</font> account, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">if</font> (account == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ERC20InvalidSender(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        }
        _update(account, <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>), value);
    }

    <font style="color:#6a9955;">/**
     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */</font>
    <font style="color:#569cd6;">function</font> _approve(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> {
        _approve(owner, spender, value, <font style="color:#569cd6;">true</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation sets the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the `transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */</font>
    <font style="color:#569cd6;">function</font> _approve(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> value, <font style="color:#4ec9b0;">bool</font> emitEvent) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        ERC20Storage <font style="color:#569cd6;">storage</font> $ = _getERC20Storage();
        <font style="color:#569cd6;">if</font> (owner == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ERC20InvalidApprover(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        }
        <font style="color:#569cd6;">if</font> (spender == <font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>)) {
            <font style="color:#569cd6;">revert</font> ERC20InvalidSpender(<font style="color:#4ec9b0;">address</font>(<font style="color:#b5cea8;">0</font>));
        }
        $._allowances[owner][spender] = value;
        <font style="color:#569cd6;">if</font> (emitEvent) {
            <font style="color:#569cd6;">emit</font> Approval(owner, spender, value);
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */</font>
    <font style="color:#569cd6;">function</font> _spendAllowance(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">virtual</font> {
        <font style="color:#4ec9b0;">uint256</font> currentAllowance = allowance(owner, spender);
        <font style="color:#569cd6;">if</font> (currentAllowance < type(<font style="color:#4ec9b0;">uint256</font>).max) {
            <font style="color:#569cd6;">if</font> (currentAllowance < value) {
                <font style="color:#569cd6;">revert</font> ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            <font style="color:#569cd6;">unchecked</font> {
                _approve(owner, spender, currentAllowance - value, <font style="color:#569cd6;">false</font>);
            }
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IERC20Metadata.sol

---

| |
|:---|
| **contracts/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#569cd6;">import</font> <font style="color:#ce9178;">"../IERC20.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */</font>
<font style="color:#569cd6;">interface</font> IERC20Metadata <font style="color:#569cd6;">is</font> IERC20 {
    <font style="color:#6a9955;">/**
     * @dev Returns the name of the token.
     */</font>
    <font style="color:#569cd6;">function</font> name() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns the symbol of the token.
     */</font>
    <font style="color:#569cd6;">function</font> symbol() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns the decimals places of the token.
     */</font>
    <font style="color:#569cd6;">function</font> decimals() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint8</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## IERC20.sol

---

| |
|:---|
| **contracts/openzeppelin/token/ERC20/IERC20.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#6a9955;">/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */</font>
<font style="color:#569cd6;">interface</font> IERC20 {
    <font style="color:#6a9955;">/**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */</font>
    <font style="color:#569cd6;">event</font> Transfer(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> to, <font style="color:#4ec9b0;">uint256</font> value);

    <font style="color:#6a9955;">/**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */</font>
    <font style="color:#569cd6;">event</font> Approval(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> owner, <font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">indexed</font> spender, <font style="color:#4ec9b0;">uint256</font> value);

    <font style="color:#6a9955;">/**
     * @dev Returns the amount of tokens in existence.
     */</font>
    <font style="color:#569cd6;">function</font> totalSupply() <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns the amount of tokens owned by `account`.
     */</font>
    <font style="color:#569cd6;">function</font> balanceOf(<font style="color:#4ec9b0;">address</font> account) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */</font>
    <font style="color:#569cd6;">function</font> transfer(<font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */</font>
    <font style="color:#569cd6;">function</font> allowance(<font style="color:#4ec9b0;">address</font> owner, <font style="color:#4ec9b0;">address</font> spender) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>);

    <font style="color:#6a9955;">/**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */</font>
    <font style="color:#569cd6;">function</font> approve(<font style="color:#4ec9b0;">address</font> spender, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);

    <font style="color:#6a9955;">/**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */</font>
    <font style="color:#569cd6;">function</font> transferFrom(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">from</font>, <font style="color:#4ec9b0;">address</font> to, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">external</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>);
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Address.sol

---

| |
|:---|
| **contracts/openzeppelin/utils/Address.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/**
 * @dev Collection of functions related to the address type
 */</font>
<font style="color:#569cd6;">library</font> Address {
    <font style="color:#6a9955;">/**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */</font>
    <font style="color:#569cd6;">function</font> isContract(<font style="color:#4ec9b0;">address</font> account) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#6a9955;">// This method relies on extcodesize/address.code.length, which returns 0</font>
        <font style="color:#6a9955;">// for contracts in construction, since the code is only stored at the end</font>
        <font style="color:#6a9955;">// of the constructor execution.</font>

        <font style="color:#569cd6;">return</font> account.code.length > <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */</font>
    <font style="color:#569cd6;">function</font> sendValue(<font style="color:#4ec9b0;">address</font> <font style="color:#569cd6;">payable</font> recipient, <font style="color:#4ec9b0;">uint256</font> amount) <font style="color:#569cd6;">internal</font> {
        <font style="color:#569cd6;">require</font>(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).balance >= amount, <font style="color:#ce9178;">"Address: insufficient balance"</font>);

        (<font style="color:#4ec9b0;">bool</font> success, ) = recipient.call{value: amount}(<font style="color:#ce9178;">""</font>);
        <font style="color:#569cd6;">require</font>(success, <font style="color:#ce9178;">"Address: unable to send value, recipient may have reverted"</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */</font>
    <font style="color:#569cd6;">function</font> functionCall(<font style="color:#4ec9b0;">address</font> target, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> functionCallWithValue(target, data, <font style="color:#b5cea8;">0</font>, <font style="color:#ce9178;">"Address: low-level call failed"</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */</font>
    <font style="color:#569cd6;">function</font> functionCall(
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage
    ) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> functionCallWithValue(target, data, <font style="color:#b5cea8;">0</font>, errorMessage);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */</font>
    <font style="color:#569cd6;">function</font> functionCallWithValue(<font style="color:#4ec9b0;">address</font> target, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> functionCallWithValue(target, data, value, <font style="color:#ce9178;">"Address: low-level call with value failed"</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */</font>
    <font style="color:#569cd6;">function</font> functionCallWithValue(
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data,
        <font style="color:#4ec9b0;">uint256</font> value,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage
    ) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">require</font>(<font style="color:#4ec9b0;">address</font>(<font style="color:#569cd6;">this</font>).balance >= value, <font style="color:#ce9178;">"Address: insufficient balance for call"</font>);
        (<font style="color:#4ec9b0;">bool</font> success, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> returndata) = target.call{value: value}(data);
        <font style="color:#569cd6;">return</font> verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */</font>
    <font style="color:#569cd6;">function</font> functionStaticCall(<font style="color:#4ec9b0;">address</font> target, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> functionStaticCall(target, data, <font style="color:#ce9178;">"Address: low-level static call failed"</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */</font>
    <font style="color:#569cd6;">function</font> functionStaticCall(
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage
    ) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        (<font style="color:#4ec9b0;">bool</font> success, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> returndata) = target.staticcall(data);
        <font style="color:#569cd6;">return</font> verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */</font>
    <font style="color:#569cd6;">function</font> functionDelegateCall(<font style="color:#4ec9b0;">address</font> target, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> functionDelegateCall(target, data, <font style="color:#ce9178;">"Address: low-level delegate call failed"</font>);
    }

    <font style="color:#6a9955;">/**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */</font>
    <font style="color:#569cd6;">function</font> functionDelegateCall(
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> data,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage
    ) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        (<font style="color:#4ec9b0;">bool</font> success, <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> returndata) = target.delegatecall(data);
        <font style="color:#569cd6;">return</font> verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    <font style="color:#6a9955;">/**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */</font>
    <font style="color:#569cd6;">function</font> verifyCallResultFromTarget(
        <font style="color:#4ec9b0;">address</font> target,
        <font style="color:#4ec9b0;">bool</font> success,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> returndata,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage
    ) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (success) {
            <font style="color:#569cd6;">if</font> (returndata.length == <font style="color:#b5cea8;">0</font>) {
                <font style="color:#6a9955;">// only check isContract if the call was successful and the return data is empty</font>
                <font style="color:#6a9955;">// otherwise we already know that it was a contract</font>
                <font style="color:#569cd6;">require</font>(isContract(target), <font style="color:#ce9178;">"Address: call to non-contract"</font>);
            }
            <font style="color:#569cd6;">return</font> returndata;
        } <font style="color:#569cd6;">else</font> {
            _revert(returndata, errorMessage);
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */</font>
    <font style="color:#569cd6;">function</font> verifyCallResult(
        <font style="color:#4ec9b0;">bool</font> success,
        <font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> returndata,
        <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage
    ) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">if</font> (success) {
            <font style="color:#569cd6;">return</font> returndata;
        } <font style="color:#569cd6;">else</font> {
            _revert(returndata, errorMessage);
        }
    }

    <font style="color:#569cd6;">function</font> _revert(<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">memory</font> returndata, <font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">memory</font> errorMessage) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">pure</font> {
        <font style="color:#6a9955;">// Look for revert reason and bubble it up if present</font>
        <font style="color:#569cd6;">if</font> (returndata.length > <font style="color:#b5cea8;">0</font>) {
            <font style="color:#6a9955;">// The easiest way to bubble the revert reason is using memory via assembly</font>
            <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
            <font style="color:#569cd6;">assembly</font> {
                let returndata_size := mload(returndata)
                <font style="color:#569cd6;">revert</font>(add(<font style="color:#b5cea8;">32</font>, returndata), returndata_size)
            }
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">revert</font>(errorMessage);
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Context.sol

---

| |
|:---|
| **contracts/openzeppelin/utils/Context.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">0</font>;

<font style="color:#6a9955;">/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> Context {
    <font style="color:#569cd6;">function</font> _msgSender() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> msg.sender;
    }

    <font style="color:#569cd6;">function</font> _msgData() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">calldata</font>) {
        <font style="color:#569cd6;">return</font> msg.data;
    }

    <font style="color:#569cd6;">function</font> _contextSuffixLength() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## ContextUpgradeable.sol

---

| |
|:---|
| **contracts/openzeppelin/utils/ContextUpgradeable.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;
<font style="color:#569cd6;">import</font> {Initializable} <font style="color:#569cd6;">from</font> <font style="color:#ce9178;">"../proxy/utils/Initializable.sol"</font>;

<font style="color:#6a9955;">/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */</font>
<font style="color:#569cd6;">abstract</font> <font style="color:#569cd6;">contract</font> ContextUpgradeable <font style="color:#569cd6;">is</font> Initializable {
    <font style="color:#569cd6;">function</font> __Context_init() <font style="color:#569cd6;">internal</font> onlyInitializing {
    }

    <font style="color:#569cd6;">function</font> __Context_init_unchained() <font style="color:#569cd6;">internal</font> onlyInitializing {
    }
    <font style="color:#569cd6;">function</font> _msgSender() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> msg.sender;
    }

    <font style="color:#569cd6;">function</font> _msgData() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">calldata</font>) {
        <font style="color:#569cd6;">return</font> msg.data;
    }

    <font style="color:#569cd6;">function</font> _contextSuffixLength() <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">virtual</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#b5cea8;">0</font>;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## StorageSlot.sol

---

| |
|:---|
| **contracts/openzeppelin/utils/StorageSlot.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)</font>
<font style="color:#6a9955;">// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */</font>
<font style="color:#569cd6;">library</font> StorageSlot {
    <font style="color:#569cd6;">struct</font> AddressSlot {
        <font style="color:#4ec9b0;">address</font> value;
    }

    <font style="color:#569cd6;">struct</font> BooleanSlot {
        <font style="color:#4ec9b0;">bool</font> value;
    }

    <font style="color:#569cd6;">struct</font> Bytes32Slot {
        <font style="color:#4ec9b0;">bytes32</font> value;
    }

    <font style="color:#569cd6;">struct</font> Uint256Slot {
        <font style="color:#4ec9b0;">uint256</font> value;
    }

    <font style="color:#569cd6;">struct</font> StringSlot {
        <font style="color:#4ec9b0;">string</font> value;
    }

    <font style="color:#569cd6;">struct</font> BytesSlot {
        <font style="color:#4ec9b0;">bytes</font> value;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */</font>
    <font style="color:#569cd6;">function</font> getAddressSlot(<font style="color:#4ec9b0;">bytes32</font> slot) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (AddressSlot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */</font>
    <font style="color:#569cd6;">function</font> getBooleanSlot(<font style="color:#4ec9b0;">bytes32</font> slot) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (BooleanSlot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */</font>
    <font style="color:#569cd6;">function</font> getBytes32Slot(<font style="color:#4ec9b0;">bytes32</font> slot) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Bytes32Slot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */</font>
    <font style="color:#569cd6;">function</font> getUint256Slot(<font style="color:#4ec9b0;">bytes32</font> slot) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (Uint256Slot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */</font>
    <font style="color:#569cd6;">function</font> getStringSlot(<font style="color:#4ec9b0;">bytes32</font> slot) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (StringSlot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */</font>
    <font style="color:#569cd6;">function</font> getStringSlot(<font style="color:#4ec9b0;">string</font> <font style="color:#569cd6;">storage</font> store) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (StringSlot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := store.slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */</font>
    <font style="color:#569cd6;">function</font> getBytesSlot(<font style="color:#4ec9b0;">bytes32</font> slot) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (BytesSlot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := slot
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */</font>
    <font style="color:#569cd6;">function</font> getBytesSlot(<font style="color:#4ec9b0;">bytes</font> <font style="color:#569cd6;">storage</font> store) <font style="color:#569cd6;">internal</font> <font style="color:#569cd6;">pure</font> <font style="color:#569cd6;">returns</font> (BytesSlot <font style="color:#569cd6;">storage</font> r) {
        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            r.slot := store.slot
        }
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## EnumerableSet.sol

---

| |
|:---|
| **contracts/openzeppelin/utils/structs/EnumerableSet.sol** |
| 
```
<pre class="language-solidity" style="margin: 0; padding: 10px 12px; color: #d4d4d4; background-color: #1e1e1e; white-space: pre; tab-size: 4; -moz-tab-size: 4; overflow-x: auto; font-family: Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.45;"><code class="language-solidity"><font style="color:#6a9955;">// SPDX-License-Identifier: MIT</font>
<font style="color:#6a9955;">// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)</font>
<font style="color:#6a9955;">// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.</font>

<font style="color:#6a9955;">/// @notice for saving bytes codes, some private funcs are revised into public</font>
<font style="color:#6a9955;">/// so as to be called by other libraries or contracts by using link.</font>

<font style="color:#569cd6;">pragma</font> <font style="color:#569cd6;">solidity</font> ^<font style="color:#b5cea8;">0</font>.<font style="color:#b5cea8;">8</font>.<font style="color:#b5cea8;">24</font>;

<font style="color:#6a9955;">/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */</font>
<font style="color:#569cd6;">library</font> EnumerableSet {
    <font style="color:#6a9955;">// To implement this library for multiple types with as little code</font>
    <font style="color:#6a9955;">// repetition as possible, we write it in terms of a generic Set type with</font>
    <font style="color:#6a9955;">// bytes32 values.</font>
    <font style="color:#6a9955;">// The Set implementation uses private functions, and user-facing</font>
    <font style="color:#6a9955;">// implementations (such as AddressSet) are just wrappers around the</font>
    <font style="color:#6a9955;">// underlying Set.</font>
    <font style="color:#6a9955;">// This means that we can only create new EnumerableSets for types that fit</font>
    <font style="color:#6a9955;">// in bytes32.</font>

    <font style="color:#569cd6;">struct</font> Set {
        <font style="color:#6a9955;">// Storage of set values</font>
        <font style="color:#4ec9b0;">bytes32</font>[] _values;
        <font style="color:#6a9955;">// Position of the value in the `values` array, plus 1 because index 0</font>
        <font style="color:#6a9955;">// means a value is not in the set.</font>
        <font style="color:#569cd6;">mapping</font>(<font style="color:#4ec9b0;">bytes32</font> => <font style="color:#4ec9b0;">uint256</font>) _indexes;
    }

    <font style="color:#6a9955;">/**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */</font>
    <font style="color:#569cd6;">function</font> _add(Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">bytes32</font> value) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">if</font> (!_contains(set, value)) {
            set._values.push(value);
            <font style="color:#6a9955;">// The value is stored at length-1, but we add 1 to all indexes</font>
            <font style="color:#6a9955;">// and use 0 as a sentinel value</font>
            set._indexes[value] = set._values.length;
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */</font>
    <font style="color:#569cd6;">function</font> _remove(Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">bytes32</font> value) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#6a9955;">// We read and store the value's index to prevent multiple reads from the same storage slot</font>
        <font style="color:#4ec9b0;">uint256</font> valueIndex = set._indexes[value];

        <font style="color:#569cd6;">if</font> (valueIndex != <font style="color:#b5cea8;">0</font>) {
            <font style="color:#6a9955;">// Equivalent to contains(set, value)</font>
            <font style="color:#6a9955;">// To delete an element from the _values array in O(1), we swap the element to delete with the last one in</font>
            <font style="color:#6a9955;">// the array, and then remove the last element (sometimes called as 'swap and pop').</font>
            <font style="color:#6a9955;">// This modifies the order of the array, as noted in {at}.</font>

            <font style="color:#4ec9b0;">uint256</font> toDeleteIndex = valueIndex - <font style="color:#b5cea8;">1</font>;
            <font style="color:#4ec9b0;">uint256</font> lastIndex = set._values.length - <font style="color:#b5cea8;">1</font>;

            <font style="color:#569cd6;">if</font> (lastIndex != toDeleteIndex) {
                <font style="color:#4ec9b0;">bytes32</font> lastValue = set._values[lastIndex];

                <font style="color:#6a9955;">// Move the last value to the index where the value to delete is</font>
                set._values[toDeleteIndex] = lastValue;
                <font style="color:#6a9955;">// Update the index for the moved value</font>
                set._indexes[lastValue] = valueIndex; <font style="color:#6a9955;">// Replace lastValue's index to valueIndex</font>
            }

            <font style="color:#6a9955;">// Delete the slot where the moved value was stored</font>
            set._values.pop();

            <font style="color:#6a9955;">// Delete the index for the deleted slot</font>
            <font style="color:#569cd6;">delete</font> set._indexes[value];

            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">true</font>;
        } <font style="color:#569cd6;">else</font> {
            <font style="color:#569cd6;">return</font> <font style="color:#569cd6;">false</font>;
        }
    }

    <font style="color:#6a9955;">/**
     * @dev Returns true if the value is in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> _contains(Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">bytes32</font> value) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> set._indexes[value] != <font style="color:#b5cea8;">0</font>;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the number of values on the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> _length(Set <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> set._values.length;
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */</font>
    <font style="color:#569cd6;">function</font> _at(Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> index) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>) {
        <font style="color:#569cd6;">return</font> set._values[index];
    }

    <font style="color:#6a9955;">/**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */</font>
    <font style="color:#569cd6;">function</font> _values(Set <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">private</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#569cd6;">return</font> set._values;
    }

    <font style="color:#6a9955;">// Bytes32Set</font>

    <font style="color:#569cd6;">struct</font> Bytes32Set {
        Set _inner;
    }

    <font style="color:#6a9955;">/**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */</font>
    <font style="color:#569cd6;">function</font> add(Bytes32Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">bytes32</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _add(set._inner, value);
    }

    <font style="color:#6a9955;">/**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */</font>
    <font style="color:#569cd6;">function</font> remove(Bytes32Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">bytes32</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _remove(set._inner, value);
    }

    <font style="color:#6a9955;">/**
     * @dev Returns true if the value is in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> contains(Bytes32Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">bytes32</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _contains(set._inner, value);
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the number of values in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> length(Bytes32Set <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _length(set._inner);
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */</font>
    <font style="color:#569cd6;">function</font> at(Bytes32Set <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> index) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>) {
        <font style="color:#569cd6;">return</font> _at(set._inner, index);
    }

    <font style="color:#6a9955;">/**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */</font>
    <font style="color:#569cd6;">function</font> values(Bytes32Set <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> store = _values(set._inner);
        <font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> result;

        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            result := store
        }

        <font style="color:#569cd6;">return</font> result;
    }

    <font style="color:#6a9955;">// AddressSet</font>

    <font style="color:#569cd6;">struct</font> AddressSet {
        Set _inner;
    }

    <font style="color:#6a9955;">/**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */</font>
    <font style="color:#569cd6;">function</font> add(AddressSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">address</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _add(set._inner, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint256</font>(<font style="color:#4ec9b0;">uint160</font>(value))));
    }

    <font style="color:#6a9955;">/**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */</font>
    <font style="color:#569cd6;">function</font> remove(AddressSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">address</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _remove(set._inner, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint256</font>(<font style="color:#4ec9b0;">uint160</font>(value))));
    }

    <font style="color:#6a9955;">/**
     * @dev Returns true if the value is in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> contains(AddressSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">address</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _contains(set._inner, <font style="color:#4ec9b0;">bytes32</font>(<font style="color:#4ec9b0;">uint256</font>(<font style="color:#4ec9b0;">uint160</font>(value))));
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the number of values in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> length(AddressSet <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _length(set._inner);
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */</font>
    <font style="color:#569cd6;">function</font> at(AddressSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> index) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">address</font>(<font style="color:#4ec9b0;">uint160</font>(<font style="color:#4ec9b0;">uint256</font>(_at(set._inner, index))));
    }

    <font style="color:#6a9955;">/**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */</font>
    <font style="color:#569cd6;">function</font> values(AddressSet <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> store = _values(set._inner);
        <font style="color:#4ec9b0;">address</font>[] <font style="color:#569cd6;">memory</font> result;

        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            result := store
        }

        <font style="color:#569cd6;">return</font> result;
    }

    <font style="color:#6a9955;">// UintSet</font>

    <font style="color:#569cd6;">struct</font> UintSet {
        Set _inner;
    }

    <font style="color:#6a9955;">/**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */</font>
    <font style="color:#569cd6;">function</font> add(UintSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _add(set._inner, <font style="color:#4ec9b0;">bytes32</font>(value));
    }

    <font style="color:#6a9955;">/**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */</font>
    <font style="color:#569cd6;">function</font> remove(UintSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _remove(set._inner, <font style="color:#4ec9b0;">bytes32</font>(value));
    }

    <font style="color:#6a9955;">/**
     * @dev Returns true if the value is in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> contains(UintSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> value) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">bool</font>) {
        <font style="color:#569cd6;">return</font> _contains(set._inner, <font style="color:#4ec9b0;">bytes32</font>(value));
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the number of values in the set. O(1).
     */</font>
    <font style="color:#569cd6;">function</font> length(UintSet <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> _length(set._inner);
    }

    <font style="color:#6a9955;">/**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */</font>
    <font style="color:#569cd6;">function</font> at(UintSet <font style="color:#569cd6;">storage</font> set, <font style="color:#4ec9b0;">uint256</font> index) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>) {
        <font style="color:#569cd6;">return</font> <font style="color:#4ec9b0;">uint256</font>(_at(set._inner, index));
    }

    <font style="color:#6a9955;">/**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */</font>
    <font style="color:#569cd6;">function</font> values(UintSet <font style="color:#569cd6;">storage</font> set) <font style="color:#569cd6;">public</font> <font style="color:#569cd6;">view</font> <font style="color:#569cd6;">returns</font> (<font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font>) {
        <font style="color:#4ec9b0;">bytes32</font>[] <font style="color:#569cd6;">memory</font> store = _values(set._inner);
        <font style="color:#4ec9b0;">uint256</font>[] <font style="color:#569cd6;">memory</font> result;

        <font style="color:#6a9955;">/// @solidity memory-safe-assembly</font>
        <font style="color:#569cd6;">assembly</font> {
            result := store
        }

        <font style="color:#569cd6;">return</font> result;
    }
}</code></pre>
```
 |
| [Contents](#toc) |

---

## Ex-32

&nbsp;&nbsp;&nbsp;&nbsp; **Undertaking of Founding Member**

I, <u>Li Li</u>, the Founding Member of <u>ComBoox DAO LLC (the "**Company**")</u> , hereby irrevocably undertake to use my best efforts to advance fiat currency payments required under third-party service agreements of the Company.

&nbsp;&nbsp;&nbsp;&nbsp; Executed this day of <u>September 28</u>, 2025.

 <u>/s/ Li Li</u> <br> Li Li

&nbsp;&nbsp;&nbsp;&nbsp; Founding Member <br> ComBoox DAO LLC