├── Disclosure.md ├── LICENSE ├── PO ├── Demo │ └── Grant-Agreement_Acme-Ang.md ├── Foundation_Bylaws_DAO.md ├── Grant_Agreement_DAO.md └── NDA.md ├── README.md ├── forms ├── README.md └── legal │ ├── DE Master LLC Certificate of Formation.md │ ├── DE Master LLC Operating Agreement.md │ ├── DE Series LLC Operating Agreement.md │ ├── Foundation Bylaws (DAO).md │ ├── Foundation Memorandum of Association.md │ ├── Grant Agreement (DAO).md │ ├── Invoice.md │ ├── Multisig Simple Code Deference Agreement (DE).md │ ├── NDA.md │ ├── Notice of Termination.md │ ├── SMLLC Checklist.md │ ├── Single Member LLC Operating Agreement.md │ ├── Unincorporated Nonprofit Association Charter Form (DC).md │ ├── Vote Delegate Disclosure.md │ └── Whitepaper Disclaimer.md ├── scripts ├── rand_num_oracle.py └── send_all_tokens.py └── solidity ├── AccessByHash.sol ├── AutoLp.sol ├── DealStamp.sol ├── ETHescrow.sol ├── EscrowStablecoin.sol ├── FunctionSelector.sol ├── NFTicket.sol ├── OpenOffer.sol ├── PayInEth.sol ├── README.md ├── TaxWithholding.sol ├── TokenConverter.sol ├── VoteCounter.sol ├── interfaces ├── IDealStamp.sol ├── ITaxWithholding.sol └── IVoteCounter.sol └── tests ├── ETHEscrow.t.sol ├── OpenOffer.t.sol └── PayInEth.t.sol /Disclosure.md: -------------------------------------------------------------------------------- 1 | Autonomous Attorney Disclosure and Disclaimer { 2 | 3 | *Last updated: 25 January 2023* 4 | 5 | Please be advised: I am an attorney admitted to practice in the State of Maryland and the District of Columbia. Unless we have entered into a written and signed engagement letter providing for paid legal services, I am not your lawyer and do not represent you or your interests. 6 | 7 | From time to time I provide open source materials and generally engage as an "autonomous attorney" -- this means that in analyzing or discussing legal, regulatory or law-related matters, or creating related public or open source materials, I am representing myself or acting non-representationally in the context of belonging to a community of incentive-aligned supporters, typically of decentralized technology systems. Such communities and affiliated persons are not my clients, and I have no intention to treat their information as confidential or attorney-client privileged. I am acting on my own behalf, but will seek to provide accurate and honest information while observing my general nonrepresentational professional and ethical responsibilities. 8 | 9 | In engaging as an autonomous attorney, I am not acting on behalf of any person or entity other than my law practice where so designated in writing, nor on behalf of any client (one with whom I have a signed engagement letter providing that I will act as their attorney). Any expressed views or provided analysis or other work product are provided “as is” for public discourse and discussion purposes only, on matters of interest with no guarantees of completeness, accuracy, usefulness or timeliness and without warranty of any kind, express or implied. If my views expressed in such autonomous attorney contexts are inaccurate or are interpreted or used in a manner that leads to some injury or detriment, there will be no legal recourse against me and an injured party will not be covered by malpractice insurance. In no event will I or my law practice be liable to you or anyone else for any decision made or action taken in reliance on the information in any work product or for any consequential, special or similar damages, even if advised of the possibility of such damages. Any views or open source materials I provide should not be used without, nor as a substitute for, consultation with professional accounting, tax, legal or other competent advisers. 10 | 11 | I currently act as external general counsel for the API3 Foundation, but I may separately provide non-privileged views and materials as an autonomous attorney in the API3 DAO, LexDAO, and other decentralized technology communities from time to time. I may have economic interests in, and separate engagements and contractual obligations with, various entities and persons related to the foregoing, and I also use and hold various other cryptocurrencies, tokens, stablecoins and other digital assets from time to time. 12 | 13 | I assume no duty and provide no guarantee of keeping these disclosures up to date, but currently anticipate updating them from time to time to reflect the changes I deem sufficiently material to warrant disclosure. 14 | 15 | For more about autonomous lawyering, please see [this piece by Gabriel Shapiro](https://lexnode.substack.com/p/autonomous-lawyering) and [this piece by Open, Esq]( https://openlawesq.medium.com/autonomous-lawyering-using-openlaw-dad9c604975b). This disclosure was adapted from [this precedent](https://github.com/LeXpunK-Army/lawyer_disclaimer_template). 16 | 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Varia LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PO/Demo/Grant-Agreement_Acme-Ang.md: -------------------------------------------------------------------------------- 1 | CodersNote=First a few links. 2 | 3 | P1.=[G/U/Who/andrea_ang.md] 4 | 5 | P2.=[G/U/Who/acme_incorporated.md] 6 | 7 | =[G/Open-Source-Law/PO/Grant_Agreement_DAO.md] 8 | 9 | Law.Dispute.sec={ICC.ARB.1.sec} 10 | 11 | ICC.=[G/ICCWBO-Arbitration-CmA/Sec/EN/0.md] 12 | 13 | ICC.ARB.#=a single arbitrator 14 | 15 | CodersNote=Then some parameters and choices. 16 | 17 | Doc.GUID=SomeKindOfHash-xrw64kKen823xoxoxo 18 | 19 | EffectiveDate.YMD=2021-08-21 20 | 21 | DAO.Name.Full=Acme Online 22 | 23 | DAO.BlockchainAddress=SomeHash-c8s9fE3kwlololol 24 | 25 | Services.Description.cl=improve legal terms for transactions like this 26 | 27 | ContractLife.Stop.AtWill.NoticePeriod.cl=fifteen (15) calendar days 28 | 29 | Comp.Monthly.Amount.$=USD $500 30 | 31 | Law.State.the=the State of Delaware 32 | 33 | Term.End.sec={Term.End.Milestone.sec} 34 | 35 | Work.Milestone.Description.cl=a deployable Grant Agreement in Prose Object format 36 | 37 | Stablecoin.Name=MountRushmoreCoin 38 | 39 | Conf.CoreSubject.cl=customer confidences 40 | 41 | License.Sec={License.OpenSource.Sec} 42 | 43 | Arb.Rule.Option.sec={Arb.Rule.Option.JAMS-Expedited.sec} 44 | 45 | Arbitration.Seat.Geo=Suffolk County, Massachusetts, USA 46 | 47 | Annex.Div=NO ANNEX -------------------------------------------------------------------------------- /PO/NDA.md: -------------------------------------------------------------------------------- 1 | // A Prose Objectification of the [forms/legal/NDA.md] 2 | 3 | // drafted from the perspective of a DAO’s legal wrapper engaging a new or potential contributor/grantee who will encounter confidential information (internal or third party) 4 | 5 | // insert any specific concepts or references to be expressly confidential in Section 1 6 | 7 | // consider including identities of pseudo-anon contributors as Confidential Information 8 | 9 | Law.State.the=the State of New York 10 | 11 | ArbitrationOrg.Name.Full=New York International Arbitration Center 12 | 13 | Def.DAO.target={_DAO} 14 | 15 | _DAO=DAO 16 | Doc.Ti=Non-Disclosure and Confidentiality Agreement 17 | 18 | P2.ID.cl=[DAO WRAPPER], an [ENTITY TYPE] (the “Entity”), represented and governed by the {DAO.Rep.Name} decentralized autonomous organization 19 | 20 | This.sec=This Non-Disclosure and Confidentiality Agreement (this “Agreement”) is entered into as of {EffectiveDate.YMD} (the “Effective Date”) by and between {P1.US.N,E,A} (“Party A”) and {P2.ID.cl} (“DAO”) (DAO and the Entity, together with any subsidiaries and affiliates, “{Def.DAO.target}”) (Party A and {_DAO} are each a “Party” and both, the “Parties”). 21 | 22 | Why.sec={_DAO} and Party A have indicated an interest in exploring a potential commercial relationship and/or contractor or employment relationship (the “Relationship”). In connection with its respective evaluation of the Relationship, each Party, their respective affiliates and their respective directors, officers, employers, employees, contractors, agents, members, or advisors (collectively, “Representatives”) may be alerted of, become privy to, provide or gain access to certain confidential and/or proprietary information. A Party or its Representative disclosing its Confidential Information (as such term is defined in Section 1 below) to the other Party is hereafter referred to as a “Disclosing Party.” A Party or its Representative receiving the Confidential Information of the Disclosing Party is hereafter referred to as a “Receiving Party.” In consideration for being furnished Confidential Information and for the Relationship, {_DAO} and Party A agree as follows: 23 | 24 | 1.Ti=Confidential Information 25 | 26 | 1.1.sec=The term “Confidential Information” as used in this Agreement shall mean any data or information that is reasonably sensitive material and not generally known to the public or any third parties, including, but not limited to, information relating to any of the following: non-public product development and plans, proprietary concepts, documentation, operations, systems, computer software, source code, trade secrets, customer lists, customer relationships, present or future business activities, design, verbal conversations or representations, writings, technical information and integrations which the Disclosing Party reasonably communicates as confidential, and anything {_DAO} sets forth in writing as being confidential or sensitive material. 27 | 28 | Note=Optional 29 | 30 | 1.2.sec=Unless expressly set forth in writing otherwise, any and all data, information, correspondence, materials, activities, operations, or relationships in any way related to {CoreConfSubjectMatter.cl} or any reference thereof shall be deemed included in the definition of “Confidential Information.” 31 | 32 | 1.=[G/Z/para/s2] 33 | 34 | 2.Ti=Exclusions from Confidential Information 35 | 36 | 2.sec=The obligation of confidentiality with respect to Confidential Information will not apply to any information publicly known due to prior authorized or lawful disclosure, or if the information is disclosed by the Receiving Party with the Disclosing Party’s prior written consent and approval. 37 | 38 | 3.Ti=Obligation to Maintain Confidentiality 39 | 40 | 3.0.sec=With respect to Confidential Information: 41 | 42 | 3.1.sec=Receiving Party and its Representatives agree to retain the Confidential Information of the Disclosing Party in strict confidence, to use commercially reasonable measures to protect the security, integrity and confidentiality of such information and to not permit unauthorized access to or unauthorized use, disclosure, publication or dissemination of Confidential Information except in conformity with this Agreement; 43 | 44 | 3.2.sec=Receiving Party and its Representatives shall adopt and/or maintain security processes and procedures to safeguard the confidentiality of all Confidential Information received by Disclosing Party using a reasonable degree of care, but not less than that degree of care used in safeguarding its own similar information or material; 45 | 46 | 3.3.sec=Upon termination the termination of this Agreement, Receiving Party will ensure that all documents, writings, and other electronic records that include or reflect any Confidential Information are returned to Disclosing Party or are destroyed as directed by Disclosing Party; 47 | 48 | 3.4.sec=d. If there is an unauthorized disclosure or loss of any of the Confidential Information by Receiving Party or any of its Representatives, Receiving Party will promptly, at its own expense, notify Disclosing Party in writing and take all actions as may be necessary or reasonably requested by Disclosing Party to minimize any damage to the Disclosing Party or a third party as a result of the disclosure or loss; and 49 | 50 | 3.5.sec=e. The obligation not to disclose Confidential Information shall survive the termination of this Agreement, and at no time will Receiving Party or any of its Representatives be permitted to disclose Confidential Information, except to the extent that such Confidential Information is excluded from the obligations of confidentiality under this Agreement pursuant to Section 2 above. 51 | 52 | 3.=[G/Z/ol-a/s5] 53 | 54 | 4.Ti=Non-Disclosure of Relationship 55 | 56 | 4.sec=Without Disclosing Party’s prior written consent, neither Receiving Party nor its Representatives shall disclose to any other person (a) the fact that Confidential Information has been made available to it or that it has inspected any portion of the Confidential Information; (b) the fact that the Disclosing Party and Receiving Party are having discussions or negotiation concerning the Relationship; or (c) any of the terms, conditions, discussions, plans or other facts with respect to the Relationship. 57 | 58 | 5.Ti=Representatives 59 | 60 | 5.sec=Receiving Party will take reasonable steps to ensure that its Representatives adhere to the terms of this Agreement, and Receiving Party will be responsible for any breach of this Agreement by any of its Representatives. 61 | 62 | 6.Ti=Disclaimer 63 | 64 | 6.sec=There is no representation or warranty made by Disclosing Party as to the accuracy or completeness of any of the Confidential Information. Either Party may, in its sole discretion: (a) reject any proposals made by the other Party or its Representatives with respect to the Relationship; and (b) terminate discussions or negotiations at any time. 65 | 66 | 7.Ti=Remedies 67 | 68 | 7.0.sec=Each Party agrees that use or disclosure of any Confidential Information in a manner inconsistent with this Agreement will give rise to irreparable injury for which: 69 | 70 | 7.1.sec=money damages may not be a sufficient remedy for any breach of this Agreement by such Party; 71 | 72 | 7.2.sec=the other Party may be entitled to specific performance and injunction and other equitable relief with respect to any such breach; 73 | 74 | 7.3.sec=such remedies will not be the exclusive remedies for any such breach, but will be in addition to all other remedies available at law or in equity; and 75 | 76 | 7.4.sec=in the event of litigation relating to this Agreement, if a court of competent jurisdiction determines in a final non-appealable order that one Party, or any of its Representatives, has breached this Agreement, such Party will be liable for reasonable legal fees and expenses incurred by the other Party in connection with such litigation, including, but not limited to, any appeals. 77 | 78 | 7.=[G/Z/ol-a/s4] 79 | 80 | 8.Ti=Notices 81 | 82 | 8.sec=All notices given under this Agreement shall be in writing and provided in the same manner and to the same addresses and addressees as the Agreement itself or as otherwise designated in writing by the Parties. 83 | 84 | 9.Ti=Termination 85 | 86 | 9.sec=This Agreement will terminate only upon the mutual written agreement of the Parties to terminate this Agreement. 87 | 88 | 10.Ti=Amendment 89 | 90 | 10.sec=This Agreement may be amended or modified only by a written agreement signed by both Parties. 91 | 92 | 11.Ti=Jurisdiction 93 | 94 | 11.sec=This Agreement is governed by the laws of {Law.State.the}, without regard to any conflicts of law provisions. The Parties hereby consent to the exclusive jurisdiction of the {ArbitrationOrg.Name.Full} with respect to any dispute arising under or relating to this Agreement, and waive any respective rights to a jury trial. 95 | 96 | 12.Ti=Miscellaneous 97 | 98 | 12.1.sec=This Agreement will inure to the benefit of and be binding on the respective successors and permitted assigns of the Parties. Neither Party may assign its rights or delegate its duties under this Agreement without the other party’s prior written consent. 99 | 100 | 12.2.sec=In the event that any provision of this Agreement is held to be invalid, illegal or unenforceable in whole or in part, the remaining provisions shall not be affected and shall continue to be valid, legal and enforceable as though the invalid, illegal or unenforceable parts were severed from this Agreement. 101 | 102 | 12.3.sec=This Agreement may be executed in counterparts, each of which shall be deemed an original, but both of which together shall constitute one and the same instrument. This Agreement may be executed by electronic means, and any electronic signatures to this Agreement are deemed the same as handwritten signatures for purposes of validity, enforceability, and admissibility. 103 | 104 | 12.=[G/Z/ol-a/s3] 105 | 106 | =[G/Agt-Form-CmA/US/0.md] 107 | 108 | =[G/Z/ol/12] 109 | ***************************************************** 110 | 111 | 112 | 113 | The Parties hereto have executed this Agreement as of the Effective Date. 114 | 115 | 116 | 117 | ________ 118 | By: 119 | Party A 120 | 121 | 122 | ________ 123 | By: 124 | [DAO WRAPPER] 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open Source Legal Ξngineering 2 | 3 | *Please read [this disclosure](https://github.com/ErichDylus/Open-Source-Law/blob/main/Disclosure.md) and note that all software, forms, files, and other materials provided or linked herein are licensed under the [MIT License](https://github.com/ErichDylus/Open-Source-Law/blob/main/LICENSE) without warranties of any kind, and should not be used without consulting an attorney or other applicable professional.* 4 | 5 | #### [Legal Forms and Resources](https://github.com/ErichDylus/Open-Source-Legal-Engineering/tree/main/forms) 6 | 7 | #### [Solidity Snippets](https://github.com/ErichDylus/Open-Source-Legal-Engineering/tree/main/solidity) 8 | 9 | #### [Python Miniscripts](https://github.com/ErichDylus/Open-Source-Legal-Engineering/tree/main/scripts) 10 | 11 | --- 12 | ### General Open Source References 13 | 14 | - [Open source license menu](https://choosealicense.com/licenses/) 15 | - [Resources and guide to contributing to open source projects](https://github.com/github/opensource.guide) 16 | - [FAQ/flowchart on open source legal considerations](https://opensource.guide/legal/) 17 | 18 | -------------------------------------------------------------------------------- /forms/README.md: -------------------------------------------------------------------------------- 1 | ## Open Source Legal Agreement Forms 2 | 3 | Read [this disclosure](https://github.com/ErichDylus/Open-Source-Law/blob/main/Disclosure.md) and note that all forms, templates, code or other materials provided or linked herein carry [no warranty whatsoever](https://github.com/ErichDylus/Open-Source-Law/blob/main/LICENSE) and should not be used without consulting an attorney or other applicable professional. Circumstances, facts, and jurisdictions differ, and these forms are not meant to be used in their current form without adjustment according to such facts, circumstances, and jurisdictions. 4 | 5 | No duty is assumed nor is any guarantee provided of keeping these forms up to date as law, regulations, and market standards change. PRs, issues, forks, and discussion are all welcomed. 6 | 7 | ### Templates 8 | 9 | [Legal agreement and organizational document forms](https://github.com/ErichDylus/Open-Source-Law/tree/main/forms/legal) - Including formation documents, DAO-independent contractor grant agreement, NDA, etc. 10 | 11 | [Rarible's NFT Licenses](https://github.com/rariblecom/nft-license) - by Gabriel Shapiro & Stuart Smolen 12 | 13 | [One-Page SAFT](https://github.com/BranDAOn/OP-SAFT) - one page simple agreement for future tokens which sets out the consideration amount and token allotment, the token delivery triggers, and the lock-up, by [BranDAOn](https://github.com/BranDAOn) 14 | 15 | [Form Token Warrant](https://docs.google.com/document/d/1fkdvQsvblne4zXTPQOO3GDYOh-uJ497S_JclsP8PHv4/edit) by [OC Advisory](https://www.ocadvisory.co/) and [Magna](https://www.magna.so/) 16 | 17 | [Ricardian LLC Master Operating Agreement](https://github.com/lexDAO/Ricardian/blob/main/contracts/MasterOperatingAgreement.txt) - LexDAO's Ricardian master LLC operating agreement form (for use in initiating a series), deployed and represented on-chain by an [ERC-721 standard NFT](https://github.com/lexDAO/Ricardian/blob/main/contracts/RicardianLLC.sol) 18 | 19 | ### Template libraries 20 | 21 | [LexDAO Startup Pack]( 22 | https://github.com/lexDAO/LexCorpus/tree/master/contracts/legal/startup) - collection of templates for typical startup setup and fundraising 23 | 24 | [CommonAccord](https://github.com/commonaccord) - CommonAccord's open source effort to codify and automate legal agreements 25 | 26 | [NVCA forms](https://nvca.org/model-legal-documents/) - model documents from the National Venture Capital Association 27 | 28 | [CooleyGo templates and generators](https://www.cooleygo.com/documents/) - sample documents and document generators from Cooley LLP 29 | 30 | [Orrick startup forms](https://www.orrick.com/en/Total-Access/Tool-Kit/Start-Up-Forms) - startup-relevant form documents from Orrick Herrington & Sutcliffe LLP 31 | 32 | [Free Law Project](https://free.law/non-profit-documents/) - open source non-profit document forms by the Free Law Project 33 | 34 | [Openlaw templates](https://lib.openlaw.io/web/default/templates) - free searchable legal form repository 35 | 36 | ### Legal Resources and Research 37 | 38 | [Caselaw Access Project](https://case.law/) - published U.S. court decisions digitized from the collection of the Harvard Law School Library 39 | 40 | [Metacartel legal repo](https://github.com/metacartel/MCV/tree/master/Legal) - Grimoire and exhibits for the Metacartel Ventures DAO 41 | 42 | ### Books and articles 43 | 44 | [Open Textbooks](https://open.umn.edu/opentextbooks/subjects/law) - free textbooks on various areas of law 45 | 46 | [Open Source Licensing: What every technologist should know](https://opensource.com/article/17/9/open-source-licensing) - Meeker, 2017 47 | 48 | [Trademark Law: an Open-Source Casebook](http://tmcasebook.org/) - Beebe, 2020 49 | 50 | [Extended Readings on Copyright](https://www.dropbox.com/s/gmcl8u0b7vnire1/ERoC%202019%20%28Consolidated%20August%205%2C%202019%29.pdf?dl=0) – Sag, 2019 51 | 52 | [Intellectual Property: Law & the Information Society](https://web.law.duke.edu/cspd/casebook/) – Boyle & Jenkins, 2018 53 | -------------------------------------------------------------------------------- /forms/legal/DE Master LLC Certificate of Formation.md: -------------------------------------------------------------------------------- 1 | CERTIFICATE OF FORMATION OF [________] LLC 2 | 3 | A Delaware Limited Liability Company 4 | 5 | 6 | This Certificate of Formation of [______] LLC (the “Company”), dated as of [DATE], is duly executed and filed by the undersigned, as an authorized person, to form a limited liability company under the Delaware Limited Liability Company Act (6 Del. C. 18-101 et seq.) as in effect as of the date hereof (the “Act”). 7 | 8 | First: The name of the limited liability company formed hereby is [________] LLC. 9 | 10 | Second: The address of the registered office of the Company in the State of Delaware is located at [REGISTERED AGENT ADDRESS] and the name of the registered agent of the Company in the State of Delaware at such address is [REGISTERED AGENT NAME]. 11 | 12 | Third: The Company is established pursuant to Section 18-215 of the Act and may establish separate and distinct series of members, managers, and interests, each having separate rights, assets, powers or duties with respect to specified property or obligations of the Company or profits and losses associated with specified property or obligations of the Company. The debts, liabilities, obligations and expenses incurred, contracted for or otherwise existing with respect to a particular series shall be enforceable against the assets of such series only, and not against the assets of the Company generally or any other series thereof, and none of the debts, liabilities, obligations and expenses incurred, contracted for or otherwise existing with respect to the Company generally or any other series thereof shall be enforceable against the assets of such series. 13 | 14 | Fourth: The Company’s operating agreement and all matters relating to the Company's governance, finances, operations and the establishment of separate series may be accomplished or executed through the use of blockchain, distributed ledger, or other algorithmic or automated software or similar technology, as contemplated in the Company’s operating agreement. 15 | 16 | IN WITNESS WHEREOF, the undersigned, being fully authorized to execute and file this document executes this Certificate of Formation on the date first above written. 17 | 18 | 19 | ______________________ 20 | Authorized Signatory 21 | [On behalf of [Member of Company]] 22 | -------------------------------------------------------------------------------- /forms/legal/DE Master LLC Operating Agreement.md: -------------------------------------------------------------------------------- 1 | // form Delaware Master LLC Operating Agreement, contemplating formation of various Series LLCs thereunder. Provided without warranty of any kind and subject to the Open-Source-Law repo disclaimer 2 | 3 | // drafted in the context of a data provider creating Series LLC structures for its deployed Airnodes (and licensing rights to such Series), but broadly adaptable 4 | 5 | ### LIMITED LIABILITY COMPANY AGREEMENT OF [__________] LLC 6 | 7 | a Delaware Limited Liability Company 8 | 9 | THIS LIMITED LIABILITY COMPANY AGREEMENT (this "Agreement") of [______] LLC, a Delaware limited liability company (the "Company"), is effective as of [Date], by [Member], a [Member Type] (the "Member") as the initial member of the Company. 10 | 11 | RECITALS 12 | 13 | A. The Company has been organized as a Delaware limited liability company by the filing of a certificate of formation (the "Certificate") in accordance with the Delaware Limited Liability Company Act, 6 Del. C. Section 18-101, et seq. (as amended from time to time, the "Act"). 14 | 15 | B. The Certificate includes a notice of limitation of liabilities of series limited liability company interests established herein in accordance with Section 215(b) of the Act. 16 | 17 | C. The Company is authorized to establish, pursuant to this Agreement, one or more series with members and limited liability company interests with separate and distinct rights, powers, duties, obligations, assets, businesses and objectives from that of the Company (each a "Series"). 18 | 19 | D. Each Series formed under the Company will functionally operate as a separate limited liability company and each Series shall be governed by a separately executed limited liability company operating agreement. 20 | 21 | E. The Company is hereby formed as the "master" limited liability company (the "Master LLC") and shall not maintain any ownership interest in any Series or assets held on behalf of any Series. 22 | 23 | F. [Member], as the initial Member of the Master LLC, desires to enter into a written limited liability company agreement as to the affairs of the Master LLC. 24 | NOW, THEREFORE, in consideration of the agreements and obligations set forth herein and for other good and valuable consideration, the receipt and sufficiency of which are hereby acknowledged, Member hereby agrees as follows: 25 | 26 | ARTICLE I. ORGANIZATIONAL MATTERS 27 | 1. Name. The name of the Company shall be "[__________] LLC". The Member or Manager shall file or cause to be filed any trade name or fictitious name certificates and similar filings, and any amendments thereto, that the Member or Manager considers appropriate or advisable. 28 | 2. Term. The "Term" of the Company is perpetual or until dissolved as provided in Article VI Section 1. 29 | 3. Registered Office and Agent. The Company shall continuously maintain a Delaware registered office and a registered agent for service of process as required by the Act. The initial registered office and agent of the Company shall be as stated in the Certificate. If the registered agent ceases to act as such for any reason, or the registered office shall change, then the Member or Manager shall promptly designate a replacement registered agent or file or cause to be filed a notice of change of address, as the case may be. 30 | 4. Principal Office. The Company will maintain its principal business office at such places of business as the Member or Manager may deem advisable for the conduct of the Company’s business. The Company may have such other offices and in such locations as the Manager from time to time may determine, or the business of the Company may require. 31 | 5. Purpose. The Company has been created to engage in any and all lawful activities and transactions as may be necessary or advisable to complete the Company’s business as determined by the Member or Manager, and to serve as the "master" limited liability company for each separately formed Series. Each Series shall have a separate purpose and may engage in any business, purpose or activity in which a limited liability company may engage under applicable law (including, without limitation, the Act) and in which the Manager causes the Company to engage. 32 | 6. Additional Documents. The Manager shall cause to be executed, filed, recorded, published, or amended in the name of the Company any documents, as the Manager in its sole and absolute discretion determines to be necessary or advisable, (a) in connection with the conversion or the formation, operation, dissolution, winding up, or termination of the Company or any Series pursuant to applicable law, or (b) to otherwise give effect to the terms of this Agreement or any Separate Series Operating Agreement (as defined in Article II below), and such terms shall be consistent with the terms and provisions of this Agreement or any Separate Series Operating Agreement. 33 | 7. Taxation. At all times that the Company has only one Member (who owns 100% of the limited liability company interests in the Company), it is the intention of the Member that the Company be disregarded for federal, state, local and foreign income tax purposes. Each Series shall be, to the extent permissible by applicable law, treated as a separate partnership for federal and applicable State tax purposes. 34 | 35 | ARTICLE II. SEPARATE SERIES, AND CAPITALIZATION 36 | 1. Separate Series. 37 | a. The Company is authorized to establish, pursuant to this Agreement, one or more series with members and limited liability company interests with separate and distinct rights, powers, duties, obligations, operations, businesses and objectives from that of the Company described herein as a "Series". To the maximum extent permitted by the Act (including, without limitation, Section 18-215(b)), the assets, income, gains, losses, expenses, deductions, credits, distributions, debts, rights, obligations, penalties and liabilities of any Series shall be associated with and limited to such Series, and not any other Series or the Company. 38 | 39 | b. To the maximum extent permitted by the Act, each Series shall constitute and be treated as a designated separate "series" of the Company interests and the debts, liabilities, obligations and expenses associated with an individual Series shall not be asserted against income, gains or assets of any other Series or the Company. 40 | 41 | c. The specific provisions, rights, powers, obligations, and privileges with respect to each Series shall be set forth in a writing referred to herein as a "Separate Series Operating Agreement" that will be separately executed by and between the Manager and the member(s) of such Series. The respective capital contributions and limited liability company interests of the members participating in each Series shall be set forth in the Separate Series Operating Agreement therefor and limited accordingly thereto. 42 | 43 | d. A member participating in one Series shall have no rights or interest with respect to any other Series, unless such member independently acquires an interest in such other Series. 44 | 45 | e. The manager and members of each Series shall take such reasonable steps as are necessary to implement the foregoing provisions of this Article II Section 1, including maintaining separate and distinct records for each Series, separately holding and accounting for the assets of each such Series, and shall otherwise comply with the requirements of Section 18-215 of the Act. 46 | 47 | f. The dissolution and termination of a Series shall not, in and of itself, cause or result in the dissolution or termination of the Company or any other Series. 48 | 49 | g. All Series and any members participating in a Series agree to the disclaimers set forth under Schedule A hereto and each Separate Series Operating Agreement shall contain the entire language of Schedule A. 50 | 51 | 2. Capital Contributions. At the time of, and in connection with, the admission of a member to a particular Series, each Member shall contribute to the capital of such Series the amount set forth in the Separate Series Operating Agreement therefor. 52 | 53 | ARTICLE III. MEMBERS 54 | 1. Admission of Member. [Member] is hereby admitted as a Member of the Master LLC. 55 | 2. Limited Liability. No Member shall be personally liable for any debt, obligation, or liability of the Company or a Series, whether that liability or obligation arises in contract, tort, or otherwise, solely by reason of being a Member of the Company or a Series. 56 | 3. Nature of Interest. A Member's interest in the Master LLC or any Series constitutes personal property. No Member has any interest in any specific asset, right or property of the Company or any Series. 57 | 58 | ARTICLE IV. MANAGEMENT AND CONTROL OF THE COMPANY 59 | 1. Management of the Company. The business, property, and affairs of the Company shall be managed exclusively by or under the direction of a manager (the "Manager"). The Manager shall be a "manager" within the meaning of Section 18-101(10) of the Act. Except for situations in which the approval of the Members of a particular Series is expressly required by the Act, the Certificate, this Agreement, or a Separate Series Operating Agreement, the Manager shall have full, complete, and exclusive authority, power, and discretion to manage and control the business, property, and affairs of the Company, to make all decisions regarding those matters, and to perform any and all other acts or activities customary or incident to the management of the Company's business, property, and affairs. 60 | 2. Management of each Series. Each Separate Series Operating Agreement shall each provide for a Manager. The provisions under this Agreement relating to the Company’s Manager shall be reasonably applied to each Series’ Manager, unless otherwise provided in the Separate Series Operating Agreement. 61 | 3. Manager. The initial Manager of the Company shall be [the Member] [__________]. 62 | 4. Powers of the Manager. Without limiting the generality of Section 4.1, but subject to the express limitations set forth elsewhere in this Agreement or a Separate Series Operating Agreement, the Manager shall possess and may exercise all powers and privileges necessary, appropriate, or convenient to manage and carry out the purposes, business, property, and affairs of the Company and to make all decisions affecting such business and affairs, including, without limitation, the power to exercise on behalf of the Company all powers and privileges described in Section 18-106(b) of the Act and the power to open bank accounts in the name of the Company with the Manager or a representative of the Manager as signatory thereon. 63 | 5. Performance of Duties. 64 | a. Notwithstanding anything herein or in any Separate Series Operating Agreement to the contrary, the Manager does not, shall not and will not owe any fiduciary duties of any kind whatsoever to any Series or to any of the Members of any Series, by virtue of its role as the Manager, including, but not limited to, the duties of due care and loyalty, whether such duties were established as of the date of this Agreement or any time hereafter, and whether established under common law, at equity or legislatively defined. It is the intention of the parties hereto that any such fiduciary duties be affirmatively eliminated as permitted by Delaware law and under the Act and the Member hereby waives any rights with respect to such fiduciary duties. 65 | 66 | b. Notwithstanding any other provision of this Agreement, any Separate Series Operating Agreement or otherwise applicable provision of law or equity, the Manager is permitted or required to make a decision (i) in its "sole discretion" or "discretion" or under a grant of similar authority or latitude, the Manager shall be entitled to consider only such interests and factors as it desires, including its own interests, and shall, to the fullest extent permitted by applicable law, have no duty or obligation to give any consideration to any interest of or factors affecting any Series or any of the Members thereto, or (ii) in its "good faith" or under another expressed standard, the Manager shall act under such express standard and shall not be subject to any other or different standards. 67 | 68 | 6. Limited Liability of the Managers. No person who is a Manager of the Company or any Series shall be personally liable under any judgment of a court, or in any other manner, for any debt, obligation, or liability of the Company or any Series, whether that liability or obligation arises in contract, tort, or otherwise, solely by reason of being a Manager of the Company or any Series. 69 | 70 | ARTICLE V. ACCOUNTING, RECORDS 71 | 1. Books and Records. The books and records of each Series (i) shall be kept, and the financial position and operations recorded, in accordance with any appropriate accounting method selected by the Manager in its sole discretion and consistently applied; (ii) shall be appropriate and adequate for each Series' business; and (iii) may be maintained in other than written form, provided that such form is capable of conversion to written form within a reasonable time. 72 | 73 | ARTICLE VI. DISSOLUTION AND WINDING UP 74 | 1. Dissolution. The Company shall be dissolved, its affairs wound up and its assets disposed of upon the termination of the last remaining Series (as provided in a Separate Series Operating Agreement), the termination of the legal existence of the last remaining Member of the last remaining Series or the occurrence of any other event which terminates the continued membership of the last remaining Member of the last remaining Series, unless the Company is continued in a manner permitted by this Agreement or the Act. The termination and winding up of a Series will not, in and of itself, cause a dissolution of the Company or the termination of any other Series. The termination of a Series will not affect the limitation on liabilities of the Series or any other Series provided by this Agreement, a Separate Series Operating Agreement, the Certificate or the Act. The Company shall undertake reasonable efforts, to the extent lawful, to notify each Series of any material issues that may result in the dissolution of the Company. 75 | 2. Continuation Following Dissolution. If at any time there is no Member for the Company or a Series, such Company or Series shall not dissolve but the "personal representative" (as such term is defined in the Section 18-101(13) of the Act) of the last remaining Member (the "Last Member") shall, within ninety (90) days of the event that terminated the continued membership of the Last Member, continue the Company or such Series effective as of the occurrence of the event that terminated the continued membership of the Last Member. 76 | 77 | ARTICLE VII. MISCELLANEOUS 78 | 1. Complete Agreement. This Agreement, any applicable Separate Series Operating Agreement and the Certificate constitute the complete and exclusive statement of agreement among the Members participating in such Series, the Managers, the Company and any Series with respect to the subject matter herein and therein and replace and supersede all prior written and oral agreements or statements by and among any of the Members, Managers, the Company and any Series. To the extent that any provision of the Certificate conflicts with any provision of this Agreement or a Separate Series Operating Agreement, the Certificate shall control. To the extent that any provision of a Separate Series Operating Agreement conflicts with any provision of this Agreement, this Agreement shall control. 79 | 2. Governing Law. The interpretation and enforceability of this Agreement or a Separate Series Operating Agreement and the rights and liabilities of the Members as such shall be governed by the laws of the State of Delaware. To the extent permitted by the Act and other applicable laws, the provisions of this Agreement or a Separate Series Operating Agreement shall supersede any contrary provisions of the Act or other applicable laws. 80 | 3. Dispute Resolution. Any controversy or claim arising out of or relating to this Agreement, or the breach thereof, shall be settled exclusively by online arbitration in accordance with the Commercial Arbitration Rules of the American Arbitration Association then in effect, and judgment upon the award rendered by the arbitrator(s) may be entered in any court having jurisdiction thereof. All costs and fees of the arbitration shall be allocated between the parties as determined therein, with the prevailing party made whole with respect to its expenses. 81 | 4. Severability. In the event any provision of this Agreement or a Separate Series Operating Agreement is determined to be invalid or unenforceable, such provision shall be deemed severed from the remainder of this Agreement or such Separate Series Operating Agreement and shall not cause the invalidity or unenforceability of the remainder of this Agreement or such Separate Series Operating Agreement. 82 | 5. Amendment and Waiver. 83 | a. Each Separate Series Operating Agreement may only be amended with the consent of its Member and the Manager as required under such Separate Series Operating Agreement. 84 | 85 | b. No amendment of this Agreement may modify the method of making allocations or distributions under a Separate Series Operating Agreement, modify the method of determining the interest or ownership percentage for any Series or any member of such Series under a Separate Series Operating Agreement, or modify any provision of this Agreement or a Separate Series Operating Agreement pertaining to limitations on liability of the members of a Series, unless such amendment is authorized and approved by the Members and the Manager of the applicable Series as required under such Separate Series Operating Agreement. 86 | 87 | c. The Manager's noncompliance with any provision hereof in any single transaction or event that would otherwise require the consent of the members of a Series under the applicable Separate Series Operating Agreement of such Series may be waived prospectively or retroactively in writing by the same percentage of the members of such Series that would be required to amend such provision pursuant to such applicable Separate Series Operating Agreement. No waiver shall be deemed a waiver of any subsequent event of noncompliance except to the extent expressly provided in such waiver. 88 | 89 | _[SIGNATURE PAGE FOLLOWS]_ 90 | 91 | 92 | 93 | IN WITNESS WHEREOF, the undersigned has executed this Limited Liability Company Agreement of the Company as of the date first written above. 94 | 95 | 96 | ________________________ 97 | [Member], as Member 98 | 99 | 100 | 101 | 102 | ACCEPTANCE OF APPOINTMENT 103 | 104 | WHEREAS, the undersigned hereby accepts appointment as the Manager of the Company and agree to be bound by the terms and conditions applicable to such of this Liability Company Agreement, as amended from time to time in accordance with the provisions hereof. 105 | 106 | MANAGER: [Manager] 107 | 108 | 109 | 110 | ### SCHEDULE A – SERIES DISCLAIMERS 111 | 112 | Each Series, its members and managers hereby agree as follows: 113 | 114 | • The use of a “Series”, “Protected”, “Registered” or similar LLC is subject to various legal uncertainties regarding its validity, separateness, and use cases, including, without limitation, uncertainties relating to: 115 | 116 | o the non-recognition of such type of legal entity and structure by other U.S. States, such as California, New York and Massachusetts; 117 | 118 | o the lack of established case or other legal precedent regarding Series LLCs and any liability spill-over or piercing risks between the Series and the Company; 119 | 120 | o the taxation of a Series LLC; and 121 | 122 | o the bankruptcy proceedings of a Series LLC under federal law; 123 | 124 | • Notwithstanding anything to the contrary in the Agreement, the Member and Manager shall be entitled to dissolve the Company at any time, in the event where there is any risk or threatened risk of liability to the Company, Member or the Manager in relation to the Company’s or any Series’ affairs; 125 | 126 | • Each Series, its members and managers may be required by the Company, at any time, to provide basic Know Your Customer (KYC) information, such as (without limitation)a copy of a widely accepted national ID, name, and proof of address, in the event where: (i) such Series desires to obtain a bank account; (ii) the Company, Member or the Manager are legally required to provide such information; or (iii) such Series desires to become a “registered” series in the State of Delaware; 127 | 128 | • THE CODE, SOFTWARE AND DOCUMENTATION FOR THE IMPLEMENTATION OF A SERIES ARE PROVIDED "AS IS" AND THE COMPANY, MEMBER AND THE MANAGER HEREBY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, AND ALL WARRANTIES ARISING FROM COURSE OF DEALING, USAGE, OR TRADE PRACTICE. NO WARRANTY OF ANY KIND IS MADE THAT THE CODE, SOFTWARE AND DOCUMENTATION, OR ANY PRODUCTS OR RESULTS OF THE USE THEREOF, WILL MEET LICENSEE'S OR ANY OTHER PERSON'S REQUIREMENTS, OPERATE WITHOUT INTERRUPTION, ACHIEVE ANY INTENDED RESULT, BE COMPATIBLE OR WORK WITH ANY SOFTWARE, SYSTEM OR OTHER SERVICES, OR BE SECURE, ACCURATE, COMPLETE, FREE OF HARMFUL CODE OR ERROR; and 129 | 130 | • The Series, its members and managers shall indemnify and hold harmless the Company, Member and the Manager (the "Indemnified Parties") against any claims, liabilities, legal fees, judgements, or other losses incurred by the Indemnified Parties that relate to the disclaimers set forth above or that may arise from i) a Series’ non-compliance with the provisions of the Agreement; ii) any business or action undertaken of the Series, its members or managers; iii) the use of or direct interaction with any distributed ledger or blockchain. 131 | -------------------------------------------------------------------------------- /forms/legal/Foundation Memorandum of Association.md: -------------------------------------------------------------------------------- 1 | // form adapted from a [Cayman Foundation Company](https://legislation.gov.ky/cms/images/LEGISLATION/PRINCIPAL/2017/2017-0029/FoundationCompaniesAct_Act%2029%20of%202017.pdf) precedent, contemplating no members, no share capital, no dividends nor distributions, and would have a corresponding Articles of Association 2 | 3 | // **Provided without warranty of any kind, do not use without consulting an attorney in the applicable jurisdiction, all open-source-law repo disclosures apply** 4 | 5 | ### MEMORANDUM OF ASSOCIATION OF [FOUNDATION COMPANY NAME] 6 | 7 | a foundation company limited by guarantee 8 | 9 | 10 | 1. The name of the foundation company is [______________]. 11 | 12 | 2. The foundation company is a [company within the meaning of the Companies Law and a foundation company within the meaning of the Foundation Companies Law, 2017]. 13 | 14 | // form, broad language, adaptable 15 | 16 | 3. The objects for which the foundation company is established are: 17 | 18 | (a) to act as a holding company and an investment company, with no restriction on the objects or operations of its subsidiaries or on the nature of its or their investments, 19 | 20 | (b) to provide financial assistance or benefits to beneficiaries designated under the Articles of Association; and 21 | 22 | (c) to do all such things as in the opinion of the directors are or may be incidental or conducive to the above objects or any of them. 23 | 24 | 4. The foundation company shall have and be capable of exercising all the functions of a natural person of full capacity irrespective of any question or corporate benefit, as provided by [section 27(2) of the Companies Law (2018 Revision)]. 25 | 26 | 5. The foundation company may not carry on a business for which a licence is required under the laws of [the Cayman Islands] unless duly licensed. 27 | 28 | 6. No portion of the income or property of the foundation company from whatever place or source shall be paid or transferred directly or indirectly by way of divided, bonus or otherwise howsoever by way of profit to the members or directors of the foundation company, as such, apart from authorised remuneration for services to the foundation company. 29 | 30 | 7. The liability of the directors, founders, supervisors, beneficiaries, members, professional advisors, and contractors (current and former) is limited, and for avoidance of doubt, no such person or entity shall be liable for the debts, obligations, actions, proceedings, costs, charges, fines, expenses, losses, damages or liabilities of the foundation company or decentralized autonomous organization by which it is governed or any related subsidiaries, affiliates, members or participants thereto, including under a judgment, decree or order of a court. 31 | 32 | 8. The foundation company may operate without members or cease to have members. 33 | 34 | 9. Each person who is a member undertakes to contribute to the assets of the foundation company in the event of the foundation company being wound up during the time that person is a member, or within one year afterwards, for payment of the debts and liabilities of the foundation company contracted before the time at which the person ceases to be a member, and the cost, charges and expenses of the winding-up of the foundation company, and for the adjustments of the rights of the contributories amongst themselves, such amounts as may be required, not exceeding the sum of one United States dollar (US$1.00). 35 | 36 | 10. If on the winding-up or dissolution of the foundation company there remain surplus assets after the satisfaction of its debts and liabilities, the same shall be applied or distributed under the Articles of Association of the foundation company and, subject thereto, shall be paid or transferred to such charitable objects as shall be decided by ordinary resolution of the foundation company. 37 | 38 | 11. This Memorandum and the Articles of Association may be altered by Special Resolution, except that neither clause 6 nor clause 10 of this Memorandum may be altered, and no other alteration may be made which is in any way inconsistent with clause 6 or clause 10. 39 | 40 | Dated this _____ day of ____________, ______. 41 | 42 | Signature and Address of Subscriber 43 | 44 | 45 | [______] 46 | 47 | acting by: 48 | 49 | _______________________________ 50 | Name: 51 | 52 | 53 | _______________________________ 54 | Name: 55 | 56 | Witness to the above signature 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /forms/legal/Grant Agreement (DAO).md: -------------------------------------------------------------------------------- 1 | // simple agreement contemplating grants for independent contractor services by decentrally-governed grantors, adaptable for individuals or entities 2 | 3 | // effective date should correspond to commencement of applicable grant cycle 4 | 5 | // provided without warranty of any kind, do not use without consulting an attorney, all open-source-law repo disclosures apply 6 | 7 | ## Grant Agreement 8 | 9 | This Grant Agreement (this “Agreement”) is entered into as of [DATE] (the “Effective Date”) by and between __________________ (“Party A”) and [DAO LEGAL WRAPPER], a [ENTITY TYPE] (the “[ENTITY]”), governed by or otherwise legally associated with the [NAME] Decentralized Autonomous Organization with [DESIGNATED BLOCKCHAIN] contract address [CONTRACT ADDRESS] (“[NAME] DAO”) ([______] DAO and the [ENTITY], together with any and all subsidiaries and affiliates, “[DAO NAME]”) (Party A and [DAO NAME] are each a “Party” and both, the “Parties”). 10 | 11 | [DAO NAME] has deemed that Party A has the necessary qualifications, experience, and abilities to provide Services (as such term is defined in Section 1 below) to and for the benefit of [DAO NAME], and Party A has agreed to provide such Services to and for the benefit of [DAO NAME] pursuant to the terms and conditions set forth in this Agreement, with Party A to be deemed an independent contractor for [DAO NAME] (as more particularly set forth in Section 4 below, the “Relationship”). 12 | 13 | In consideration of the mutual benefits and obligations set forth in this Agreement, the receipt and sufficiency of which is hereby acknowledged, Party A and [DAO NAME] agree as follows: 14 | 15 | 1. **Services**. [DAO NAME] hereby engages Party A to provide [DAO NAME] or its written designee with the following services: _____________________ (including any other services reasonably related thereto and/or as mutually agreed in writing between the Parties, the “Services”). 16 | 17 | 2. **Term**. 18 | 19 | a. The term of this Agreement (the "Term") commences on the Effective Date and remains in full force and effect (except for the terms of this Agreement which expressly survive the expiry or termination of this Agreement) until [DATE] /// [milestone completion (as confirmed in writing by [DAO NAME]) of ____________] or until terminated pursuant to the terms of this Agreement. 20 | 21 | b. This Agreement may be terminated in writing upon [thirty (30) calendar days’] prior written notice by either Party, or by mutual written agreement of the Parties. However, notwithstanding the foregoing sentence, if Party A has been provided written notice from [DAO NAME] as to any material issue with the quality or provision of the Services which remains uncured for ten days in [DAO NAME]’s sole reasonable discretion, this Agreement may be terminated immediately by written notice from [DAO NAME]. 22 | 23 | c. For avoidance of doubt, this Agreement may be terminated in accordance with this section at any point in a calendar month or compensation cycle, and Party A’s compensation for such calendar month or compensation cycle shall be reduced or prorated accordingly to match the actual number of days providing Services for such calendar month or compensation cycle, as applicable. 24 | 25 | 3. **Compensation**. 26 | 27 | a. [DAO NAME] or its written designee will pay Party A [USD$______][_______ tokens (contract address 0x____ on Designated Blockchain)][the compensation set forth in the applicable [DAO NAME] resolution [applicable hereto]/[set forth at [____]]] or other mutually agreed payment method and calculation[ within the first calendar week of each applicable month during the Term, or as otherwise mutually agreed in writing]. 28 | 29 | b. [DAO NAME] will reimburse Party A for all reasonable and necessary expenses incurred by Party A directly attributable to the Services, subject to [DAO NAME]’s express prior written approval of such expenses. 30 | 31 | 4. **Independent Contractor Relationship**. 32 | 33 | a. In providing the Services under this Agreement, the Parties expressly agree that Party A is acting as an independent contractor and not as an employee or agent of [ENTITY], [DAO NAME] or any other related entity. Party A and [DAO NAME] acknowledge and agree that this Agreement does not create a partnership of any kind, nor any joint venture or similar relationship, and is exclusively a contract for service. Party A is not required to pay or make any contributions of any monetary value towards any governmental entity for tax purposes, unemployment compensation, worker’s compensation, insurance premium, pension or any other employee benefit with respect to [DAO NAME] during the Term. 34 | 35 | b. Party A acknowledges and agrees that Party A is solely responsible for complying with all laws, regulations, and other governmental requirements applicable to Party A including but not limited to paying all taxes, expenses, and other amounts due from Party A of any kind related to this Agreement. 36 | 37 | // consider inclusion (if applicable) to strengthen independent contractor fact pattern, mitigating employment-related risks to Entity 38 | 39 | [c. Party A represents that their provision of Services and compensation received under this Agreement is reasonably likely to comprise approximately 30% or less of their aggregate workload and income received from all counterparties, employers, customers, and other third parties as of the Effective Date.]. 40 | 41 | // applicable for where grantee will be privy to confidential information, such as information subject to a third party's NDA, or perhaps where a grantee wishes to preserve their own anonymity, etc. 42 | 43 | 5. **Confidential Information**. 44 | 45 | a. Each Party, their respective affiliates and their respective directors, officers, employers, employees, agents, members, or advisors (collectively, “Representatives”) may be alerted of, become privy to, provide, or gain access to certain confidential and/or proprietary information of the other Party. A Party or its Representative disclosing its Confidential Information (as such term is defined in Section 5(b) below) to the other Party is hereafter referred to as a “Disclosing Party.” A Party or its Representative receiving the Confidential Information of the Disclosing Party is hereafter referred to as a “Receiving Party.” 46 | 47 | b. The term “Confidential Information” as used in this Agreement shall mean any data or information that is reasonably sensitive material and not generally known to the public or any third parties, including, but not limited to, information relating to any of the following: the Relationship, product development and plans, proprietary concepts, documentation, operations, systems, computer software, source code, trade secrets, customer lists, customer relationships, negotiations, present or future business activities, design, verbal conversations or representations, writings, technical information and details which the Disclosing Party reasonably considers confidential, and anything [DAO NAME] sets forth in writing as being confidential or sensitive material. [Unless expressly set forth in writing otherwise, any and all data, information, correspondence, materials, activities, operations, or relationships in any way related to “[______]” or any reference thereof shall be deemed included in the definition of “Confidential Information.”] 48 | 49 | c. The obligation of confidentiality with respect to Confidential Information will not apply to any information publicly known or accessible due to prior authorized or lawful disclosure, or if the information is disclosed by the Receiving Party with the Disclosing Party’s prior written consent and approval. 50 | 51 | d. With respect to Confidential Information: 52 | 53 | i. Receiving Party and its Representatives agree to retain the Confidential Information of the Disclosing Party in strict confidence, to protect the security, integrity and confidentiality of such information and to not permit unauthorized access to or unauthorized use, disclosure, publication or dissemination of Confidential Information except in conformity with this Agreement; 54 | 55 | ii. Receiving Party and its Representatives shall adopt and/or maintain security processes and procedures to safeguard the confidentiality of all Confidential Information received by Disclosing Party using a reasonable degree of care, but not less than that degree of care used in safeguarding its own similar information or material; 56 | 57 | iii. Upon termination the termination of this Agreement, Receiving Party will ensure that all documents, writings, and other electronic records that include or reflect any Confidential Information are returned to Disclosing Party or are destroyed as directed by Disclosing Party; 58 | 59 | iv. If there is an unauthorized disclosure or loss of any of the Confidential Information by Receiving Party or any of its Representatives, Receiving Party will promptly, at its own expense, notify Disclosing Party in writing and take all actions as may be necessary or reasonably requested by Disclosing Party to minimize any damage to the Disclosing Party or a third party as a result of the disclosure or loss; and 60 | 61 | v. The obligation not to disclose Confidential Information shall survive the termination of this Agreement, and at no time will Receiving Party or any of its Representatives be permitted to disclose Confidential Information, except to the extent that such Confidential Information is excluded from the obligations of confidentiality under this Agreement pursuant to Section 5(c) above. 62 | 63 | 6. **[Open Source /// Ownership of Intellectual Property]**. [The Parties acknowledge and agree that all work product and materials from the Services, unless expressly agreed in writing to the contrary, are and will be made and distributed under the [LICENSE TYPE]. /// All intellectual property, work product, and related material including any trade secrets, moral rights, goodwill, relevant registrations or applications for registration, and rights in any patent, copyright, trademark, trade dress, industrial design, non-open source software, method, trade name and communications (the “Intellectual Property”) that is developed, progressed, or produced under this Agreement is a “work made for hire” and will be the sole property of [DAO NAME]. Party A may not use the Intellectual Property for any purpose other than as agreed herein except with the prior written consent of [DAO NAME]. The use of the Intellectual Property by [DAO NAME] will not be restricted in any manner. Party A will be responsible for any and all damages resulting from Party A’s or its Representatives’ or a third party’s (to the extent such third party received or became aware of Intellectual Property from Party A) unauthorized use of the Intellectual Property.] 64 | 65 | 7. **Remedies and Indemnity**. 66 | 67 | a. Each Party agrees that use or disclosure of any Confidential Information [or Intellectual Property] in a manner inconsistent with this Agreement will give rise to irreparable injury for which: (i) money damages may not be a sufficient remedy for any breach of this Agreement by such Party; (ii) the other Party may be entitled to specific performance and injunction and other equitable relief with respect to any such breach; (iii) such remedies will not be the exclusive remedies for any such breach, but will be in addition to all other remedies available at law or in equity; and (iv) in the event of litigation relating to this Agreement, if a court of competent jurisdiction determines in a final non-appealable order that one Party or any of its Representatives has breached this Agreement, such Party will be liable for reasonable legal fees and expenses incurred by the other Party in connection with such litigation. 68 | 69 | b. Each Party agrees to defend, indemnify and hold harmless the other Party against any and all liabilities, claims, suits, losses, damages and expenses, including reasonable attorney's fees, incurred by or asserted against the indemnified Party to the extent caused by the acts or omissions of the indemnifying Party in connection with the performance of Services under this Agreement. 70 | 71 | c. [ENTITY] hereby acknowledges and agrees that Party A has made no express warranties concerning the Services. It is solely [ENTITY]’s responsibility to determine whether the Services will suit [DAO NAME]’s needs or goals. THE SERVICES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. [ENTITY], TO THE FULLEST EXTENT PERMITTED BY LAW, HEREBY DISCLAIMS AND [ENTITY] HEREBY WAIVES ALL WARRANTIES BY PARTY A, INCLUDING, BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND WARRANTIES OF NON-INFRINGEMENT OF THIRD PARTY RIGHTS IN CONNECTION WITH THE SERVICES. PARTY A DOES NOT WARRANT, AND [ENTITY] HEREBY WAIVES ANY WARRANTY, THAT THE SERVICES WILL YIELD ANY PARTICULAR RESULTS OR SUCCESSFUL OUTCOMES. PARTY A DOES NOT MAKE ANY WARRANTY AND [ENTITY] HEREBY WAIVES ANY AND ALL WARRANTIES AS TO THE RESULTS OBTAINED FROM THE SERVICES. 72 | 73 | d. LIMITATION OF LIABILITY: NEITHER PARTY SHALL BE LIABLE FOR ANY LOST PROFITS OR CONSEQUENTIAL, EXEMPLARY, INCIDENTAL OR PUNITIVE DAMAGES (INCLUDING, WITHOUT LIMITATION, IN CONNECTION WITH THE SERVICES PROVIDED HEREUNDER, REGARDLESS OF THE FORM OF ACTION, WHETHER IN CONTRACT OR IN TORT, INCLUDING NEGLIGENCE, AND REGARDLESS OF WHETHER SUCH DAMAGES ARE REASONABLY FORESEEABLE. 74 | 75 | 8. **Assignment**. Neither Party will voluntarily, or by operation of law, assign or otherwise transfer its obligations under this Agreement without the prior written consent of the other Party. 76 | 77 | 9. **Notices**. All notices given under this Agreement shall be in writing and provided in the same manner and to the same addresses and addressees as the Agreement itself or as otherwise designated in writing by the Parties. 78 | 79 | 10. **Amendment**. This Agreement may be amended or modified only by a written agreement signed by both Parties. 80 | 81 | 11. **Jurisdiction and Governing Law**. This Agreement will be governed by and construed in accordance with the laws of [JURISDICTION], without regard to the principles of conflict of laws. Any dispute, claim or controversy arising out of or relating to this Agreement or the breach, termination, enforcement, interpretation or validity thereof, including the determination of the scope or applicability of this Agreement to arbitrate, shall be determined by arbitration in [location] before one arbitrator. The arbitration shall be administered by JAMS pursuant to its Comprehensive Arbitration Rules and Procedures [and in accordance with the Expedited Procedures in those Rules] [or pursuant to JAMS' Streamlined Arbitration Rules and Procedures]. 82 | 83 | 12. **Miscellaneous**. 84 | 85 | a. This Agreement will inure to the benefit of and be binding on the respective successors and permitted assigns of the Parties. 86 | 87 | b. The waiver by either Party of a breach, default, delay or omission of any of the provisions of this Agreement by the other Party will not be construed as a waiver of any subsequent breach of the same or any other provision. 88 | 89 | c. Neither Party shall be in default or otherwise liable for any delay in, or failure of its performance under this Agreement, where such delay or failure arises by reason of any Act of God, or of any government or any governmental body, any material bug, defect or error in any of the [DAO NAME] code, framework or interface or any smart contract or third party oracle or storage program, network or layer or other infrastructure on which the [DAO NAME] code is reliant, or the unauthorized triggering, use or exploitation (whether intentional or unintentional) of any of the foregoing which renders Party A reasonably unable to provide the Services, or other cause beyond the control of the Parties (any of the foregoing, a “force majeure”); provided, however, that the delay or failure in performance could not have reasonably been foreseen or provided against; and provided further that each Party exercises such diligence in resolving the force majeure as the circumstances may require. 90 | 91 | d. If any provision of this Agreement is held to be invalid, illegal or unenforceable in whole or in part, the remaining provisions shall not be affected and shall continue to be valid, legal and enforceable as though the invalid, illegal or unenforceable parts were severed from this Agreement. 92 | 93 | e. This Agreement may be executed in counterparts, each of which shall be deemed an original, but both of which together shall constitute one and the same instrument. This Agreement may be executed by commercially acceptable electronic means, and any electronic signatures to this Agreement are the same as handwritten signatures for purposes of validity, enforceability, and admissibility. 94 | 95 | f. Any consents, approvals or acknowledgements provided by [DAO NAME] may be provided through [DAO NAME]'s governance framework pursuant to its applicable requirements. 96 | 97 | ***************************************************** 98 | 99 | 100 | 101 | The Parties hereto have executed this Agreement as of the Effective Date. 102 | 103 | 104 | 105 | [PARTY A SIGNATURE] 106 | By: 107 | **[Party A]** 108 | 109 | 110 | 111 | [DAO SIGNATURE] 112 | By: 113 | **[DAO LEGAL WRAPPER]** 114 | -------------------------------------------------------------------------------- /forms/legal/Invoice.md: -------------------------------------------------------------------------------- 1 | [Invoicing Entity / Individual] 2 | 3 | INVOICE NO. _______ 4 | 5 | Date: 6 | 7 | 8 | Bill to: 9 | [Entity / Individual] 10 | 11 | [Attn] 12 | 13 | [Email address / Communications handle] 14 | 15 | 16 | 17 | 18 | 20 | 22 | 24 | 26 | 27 | 28 | 30 | 32 | 34 | 36 | 37 | 38 | 40 | 42 | 44 | 46 |
    47 |
Description of Services 19 | Reference 21 | [Grant Amount || Flat Fee || Hours * Hourly Rate] 23 | Total 25 |
29 | 31 | 33 | 35 |
39 | 41 | 43 | 45 |
48 | 49 | Total Due: $_______________ 50 | 51 | Payment methods accepted: 52 | 53 | - [ ] token with corresponding symbol "[ ]" and [ ] mainnet contract address [ ] or other mutually agreed (including as to calculation) token transfer to [Recipient ENS || Recipient Blockchain Address]. Contact for addresses on other chains, or to pay to an address without prior token transaction history. 54 | 55 | - Contact for centralized service provider payment service options (Circle, Zelle, Venmo, Bitpay, etc.). 56 | 57 | - ACH/Wire/bank transfer 58 | 59 | - Account Title: ______________ 60 | 61 | - Routing Number: ______________ 62 | 63 | - Account Number: ______________ 64 | 65 | - SWIFT Code (foreign wire transfers): ______________ 66 | -------------------------------------------------------------------------------- /forms/legal/NDA.md: -------------------------------------------------------------------------------- 1 | // drafted from the perspective of a DAO’s legal wrapper engaging a new or potential contributor/grantee who will encounter confidential information (internal or third party) 2 | 3 | // insert any specific concepts or references to be expressly confidential in Section 1 4 | 5 | // consider including identities of pseudo-anon contributors as Confidential Information 6 | 7 | ## Non-Disclosure and Confidentiality Agreement 8 | 9 | This Non-Disclosure and Confidentiality Agreement (this “Agreement”) is entered into as of [DATE] (the “Effective Date”) by and between [INDIVIDUAL OR ENTITY] (“Party A”) and [DAO LEGAL WRAPPER], a [ENTITY TYPE] (the “Entity”), governed by or otherwise legally associated with the [NAME] Decentralized Autonomous Organization with [DESIGNATED BLOCKCHAIN] contract address [CONTRACT ADDRESS] (“[NAME] DAO”) ([______] DAO and the Entity, together with any and all subsidiaries and affiliates, “[DAO NAME]”)) (Party A and [NAME] are each a “Party” and both, the “Parties”). 10 | 11 | [DAO NAME] and Party A have indicated an interest in exploring a potential commercial relationship and/or contractor or employment relationship (the “Relationship”). In connection with its respective evaluation of the Relationship, each Party, their respective affiliates and their respective directors, officers, employers, employees, contractors, agents, members, or advisors (collectively, “Representatives”) may be alerted of, become privy to, provide or gain access to certain confidential and/or proprietary information. A Party or its Representative disclosing its Confidential Information (as such term is defined in Section 1 below) to the other Party is hereafter referred to as a “Disclosing Party.” A Party or its Representative receiving the Confidential Information of the Disclosing Party is hereafter referred to as a “Receiving Party.” In consideration for being furnished Confidential Information and for the Relationship, [DAO NAME] and Party A agree as follows: 12 | 13 | 1. Confidential Information. The term “Confidential Information” as used in this Agreement shall mean any data or information that is reasonably sensitive material and not generally known to the public or any third parties, including, but not limited to, information relating to any of the following: non-public product development and plans, proprietary concepts, documentation, operations, systems, computer software, source code, trade secrets, customer lists, customer relationships, present or future business activities, design, verbal conversations or representations, writings, technical information and integrations which the Disclosing Party reasonably communicates as confidential, and anything [DAO NAME] sets forth in writing as being confidential or sensitive material. [Unless expressly set forth in writing otherwise, any and all data, information, correspondence, materials, activities, operations, or relationships in any way related to [__________] or any reference thereof shall be deemed included in the definition of “Confidential Information.”] 14 | 15 | 2. Exclusions from Confidential Information. The obligation of confidentiality with respect to Confidential Information will not apply to any information publicly known due to prior authorized or lawful disclosure, or if the information is disclosed by the Receiving Party with the Disclosing Party’s prior written consent and approval. 16 | 17 | 3. Obligation to Maintain Confidentiality. With respect to Confidential Information: 18 | 19 | a. Receiving Party and its Representatives agree to retain the Confidential Information of the Disclosing Party in strict confidence, to use commercially reasonable measures to protect the security, integrity and confidentiality of such information and to not permit unauthorized access to or unauthorized use, disclosure, publication or dissemination of Confidential Information except in conformity with this Agreement; 20 | 21 | b. Receiving Party and its Representatives shall adopt and/or maintain security processes and procedures to safeguard the confidentiality of all Confidential Information received by Disclosing Party using a reasonable degree of care, but not less than that degree of care used in safeguarding its own similar information or material; 22 | 23 | c. Upon termination the termination of this Agreement, Receiving Party will ensure that all documents, writings, and other electronic records that include or reflect any Confidential Information are returned to Disclosing Party or are destroyed as directed by Disclosing Party; 24 | 25 | d. If there is an unauthorized disclosure or loss of any of the Confidential Information by Receiving Party or any of its Representatives, Receiving Party will promptly, at its own expense, notify Disclosing Party in writing and take all actions as may be necessary or reasonably requested by Disclosing Party to minimize any damage to the Disclosing Party or a third party as a result of the disclosure or loss; and 26 | 27 | e. The obligation not to disclose Confidential Information shall survive the termination of this Agreement, and at no time will Receiving Party or any of its Representatives be permitted to disclose Confidential Information, except to the extent that such Confidential Information is excluded from the obligations of confidentiality under this Agreement pursuant to Section 2 above. 28 | 29 | 4. Non-Disclosure of Relationship. Without Disclosing Party’s prior written consent, neither Receiving Party nor its Representatives shall disclose to any other person (a) the fact that Confidential Information has been made available to it or that it has inspected any portion of the Confidential Information; (b) the fact that the Disclosing Party and Receiving Party are having discussions or negotiation concerning the Relationship; or (c) any of the terms, conditions, discussions, plans or other facts with respect to the Relationship. 30 | 31 | 5. Representatives. Receiving Party will take reasonable steps to ensure that its Representatives adhere to the terms of this Agreement, and Receiving Party will be responsible for any breach of this Agreement by any of its Representatives. 32 | 33 | 6. Disclaimer. There is no representation or warranty made by Disclosing Party as to the accuracy or completeness of any of the Confidential Information. Either Party may, in its sole discretion: (a) reject any proposals made by the other Party or its Representatives with respect to the Relationship; and (b) terminate discussions or negotiations at any time. 34 | 35 | 7. Remedies. Each Party agrees that use or disclosure of any Confidential Information in a manner inconsistent with this Agreement will give rise to irreparable injury for which: (a) money damages may not be a sufficient remedy for any breach of this Agreement by such Party; (b) the other Party may be entitled to specific performance and injunction and other equitable relief with respect to any such breach; (c) such remedies will not be the exclusive remedies for any such breach, but will be in addition to all other remedies available at law or in equity; and (d) in the event of litigation relating to this Agreement, if a court of competent jurisdiction determines in a final non-appealable order that one Party, or any of its Representatives, has breached this Agreement, such Party will be liable for reasonable legal fees and expenses incurred by the other Party in connection with such litigation, including, but not limited to, any appeals. 36 | 37 | 8. Notices. All notices given under this Agreement shall be in writing and provided in the same manner and to the same addresses and addressees as the Agreement itself or as otherwise designated in writing by the Parties. 38 | 39 | 9. Termination. This Agreement will terminate only upon the mutual written agreement of the Parties to terminate this Agreement. 40 | 41 | 10. Amendment. This Agreement may be amended or modified only by a written agreement signed by both Parties. 42 | 43 | 11. Governing Law and Jurisdiction. This Agreement is governed by the laws of the State of New York, without regard to any conflicts of law provisions. The Parties hereby consent to the exclusive jurisdiction of the New York International Arbitration Center with respect to any dispute arising under or relating to this Agreement, and waive any respective rights to a jury trial. 44 | 45 | 12. Miscellaneous. 46 | 47 | a. This Agreement will inure to the benefit of and be binding on the respective successors and permitted assigns of the Parties. Neither Party may assign its rights or delegate its duties under this Agreement without the other party’s prior written consent. 48 | 49 | b. In the event that any provision of this Agreement is held to be invalid, illegal or unenforceable in whole or in part, the remaining provisions shall not be affected and shall continue to be valid, legal and enforceable as though the invalid, illegal or unenforceable parts were severed from this Agreement. 50 | 51 | c. This Agreement may be executed in counterparts, each of which shall be deemed an original, but both of which together shall constitute one and the same instrument. This Agreement may be executed by electronic means, and any electronic signatures to this Agreement are deemed the same as handwritten signatures for purposes of validity, enforceability, and admissibility. 52 | 53 | 54 | ***************************************************** 55 | 56 | 57 | 58 | The Parties hereto have executed this Agreement as of the Effective Date. 59 | 60 | 61 | 62 | ________ 63 | By: 64 | Party A 65 | 66 | 67 | ________ 68 | By: 69 | [DAO NAME] 70 | -------------------------------------------------------------------------------- /forms/legal/Notice of Termination.md: -------------------------------------------------------------------------------- 1 | ### NOTICE OF TERMINATION 2 | 3 | [DATE] 4 | 5 | To: [COUNTERPARTY] (“[COUNTERPARTY]”) 6 | 7 | Attn: [ADDRESSEE] 8 | 9 | Re: [AGREEMENT TITLE] (the “Agreement”) dated [DATE] between [COUNTERPARTY] and [ENTITY] (“[ENTITY]”) 10 | 11 | Dear [ADDRESSEE], 12 | 13 | Pursuant to Section __ of the Agreement, this Notice of Termination (this “Notice”) serves as written notice of [ENTITY]’s termination of the Agreement effective on the date falling [NOTICE PERIOD] after the date of this Notice, as provided in such Section __ (the “Termination Date”). 14 | As of the Termination Date, all obligations of and between [COUNTERPARTY] and [ENTITY] under the Agreement shall be deemed discharged, with the exception of those terms and obligations which expressly survive the termination of the Agreement as set forth in Section __ of the Agreement. 15 | The provisions of Sections __ through __ of the Agreement shall apply to this Notice mutatis mutandis as if fully set forth herein. 16 | 17 | Sincerely, 18 | 19 | [____________________] 20 | [NAME] 21 | 22 | [TITLE] 23 | 24 | [ENTITY] 25 | 26 | 27 | -------------------------------------------------------------------------------- /forms/legal/SMLLC Checklist.md: -------------------------------------------------------------------------------- 1 | # Single Member LLC Formation Checklist 2 | 3 | _First step is always to consult a *lawyer in your jurisdiction* and an *accountant*. Applicability of each item in this list may vary according to your particular details._ 4 | 5 | - [ ] Choose a name 6 | - search the applicable state's corporate directory for availability (for example, [DE's Division of Corp. Name Search](https://icis.corp.delaware.gov/Ecorp/EntitySearch/NameSearch.aspx)) 7 | - [ ] `State-specific` ensure your chosen name complies with state law 8 | - for example, many states require "LLC", "L.L.C.", or "Ltd." as a suffix for your entity name, and there are usually restrictions on certain sensitive or materially misleading names (for example, a carpentry business probably should not be named "Cardiac Surgeons LLC") 9 | - [ ] `State-specific` check whether any professional licensing is required for your commercial operation 10 | - [ ] `Local-specific` check whether any licenses or permits are needed for your LLC's business 11 | - [ ] `State-specific` file the necessary formation documents, or consider using a corporate service company for formation of the entity, registered agent, and state filings (including payment of annual fees and handling annual reports). 12 | - popular choices include doola, Zenbusiness, LegalZoom, etc. 13 | - such services may also assist in any "doing business as" (DBA) name filings, annual property filings, etc. 14 | - [ ] `State-specific` ask your lawyer whether the registered agent's address may be used as the LLC's address 15 | - some states require the primary address where your business is conducted (which for many SMLLCs might be a home address) 16 | - [ ] `State-specific` have your lawyer draft an LLC [Operating Agreement](https://github.com/ErichDylus/Open-Source-Law/blob/main/forms/legal/Single%20Member%20LLC%20Operating%20Agreement.md), to be signed by you (individually) and the LLC 17 | - [ ] Open a bank account for your LLC 18 | - [ ] Purchase business/professional insurance for your LLC 19 | - [ ] Register service accounts for your LLC 20 | - email address, domain (if applicable), and anything else you'll use for your LLC's business (cloud storage, GitHub, social media, etc.) 21 | - update professional profiles 22 | - [ ] If accepting crypto, consider a centralized exchange or other "off-ramp" account for your LLC if accepting crypto payments (for some business types, permission for this may be `State-specific`) 23 | - also consider further ways to distinguish and separate your LLC crypto income/assets from personal assets, for example an ENS for your LLC's EOA/multi-sig that includes your LLC's name 24 | - [ ] Keep a private Confirmation of Accounts document with your LLC's blockchain address(es) and other accounts 25 | - [ ] Consider using bookkeeping software to keep track of income and expenses, and calculate estimated federal quarterly taxes. 26 | - options such as Quickbooks will provide aggregated forms for annual tax filings 27 | - [ ] Apply for an [EIN](https://www.irs.gov/businesses/small-businesses-self-employed/apply-for-an-employer-identification-number-ein-online) if applicable. 28 | - [ ] Consider an [EFTPS](https://www.eftps.gov/eftps/) account for paying quarterly estimated federal tax payments online from your LLC's bank account 29 | - [ ] `State-specific` each state has its own system for paying quarterly estimated state taxes. 30 | - these estimated amount payments can often be scheduled in advance for a taxable year and auto-withdrawn from your LLC's bank account (make a note of these payment dates) 31 | - [ ] Consult a CPA for annual tax filings/payments and any other tax or accounting concerns 32 | - for example, whether your SMLLC should be taxed as a pass-through (most common) or a corporation (and if so, handling IRS form 8832 and other necessary payment flows and administrative tasks), or what retirement account/plan may best suit your situation 33 | - [ ] Consult a lawyer for: 34 | - contracts your LLC may enter into, including any form agreements you may want your clients to sign (your lawyer should be involved any time a contract is signed) 35 | - any litigation activity (obviously) 36 | - any necessary IP protections, such as copyright or trademark filings for your LLC's name, logo, or products if applicable 37 | - any other legal or regulatory concerns 38 | -------------------------------------------------------------------------------- /forms/legal/Single Member LLC Operating Agreement.md: -------------------------------------------------------------------------------- 1 | // _simple operating agreement for a single member, member-managed LLC_ 2 | 3 | // _provided as-is without warranty of any kind; do not use without consulting an attorney; all disclosures and disclaimers including [as set out in this repo's readme and license](https://github.com/ErichDylus/Open-Source-Law/blob/main/README.md) and the [cited disclosures and disclaimers](https://github.com/ErichDylus/Open-Source-Law/blob/main/Disclosure.md) apply_ 4 | 5 | 6 | LIMITED LIABILITY COMPANY OPERATING AGREEMENT 7 | OF 8 | [NAME] LLC 9 | 10 | A Single-Member, Member-Managed Limited Liability Company 11 | 12 | 13 | This Limited Liability Company Operating Agreement (this “Agreement”) is entered into as of [EFFECTIVE DATE], by and between [NAME] LLC, a [STATE OF ORGANIZATION] limited liability company, (the “Company”), and [MEMBER], an individual, (the “Member”). 14 | 15 | The Member desires to create a limited liability company and set forth the terms of the Company’s operation. 16 | 17 | NOW, THEREFORE, in consideration of the mutual covenants set forth herein and other valuable consideration, the receipt and sufficiency of which hereby are acknowledged, the Member and the Company agree as follows: 18 | 19 | 1. Formation. The Company was formed in [STATE OF ORGANIZATION] on [ORGANIZATION DATE] pursuant to the statutes thereto governing limited liability companies [including but not limited to [STATUTE REFERENCE(S)]] (the “Statutes”). 20 | 21 | 2. Name and Principal Place of Business. The name of the Company is “[NAME] LLC” and has a principal place of business at [ADDRESS], or as otherwise selected by the Member. 22 | 23 | 3. Purpose. The Company may conduct any and all lawful business, activity or functions appropriate in carrying out the Company’s objectives as determined by the Member. 24 | 25 | 4. Registered Office and Agent. The location and name of the registered agent will be as stated in the Company’s formation documents or any amendment thereof. 26 | 27 | 5. Term. The term of the Company shall be perpetual, commencing on the filing of the [Articles of Organization][Certificate of Formation] of the Company, and continuing until terminated pursuant to this Agreement. 28 | 29 | 6. Member Capital Contributions. The Member may make such capital contributions (each a “Capital Contribution”) in such amounts and at such times as the Member shall determine. The Member shall not be obligated to make any Capital Contributions. 30 | 31 | 7. Distributions. 32 | 33 | (a) The Member may take distributions of the Company’s capital from time to time as permitted by and subject to any limitations of the Statutes. 34 | 35 | (b) A “Capital Account” for the Member shall be maintained by the Company. The Member's Capital Account shall reflect the Member’s Capital Contributions and increases for any net income or gain of the Company, and decreases for distributions made to the Member and the Member’s share of any losses and deductions of the Company (accounting for applicable expenses, depreciation, and other fees and obligations incurred in connection with the conduct of the Company’s business), as applicable. 36 | 37 | 8. Books, Records and Tax Returns 38 | 39 | (a) The Company shall maintain complete and accurate books and records of the Company's business and affairs as required by the Statutes and such books and records shall be kept at the Company's Registered Office and shall in all respects be independent of the books, records and transactions of the Member. 40 | 41 | (b) The Company's fiscal year shall be the calendar year with an ending month of December. 42 | 43 | (c) The Member intends that the Company, as a single member LLC, shall be taxed as [a sole proprietorship in accordance with the provisions of the Internal Revenue Code and the Statutes. Any provisions herein that may cause the Company not to be taxed as a sole proprietorship shall be inoperative]. 44 | 45 | 9. Bank Accounts and Blockchain Addresses. All funds of the Company shall be deposited in the Company’s name in (i) bank or other service provider accounts or (ii) blockchain addresses (including but not limited to Company-controlled externally owned accounts or contract addresses), as applicable and as chosen by the Member. Withdrawals from any such accounts shall be made only in the regular course of business of the Company and shall be made upon such applicable action by the Member as the Member from time to time may designate. [For avoidance of doubt, the blockchain address registered to Ethereum Name Service address [ENS ADDRESS].eth and controlling the ERC-721 nonfungible token corresponding thereto, including all cryptocurrencies, tokens, and other digital assets held by such address or solely controlled thereby (inclusive of all ChainIds), shall be deemed the exclusive property of the Company.] 46 | 47 | 10. Management of the Company. The business and affairs of the Company shall be conducted and managed by the Member in accordance with this Agreement and the laws of the State of [STATE OF ORGANIZATION]. The Member, as sole member of the Company, has sole authority and power to act for or on behalf of the Company, to do any act that would be binding on the Company, or incur any expenditures on behalf of the Company. The Member shall not be liable for the debts, obligations or liabilities of the Company, including under a judgment, decree or order of a court. The Company is organized as a “member-managed” limited liability company. The Member is designated as the initial managing member. 48 | 49 | 11. Ownership of Company Property. The Company’s assets shall be deemed owned by the Company as an entity, and the Member shall have no ownership interest in such assets or any portion thereof. Title to any or all such Company assets may be held in the name of the Company, or one or more nominees or trustees, as the Member may determine. Except as limited by the Statutes, the Member may engage in other business ventures of any nature, including, without limitation by specification, the ownership of another business similar to that operated by the Company. The Company shall not have any right or interest in any such independent ventures nor to the income and profits derived therefrom. 50 | 51 | 12. Admission of New Members. 52 | 53 | (a) The Company may admit new Members (or transferees of any interests of existing Members) into the Company by the unanimous vote or consent of the Members. As a condition to the admission of a new Member, such Member shall execute and acknowledge such instruments, in form and substance satisfactory to the Company, as the Company may deem necessary or desirable to effectuate such admission and to confirm the agreement of such Member to be bound by all of the terms, covenants and conditions of this Agreement, as the same may have been amended. Such new Member shall pay all reasonable expenses in connection with such admission, including without limitation, reasonable attorneys’ fees and the cost of the preparation, filing or publication of any amendment to this Agreement or the [Articles of Organization/Certificate of Formation], which the Company may deem necessary or desirable in connection with such admission. 54 | 55 | (b) No new Member shall be entitled to any retroactive allocation of income, losses, or expense deductions of the Company. The Company may make pro rata allocations of income, losses or expense deductions to a new Member for that portion of the tax year in which the Member was admitted in accordance with Section 706(d) of the Internal Revenue Code and regulations thereunder. 56 | 57 | (c) In no event shall a new Member be admitted to the Company if such admission would be in violation of applicable Federal or State securities laws or would adversely affect the intended treatment of the Company for income tax purposes. 58 | 59 | 13. Termination, Dissolution, and Liquidation 60 | 61 | (a) The Company shall dissolve and its affairs shall be wound up on the first to occur of: (i) at a time, or upon the occurrence of an event specified in the [Articles of Organization/Certificate of Formation] or this Agreement, or (ii) the determination by the Member that the Company shall be dissolved. 62 | 63 | (b) Upon the death of the Member, the Company shall be dissolved. By separate written documentation, the Member may designate and appoint the individual who will wind down the Company’s business and transfer or distribute the Member's Interests and Capital Account as designated by the Member or as may otherwise be required by law. 64 | 65 | (c) Upon the disability of a Member, the Member may continue to act as Manager hereunder or appoint a person to so serve until the Member's Interests and Capital Account of the Member have been transferred or distributed and this Agreement shall be terminated. 66 | 67 | 14. Indemnification 68 | 69 | (a) The Member (including, for purposes of this Section, any estate, heir, personal representative, receiver, trustee, successor, assignee and/or transferee of the Member) shall not be liable, responsible or accountable, in damages or otherwise, to the Company or any other person for: (i) any act performed, or the omission to perform any act, within the scope of the power and authority conferred on the Member by this agreement and/or by the Statutes except by reason of acts or omissions found by a court of competent jurisdiction upon entry of a final judgment rendered and un-appealable or not timely appealed (“Judicially Determined”) to constitute fraud, gross negligence, or intentional misconduct; (ii) the termination of the Company and this Agreement pursuant to the terms hereof; (iii) the performance by the Member of, or the omission by the Member to perform, any act which the Member reasonably believed to be consistent with the advice of attorneys, accountants or other professional advisers to the Company with respect to matters relating to the Company, including actions or omissions determined to constitute violations of law but which were not undertaken in bad faith; or (iv) the conduct of any person selected or engaged by the Member. 70 | 71 | (b) The Company, its receivers, trustees, successors, assignees and/or transferees shall indemnify, defend and hold the Member harmless from and against any and all liabilities, damages, losses, costs and expenses of any nature whatsoever, known or unknown, liquidated or unliquidated, that are incurred by the Member (including amounts paid in satisfaction of judgments, in settlement of any action, suit, demand, investigation, claim or proceeding (“Claim”), as fines or penalties) and from and against all legal or other such costs as well as the expenses of investigating or defending against any Claim or threatened or anticipated Claim arising out of, connected with or relating to this Agreement, the Company or its business affairs in any way; provided, that the conduct of the Member which gave rise to the action against the Member is indemnifiable under the standards set forth herein. 72 | 73 | (c) Upon application, the Member shall be entitled to receive advances to cover the costs of defending or settling any Claim or any threatened or anticipated Claim against the Member that may be subject to indemnification hereunder upon receipt by the Company of any undertaking by or on behalf of the Member to repay such advances to the Company, without interest, if the Member is Judicially Determined not to be entitled to indemnification as set forth herein. 74 | 75 | (d) All rights of the Member to indemnification under this Agreement shall (i) be cumulative of, and in addition to, any right to which the Member may be entitled to by contract or as a matter of law or equity, and (ii) survive the dissolution, liquidation or termination of the Company as well as the death, removal, incompetency or insolvency of the Member. 76 | 77 | (e) The termination of any Claim or threatened Claim against the Member by judgment, order, settlement or upon a plea of nolo contendere or its equivalent shall not, of itself, cause the Member not to be entitled to indemnification as provided herein unless and until Judicially Determined to not be so entitled. 78 | 79 | 15. Miscellaneous 80 | 81 | (a) This Agreement and the rights and liabilities of the parties hereunder shall be governed by and determined in accordance with the laws of the State of [STATE OF ORGANIZATION]. If any provision of this Agreement shall be invalid or unenforceable, such invalidity or unenforceability shall not affect the other provisions of this Agreement, which shall remain in full force and effect. 82 | 83 | (b) The captions in this Agreement are for convenience only and are not to be considered in construing this Agreement. All pronouns shall be deemed to be the masculine, feminine, neuter, singular or plural as the identity of the person or persons may require. References to a person or persons shall include partnerships, corporations, limited liability companies, unincorporated associations, foundations, cooperatives, trusts, estates and other types of entities as applicable. 84 | 85 | (c) This Agreement sets forth the entire agreement of the parties hereto with respect to the subject matter hereof. It is the intention of the Member that this Agreement shall be the sole agreement of the parties, and, except to the extent a provision of this Agreement provides for the incorporation of federal income tax rules or is expressly prohibited or ineffective under the Statutes, this Agreement shall govern even when inconsistent with, or different from, the provisions of any applicable law or rule. To the extent any provision of this Agreement is prohibited or otherwise ineffective under the Statutes, such provision shall be considered to be ineffective to the smallest degree possible in order to make this Agreement effective under the Statutes. 86 | 87 | (d) Subject to the limitations on transferability set forth above, this Agreement shall be binding upon and inure to the benefit of the parties hereto and to their respective heirs, executors, administrators, successors and assigns. No provision of this Agreement is intended to be for the benefit of or enforceable by any third party. 88 | 89 | (e) This Agreement, and any amendments hereto may be executed in counterparts all of which taken together shall constitute one agreement. 90 | 91 | [Signature Page Follows] 92 | 93 | ********************************************************************** 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | IN WITNESS WHEREOF, the parties have executed this Agreement this [DATE]. 114 | 115 | 116 | 117 | [NAME] LLC 118 | 119 | 120 | 121 | By: ____________________________ 122 | 123 | [MEMBER], as Member 124 | 125 | 126 | [MEMBER] 127 | 128 | 129 | 130 | By: ____________________________ 131 | 132 | [MEMBER], in their individual capacity 133 | -------------------------------------------------------------------------------- /forms/legal/Unincorporated Nonprofit Association Charter Form (DC).md: -------------------------------------------------------------------------------- 1 | // provided without warranty or guarantees of any kind, [this disclosure](https://github.com/ErichDylus/Open-Source-Law/blob/main/Disclosure.md) applies 2 | 3 | // contemplates all governance processes through the Designated Smart Contract, no pro-rata distributions to DAO Members (per DC UUNAA law), tokenized membership 4 | 5 | // adapted for DC law in part from the [LexDAO Constitution](https://github.com/lexDAO/LexDAO-Constitution), provided under the [CCA Share Alike 4.0 License](https://github.com/lexDAO/LexDAO-Constitution/blob/master/LICENSE.md) 6 | 7 | ### I. Nature of Charter and Name of the DAO 8 | (a) This charter (this “Charter”) is the official legal charter of [DAO NAME] (the “**DAO**”). This Charter is intended to be a legal agreement & contract binding upon all DAO Members and the other DAO Participants, as they may join and exit the DAO from time to time, as each such term is defined herein, and is enforceable in accordance with its terms under the laws of the District of Columbia. Certain capitalized terms used in this Charter are defined in Section VI. 9 | 10 | (b) If you have [received (actually or constructively)][contributed or staked] any DAO Membership Token [in the Designated Smart Contract] or are otherwise a member of [DAO NAME] in accord with Section III(a) of this Charter, you consent to & agree to become legally bound by this Charter as both a DAO Participant and more specifically a "DAO Member" as such term is defined in this Charter. 11 | 12 | (c) [DAO NAME] is an unincorporated nonprofit association under the District of Columbia Uniform Unincorporated Nonprofit Association Act of 2010 (D.C. Stat. Title 29, Ch. 11) (the “**DC UUNAA**”). [DAO NAME] is not intended to be, and shall not be deemed to be, a partnership. This Charter together with the Designated Smart Contract comprise the ‘governing principles’ of the DAO, as such term is defined in §29–1102 of the DC UUNAA. 13 | 14 | ### II. Purposes and Structure of the DAO 15 | (a) The DAO is a "decentralized autonomous organization", or a collective of individuals, entities, associations and/or other persons or groups of persons, which defers certain aspects of the governance, structure, operations, and other capabilities to the consensus mechanisms, computations, and data storage and transactions of the Designated Smart Contract’s code and underlying permission-less blockchain. 16 | 17 | (b) The DAO Members shall utilize the Designated Smart Contract (as such term is defined in Section VI of this Charter) as the controlling and primary method of holding, allocating among the DAO Members, and spending or otherwise distributing, any Tokens that are DAO Property, of minting and issuing any DAO Membership Tokens, of holding and recording votes of the DAO Members, and setting or altering parameters to the Designated Smart Contract, as applicable. The DAO may also utilize the Designated Smart Contract to administer and facilitate certain other arrangements and transactions involving the DAO, the DAO Members and/or third Members. 18 | 19 | (c) The primary purposes of the DAO are to facilitate, support, promote, operate, represent and advance [DAO PURPOSES] (the “**Purposes**”). 20 | 21 | ### III. DAO Membership 22 | (a) A person, represented by the public key of their applicable externally owned account, shall be deemed to be a “DAO Member” if and only if: [DAO MEMBERSHIP REQUIREMENTS]. 23 | 24 | (b) Membership rights in the DAO shall be represented by [an externally owned account address’s control of Tokens with contract address [TOKEN ADDRESS] and bearing symbol “[SYMBOL]” (the "**DAO Membership Tokens**")]. The ability to become a Member, as defined in §29–1102 of the DC UUNAA, shall be voluntary and application open to any individual of at least 18 years of age whose purpose or presumed intent is commensurate with the Purposes and is willing to accept the responsibilities and terms of membership including the terms of this Charter, and follow the applicable membership processes. 25 | 26 | (c) DAO Members shall have the rights, powers and privileges that are possible to be taken or exercised by DAO Members through the Designated Smart Contract as further set forth in Section IV which are in accordance with this Charter. The rights, powers and privileges of DAO Members are referred to herein as the "**DAO Membership Rights**". 27 | 28 | (d) Status as a DAO Member does not (and shall not be deemed to) create, and the DAO Membership Rights do not (and shall not be deemed to) include, any authority, right or power on the part of a DAO Member to act as the agent, representative or attorney of or otherwise act on behalf of the DAO or any other DAO Member, to bind the DAO or any other DAO Member to any Contract or Liability or to Convey (as such term is defined in Section IV(A)(ii) below) any DAO Property or any asset, right or property owned or held by or on behalf of the DAO or any DAO Member. Without limiting the generality of the foregoing, no DAO Member shall be deemed the partner of the DAO or any other DAO Member. No DAO Member shall state, purport, imply, hold out or represent to any person that such DAO Member or any other DAO Member has any such authority, right or power. 29 | 30 | (e) To the maximum extent permitted by applicable law, no DAO Member shall be (or shall be deemed to be) Liable for any Liability of the DAO or any other DAO Member. This clause "(e)" shall not (and shall not be deemed to) create or imply any obligation of the DAO or any DAO Member to indemnify or compensate any DAO Member from, or hold any DAO Member harmless against, any Liabilities incurred by such DAO Member under any applicable law, in connection with the DAO Member's participation in the DAO or otherwise. 31 | 32 | ### IV. Binding Effect of the Designated Smart Contract 33 | (A) *Prohibition of Legal Proceedings & Transfers.* No DAO Member shall, without the prior written [unanimous/majority] consent of the other DAO Members, directly or indirectly take or attempt to take any of the following actions: 34 | (i) except as set forth in Section IV(b) or to the extent necessary to enforce the express provisions of this Charter, commence or continue any Legal Proceeding, assert any Claim or enforce any judgment or other Order, in each case, that (1) is against or involves any other DAO Member(s), (2) relates to this Charter or the matters contemplated by this Charter, the Designated Smart Contract, the DAO Property or any of the other DAO Matters, including, for the avoidance of doubt, any Legal Proceeding or Order *in rem* pertaining to the DAO Property or any Legal Proceeding or Claim challenging the enforceability of any provision of this Charter; 35 | (ii) Convey any of the DAO Property other than such DAO Member's Distributed DAO Property (it being understood that for a DAO Member to “**Convey**” any of the DAO Property means for such DAO Member to, or to enter into any Contract that may obligate such DAO Member, any other DAO Member or the DAO to: (1) create, perfect or enforce any Lien on or otherwise encumber, (2) pledge, hypothecate, grant an option or derivative security, swap or other instrument with respect to or (3) convey, sell, transfer or dispose of such DAO Property or any right or interest of the DAO or any DAO Member to or in such DAO Property); or 36 | (iii) cause, assist, encourage or facilitate, a Material Adverse Exception Event. 37 | 38 | ### V. Representations and Warranties 39 | Each DAO Member (as the "**Representing DAO Member**") hereby represents and warrants, to and for the benefit of each other DAO Member, as of all dates that such Person remains a DAO Member, as follows: 40 | 41 | (a) *Authorization and Enforceability.* The Representing DAO Member has all necessary power, authority and capacity to enter into, agrees to the terms and conditions of, and becomes bound by this Charter. This Charter has been duly entered into by the Representing DAO Member and constitutes a legal, valid and binding obligation of the Representing DAO Member, enforceable against the Representing DAO Member in accordance with its terms 42 | 43 | (b) *Reliance on Own Due Diligence; Informed Consent.* 44 | (i) The Representing DAO Member has received and carefully reviewed a copy of this Charter. The Representing DAO Member has been given a full and fair opportunity to: (A) to ask questions of, and to receive answers from, the other DAO Members regarding the subject matter of this Charter, and (B) to obtain any additional information that is reasonably necessary to evaluate this Charter and the matters contemplated thereby. 45 | (ii) Other than the representations and warranties of the other DAO Members expressly set forth in this Section V, the Representing DAO Member has not relied on any statement, information, representation, or warranty including oral statements, due diligence presentations, etc., or any omission of any statement, information, representation or warranty, made by or on behalf of the other DAO Members in determining to enter into or perform this Charter. The Representing DAO Member understands that the other DAO Members has not made and has not authorized any of its representatives to make, any representation, warranty or other statement intended to be relied upon or to give rise to any claim, obligation or liability based on the accuracy or completeness thereof. 46 | 47 | ### VI. Definitions 48 | 49 | (a) “**Claim**” means any past, present or future dispute, claim, controversy, demand, right, obligation, liability, action or cause of action of any kind or nature. 50 | 51 | (b) “**Consensus Rules**” means the rules for transaction validity, block validity and determination of the canonical blockchain that are embodied in the Designated Client. 52 | 53 | (c) “**Contract**” means any: (i) written, oral, implied by course of performance or otherwise or other agreement, contract, understanding, arrangement, settlement, instrument, warranty, license, insurance policy, benefit plan or legally binding commitment or undertaking; or (ii) any representation, statement, promise, commitment, undertaking, right or obligation that may be enforceable, or become subject to an Order directing performance thereof, based on equitable principles or doctrines such as estoppel, reliance, or quasi-contract. 54 | 55 | (d) “**DAO Member**” has the meaning assigned to it in Section III(a) of this Charter. 56 | 57 | (e) “**DAO Property**" means any Token or other asset, right or property licensed to or on deposit with or owned, held, custodied, controlled or possessed by or on behalf of the DAO, including any Token on deposit with or held, controlled, possessed by or on deposit with the Designated Smart Contract. 58 | 59 | (f) “**Designated Blockchain**” means at any given time, the version of the digital blockchain ledger that at least a majority of nodes running the Designated Client on the Designated Blockchain Network recognize as canonical as of such time in accordance with the Consensus Rules. 60 | 61 | (g) “**Designated Blockchain Network**” means the Ethereum mainnet (networkID:1, chainID:1), as recognized by the Designated Client. 62 | 63 | (h) “**Designated Client**” means the Official Go Ethereum client available at https://github.com/ethereum/go-ethereum. 64 | 65 | (i) “**Designated Smart Contract**” means the smart contract [at contract address 0x[_________________]][at the contract address registered as ENS Resolver for Ethereum Name Service address [ENS ADDRESS].eth and controlling the ERC-721 nonfungible token corresponding thereto] on the Designated Blockchain as of the date of this Charter’s adoption. 66 | 67 | (j) “**Distributed DAO Property**” means any asset, right or property that was once DAO Property and has been distributed to a DAO Member, in accordance with the DC UUNAA. 68 | 69 | (k) “**Legal Order**” means any restraining order, preliminary or permanent injunction, stay or other order, writ, injunction, judgment or decree that either: (i) is issued by a court of competent jurisdiction, or (ii) arises by operation of applicable law as if issued by a court of competent jurisdiction, including, in the case of clause “(ii)” an automatic stay imposed by applicable law upon the filing of a petition for bankruptcy. 70 | 71 | (l) “**Legal Proceeding**” means any private or governmental action, suit, litigation, arbitration, claim, proceeding (including any civil, criminal, administrative, investigative or appellate proceeding), hearing, inquiry, audit, examination or investigation commenced, brought, conducted or heard by or before, or otherwise involving, any court or other governmental entity or any arbitrator or arbitration panel. 72 | 73 | (m) “**Liability**” means any debt, obligation, duty or liability of any nature (including any unknown, undisclosed, unmatured, unaccrued, unasserted, contingent, indirect, conditional, implied, vicarious, inchoate derivative, joint, several or secondary liability), regardless of whether such debt, obligation, duty or liability would be required to be disclosed on a balance sheet prepared in accordance with generally accepted accounting principles and regardless of whether such debt, obligation, duty or liability is immediately due and payable. To be “**Liable**” means to have, suffer, incur, be obligated for or be subject to a Liability. 74 | 75 | (n) “**Lien**” means any lien, pledge, hypothecation, charge, mortgage, security interest, encumbrance, other possessory interest, conditional sale or other title retention agreement, intangible property right, claim, infringement, option, right of first refusal, preemptive right, exclusive license of intellectual property, community property interest or restriction of any nature including any restriction on the voting of any security or restriction on the transfer, use or ownership of any security or other asset. 76 | 77 | (o) “**Material Adverse Exception Event**” means that one or more of the following has occurred, is occurring or would reasonably be expected to occur: 78 | (i) the Designated Smart Contract having become inoperable, inaccessible or unusable; 79 | (ii) a material and adverse effect on the use, functionality or performance of the Designated Smart Contract as the result of any bug, defect or error in the Designated Smart Contract or any third party interface, library, or repository used, imported, or incorporated by reference, or the triggering, use or exploitation (whether intentional or unintentional) of any of the foregoing; 80 | (iii) any unauthorized use of an administrative function or privilege of the Designated Smart Contract, including: (A) any use of any administrative credential, key, password, account or address by a Person who has misappropriated or gained unauthorized access to such administrative credential, key, password, account or address or (B) any unauthorized use of an administrative function or privilege by a DAO Member or a representative of a DAO Member; or 81 | (iv) the Designated Smart Contract, any of the DAO Members or the DAO Property is subject to a Legal Order that prohibits the Designated Smart Contract (or that, if the Designated Smart Contract were a Person, would prohibit the Designated Smart Contract) from executing any function or operation it would otherwise reasonably be expected to execute. 82 | 83 | (p) “**Person**” means any human, robot, bot, artificial intelligence, corporation, partnership, association or other individual or entity recognized as having the status of a person under the law. 84 | 85 | (q) “**Token**” means a digital unit that is recognized by the Designated Client on the Designated Blockchain Network as capable of being uniquely associated with, controlled or “owned” by a particular public-key address on the Designated Blockchain Network at each particular block height. 86 | 87 | ### VI. Indemnification and other Fiscal Matters 88 | (a) *Indemnification.* The DAO shall indemnify its directors, officers, DAO Members, employees, contractors, contributors, advisors and agents and other persons acting in accordance with the governance processes of the DAO, as required under District of Columbia law, and may indemnify such persons as permitted under District of Columbia law. Indemnification payments shall be made on a priority basis. 89 | 90 | (b) *Loss.* No portion of a net operating loss realized by the DAO shall be allocated to DAO Members. As a nonprofit unincorporated association, it is not anticipated there will be tax returns or profits. 91 | 92 | (c) *Fiscal Year.* The fiscal year of the DAO shall be the calendar year beginning January 1st and ending December 31st. 93 | 94 | ### VIII. Miscellaneous 95 | (a) *Amendments.* Any provision of this Charter may be amended, waived or modified only upon [a majority vote in favor] of such amendment, waiver or modification by the DAO Members through the Designated Smart Contract. 96 | 97 | (b) *Severability.* In the event any one or more of the provisions of this Charter is for any reason held to be invalid, illegal or unenforceable, in whole or in part or in any respect, or in the event that any one or more of the provisions of this Charter operate or would prospectively operate to invalidate this Charter, then and in any such event, such provisions) only will be deemed null and void and will not affect any other provision of this Charter and the remaining provisions of this Charter will remain operative and in full force and effect and will not be affected, prejudiced, or disturbed thereby. 98 | 99 | (c) *Construction.* This Charter constitutes the entire agreement among the DAO Members with respect to the subject matter hereof and supersedes all prior agreements and understandings, both written and oral, among the DAO Members with respect to the subject matter hereof. Except as to matters reserved to DAO Members by law or by this Charter, all DAO powers shall be exercised by or under the authority of DAO Members or such agents or designees approved by DAO Members through Designated Smart Contract voting or other applicable governance process enabled by the Designated Smart Contract or DAO Membership Tokens, as applicable. 100 | 101 | (d) *Disputes; Mandatory Arbitration.* Any Legal Proceeding, Claim or other dispute or controversy arising out of or relating to this Charter, its enforcement, or the breach thereof shall be finally resolved by LexDAO Arbitration in accordance with the rules and procedures recorded on https://github.com/lexDAO/Arbitration; *provided, however*, that any DAO Member may seek injunctive relief in aid of arbitration in order to prevent irreparable harm or preserve the status quo. EACH DAO MEMBER HEREBY IRREVOCABLY WAIVES ALL RIGHT TO TRIAL BY JURY IN ANY ACTION, PROCEEDING OR COUNTERCLAIM WHETHER BASED ON CONTRACT, TORT OR OTHERWISE) ARISING OUT OF OR RELATING TO THIS CHARTER, THE DESIGNATED SMART CONTRACT, THE DAO MATTERS OR THE ACTIONS OF THE DAO MEMBERS IN THE NEGOTIATION, ADMINISTRATION, PERFORMANCE AND ENFORCEMENT OF THIS CHARTER. 102 | 103 | (e) *Governing Law.* All rights and obligations hereunder will be governed by the laws of the District of Columbia, without regard to the conflicts of law provisions thereof. 104 | 105 | (f) *Communication by Electronic Means.* Unless otherwise required by law or by agreement, any notice, vote, consent, petition, or other oral or written communication required or permitted can be delivered by electronic means, provided that, in the case where such communication expressly or impliedly requires the signature of the person submitting the communication, means are in place to reasonably assure the authenticity of the signature. 106 | 107 | 108 | -------------------------------------------------------------------------------- /forms/legal/Vote Delegate Disclosure.md: -------------------------------------------------------------------------------- 1 | //for a potential delegate of DAO governance token voting power; co-drafted with [Sarah Brennan](https://github.com/SHBrennan) 2 | 3 | **Vote Delegate Disclosure** 4 | 5 | ***Last updated: [DATE]*** 6 | 7 | Please be advised: 8 | 9 | I control the private key for the externally owned account[s]: 10 | 11 | [PUBLIC KEY ADDRESS[ES]] ([collectively,] the “Delegated Address[es]”), 12 | 13 | [The Delegated Address has/Each of the Delegated Addresses have] staked a certain amount of [DAO GOV TOKENS] tokens in the governance contract for [DAO] and I intend to participate in the governance of [DAO], whether by proposing, voting, abstaining, or engaging in related discourse or otherwise, in accordance with its applicable parameters and guidelines. I understand that other externally owned accounts and addresses may delegate their voting power to [the Delegated Address[es]/me] from time to time and intend that this disclosure will generally govern my actions as a delegate. 14 | 15 | [I/the Delegators] have instituted policies and procedures with respect to delegations in the interest of transparency, which may be subject to update from time to time and are available here [LINK] || Though [I/the Delegator(s)] do not have a formal policy, in participating in the governance of [DAO], I intend to act on the following principles: 16 | 17 | - I will seek to remain informed about governance proposals and vote on matters from time to time using my independent judgment unless otherwise disclosed; 18 | 19 | - I will act in good faith and use reasonable care in participating in governance, including in making proposals and in voting; 20 | 21 | - I will endeavor to provide transparent, good faith, and honest information as to my motivations and reasoning in carrying out my role as a delegate, or when soliciting the delegation of voting power [or votes]; 22 | 23 | - I am not a party to any voting bloc, trust, or other group and will not engage in vote-buying, vote-selling, bribery, manipulation, or other undisclosed vote solicitation or coordination; and 24 | 25 | - [To the extent I am aware of a material non-public conflict of interest that exists for a Delegator with respect to a proposal, I will refrain from voting in my capacity as a delegate for such Delegator with respect to such proposal] 26 | 27 | **Conflict Disclosure** 28 | 29 | I currently have [economic interests in][contractual obligations with][other relationships with] [EMPLOYER/CONTRACTOR/ASSOCIATION/AFFILIATED ENTITY], and may engage in the [OTHER DAO(S) OR PROJECT(S)] community(ies) from time to time. I may have direct or indirect economic interests in the various projects, entities, networks, and protocols related to the foregoing, and I also use and hold various other cryptocurrencies, tokens, stablecoins and other digital assets from time to time, including but not limited to [____________]. 30 | 31 | Except as disclosed herein, in participating in the governance of [DAO], I am not acting on behalf of [EMPLOYER/CONTRACTOR/AFFILIATED ENTITY, nor][on behalf of any client, nor] any voting power delegator, whether or not such delegation was solicited. If my views expressed in governance contexts are interpreted or used in a manner that leads to some injury or detriment, there will be no legal recourse against me as a vote delegate or otherwise, nor will there be any coverage or indemnity from any applicable insurance or similar mechanism. 32 | 33 | **Disclaimer of Duty to Update** 34 | 35 | I assume no duty and provide no guarantee of keeping these disclosures up to date, nor of adjusting these disclosures for each applicable governance process, but will endeavor to act in good faith when soliciting the delegation of voting power and when acting in my capacity as a delegate. 36 | 37 | You may contact me at [EMAIL ADDRESS/COMMS HANDLES], though I assume no duty for, and cannot guarantee my responsiveness to, or any action upon, any individual question, feedback, or request from a vote delegator or otherwise. 38 | -------------------------------------------------------------------------------- /forms/legal/Whitepaper Disclaimer.md: -------------------------------------------------------------------------------- 1 | The writings herein are for informative, theoretical, and educational purposes only and do not constitute financial, legal, or other professional advice of any kind, nor do they commit any authors or any related entities or persons to undertake any described, related, or implied actions. 2 | 3 | Any forward-looking statements herein are subject to risks, uncertainties, and assumptions which could prove to be inaccurate and, as a result, such statements could be materially incorrect and readers should not rely upon them. 4 | 5 | Neither the authors nor any of their affiliates, nor any of their respective directors, advisors, contractors, employees or representatives make any representations or warranties, express or implied, with respect to any of the material or information contained herein, nor do any of the foregoing assume or otherwise have any responsibility or any obligation or liability whatsoever to any reader, any affiliate of any reader, or any of a reader’s or a reader’s affiliates’ respective directors, advisors, contractors, employees or representatives resulting from the use of the information and material contained herein. 6 | -------------------------------------------------------------------------------- /scripts/rand_num_oracle.py: -------------------------------------------------------------------------------- 1 | """ 2 | This script acts as a centralized random number oracle by using the python `random` library, and using 3 | `WALLET_ADDRESS' to call a function depending on the result. 4 | 5 | NOTE: This file is not audited and is intended for educational purposes only. 6 | Anyone with access to `secrets.env` will have full control over `WALLET_ADDRESS` via the private key. 7 | Exercise caution and avoid hardcoding sensitive data. 8 | 9 | This is a simple example of a centralized random number oracle that requires corresponding 10 | completed secrets.env and requirements.txt files to run, and acts through an EOA it controls (`WALLET_ADDRESS`). 11 | 12 | `WALLET_ADDRESS` must also have enough gas for the transactions. 13 | 14 | Replace all placeholders marked <<< >>> in secrets.env before running the script. 15 | 16 | # --- requirements.txt --- 17 | python-dotenv 18 | web3 19 | 20 | # --- secrets.env --- 21 | PRIVATE_KEY=<<>> 22 | RPC_URL=<<>> 23 | WALLET_ADDRESS=<<>> 24 | REQUESTER_ADDRESS=<<>> 25 | CHAIN_ID=<<>> 26 | GAS_LIMIT=<<>> 27 | GAS_PRICE=<<>> 28 | 29 | # --- run_script.bat (Windows) --- 30 | @echo off 31 | REM Navigate to the folder containing the Python script 32 | cd /d C:\path\to\pyoracle 33 | 34 | REM Check if the virtual environment folder exists; create it if not 35 | if not exist venv ( 36 | echo Creating virtual environment... 37 | python -m venv venv 38 | ) 39 | 40 | REM Activate the virtual environment 41 | call venv\Scripts\activate 42 | 43 | REM Install dependencies 44 | pip install -r requirements.txt 45 | 46 | REM Run the Python script 47 | python rand_num_oracle.py 48 | 49 | REM Keep the window open after execution 50 | pause 51 | 52 | # --- command line (Windows) --- 53 | python -m venv venv 54 | venv\Scripts\activate 55 | pip install -r requirements.txt 56 | python rand_num_oracle.py 57 | 58 | # --- terminal (Mac) --- 59 | python3 -m venv venv 60 | source venv/bin/activate 61 | pip install -r requirements.txt 62 | python rand_num_oracle.py 63 | 64 | """ 65 | 66 | from dotenv import load_dotenv 67 | from random import randint 68 | import os 69 | from web3 import Web3 70 | 71 | # --- Load Environment Variables --- 72 | load_dotenv(dotenv_path="secrets.env") 73 | 74 | PRIVATE_KEY = os.getenv("PRIVATE_KEY") 75 | RPC_URL = os.getenv("RPC_URL") # RPC URL for the blockchain network, through which `WALLET_ADDRESS` will send txns 76 | WALLET_ADDRESS = os.getenv("WALLET_ADDRESS") # Oracle wallet address, which must have enough gas for the txns 77 | REQUESTER_ADDRESS = os.getenv("REQUESTER_ADDRESS") # address requesting the oracle response from `WALLET_ADDRESS` 78 | CHAIN_ID = int(os.getenv("CHAIN_ID")) # Blockchain network chain ID 79 | GAS_LIMIT = int(os.getenv("GAS_LIMIT")) # Gas limit for transactions 80 | GAS_PRICE = int(os.getenv("GAS_PRICE")) # Gas price in gwei 81 | 82 | min_value = 0 # Update as necessary 83 | max_value = 100 # Update as necessary 84 | 85 | # --- Example Requester contract ABI to return the randint, update as necessary --- 86 | requester_abi = [ 87 | { 88 | "constant": False, 89 | "inputs": [{"name": "randomNumber", "type": "uint256"}], 90 | "name": "updateRandomNumber", 91 | "outputs": [], 92 | "payable": False, 93 | "stateMutability": "nonpayable", 94 | "type": "function", 95 | } 96 | ] 97 | 98 | # --- Connect to Network --- 99 | web3 = Web3(Web3.HTTPProvider(RPC_URL)) 100 | if not web3.is_connected(): 101 | print("Failed to connect to network, check RPC_URL.") 102 | exit() 103 | 104 | # --- Helper Functions --- 105 | def send_random_number_to_contract(random_number): 106 | # Initialize requester contract 107 | contract = web3.eth.contract(address=REQUESTER_ADDRESS, abi=requester_abi) 108 | 109 | # Build transaction 110 | nonce = web3.eth.get_transaction_count(WALLET_ADDRESS) 111 | tx = contract.functions.updateRandomNumber(random_number).build_transaction({ 112 | 'chainId': CHAIN_ID, 113 | 'gas': GAS_LIMIT, 114 | 'gasPrice': web3.to_wei(GAS_PRICE, 'gwei'), 115 | 'nonce': nonce 116 | }) 117 | try: 118 | # Sign and send transaction 119 | signed_tx = web3.eth.account.sign_transaction(tx, PRIVATE_KEY) 120 | tx_hash = web3.eth.send_raw_transaction(signed_tx.raw_transaction) 121 | receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=120) 122 | # Check status of the transaction 123 | if receipt.status == 1: 124 | return web3.to_hex(tx_hash), True # Transaction successful 125 | else: 126 | return web3.to_hex(tx_hash), False # Transaction failed 127 | except Exception as e: 128 | print(f"Error sending transaction: {e}") 129 | return None, False 130 | 131 | # --- Main Logic --- 132 | random_number = randint(min_value, max_value) # Generate the random number 133 | 134 | print(f"Generated random number: {random_number}.") # Print before sending to the contract 135 | 136 | tx_hash, success = send_random_number_to_contract(random_number) 137 | if success: 138 | print(f"Random number: {random_number} provided to {REQUESTER_ADDRESS}. Transaction hash: {tx_hash}") 139 | elif tx_hash: 140 | print(f"Transaction failed. Hash: {tx_hash}") 141 | else: 142 | print("Transaction could not be sent due to an error.") 143 | 144 | -------------------------------------------------------------------------------- /scripts/send_all_tokens.py: -------------------------------------------------------------------------------- 1 | """ 2 | This script checks the token balance of `TOKEN_CONTRACT_ADDRESS` in `WALLET_ADDRESS` 3 | and sends the balance to `RECIPIENT_ADDRESS` if it is nonzero. 4 | 5 | NOTE: This file is not audited. Anyone with access to `secrets.env` will have full control 6 | over `WALLET_ADDRESS` via the private key. Exercise caution and avoid hardcoding sensitive data. 7 | 8 | Replace all placeholders marked <<< >>> in secrets.env before running the script. 9 | 10 | # --- requirements.txt --- 11 | python-dotenv 12 | web3 13 | 14 | # --- secrets.env --- 15 | PRIVATE_KEY=<<>> 16 | RPC_URL=<<>> 17 | WALLET_ADDRESS=<<>> 18 | RECIPIENT_ADDRESS=<<>> 19 | TOKEN_CONTRACT_ADDRESS=<<>> 20 | CHAIN_ID=<<>> 21 | GAS_LIMIT=<<>> 22 | GAS_PRICE=<<>> 23 | 24 | # --- run_script.bat (Windows) --- 25 | @echo off 26 | REM Navigate to the folder containing the Python script 27 | cd /d C:\path\to\script_folder 28 | 29 | REM Check if the virtual environment folder exists; create it if not 30 | if not exist venv ( 31 | echo Creating virtual environment... 32 | python -m venv venv 33 | ) 34 | 35 | REM Activate the virtual environment 36 | call venv\Scripts\activate 37 | 38 | REM Install dependencies 39 | pip install -r requirements.txt 40 | 41 | REM Run the Python script 42 | python send_all_tokens.py 43 | 44 | REM Keep the window open after execution 45 | pause 46 | 47 | if command line, first create local python environment with `python -m venv venv` and install dependencies 48 | """ 49 | 50 | from dotenv import load_dotenv 51 | import os 52 | from web3 import Web3 53 | 54 | # --- Load Environment Variables --- 55 | load_dotenv(dotenv_path="secrets.env") 56 | 57 | PRIVATE_KEY = os.getenv("PRIVATE_KEY") 58 | RPC_URL = os.getenv("RPC_URL") # RPC URL for the blockchain network 59 | WALLET_ADDRESS = os.getenv("WALLET_ADDRESS") # Sender wallet address 60 | RECIPIENT_ADDRESS = os.getenv("RECIPIENT_ADDRESS") # Recipient wallet address 61 | TOKEN_CONTRACT_ADDRESS = os.getenv("TOKEN_CONTRACT_ADDRESS") # ERC20 token address 62 | CHAIN_ID = int(os.getenv("CHAIN_ID")) # Blockchain network chain ID 63 | GAS_LIMIT = int(os.getenv("GAS_LIMIT")) # Gas limit for transactions 64 | GAS_PRICE = int(os.getenv("GAS_PRICE")) # Gas price in gwei 65 | 66 | # --- ERC20 ABI (balanceOf, decimals, symbol, and transfer) --- 67 | ERC20_ABI = [ 68 | {"constant": True, "inputs": [{"name": "_owner", "type": "address"}], "name": "balanceOf", "outputs": [{"name": "balance", "type": "uint256"}], "payable": False, "stateMutability": "view", "type": "function"}, 69 | {"constant": True, "inputs": [], "name": "decimals", "outputs": [{"name": "", "type": "uint8"}], "payable": False, "stateMutability": "view", "type": "function"}, 70 | {"constant": True, "inputs": [], "name": "symbol", "outputs": [{"name": "", "type": "string"}], "payable": False, "stateMutability": "view", "type": "function"}, 71 | {"constant": False, "inputs": [{"name": "_to", "type": "address"}, {"name": "_value", "type": "uint256"}], "name": "transfer", "outputs": [{"name": "success", "type": "bool"}], "payable": False, "stateMutability": "nonpayable", "type": "function"}, 72 | ] 73 | 74 | # --- Connect to Network --- 75 | web3 = Web3(Web3.HTTPProvider(RPC_URL)) 76 | if not web3.is_connected(): 77 | print("Failed to connect to network, check RPC_URL.") 78 | exit() 79 | 80 | # --- Load the Token Contract --- 81 | token_contract = web3.eth.contract(address=TOKEN_CONTRACT_ADDRESS, abi=ERC20_ABI) 82 | 83 | # --- Helper Functions --- 84 | def get_token_decimals(token_contract): 85 | return token_contract.functions.decimals().call() 86 | 87 | def get_token_symbol(contract): 88 | return contract.functions.symbol().call() 89 | 90 | def get_token_balance(address, decimals): 91 | balance = token_contract.functions.balanceOf(address).call() 92 | return balance / (10 ** decimals) # Convert to human-readable format 93 | 94 | def send_tokens(private_key, from_address, to_address, amount, decimals): 95 | amount_in_wei = int(amount * (10 ** decimals)) # Convert to smallest unit 96 | nonce = web3.eth.get_transaction_count(from_address) 97 | 98 | # Build transaction 99 | tx = token_contract.functions.transfer(to_address, amount_in_wei).build_transaction({ 100 | 'chainId': CHAIN_ID, 101 | 'gas': GAS_LIMIT, 102 | 'gasPrice': web3.to_wei(GAS_PRICE, 'gwei'), 103 | 'nonce': nonce, 104 | }) 105 | 106 | try: 107 | # Sign and send the transaction 108 | signed_tx = web3.eth.account.sign_transaction(tx, private_key) 109 | tx_hash = web3.eth.send_raw_transaction(signed_tx.raw_transaction) 110 | receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=120) 111 | # Check status of the transaction 112 | if receipt.status == 1: 113 | return web3.to_hex(tx_hash), True # Transaction successful 114 | else: 115 | return web3.to_hex(tx_hash), False # Transaction failed 116 | except Exception as e: 117 | print(f"Error sending transaction: {e}") 118 | return None, False 119 | 120 | # --- Main Logic --- 121 | decimals = get_token_decimals(token_contract) 122 | token_symbol = get_token_symbol(token_contract) 123 | balance = get_token_balance(WALLET_ADDRESS, decimals) 124 | 125 | if balance == 0: 126 | print(f"No {token_symbol} balance") 127 | else: 128 | print(f"Detected balance: {balance:.{decimals}f} {token_symbol} tokens.") 129 | tx_hash, success = send_tokens(PRIVATE_KEY, WALLET_ADDRESS, RECIPIENT_ADDRESS, balance, decimals) 130 | if success: 131 | print(f"Sent {balance:.{decimals}f} {token_symbol} tokens to {RECIPIENT_ADDRESS}. Transaction hash: {tx_hash}") 132 | elif tx_hash: 133 | print(f"Transaction failed. Hash: {tx_hash}") 134 | else: 135 | print("Transaction could not be sent due to an error.") 136 | -------------------------------------------------------------------------------- /solidity/AccessByHash.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // FOR DEMONSTRATION ONLY, unaudited, not recommended to be used for any purpose, carries absolutely no warranty of any kind 3 | /// @dev allows a contract owner to set access permission for other addresses without revealing those addresses until they access by passing a secret 4 | /// mappings are public so other contracts can access getters 5 | 6 | pragma solidity ^0.8.4; 7 | 8 | contract AccessByHash { 9 | address public immutable owner; 10 | 11 | mapping(address => bool) public accessed; // whether an address has matched an owner-provided hash and accessed 12 | mapping(bytes32 => bool) public permitted; // hash to permission 13 | 14 | error NotOwner(); 15 | error NotPermitted(); 16 | 17 | event HashChanged(bytes32 hash, bool status); 18 | 19 | constructor() payable { 20 | owner = msg.sender; 21 | } 22 | 23 | /// @notice owner can update hash info to permitted or not permitted. _infoHash should equal the keccak256(abi.encodePacked(address, salt)), 24 | /// where address = user's address and salt is random bytes given offchain to the user as a secret 25 | /// @param _infoHash access key hash; added for each new permitted member without passing address 26 | /// @param _status status of hash: true = permitted, false = revoked/not permitted 27 | function updateHashStatus(bytes32 _infoHash, bool _status) external { 28 | if (msg.sender != owner) revert NotOwner(); 29 | permitted[_infoHash] = _status; 30 | 31 | emit HashChanged(_infoHash, _status); 32 | } 33 | 34 | /// @notice user passes their secret in order to change access mapping 35 | /// @param _salt: secret that must be passed for an access token; avoids simple access by calling without params if an account is compromised 36 | function access(bytes calldata _salt) external { 37 | if (!permitted[keccak256(abi.encodePacked(msg.sender, _salt))]) 38 | revert NotPermitted(); 39 | 40 | accessed[msg.sender] = true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /solidity/AutoLp.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | /** 4 | ** CAUTION: this code is provided for demonstration purposes only and strictly as-is with no guarantees, representations nor warranties (express or implied) of any kind 5 | */ 6 | 7 | pragma solidity ^0.8.17; 8 | 9 | /// 10 | /// Interfaces 11 | /// 12 | 13 | interface IUniswapV2Router02 { 14 | function addLiquidityETH( 15 | address token, 16 | uint256 amountTokenDesired, 17 | uint256 amountTokenMin, 18 | uint256 amountETHMin, 19 | address to, 20 | uint256 deadline 21 | ) 22 | external 23 | payable 24 | returns (uint256 amountToken, uint256 amountETH, uint256 liquidity); 25 | 26 | /// @dev Returns the address of the pair for tokenA and tokenB, if it has been created, else address(0); tokenA and tokenB are interchangeable 27 | function getPair( 28 | address tokenA, 29 | address tokenB 30 | ) external view returns (address pair); 31 | 32 | function quote( 33 | uint256 amountA, 34 | uint256 reserveA, 35 | uint256 reserveB 36 | ) external pure returns (uint256 amountB); 37 | 38 | function removeLiquidityETH( 39 | address token, 40 | uint256 liquidity, 41 | uint256 amountTokenMin, 42 | uint256 amountETHMin, 43 | address to, 44 | uint256 deadline 45 | ) external returns (uint256 amountToken, uint256 amountETH); 46 | 47 | function swapExactETHForTokens( 48 | uint256 amountOutMin, 49 | address[] calldata path, 50 | address to, 51 | uint256 deadline 52 | ) external payable returns (uint256[] memory amounts); 53 | } 54 | 55 | interface IERC20 { 56 | function approve(address spender, uint256 amount) external returns (bool); 57 | 58 | function balanceOf(address account) external view returns (uint256); 59 | 60 | /// @dev for iLpToken only 61 | function token0() external view returns (address); 62 | 63 | function token1() external view returns (address); 64 | 65 | function transfer(address to, uint256 amount) external returns (bool); 66 | } 67 | 68 | interface IUniswapV2Pair { 69 | function getReserves() 70 | external 71 | view 72 | returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 73 | } 74 | 75 | /// @title AutoLP 76 | /** @notice this ownerless immutable contract automatically uses any ETH sent to address(this) to LP the selected token's pair with ETH in UniswapV2; each LP is then queued chronologically. 77 | *** LP position is redeemable to this contract by any caller, which is swapped to the constructor-supplied tokens via UniswapV2 and burned via the null address 78 | *** for illustrative purposes, though a native burn function in the applicable token contract would be a preferable practice 79 | ****/ 80 | /// @dev be advised there is inherent slippage risk for large amounts, with some protection via '_getTokenMinAmountOut' 81 | contract AutoLP { 82 | struct Liquidity { 83 | uint256 withdrawTime; 84 | uint256 amount; 85 | } 86 | 87 | /// @notice UniV2 Router Address 88 | address internal constant UNI_ROUTER_ADDR = 89 | 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; 90 | /// @notice WETH9 used in the UniV2 Router 91 | address internal constant WETH_TOKEN_ADDR = 92 | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 93 | 94 | IUniswapV2Router02 internal constant router = 95 | IUniswapV2Router02(UNI_ROUTER_ADDR); 96 | 97 | IERC20 internal immutable iToken; 98 | IERC20 internal immutable iLpToken; 99 | 100 | address internal immutable tokenAddr; 101 | 102 | uint256 public lpAddIndex; 103 | uint256 public lpRedeemIndex; 104 | 105 | mapping(uint256 => Liquidity) public liquidityAdds; 106 | 107 | /// 108 | /// Errors 109 | /// 110 | 111 | error NoTokens(); 112 | error NoRedeemableLPTokens(); 113 | error PairUpdateDelay(); 114 | error ZeroDivisor(); 115 | 116 | /// 117 | /// Events 118 | /// 119 | 120 | event LiquidityProvided( 121 | uint256 liquidityAdded, 122 | uint256 indexed lpIndex, 123 | uint256 indexed timestamp 124 | ); 125 | event LiquidityRemoved( 126 | uint256 liquidityRemoved, 127 | uint256 indexed lpIndex, 128 | uint256 indexed timestamp 129 | ); 130 | event TokensBurned(uint256 amountBurned); 131 | 132 | /// 133 | /// Functions 134 | /// 135 | 136 | /// @notice set interfaces and approve 'router' for address(this) for 'tokenAddress' and 'lpTokenAddress' 137 | /// @param _tokenContract: the contract address of the applicable ERC20 token which is to be LPed 138 | constructor(address _tokenContract) payable { 139 | tokenAddr = _tokenContract; 140 | iToken = IERC20(_tokenContract); 141 | iLpToken = IERC20(router.getPair(_tokenContract, WETH_TOKEN_ADDR)); 142 | iToken.approve(UNI_ROUTER_ADDR, type(uint256).max); 143 | iLpToken.approve(UNI_ROUTER_ADDR, type(uint256).max); 144 | } 145 | 146 | /// @notice receives ETH sent to address(this), and if msg.sender is not the Uniswap V2 router address, initiates the automatic LP process 147 | /// small amounts are preferable to avoid sandwich-ing and reversion due to the '_getTokenMinAmountOut' check 148 | receive() external payable { 149 | if (msg.sender != UNI_ROUTER_ADDR) { 150 | uint256 _ethSwapAmount = address(this).balance / 2; 151 | 152 | // swap half of ETH for tokens 153 | router.swapExactETHForTokens{value: _ethSwapAmount}( 154 | _getTokenMinAmountOut(_ethSwapAmount), 155 | _getPath(), 156 | address(this), 157 | block.timestamp 158 | ); 159 | 160 | // LP 161 | _lpTokenEth(); 162 | } 163 | } 164 | 165 | /** @dev checks earliest Liquidity struct to see if any LP tokens are redeemable, 166 | ** then redeems that amount of liquidity to this address (which is entirely converted and burned in tokens), 167 | ** then deletes that mapped struct in 'liquidityAdds' and increments 'lpRedeemIndex' */ 168 | /// @notice redeems the earliest available liquidity; redeemed tokens are burned and redeemed ETH is converted to tokens and burned 169 | function redeemLP() external { 170 | if (liquidityAdds[lpRedeemIndex].withdrawTime > block.timestamp) 171 | revert NoRedeemableLPTokens(); 172 | uint256 _redeemableLpTokens = liquidityAdds[lpRedeemIndex].amount; 173 | 174 | // if 'lpRedeemIndex' returns zero, increment the index; otherwise call '_redeemLP' and then increment 175 | if (_redeemableLpTokens == 0) { 176 | delete liquidityAdds[lpRedeemIndex]; 177 | } else { 178 | _redeemLP(_redeemableLpTokens, lpRedeemIndex); 179 | } 180 | unchecked { 181 | ++lpRedeemIndex; 182 | } 183 | } 184 | 185 | /** @dev checks applicable Liquidity struct to see if any LP tokens are redeemable, 186 | ** then redeems that amount of liquidity to this address (which is entirely converted and burned in tokens), 187 | ** then deletes that mapped struct in 'liquidityAdds'. Implemented in case of lpAddIndex--lpRedeemIndex mismatch */ 188 | /// @notice redeems specifically indexed liquidity; redeemed tokens are burned and redeemed ETH is converted to tokens and burned 189 | /// @param _lpRedeemIndex: index of liquidity in 'liquidityAdds' mapping to be redeemed 190 | function redeemSpecificLP(uint256 _lpRedeemIndex) external { 191 | if (liquidityAdds[_lpRedeemIndex].withdrawTime > block.timestamp) 192 | revert NoRedeemableLPTokens(); 193 | uint256 _redeemableLpTokens = liquidityAdds[_lpRedeemIndex].amount; 194 | 195 | // if '_lpRedeemIndex' returns zero, delete mapping; otherwise call '_redeemLP'. Do not increment the global 'lpRedeemIndex' 196 | if (_redeemableLpTokens == 0) { 197 | delete liquidityAdds[_lpRedeemIndex]; 198 | } else { 199 | _redeemLP(_redeemableLpTokens, _lpRedeemIndex); 200 | } 201 | } 202 | 203 | /// @notice LPs ETH and tokens to UniswapV2's 'tokenAddr'/ETH pair 204 | /// @dev LP has 10% slippage buffer. Liquidity is queued chronologically. 205 | function _lpTokenEth() internal { 206 | uint256 _tokenBal = iToken.balanceOf(address(this)); 207 | if (_tokenBal == 0) revert NoTokens(); 208 | uint256 _ethBal = address(this).balance; 209 | (, , uint256 liquidity) = router.addLiquidityETH{value: _ethBal}( 210 | tokenAddr, 211 | _tokenBal, 212 | (_tokenBal * 9) / 10, // 90% of the '_tokenBal' 213 | (_ethBal * 9) / 10, // 90% of the '_ethBal' 214 | payable(address(this)), 215 | block.timestamp 216 | ); 217 | emit LiquidityProvided(liquidity, lpAddIndex, block.timestamp); 218 | unchecked { 219 | liquidityAdds[lpAddIndex] = Liquidity(block.timestamp, liquidity); 220 | // will not overflow on human timelines 221 | ++lpAddIndex; 222 | } 223 | } 224 | 225 | /// @notice redeems the LP for the corresponding 'lpRedeemIndex', swaps redeemed ETH for tokens, and burns them 226 | /// @param _redeemableLpTokens: amount of LP tokens available to redeem 227 | /// @param _lpRedeemIndex: LP index being redeemed 228 | function _redeemLP( 229 | uint256 _redeemableLpTokens, 230 | uint256 _lpRedeemIndex 231 | ) internal { 232 | router.removeLiquidityETH( 233 | tokenAddr, 234 | _redeemableLpTokens, 235 | 1, 236 | 1, 237 | payable(address(this)), 238 | block.timestamp 239 | ); 240 | delete liquidityAdds[_lpRedeemIndex]; 241 | emit LiquidityRemoved( 242 | _redeemableLpTokens, 243 | _lpRedeemIndex, 244 | block.timestamp 245 | ); 246 | 247 | // removed liquidity is 50/50 ETH and tokens; swap all newly received ETH for tokens 248 | router.swapExactETHForTokens{value: address(this).balance}( 249 | _getTokenMinAmountOut(address(this).balance), 250 | _getPath(), 251 | address(this), 252 | block.timestamp 253 | ); 254 | // burn tokens 255 | iToken.transfer(address(0), iToken.balanceOf(address(this))); 256 | } 257 | 258 | /// @notice calculate a minimum amount of tokens out, as 90% of the price in wei as of the last update 259 | /// @dev exclude pair updates in this block to prevent sandwiching (i.e. that the most recent timestamp returned by 'getReserves()' is not the same timestamp as this attempted swap) 260 | /// @param _amountIn: amount of wei to be swapped for tokens 261 | function _getTokenMinAmountOut( 262 | uint256 _amountIn 263 | ) internal view returns (uint256) { 264 | ( 265 | uint112 _token0Reserve, 266 | uint112 _token1Reserve, 267 | uint32 _timestamp 268 | ) = IUniswapV2Pair(address(iLpToken)).getReserves(); 269 | 270 | // compare current block timestamp within the range of uint32 to last pair update; must be > 0 in order to prevent sandwiching 271 | if (block.timestamp - _timestamp == 0) revert PairUpdateDelay(); 272 | 273 | // minimum amount of tokens out is 90% of the quoted price 274 | // the '_amountIn' is wei, so we want 'quote()' to return amount denominated in tokens 275 | // check whether WETH is 'token0' or 'token1' for the relevant pair in order to return the proper quote 276 | if (iLpToken.token0() == WETH_TOKEN_ADDR) 277 | return 278 | (router.quote( 279 | _amountIn, 280 | uint256(_token0Reserve), 281 | uint256(_token1Reserve) 282 | ) * 9) / 10; 283 | else 284 | return 285 | (router.quote( 286 | _amountIn, 287 | uint256(_token1Reserve), 288 | uint256(_token0Reserve) 289 | ) * 9) / 10; 290 | } 291 | 292 | /// @return path: the router path for ETH/'tokenAddr' swap 293 | function _getPath() internal view returns (address[] memory) { 294 | address[] memory path = new address[](2); 295 | path[0] = WETH_TOKEN_ADDR; 296 | path[1] = tokenAddr; 297 | return path; 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /solidity/DealStamp.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.12; 4 | 5 | /// unaudited and subject to all disclosures, licenses, and caveats set forth at https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/README.md 6 | /// @title DealStamp 7 | /// @notice An on-chain record of a deal's parties, decentralized doc room storage ref (presumably carrying an additional hash layer/other security mechanism for access), and time of closing 8 | /// adaptations/forks might include a record of oracle information used in an on-chain closing, gasless sig verification, removal of parties from array, dispute resolution details, etc. 9 | 10 | contract DealStamp { 11 | struct DealInfo { 12 | uint256 dealNumber; 13 | uint256 effectiveTime; 14 | string docsLocation; 15 | address[] parties; 16 | } 17 | 18 | DealInfo[] internal deals; // array of deal info structs, viewable via 'viewDeal()' 19 | 20 | uint256 internal dealNumber; // counter for stamped deals 21 | 22 | mapping(uint256 => string) public docsLocation; /*dealNumber => deal doc storage location ref */ 23 | mapping(uint256 => mapping(address => bool)) /*dealNumber => whether address is a party to corresponding deal*/ 24 | internal isPartyToDeal; 25 | 26 | event DealStamped( 27 | uint256 indexed dealNumber, 28 | uint256 effectiveTime, 29 | string docsLocation, 30 | address[] parties 31 | ); 32 | event PartyAdded(uint256 indexed dealNumber, address newParty); 33 | 34 | error NotPartyToDeal(); 35 | 36 | constructor() {} 37 | 38 | /// @param _docsLocationHash IPFS or other decentralized storage location hash of deal documents 39 | /// @param _effectiveTime unix time of closing, ex. block.timestamp of a stablecoin transfer or smart escrow contract closing 40 | /// @param _party1 address of first party to the deal 41 | /// @param _party2 address of second party to the deal 42 | /// @return the dealNumber of the newly stamped deal - make sure to keep record of this identifier. 43 | /// @notice intended to be called by authorized party, escrow or other closing smart contracts, by interface or arbitrary call. Record the dealNumber. Additional parties may be added by _party1 or _party2 via addPartyToDeal(). 44 | function newDealStamp( 45 | string calldata _docsLocationHash, 46 | uint256 _effectiveTime, 47 | address _party1, 48 | address _party2 49 | ) external returns (uint256) { 50 | uint256 _currentDealNumber = dealNumber; 51 | address[] memory _parties = new address[](2); 52 | _parties[0] = _party1; 53 | _parties[1] = _party2; 54 | deals.push( 55 | DealInfo( 56 | _currentDealNumber, 57 | _effectiveTime, 58 | _docsLocationHash, 59 | _parties 60 | ) 61 | ); 62 | 63 | docsLocation[_currentDealNumber] = _docsLocationHash; 64 | isPartyToDeal[_currentDealNumber][_party1] = true; 65 | isPartyToDeal[_currentDealNumber][_party2] = true; 66 | unchecked { 67 | ++dealNumber; 68 | } // increment for next newDealStamp, will not overflow on human timelines 69 | 70 | emit DealStamped( 71 | _currentDealNumber, 72 | _effectiveTime, 73 | _docsLocationHash, 74 | _parties 75 | ); 76 | 77 | return (_currentDealNumber); // DealStamper should record the dealNumber for this function call for relevant parties 78 | } 79 | 80 | /// @param _dealNumber enter dealNumber to view corresponding stamped deal information 81 | /// @return the DealInfo struct for the inputted dealNumber 82 | function viewDeal(uint256 _dealNumber) 83 | external 84 | view 85 | returns (DealInfo memory) 86 | { 87 | return (deals[_dealNumber]); 88 | } 89 | 90 | /// @param _dealNumber deal number of deal for which the new party will be added 91 | /// @param _newParty address of the new party to be added to the deal corresponding to _dealNumber 92 | function addPartyToDeal(uint256 _dealNumber, address _newParty) external { 93 | if (!isPartyToDeal[_dealNumber][msg.sender]) revert NotPartyToDeal(); 94 | isPartyToDeal[_dealNumber][_newParty] = true; 95 | deals[_dealNumber].parties.push(_newParty); 96 | emit PartyAdded(_dealNumber, _newParty); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /solidity/ETHescrow.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.8.12; 4 | 5 | /// unaudited and for demonstration only, provided as-is without any guarantees or warranties 6 | /// @title ETH Escrow 7 | /// @notice bilateral smart escrow contract, with ETH as payment, expiration denominated in seconds, deposit refunded if contract expires before closeDeal() called 8 | /// @dev intended to be deployed by buyer - may be altered for separation of deposit from purchase price, deposit non-refundability, additional conditions, etc. 9 | 10 | /// @notice Solbase / Solady's SafeTransferLib (identical in both repos) 'SafeTransferETH()'. Pasted for convenience, transparency, and size minimization. 11 | /// @author Solbase / Solady (https://github.com/Sol-DAO/solbase/blob/main/src/utils/SafeTransferLib.sol / https://github.com/Vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) 12 | library SafeTransferLib { 13 | /// @dev The ETH transfer has failed. 14 | error ETHTransferFailed(); 15 | 16 | /// @dev Sends `amount` (in wei) ETH to `to`. 17 | /// Reverts upon failure. 18 | function safeTransferETH(address to, uint256 amount) internal { 19 | /// @solidity memory-safe-assembly 20 | assembly { 21 | // Transfer the ETH and check if it succeeded or not. 22 | if iszero(call(gas(), to, amount, 0, 0, 0, 0)) { 23 | // Store the function selector of `ETHTransferFailed()`. 24 | mstore(0x00, 0xb12d13eb) 25 | // Revert with (offset, size). 26 | revert(0x1c, 0x04) 27 | } 28 | } 29 | } 30 | } 31 | 32 | contract EscrowETH { 33 | using SafeTransferLib for address payable; 34 | 35 | address payable public immutable buyer; 36 | address payable public seller; 37 | 38 | uint256 public immutable price; 39 | uint256 public immutable expirationTime; 40 | 41 | bool public sellerApproved; 42 | bool public buyerApproved; 43 | bool public isExpired; 44 | 45 | string public description; 46 | 47 | event DealExpired(); 48 | event DealClosed(uint256 effectiveTime); //event provides exact blockstamp Unix time of closing 49 | event DepositReturned(); 50 | event SellerUpdated(address newSeller); 51 | 52 | error BuyerAddrSameAsSellerAddr(); 53 | error Expired(); 54 | error IncorrectMsgValue(); 55 | error NotReadyToClose(); 56 | error NotSeller(); 57 | error PriceAlreadyInEscrow(); 58 | 59 | /// @notice deployer (buyer) initiates escrow with description, price in wei, seconds until expiry, and designate recipient seller 60 | /// @param _description: brief identifier of the deal in question - perhaps as to parties/underlying asset/documentation reference/hash 61 | /// @param _price: purchase price in wei which will be deposited in the smart escrow contract 62 | /// @param _secsUntilExpiration: number of seconds until the deal expires. input type(uint256).max for no expiry 63 | /// @param _seller: the seller's address, recipient of the purchase price if the deal closes 64 | constructor( 65 | string memory _description, 66 | uint256 _price, 67 | uint256 _secsUntilExpiration, 68 | address payable _seller 69 | ) payable { 70 | buyer = payable(msg.sender); 71 | price = _price; 72 | description = _description; 73 | seller = _seller; 74 | expirationTime = block.timestamp + _secsUntilExpiration; 75 | } 76 | 77 | /// @notice for the current seller to designate a new recipient address 78 | /// @param _seller: new recipient address of seller 79 | function updateSeller(address payable _seller) external { 80 | if (msg.sender != seller) revert NotSeller(); 81 | if (_seller == buyer) revert BuyerAddrSameAsSellerAddr(); 82 | if (!checkIfExpired()) { 83 | seller = _seller; 84 | emit SellerUpdated(_seller); 85 | } 86 | } 87 | 88 | /// @notice deposits 'price' in address(this) via msg.value from caller, presumably buyer. 89 | function depositInEscrow() external payable { 90 | if (expirationTime <= block.timestamp) revert Expired(); 91 | if (msg.value != price) revert IncorrectMsgValue(); 92 | // prevent multiple transfers of 'price' from buyer, as this method is callable by any address 93 | if (checkEscrow() >= price) revert PriceAlreadyInEscrow(); 94 | } 95 | 96 | /// @notice seller and buyer each call this when ready to close; returns approval status of each party 97 | /// @dev no need for a 'checkEscrow()' call because a reasonable seller will only pass 'true' if escrow is in place 98 | function readyToClose() external { 99 | if (msg.sender == seller) sellerApproved = true; 100 | else if (msg.sender == buyer) buyerApproved = true; 101 | } 102 | 103 | /** @notice callable by any external address: checks if both buyer and seller are ready to close and expiration has not been met; 104 | *** if so, this contract closes deal and pays seller; if not, price deposit returned to buyer **/ 105 | /// @dev if properly closes, pays seller and emits event with effective time of closing 106 | function closeDeal() external { 107 | if (!sellerApproved || !buyerApproved) revert NotReadyToClose(); 108 | 109 | // delete approvals to prevent re-entrance 110 | delete sellerApproved; 111 | delete buyerApproved; 112 | 113 | if (!checkIfExpired()) { 114 | seller.safeTransferETH(price); 115 | 116 | // effective time of closing is block.timestamp upon payment to seller 117 | emit DealClosed(block.timestamp); 118 | } 119 | } 120 | 121 | /// @notice check if expired, and if expired, return balance to buyer 122 | function checkIfExpired() public returns (bool) { 123 | if (expirationTime <= block.timestamp) { 124 | isExpired = true; 125 | buyer.safeTransferETH(price); 126 | emit DepositReturned(); 127 | emit DealExpired(); 128 | } 129 | return (isExpired); 130 | } 131 | 132 | /// @notice checks address(this)'s balance to see if 'price' is in escrow 133 | function checkEscrow() public view returns (uint256) { 134 | return address(this).balance; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /solidity/EscrowStablecoin.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.8.12; 4 | 5 | /// unaudited and for demonstration only, provided as-is without any guarantees or warranties 6 | /// @title Stablecoin Escrow 7 | /// @notice bilateral smart escrow contract, with an ERC20 stablecoin as payment, expiration denominated in seconds, deposit refunded if contract expires before closeDeal() called 8 | /// @dev intended to be deployed by buyer - may be altered for separation of deposit from purchase price, deposit non-refundability, different token standard, additional conditions, etc. 9 | 10 | /// @notice Solbase SafeTransferLib's 'SafeTransfer()' and 'SafeTransferFrom()' 11 | /// @author Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/SafeTransferLib.sol) 12 | library SafeTransferLib { 13 | /// @dev The ERC20 `transfer` has failed. 14 | error TransferFailed(); 15 | 16 | /// @dev The ERC20 `transferFrom` has failed. 17 | error TransferFromFailed(); 18 | 19 | /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. 20 | /// Reverts upon failure. 21 | function safeTransfer( 22 | address token, 23 | address to, 24 | uint256 amount 25 | ) internal { 26 | /// @solidity memory-safe-assembly 27 | assembly { 28 | // We'll write our calldata to this slot below, but restore it later. 29 | let memPointer := mload(0x40) 30 | 31 | // Write the abi-encoded calldata into memory, beginning with the function selector. 32 | mstore(0x00, 0xa9059cbb) 33 | mstore(0x20, to) // Append the "to" argument. 34 | mstore(0x40, amount) // Append the "amount" argument. 35 | 36 | if iszero( 37 | and( 38 | // Set success to whether the call reverted, if not we check it either 39 | // returned exactly 1 (can't just be non-zero data), or had no return data. 40 | or(eq(mload(0x00), 1), iszero(returndatasize())), 41 | // We use 0x44 because that's the total length of our calldata (0x04 + 0x20 * 2) 42 | // Counterintuitively, this call() must be positioned after the or() in the 43 | // surrounding and() because and() evaluates its arguments from right to left. 44 | call(gas(), token, 0, 0x1c, 0x44, 0x00, 0x20) 45 | ) 46 | ) { 47 | // Store the function selector of `TransferFailed()`. 48 | mstore(0x00, 0x90b8ec18) 49 | // Revert with (offset, size). 50 | revert(0x1c, 0x04) 51 | } 52 | 53 | mstore(0x40, memPointer) // Restore the memPointer. 54 | } 55 | } 56 | 57 | /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. 58 | /// Reverts upon failure. 59 | /// 60 | /// The `from` account must have at least `amount` approved for 61 | /// the current contract to manage. 62 | function safeTransferFrom( 63 | address token, 64 | address from, 65 | address to, 66 | uint256 amount 67 | ) internal { 68 | /// @solidity memory-safe-assembly 69 | assembly { 70 | // We'll write our calldata to this slot below, but restore it later. 71 | let memPointer := mload(0x40) 72 | 73 | // Write the abi-encoded calldata into memory, beginning with the function selector. 74 | mstore(0x00, 0x23b872dd) 75 | mstore(0x20, from) // Append the "from" argument. 76 | mstore(0x40, to) // Append the "to" argument. 77 | mstore(0x60, amount) // Append the "amount" argument. 78 | 79 | if iszero( 80 | and( 81 | // Set success to whether the call reverted, if not we check it either 82 | // returned exactly 1 (can't just be non-zero data), or had no return data. 83 | or(eq(mload(0x00), 1), iszero(returndatasize())), 84 | // We use 0x64 because that's the total length of our calldata (0x04 + 0x20 * 3) 85 | // Counterintuitively, this call() must be positioned after the or() in the 86 | // surrounding and() because and() evaluates its arguments from right to left. 87 | call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) 88 | ) 89 | ) { 90 | // Store the function selector of `TransferFromFailed()`. 91 | mstore(0x00, 0x7939f424) 92 | // Revert with (offset, size). 93 | revert(0x1c, 0x04) 94 | } 95 | 96 | mstore(0x60, 0) // Restore the zero slot to zero. 97 | mstore(0x40, memPointer) // Restore the memPointer. 98 | } 99 | } 100 | } 101 | 102 | interface IERC20 { 103 | function balanceOf(address account) external view returns (uint256); 104 | } 105 | 106 | contract EscrowStablecoin { 107 | using SafeTransferLib for address; 108 | 109 | address public immutable buyer; 110 | address public seller; 111 | address public immutable stablecoin; 112 | 113 | uint256 public immutable price; 114 | uint256 public immutable expirationTime; 115 | 116 | bool public sellerApproved; 117 | bool public buyerApproved; 118 | bool public isExpired; 119 | 120 | string public description; 121 | 122 | event DealExpired(); 123 | event DealClosed(uint256 effectiveTime); //event provides exact blockstamp Unix time of closing 124 | event DepositReturned(); 125 | event SellerUpdated(address newSeller); 126 | 127 | error BuyerAddrSameAsSellerAddr(); 128 | error Expired(); 129 | error NotReadyToClose(); 130 | error NotSeller(); 131 | error PriceAlreadyInEscrow(); 132 | 133 | /// @notice deployer (buyer) initiates escrow with description, price in tokens, address of stablecoin, seconds until expiry, and designate recipient seller 134 | /// @param _description: brief identifier of the deal in question - perhaps as to parties/underlying asset/documentation reference/hash 135 | /// @param _price: purchase price number of tokens which will be deposited in the smart escrow contract 136 | /// @param _secsUntilExpiration: number of seconds until the deal expires. input type(uint256).max for no expiry 137 | /// @param _seller: the seller's address, recipient of the purchase price if the deal closes 138 | /// @param _stablecoin: token contract address of the stablecoin to be used in this transaction 139 | constructor( 140 | string memory _description, 141 | uint256 _price, 142 | uint256 _secsUntilExpiration, 143 | address _seller, 144 | address _stablecoin 145 | ) payable { 146 | buyer = msg.sender; 147 | price = _price; 148 | stablecoin = _stablecoin; 149 | description = _description; 150 | seller = _seller; 151 | expirationTime = block.timestamp + _secsUntilExpiration; 152 | } 153 | 154 | /// @notice for the current seller to designate a new recipient address 155 | /// @param _seller: new recipient address of seller 156 | function updateSeller(address _seller) external { 157 | if (msg.sender != seller) revert NotSeller(); 158 | if (_seller == buyer) revert BuyerAddrSameAsSellerAddr(); 159 | if (!checkIfExpired()) { 160 | seller = _seller; 161 | emit SellerUpdated(_seller); 162 | } 163 | } 164 | 165 | /** @notice uses 'safeTransferFrom' to deposit 'price' in address(this) from 'buyer' *** after buyer separately ERC20-approved address(this) for at least 'price'*** 166 | * OR anyone (for example a different buyer address) can directly transfer 'price' to address(this) without using this function, 167 | * without affecting the functionality of the rest of the contract **/ 168 | function depositInEscrow() external { 169 | if (expirationTime <= block.timestamp) revert Expired(); 170 | // prevent multiple transfers of 'price' from buyer, as this method is callable by any address 171 | if (checkEscrow() >= price) revert PriceAlreadyInEscrow(); 172 | 173 | stablecoin.safeTransferFrom(buyer, address(this), price); 174 | } 175 | 176 | /// @notice seller and buyer each call this when ready to close; returns approval status of each party 177 | /// @dev no need for a 'checkEscrow()' call because a reasonable seller will only pass 'true' if escrow is in place 178 | function readyToClose() external { 179 | if (msg.sender == seller) sellerApproved = true; 180 | else if (msg.sender == buyer) buyerApproved = true; 181 | } 182 | 183 | /** @notice callable by any external address: checks if both buyer and seller are ready to close and expiration has not been met; 184 | *** if so, this contract closes deal and pays seller; if not, price deposit returned to buyer **/ 185 | /// @dev if properly closes, pays seller and emits event with effective time of closing 186 | function closeDeal() external { 187 | if (!sellerApproved || !buyerApproved) revert NotReadyToClose(); 188 | 189 | // delete approvals to prevent re-entrance 190 | delete sellerApproved; 191 | delete buyerApproved; 192 | 193 | if (!checkIfExpired()) { 194 | stablecoin.safeTransfer(seller, price); 195 | 196 | // effective time of closing is block.timestamp upon payment to seller 197 | emit DealClosed(block.timestamp); 198 | } 199 | } 200 | 201 | /// @notice check if expired, and if expired, return balance to buyer 202 | function checkIfExpired() public returns (bool) { 203 | if (expirationTime <= block.timestamp) { 204 | isExpired = true; 205 | stablecoin.safeTransfer(buyer, price); 206 | emit DepositReturned(); 207 | emit DealExpired(); 208 | } 209 | return (isExpired); 210 | } 211 | 212 | /// @notice checks address(this)'s balance to see if 'price' is in escrow 213 | function checkEscrow() public view returns (uint256) { 214 | return IERC20(stablecoin).balanceOf(address(this)); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /solidity/FunctionSelector.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | /// @dev convenience getter for function selector, for example to use with abi.encodeWithSelector 4 | 5 | pragma solidity >=0.8.0; 6 | 7 | contract FunctionSelector { 8 | constructor() {} 9 | 10 | /// @param _input the method call (function and any arguments, without spaces), for example "inputInfo(address,uint256)" 11 | /// @return bytes4 function selector 12 | function getSelector(string calldata _input) 13 | external 14 | pure 15 | returns (bytes4) 16 | { 17 | return (bytes4(keccak256(bytes(_input)))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /solidity/NFTicket.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | /**** 3 | ***** this code and any deployments of this code are strictly provided as-is; 4 | ***** no guarantee, representation or warranty is being made, 5 | ***** express or implied, as to the safety or correctness of the code 6 | ***** or any smart contracts or other software deployed from these files, 7 | ***** in accordance with the disclosures and licenses 8 | ***** found here: https://github.com/ErichDylus/Open-Source-Law/tree/main/solidity#readme 9 | ***** this code is not audited, and users, developers, or adapters of these files 10 | ***** should proceed with caution and use at their own risk. 11 | ****/ 12 | pragma solidity >=0.8.14; 13 | 14 | import "https://github.com/api3dao/airnode/blob/master/packages/airnode-protocol/contracts/rrp/requesters/RrpRequesterV0.sol"; 15 | import "https://github.com/kalidao/kali-contracts/blob/main/contracts/tokens/erc721/ERC721.sol"; 16 | 17 | /// @title NFTicket 18 | /** @notice QRNG-powered transferable NFT ticket minter with random ID number; 19 | ** random tokenID may be used as a lottery or special privilege mechanism for NFTicket holder */ 20 | /** @dev uses API3/ANU QRNG, KaliDAO ERC721 implementation. Consider modulus for _ticketID/tokenID for UX. 21 | ** steps: (1) deploy contract; (2) derive sponsorWallet address and provide to designateSponsorWallet(); (3) fund sponsorWallet */ 22 | 23 | contract NFTicket is ERC721, RrpRequesterV0 { 24 | address public immutable airnode; 25 | address payable public immutable deployer; 26 | address payable public sponsorWallet; 27 | bytes32 public immutable endpointId; 28 | uint256 public immutable ticketCap; 29 | uint256 public immutable ticketPrice; 30 | 31 | uint256 public ticketCount; 32 | 33 | mapping(bytes32 => address) public requestIdToBuyer; 34 | mapping(bytes32 => bool) public expectingRequestWithIdToBeFulfilled; 35 | mapping(uint256 => string) private _tokenURI; 36 | 37 | error OnlyDeployer(); 38 | error SubmitTicketPrice(); 39 | error TicketCapReached(); 40 | error TicketPaymentFailed(); 41 | error TransferToSponsorWalletFailed(); 42 | 43 | event ReceivedTicket(address indexed buyer, uint256 ticketID); 44 | 45 | /// @param _name: name of NFTicket 46 | /// @param _symbol: symbol/ticker of NFTicket 47 | /// @param _airnode: ANU airnode contract address, see https://docs.api3.org/qrng/providers.html 48 | /// @param _airnodeRrp: Airnode RRP contract address, see https://docs.api3.org/qrng/chains.html 49 | /// @param _endpointId: endpointID for the QRNG, see https://docs.api3.org/qrng/providers.html 50 | /// @param _ticketPrice: price of a NFTicket in wei 51 | /// @param _ticketCap: maximum number of mintable NFTickets 52 | /// @dev set parameters for airnodeRrp.makeFullRequest, ticket price & cap; must derive, designate and fund sponsorWallet after deployment 53 | constructor( 54 | string memory _name, 55 | string memory _symbol, 56 | address _airnode, 57 | address _airnodeRrp, 58 | bytes32 _endpointId, 59 | uint256 _ticketPrice, 60 | uint256 _ticketCap 61 | ) payable ERC721(_name, _symbol) RrpRequesterV0(_airnodeRrp) { 62 | airnode = _airnode; 63 | deployer = payable(msg.sender); 64 | endpointId = _endpointId; 65 | ticketPrice = _ticketPrice; 66 | ticketCap = _ticketCap; 67 | } 68 | 69 | /// @notice submit ticketPrice in msg.value to mint an NFTicket with random tokenID 70 | function buyTicket() external payable { 71 | if (msg.value != ticketPrice) revert SubmitTicketPrice(); 72 | if (ticketCount >= ticketCap) revert TicketCapReached(); 73 | 74 | (bool sent, ) = deployer.call{value: msg.value}(""); 75 | if (!sent) revert TicketPaymentFailed(); 76 | 77 | bytes32 requestId = airnodeRrp.makeFullRequest( 78 | airnode, 79 | endpointId, 80 | address(this), 81 | sponsorWallet, 82 | address(this), 83 | this.fulfillUint256.selector, 84 | "" 85 | ); 86 | expectingRequestWithIdToBeFulfilled[requestId] = true; 87 | requestIdToBuyer[requestId] = msg.sender; 88 | } 89 | 90 | /// @dev AirnodeRrp will call back here with a response 91 | function fulfillUint256(bytes32 requestId, bytes calldata data) 92 | external 93 | onlyAirnodeRrp 94 | { 95 | require( 96 | expectingRequestWithIdToBeFulfilled[requestId], 97 | "Request ID not known" 98 | ); 99 | expectingRequestWithIdToBeFulfilled[requestId] = false; 100 | uint256 _ticketID = abi.decode(data, (uint256)) % 10000000000000000; //mod to smaller random number for UX 101 | address buyer = requestIdToBuyer[requestId]; 102 | _mint(buyer, _ticketID); 103 | 104 | unchecked { 105 | ++ticketCount; 106 | } 107 | 108 | emit ReceivedTicket(buyer, _ticketID); 109 | } 110 | 111 | /// @notice for deployer to provide sponsorWallet address post-contract deployment, 112 | /// @param _sponsorWallet: derived sponsor wallet address, see dev notes 113 | /** @dev SPONSOR WALLET MUST BE DERIVED FROM ADDRESS(THIS) AFTER DEPLOYMENT: npx @api3/airnode-admin derive-sponsor-wallet-address --airnode-xpub xpub6DXSDTZBd4aPVXnv6Q3SmnGUweFv6j24SK77W4qrSFuhGgi666awUiXakjXruUSCDQhhctVG7AQt67gMdaRAsDnDXv23bBRKsMWvRzo6kbf --airnode-address 0x9d3C147cA16DB954873A498e0af5852AB39139f2 --sponsor-address address(this) 114 | ** see: https://docs.api3.org/airnode/v0.6/concepts/sponsor.html#derive-a-sponsor-wallet */ 115 | function designateSponsorWallet(address payable _sponsorWallet) external { 116 | if (msg.sender != deployer) revert OnlyDeployer(); 117 | sponsorWallet = _sponsorWallet; 118 | } 119 | 120 | /// @notice sends msg.value to sponsorWallet to ensure Airnode continues responses 121 | /// for convenience; can also just directly send ETH to the sponsorWallet address 122 | function addGasToSponsorWallet() external payable { 123 | require(msg.value != 0, "msg.value == 0"); 124 | (bool sent, ) = sponsorWallet.call{value: msg.value}(""); 125 | if (!sent) revert TransferToSponsorWalletFailed(); 126 | } 127 | 128 | /// @notice allows an NFTicket holder to burn/redeem NFTicket 129 | /// @param tokenID: token ID of NFTicket to be burned 130 | function burn(uint256 tokenID) public { 131 | if (msg.sender != ownerOf[tokenID]) revert NotOwner(); 132 | _burn(tokenID); 133 | } 134 | 135 | function tokenURI(uint256 tokenID) 136 | public 137 | view 138 | virtual 139 | override 140 | returns (string memory) 141 | { 142 | return _tokenURI[tokenID]; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /solidity/OpenOffer.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.16; 3 | 4 | /// @title Open Offer 5 | /// @notice revocable on-chain bilateral open offer, which anyone may countersign on-chain to accept 6 | /** @dev deployer submits string text of a open offer which is hashed, and is verifiable by a prospective signer submitting the string text to verifyOfferText(). 7 | ** Only one acceptance permitted. Revocable (but not amendable or replaceable) by offeror. */ 8 | 9 | contract OpenOffer { 10 | address public immutable offeror; 11 | bytes32 public immutable documentHash; 12 | 13 | bool public offerOpen; 14 | bool public signedAndOfferAccepted; 15 | 16 | error HashDoesNotMatch(); 17 | error OfferClosed(); 18 | error OffereeCannotBeOfferor(); 19 | error OnlyOfferor(); 20 | 21 | event OfferAccepted( 22 | bytes32 docHash, 23 | address signatory, 24 | uint256 effectiveTime 25 | ); 26 | event OfferOpened(bytes32 docHash, uint256 effectiveTime); 27 | event OfferRevoked(uint256 effectiveTime); 28 | 29 | /// @param _documentText string text of submitted open offer 30 | constructor(string memory _documentText) { 31 | offeror = msg.sender; 32 | offerOpen = true; 33 | documentHash = keccak256(bytes(_documentText)); 34 | emit OfferOpened(documentHash, block.timestamp); 35 | } 36 | 37 | /// @notice allows anyone except offeror to countersign and accept the open offer (recommended to first verify the offer via verifyOfferText()) 38 | /// @dev simple function call, but could be modified to have signatory type name or other acknowledgment 39 | function acceptOffer() external { 40 | if (!offerOpen || signedAndOfferAccepted) revert OfferClosed(); 41 | if (offeror == msg.sender) revert OffereeCannotBeOfferor(); 42 | signedAndOfferAccepted = true; 43 | delete (offerOpen); 44 | emit OfferAccepted(documentHash, msg.sender, block.timestamp); 45 | } 46 | 47 | /// @notice allows offeror to revoke offer 48 | function revokeOffer() external { 49 | if (msg.sender != offeror) revert OnlyOfferor(); 50 | delete (offerOpen); 51 | emit OfferRevoked(block.timestamp); 52 | } 53 | 54 | /** @notice allows a prospective signatory to ensure their intended document text matches 55 | ** the text hashed in this contract before signing */ 56 | /// @param _documentText string text of document intended to be signed 57 | /// @return true if the hashes match, otherwise the transaction will have reverted 58 | function verifyOfferText( 59 | string calldata _documentText 60 | ) external view returns (bool) { 61 | if (keccak256(bytes(_documentText)) != documentHash) 62 | revert HashDoesNotMatch(); 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /solidity/PayInEth.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | /**** 3 | ***** this code and any deployments of this code are strictly provided as-is; no guarantee, representation or warranty is being made, 4 | ***** express or implied, as to the safety or correctness of the code 5 | ***** or any smart contracts or other software deployed from these files, in accordance with the disclosures and licenses 6 | ***** found here: https://github.com/ErichDylus/Open-Source-Law/tree/main/solidity#readme 7 | ***** this code is not audited, and users, developers, or adapters of these files should proceed with caution and use at their own risk. 8 | ****/ 9 | 10 | pragma solidity >=0.8.0; 11 | 12 | /// @title Pay In ETH 13 | /// @dev uses Sushiswap router to swap incoming ETH for USDC tokens, then sends to receiver address (initially, the deployer) 14 | /// @notice permits payment for services in ETH but receiving stablecoins without manual swap, avoiding de minimus taxable events in some jurisdictions. 15 | /// may be easily forked to instead accept DAI, RAI, or any other token with a swap pair - USDC merely used as an example 16 | /// also forkable for other chains, for example Polygon/MATIC: https://gist.github.com/ErichDylus/476fb5d51683059f150f152149cc4c15 17 | 18 | interface IUniswapV2Router02 { 19 | function swapExactETHForTokens( 20 | uint256 amountOutMin, 21 | address[] calldata path, 22 | address to, 23 | uint256 deadline 24 | ) external payable returns (uint256[] memory amounts); 25 | } 26 | 27 | contract PayInETH { 28 | address constant USDC_TOKEN_ADDR = 29 | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; // USDC mainnet token contract address, change this for desired token to be received 30 | address constant WETH_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // WETH mainnet token address, alteratively could call sushiRouter.WETH() for the path 31 | address constant SUSHI_ROUTER_ADDR = 32 | 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F; // Sushiswap router contract address 33 | address public receiver; 34 | 35 | IUniswapV2Router02 public sushiRouter; 36 | 37 | error CallerNotCurrentReceiver(); 38 | 39 | constructor() payable { 40 | sushiRouter = IUniswapV2Router02(SUSHI_ROUTER_ADDR); 41 | receiver = msg.sender; 42 | } 43 | 44 | /// @notice receives ETH payment and swaps to USDC via Sushiswap router, which is then sent to receiver. 45 | /// @dev here, minimum amount set as 0 and deadline set to block.timestamp as initial options to avoid failure, but can be altered 46 | receive() external payable { 47 | sushiRouter.swapExactETHForTokens{value: msg.value}( 48 | 0, 49 | _getPathForETHtoUSDC(), 50 | receiver, 51 | block.timestamp 52 | ); 53 | } 54 | 55 | /// @return the router path for ETH/USDC swap 56 | function _getPathForETHtoUSDC() internal pure returns (address[] memory) { 57 | address[] memory path = new address[](2); 58 | path[0] = WETH_ADDR; 59 | path[1] = USDC_TOKEN_ADDR; 60 | return path; 61 | } 62 | 63 | /// @notice allows current receiver to change the receiver address for payments 64 | /// @param _newReceiver new address to receive stablecoin payment 65 | /// @return the receiver address 66 | function changeReceiver(address _newReceiver) external returns (address) { 67 | if (msg.sender != receiver) revert CallerNotCurrentReceiver(); 68 | receiver = _newReceiver; 69 | return (receiver); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /solidity/README.md: -------------------------------------------------------------------------------- 1 | **Please read [this disclosure](https://github.com/ErichDylus/Open-Source-Law/blob/main/Disclosure.md) and note that all forms, templates, code or other materials provided or linked herein carry [no warranty whatsoever](https://github.com/ErichDylus/Open-Source-Law/blob/main/LICENSE).** 2 | 3 | These solidity files are being provided as-is; no guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the code or any smart contracts or other software deployed from these files. These files are intended strictly for educational or demonstrative purposes. 4 | 5 | Unless expressly designated otherwise in writing, none of the solidity files herein have been audited and as such there can be no assurance they will work as intended, and users may experience delays, failures, errors, omissions or loss of transmitted information. Any users, developers, or adapters of these files should proceed with caution and use at their own risk. 6 | -------------------------------------------------------------------------------- /solidity/TaxWithholding.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.18; 4 | 5 | /// FOR DEMONSTRATION ONLY, unaudited, not recommended to be used for any purpose and provided with no warranty whatsoever, see https://github.com/ErichDylus/Open-Source-Law/blob/main/LICENSE 6 | 7 | interface IERC20Permit { 8 | function decimals() external view returns (uint256); 9 | 10 | function permit( 11 | address owner, 12 | address spender, 13 | uint256 value, 14 | uint256 deadline, 15 | uint8 v, 16 | bytes32 r, 17 | bytes32 s 18 | ) external; 19 | } 20 | 21 | // @notice Solbase / Solady's SafeTransferLib 'SafeTransferFrom()'. Extracted from library and pasted for convenience, transparency, and size minimization. 22 | /// @author Solbase / Solady (https://github.com/Sol-DAO/solbase/blob/main/src/utils/SafeTransferLib.sol / https://github.com/Vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) 23 | /// @dev implemented as abstract contract rather than library for size/gas reasons 24 | abstract contract SafeTransferLib { 25 | /// @dev The ERC20 `transferFrom` has failed. 26 | error TransferFromFailed(); 27 | 28 | /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. 29 | /// Reverts upon failure. 30 | /// 31 | /// The `from` account must have at least `amount` approved for 32 | /// the current contract to manage. 33 | function safeTransferFrom( 34 | address token, 35 | address from, 36 | address to, 37 | uint256 amount 38 | ) internal { 39 | /// @solidity memory-safe-assembly 40 | assembly { 41 | // We'll write our calldata to this slot below, but restore it later. 42 | let memPointer := mload(0x40) 43 | 44 | // Write the abi-encoded calldata into memory, beginning with the function selector. 45 | mstore(0x00, 0x23b872dd) 46 | mstore(0x20, from) // Append the "from" argument. 47 | mstore(0x40, to) // Append the "to" argument. 48 | mstore(0x60, amount) // Append the "amount" argument. 49 | 50 | if iszero( 51 | and( 52 | // Set success to whether the call reverted, if not we check it either 53 | // returned exactly 1 (can't just be non-zero data), or had no return data. 54 | or(eq(mload(0x00), 1), iszero(returndatasize())), 55 | // We use 0x64 because that's the total length of our calldata (0x04 + 0x20 * 3) 56 | // Counterintuitively, this call() must be positioned after the or() in the 57 | // surrounding and() because and() evaluates its arguments from right to left. 58 | call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20) 59 | ) 60 | ) { 61 | // Store the function selector of `TransferFromFailed()`. 62 | mstore(0x00, 0x7939f424) 63 | // Revert with (offset, size). 64 | revert(0x1c, 0x04) 65 | } 66 | 67 | mstore(0x60, 0) // Restore the zero slot to zero. 68 | mstore(0x40, memPointer) // Restore the memPointer. 69 | } 70 | } 71 | } 72 | 73 | /// @notice non-custodial tax withholding contract for ERC20 tokens to separate withheld estimated tax, etc.; contingent on factors such as jurisdiction and status of each msg.sender, but initially whole-number flat rate for demonstration 74 | /// @dev address(this) never receives tokens, but is programmatically enabled to safeTransferFrom the msg.sender to the designated 'taxAddress' (which can in practice be a separated wallet for account or a tax authority's recipient wallet) 75 | contract TaxWithholding is SafeTransferLib { 76 | uint256 constant DECIMALS = 18; 77 | 78 | address public immutable taxAddress; 79 | uint256 public immutable taxRate; 80 | 81 | // numbered tax withholding for each msg.sender 82 | mapping(address => uint256) public taxWithholdingNumber; 83 | // tax amount for a given msg.sender's taxWithholdingNumber 84 | mapping(uint256 => mapping(address => uint256)) 85 | public withholdingNumberToAmount; 86 | 87 | error InvalidRate(); 88 | 89 | event TaxWithheld( 90 | address indexed payor, 91 | uint256 indexed withholdingNumber, 92 | uint256 time, 93 | uint256 amount, 94 | address tokenContract 95 | ); 96 | 97 | /// @param _taxAddress designated recipient address to receive withheld amount 98 | /// @param _taxRate using 18 decimals for calculations, percentage tax rate as a nonzero uint < 1e18 (which corresponds to 100%). Ex., 1e16 == 1%, 1e17 == 10%, etc. 99 | constructor(address _taxAddress, uint256 _taxRate) payable { 100 | if (_taxRate == 0 || _taxRate >= 10 ** DECIMALS) revert InvalidRate(); 101 | taxAddress = _taxAddress; 102 | taxRate = _taxRate; 103 | } 104 | 105 | /// @dev msg.sender must first separately approve address(this) for _tokenAddress for at least _taxes amount so it may initiate the safeTransferFrom to the 'taxAddress' 106 | /// @param _amount gross amount by msg.sender in the applicable token corresponding to _tokenAddress 107 | /// @param _tokenAddress contract address of ERC20 token received 108 | /// @return taxes paid, tax withholding number for this msg.sender 109 | function payTax( 110 | uint256 _amount, 111 | address _tokenAddress 112 | ) external returns (uint256, uint256) { 113 | uint256 _taxes = (_amount * taxRate) / 10 ** DECIMALS; 114 | // adjust for decimal amount other than 18 115 | uint256 _decimals = IERC20Permit(_tokenAddress).decimals(); 116 | // if more than 18 decimals, divide the total amount by the excess decimal places; subtraction will not underflow due to condition check 117 | if (_decimals > DECIMALS) { 118 | unchecked { 119 | _taxes = (_taxes / 10 ** (_decimals - 18)); 120 | } 121 | } 122 | // if less than 18 decimals, multiple the total amount by the difference in decimal places 123 | else if (_decimals < DECIMALS) { 124 | _taxes = _taxes * (10 ** (18 - _decimals)); 125 | } 126 | 127 | unchecked { 128 | ++taxWithholdingNumber[msg.sender]; // will not overflow on human timelines 129 | } 130 | uint256 _number = taxWithholdingNumber[msg.sender]; 131 | withholdingNumberToAmount[_number][msg.sender] = _taxes; 132 | 133 | safeTransferFrom(_tokenAddress, msg.sender, taxAddress, _taxes); 134 | 135 | emit TaxWithheld( 136 | msg.sender, 137 | _number, 138 | block.timestamp, 139 | _taxes, 140 | _tokenAddress 141 | ); 142 | 143 | return (_taxes, _number); 144 | } 145 | 146 | /// @notice tax withholding via EIP712 permit for compliant tokens 147 | /// @param _amount gross amount by msg.sender in the applicable token corresponding to _tokenAddress 148 | /// @param _deadline: deadline for permit approval usage 149 | /// @param _tokenAddress contract address of ERC20 token received 150 | /// @param _v: ECDSA sig param 151 | /// @param _r: ECDSA sig param 152 | /// @param _s: ECDSA sig param 153 | /// @return taxes paid, tax withholding number for this msg.sender 154 | function payTaxViaPermit( 155 | uint256 _amount, 156 | uint256 _deadline, 157 | address _tokenAddress, 158 | uint8 _v, 159 | bytes32 _r, 160 | bytes32 _s 161 | ) external returns (uint256, uint256) { 162 | uint256 _taxes = (_amount * taxRate) / DECIMALS; 163 | // adjust for decimal amount other than 18 164 | uint256 _decimals = IERC20Permit(_tokenAddress).decimals(); 165 | // if more than 18 decimals, divide the total amount by the excess decimal places; subtraction will not underflow due to condition check 166 | if (_decimals > DECIMALS) { 167 | unchecked { 168 | _taxes = (_taxes / 10 ** (_decimals - 18)); 169 | } 170 | } 171 | // if less than 18 decimals, multiple the total amount by the difference in decimal places 172 | else if (_decimals < DECIMALS) { 173 | _taxes = _taxes * (10 ** (18 - _decimals)); 174 | } 175 | 176 | unchecked { 177 | ++taxWithholdingNumber[msg.sender]; // will not overflow on human timelines 178 | } 179 | uint256 _number = taxWithholdingNumber[msg.sender]; 180 | withholdingNumberToAmount[_number][msg.sender] = _taxes; 181 | 182 | IERC20Permit(_tokenAddress).permit( 183 | msg.sender, 184 | address(this), 185 | _taxes, 186 | _deadline, 187 | _v, 188 | _r, 189 | _s 190 | ); 191 | 192 | safeTransferFrom(_tokenAddress, msg.sender, taxAddress, _taxes); 193 | 194 | emit TaxWithheld( 195 | msg.sender, 196 | _number, 197 | block.timestamp, 198 | _taxes, 199 | _tokenAddress 200 | ); 201 | 202 | return (_taxes, _number); 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /solidity/TokenConverter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | /**** 3 | ***** INCOMPLETE 4 | ***** this code and any deployments of this code are strictly provided as-is; no guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the code 5 | ***** or any smart contracts or other software deployed from these files, in accordance with the disclosures and licenses found here: https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/README.md 6 | ***** this code is not audited, and users, developers, or adapters of these files should proceed with caution and use at their own risk. 7 | ***** 8 | ****/ 9 | 10 | pragma solidity >=0.8.12; 11 | 12 | /// @title Token Converter 13 | /// @dev uses Uniswap router to swap incoming ERC20 tokens for receiver's chosen ERC20 tokens, then sends to receiver address (initially, the deployer) 14 | /// @notice permits payment for services in any token payor chooses (provided there is a Uniswap router path with sufficient liquidity) and receiving tokens of choice by receiver 15 | 16 | interface IUniswapV2Router02 { 17 | function swapExactTokensForTokens( 18 | uint256 amountIn, 19 | uint256 amountOutMin, 20 | address[] calldata path, 21 | address to, 22 | uint256 deadline 23 | ) external payable returns (uint256[] memory amounts); 24 | 25 | function getAmountsOut( 26 | uint256 amountIn, 27 | address[] calldata path 28 | ) external view returns (uint256[] memory amounts); 29 | } 30 | 31 | interface IERC20 { 32 | function approve(address spender, uint256 amount) external returns (bool); 33 | 34 | function balanceOf(address account) external view returns (uint256); 35 | 36 | function transfer( 37 | address recipient, 38 | uint256 amount 39 | ) external returns (bool); 40 | } 41 | 42 | contract TokenConverter { 43 | address internal constant UNI_ROUTER_ADDR = 44 | 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // Uniswap v2 router contract address 45 | address public receiver; 46 | address public receiverToken; 47 | 48 | IUniswapV2Router02 internal uniRouter; 49 | 50 | error CallerNotCurrentReceiver(); 51 | error TokenAmountNotSentToThisAddress(); 52 | 53 | /// @param _tokenAddr: contract address of token desired to be received by receiver 54 | constructor(address _tokenAddr) payable { 55 | uniRouter = IUniswapV2Router02(UNI_ROUTER_ADDR); 56 | receiver = msg.sender; 57 | receiverToken = _tokenAddr; 58 | } 59 | 60 | /// @notice swaps payor '_token' to 'receiverToken' via Uniswap router, which is then sent to receiver 61 | /** @dev payor must first transfer '_amount' of '_token' to this contract address. Payor's responsibility to check '_token' address validity and liquidity via 'uniRouter' 62 | ** there is no check as to address which transferred '_amount' of '_token' to this address, as receiver can verify controller of such depositing address offchain with legal counterparty */ 63 | /// @param _token the token contract address of payor's tokens 64 | /// @param _amount the amount of tokens being paid by payor (keep decimals in mind) 65 | function completePayment(address _token, uint256 _amount) external { 66 | if (IERC20(_token).balanceOf(address(this)) < _amount) 67 | revert TokenAmountNotSentToThisAddress(); 68 | IERC20(_token).approve(UNI_ROUTER_ADDR, _amount); // allow the unirouter to swap _token held by this address 69 | uniRouter.swapExactTokensForTokens( 70 | _amount, 71 | 1, 72 | _getPath(_token), 73 | receiver, 74 | block.timestamp 75 | ); 76 | } 77 | 78 | /// @notice allows current receiver address to change the receiver token contract address 79 | /// @dev receiver's responsibility to check '_newReceiverToken' address validity and liquidity via 'uniRouter' 80 | /// @param _newReceiverToken new token address for receiver_token 81 | function changeReceiverToken(address _newReceiverToken) external { 82 | if (msg.sender != receiver) revert CallerNotCurrentReceiver(); 83 | receiverToken = _newReceiverToken; 84 | } 85 | 86 | /// @notice allows current receiver address to change the receiver address for payments 87 | /// @param _newReceiver new address to receive receiverTokens 88 | function changeReceiver(address _newReceiver) external { 89 | if (msg.sender != receiver) revert CallerNotCurrentReceiver(); 90 | receiver = _newReceiver; 91 | } 92 | 93 | /// @param _amount the amount of tokens to be paid by payor 94 | /// @param _payorToken the token contract address of payor's token 95 | /// @return amounts out for the applicable swap from _payorToken to receiverToken 96 | /// @notice convenience function to ensure liquid swap available before sending tokens to this contract 97 | function checkAmountsOut( 98 | uint256 _amount, 99 | address _payorToken 100 | ) external view returns (uint256[] memory) { 101 | address[] memory path = new address[](2); 102 | path = _getPath(_payorToken); 103 | return uniRouter.getAmountsOut(_amount, path); 104 | } 105 | 106 | /// @param _payorToken the token contract address of payor's tokens, inputted by completePayment() 107 | /// @return path for the router 108 | function _getPath( 109 | address _payorToken 110 | ) internal view returns (address[] memory) { 111 | address[] memory path = new address[](2); 112 | path[0] = _payorToken; 113 | path[1] = receiverToken; 114 | return path; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /solidity/VoteCounter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.8.16; 4 | 5 | /// unaudited and subject to all disclosures, licenses, and caveats set forth at https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/README.md 6 | /// @title VoteCounter 7 | /// @notice Counts governance votes for a given address holding an ERC1155 governance token 8 | /// intended as part of a limited cooperative association which tallies ERC1155-gated votes for patronage calculations / membership activity status 9 | 10 | interface IERC1155 { 11 | function balanceOf(address account, uint256 id) 12 | external 13 | view 14 | returns (uint256); 15 | } 16 | 17 | contract VoteCounter { 18 | IERC1155 public ierc1155; 19 | 20 | mapping(address => bool) public isVoter; 21 | mapping(address => uint256) public voteIndex; 22 | mapping(uint256 => bool) public isValidVote; 23 | 24 | event Voted( 25 | uint256 indexed voteTime, 26 | uint256 voteNumber, 27 | uint256 voteIndex, 28 | address voter 29 | ); 30 | 31 | error InvalidVote(); 32 | error NotVoter(); 33 | 34 | /// @param _govToken: address of the ERC1155 governance token used for votes 35 | constructor(address _govToken) { 36 | ierc1155 = IERC1155(_govToken); 37 | } 38 | 39 | /// @param _voteNumber: vote index for the applicable governance contract 40 | /// @param _voterId: id for the voter's ERC1155 token 41 | /// @param _voter: address of the voter 42 | /** @dev intended to be called as part of a vote cast function, 43 | *** otherwise add a _voteTime method input of the unix time (block.timestamp) of the applicable vote; 44 | *** also, may consider valuing the patronage (via bylaws) of a cast vote by some multiplier of the gas expenditure 45 | *** for such vote txn obtained by web3.eth.getTransactionReceipt(hash [, callback]); this returns the receipt of a transaction, 46 | *** including gasUsed, by transaction hash */ 47 | function newVote( 48 | uint256 _voteNumber, 49 | uint256 _voterId, 50 | address _voter 51 | ) external { 52 | if (ierc1155.balanceOf(_voter, _voterId) == 0) revert NotVoter(); 53 | if (!isValidVote[_voteNumber]) revert InvalidVote(); 54 | unchecked { 55 | ++voteIndex[_voter]; 56 | } // increment voteIndex, will not overflow on human timelines 57 | emit Voted(block.timestamp, _voteNumber, voteIndex[_voter], _voter); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /solidity/interfaces/IDealStamp.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.8.10; 4 | 5 | // unaudited and subject to all disclosures, licenses, and caveats set forth at https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/README.md 6 | // interface to DealStamp.sol, to create an on-chain record of a deal's parties, decentralized doc storage ref (which would presumably carry an additional hash layer/other security mechanism for access), and time of closing 7 | 8 | interface IDealStamp { 9 | 10 | function newDealStamp(string calldata docsLocationHash, uint256 effectiveTime, address party1, address party2) external returns (uint256); 11 | function addPartyToDeal(uint256 dealNumber, address newParty) external returns (bool); 12 | function viewDeal(uint256 dealNumber) external view returns (uint256, uint256, string memory, address[] memory); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /solidity/interfaces/ITaxWithholding.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.18; 3 | 4 | // unaudited and subject to all disclosures, licenses, and caveats set forth at https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/README.md 5 | 6 | interface ITaxWithholding { 7 | /// @dev msg.sender must first separately approve the TaxWitholding contract address for _tokenAddress for at least _taxes amount so it may initiate the safeTransferFrom to the 'taxAddress' 8 | /// @param _amount gross amount by msg.sender in the applicable token corresponding to _tokenAddress 9 | /// @param _tokenAddress contract address of ERC20 token received 10 | /// @return taxes paid, tax withholding number for this msg.sender 11 | function payTax( 12 | uint256 _amount, 13 | address _tokenAddress 14 | ) external returns (uint256, uint256); 15 | 16 | /// @notice tax withholding via EIP712 permit for compliant tokens 17 | /// @param _amount gross amount by msg.sender in the applicable token corresponding to _tokenAddress 18 | /// @param _deadline: deadline for permit approval usage 19 | /// @param _tokenAddress contract address of ERC20 token received 20 | /// @param _v: ECDSA sig param 21 | /// @param _r: ECDSA sig param 22 | /// @param _s: ECDSA sig param 23 | /// @return taxes paid, tax withholding number for this msg.sender 24 | function payTaxViaPermit( 25 | uint256 _amount, 26 | uint256 _deadline, 27 | address _tokenAddress, 28 | uint8 _v, 29 | bytes32 _r, 30 | bytes32 _s 31 | ) external returns (uint256, uint256); 32 | } 33 | -------------------------------------------------------------------------------- /solidity/interfaces/IVoteCounter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.8.16; 4 | 5 | /// unaudited and subject to all disclosures, licenses, and caveats set forth at https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/README.md 6 | 7 | interface IVoteCounter { 8 | 9 | function newVote( 10 | uint256 voteNumber, 11 | uint256 voterId, 12 | address voter 13 | ) external; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solidity/tests/ETHEscrow.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.12; 3 | 4 | import "forge-std/Test.sol"; 5 | import "src/EscrowETH.sol"; 6 | 7 | /// @notice foundry framework testing of EscrowETH.sol 8 | 9 | /// @notice test contract for EscrowETH using Foundry 10 | contract EscrowETHTest is Test { 11 | EscrowETH public escrowTest; 12 | 13 | address payable seller = payable(address(1)); 14 | uint256 deployTime; 15 | uint256 price = 1e16; 16 | uint256 secsUntilExpiration = 500; 17 | 18 | string testDescription = "description"; 19 | 20 | function setUp() public { 21 | escrowTest = new EscrowETH( 22 | testDescription, 23 | price, 24 | secsUntilExpiration, 25 | seller 26 | ); 27 | deployTime = block.timestamp; 28 | vm.deal(address(this), price); 29 | } 30 | 31 | receive() external payable {} 32 | 33 | function testConstructor() public { 34 | assertEq( 35 | escrowTest.expirationTime(), 36 | deployTime + secsUntilExpiration, 37 | "Expiry time mismatch" 38 | ); 39 | } 40 | 41 | function testUpdateSeller(address payable _addr) public { 42 | if (escrowTest.checkIfExpired()) vm.expectRevert(); 43 | 44 | vm.prank(escrowTest.seller()); 45 | escrowTest.updateSeller(_addr); 46 | assertEq(escrowTest.seller(), _addr, "seller address did not update"); 47 | } 48 | 49 | function testDepositInEscrow() public payable { 50 | if (msg.value != price || escrowTest.expirationTime() > block.timestamp) 51 | vm.expectRevert(); 52 | escrowTest.depositInEscrow(); 53 | } 54 | 55 | function testReadyToClose(address _caller) external { 56 | // if caller isn't seller or buyer and the sellerApproved and buyerApproved bools haven't already been change, any other address 57 | // calling this function should do nothing and the bools should not update 58 | if ( 59 | _caller != escrowTest.seller() && 60 | _caller != escrowTest.buyer() && 61 | !escrowTest.sellerApproved() && 62 | !escrowTest.buyerApproved() 63 | ) { 64 | vm.startPrank(_caller); 65 | escrowTest.readyToClose(); 66 | assertTrue(!escrowTest.sellerApproved()); 67 | assertTrue(!escrowTest.buyerApproved()); 68 | vm.stopPrank(); 69 | } 70 | 71 | //ensure seller and buyer can update their approved booleans 72 | vm.startPrank(escrowTest.seller()); 73 | escrowTest.readyToClose(); 74 | assertTrue(escrowTest.sellerApproved()); 75 | vm.stopPrank(); 76 | vm.startPrank(escrowTest.buyer()); 77 | escrowTest.readyToClose(); 78 | assertTrue(escrowTest.buyerApproved()); 79 | vm.stopPrank(); 80 | } 81 | 82 | function testCheckEscrow() external { 83 | assertEq( 84 | escrowTest.checkEscrow(), 85 | address(escrowTest).balance, 86 | "checkEscrow not returning contract balance" 87 | ); 88 | } 89 | 90 | // fuzz test for different timestamps 91 | // balance checks assume no other msg.value transfers during testing 92 | function testCheckIfExpired(uint256 timestamp) external { 93 | // assume 'price' is in escrow, so escrowTest can transfer 'price' back to buyer if expired 94 | vm.deal(address(escrowTest), escrowTest.price()); 95 | 96 | uint256 _preBalance = address(escrowTest).balance; 97 | uint256 _preBuyerBalance = escrowTest.buyer().balance; 98 | vm.warp(timestamp); 99 | escrowTest.checkIfExpired(); 100 | // ensure, if timestamp is past expiration time and thus escrow is expired, boolean is updated and price is returned to buyer 101 | // else, isExpired() should be false and escrow's and buyer's balances should be unchanged 102 | if (escrowTest.expirationTime() <= timestamp) { 103 | assertTrue(escrowTest.isExpired()); 104 | assertGt( 105 | _preBalance, 106 | address(escrowTest).balance, 107 | "escrow's balance should have been reduced by 'price'" 108 | ); 109 | assertGt( 110 | escrowTest.buyer().balance, 111 | _preBuyerBalance, 112 | "buyer's balance should have been increased by 'price'" 113 | ); 114 | } else { 115 | assertTrue(!escrowTest.isExpired()); 116 | assertEq( 117 | _preBalance, 118 | address(escrowTest).balance, 119 | "escrow's balance should be unchanged" 120 | ); 121 | assertEq( 122 | escrowTest.buyer().balance, 123 | _preBuyerBalance, 124 | "buyer's balance should be unchanged" 125 | ); 126 | } 127 | } 128 | 129 | function testCloseDeal() external { 130 | // assume 'price' is in escrow, or sellerApproval() will be false (which is captured by this test anyway) 131 | vm.deal(address(escrowTest), escrowTest.price()); 132 | 133 | uint256 _preBalance = address(escrowTest).balance; 134 | uint256 _preBuyerBalance = escrowTest.buyer().balance; 135 | uint256 _preSellerBalance = escrowTest.seller().balance; 136 | bool _approved; 137 | 138 | if (!escrowTest.sellerApproved() || !escrowTest.buyerApproved()) 139 | vm.expectRevert(); 140 | else _approved = true; 141 | 142 | escrowTest.closeDeal(); 143 | 144 | // both approval booleans should have been deleted regardless of whether the escrow expired 145 | assertTrue(!escrowTest.sellerApproved()); 146 | assertTrue(!escrowTest.buyerApproved()); 147 | 148 | // if both seller and buyer approved closing before the closeDeal() call, proceed 149 | if (_approved) { 150 | // if the expiration time has been met or surpassed, check the same things as in 'testCheckIfExpired()' and that both approval booleans were deleted 151 | // else, seller should have received price 152 | if (escrowTest.isExpired()) { 153 | assertGt( 154 | _preBalance, 155 | address(escrowTest).balance, 156 | "escrow's balance should have been reduced by 'price'" 157 | ); 158 | assertGt( 159 | escrowTest.buyer().balance, 160 | _preBuyerBalance, 161 | "buyer's balance should have been increased by 'price'" 162 | ); 163 | } else { 164 | assertGt( 165 | _preBalance, 166 | address(escrowTest).balance, 167 | "escrow's balance should have been reduced by 'price'" 168 | ); 169 | assertGt( 170 | escrowTest.seller().balance, 171 | _preSellerBalance, 172 | "seller's balance should have been increased by 'price'" 173 | ); 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /solidity/tests/OpenOffer.t.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.12; 3 | 4 | /// @notice import Test 5 | import "forge-std/test.sol"; 6 | 7 | /// @dev import OpenOffer.sol 8 | import "src/OpenOffer.sol"; 9 | 10 | /// @title OpenOfferTest 11 | contract TestOpenOffer is Test { 12 | OpenOffer public instance; 13 | 14 | // 'setUp()' does not accept params 15 | string input = "input text"; 16 | 17 | function setUp() public { 18 | instance = new OpenOffer(input); 19 | } 20 | 21 | function testOfferOpen() external { 22 | return assertTrue(instance.offerOpen()); 23 | } 24 | 25 | function testVerifyOfferText() external { 26 | return assertTrue(instance.verifyOfferText(input)); 27 | } 28 | 29 | /// @param _offeree: address accepting the open offer 30 | function testAcceptOffer(address _offeree) external { 31 | assertTrue(instance.offerOpen(), "offer not open"); 32 | // offeree calls 'acceptOffer()' 33 | vm.prank(_offeree); 34 | instance.acceptOffer(); 35 | assertTrue(instance.signedAndOfferAccepted(), "offer not accepted"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /solidity/tests/PayInEth.t.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | /**** 3 | ***** this code and any deployments of this code are strictly provided as-is; no guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the code 4 | ***** or any smart contracts or other software deployed from these files, in accordance with the disclosures and licenses found here: https://github.com/ErichDylus/Open-Source-Law/tree/main/solidity#readme 5 | ***** this code is not audited, and users, developers, or adapters of these files should proceed with caution and use at their own risk. 6 | ****/ 7 | 8 | pragma solidity >=0.8.4; 9 | 10 | import "https://github.com/ErichDylus/Open-Source-Law/blob/main/solidity/PayInEth.sol"; 11 | import { 12 | PRBTest 13 | } from "https://github.com/paulrberg/prb-test/blob/main/src/PRBTest.sol"; 14 | 15 | /// @title Pay In ETH Test 16 | 17 | contract PayInETHTest is PRBTest { 18 | address tester; 19 | PayInETH contracttest; 20 | 21 | function beforeEach() external { 22 | contracttest = new PayInETH(); 23 | tester = msg.sender; 24 | } 25 | 26 | function checkInitialReceiver() external { 27 | return assertEq(receiver, tester, "initial receiver should be tester"); 28 | } 29 | 30 | function checkNewReceiver(address _addr) external { 31 | (bool success, ) = address(contracttest).delegatecall( 32 | abi.encodeWithSignature("changeReceiver(address)", _addr) 33 | ); 34 | require(success, "call failed"); 35 | return assertEq(receiver, _addr, "receiver not changed"); 36 | } 37 | 38 | function checkRouter() external { 39 | return 40 | assertEq( 41 | contracttest.SUSHI_ROUTER_ADDR(), 42 | 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F, 43 | "router address mismatch" 44 | ); 45 | } 46 | 47 | function checkUSDCpath() external { 48 | address[] memory testpath = new address[](2); 49 | testpath[0] = contracttest.WETH_ADDR(); 50 | testpath[1] = contracttest.USDC_TOKEN_ADDR(); 51 | assertEq( 52 | testpath[0], 53 | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, 54 | "path incorrect" 55 | ); 56 | assertEq( 57 | testpath[1], 58 | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 59 | "path incorrect" 60 | ); 61 | } 62 | } 63 | --------------------------------------------------------------------------------