{"id":15673989,"url":"https://github.com/sshine/lira","last_synced_at":"2025-03-30T05:44:38.594Z","repository":{"id":66658567,"uuid":"485094819","full_name":"sshine/lira","owner":"sshine","description":"Lira is a fork of Sword, a financial derivatives smart-contract language for Ethereum","archived":false,"fork":false,"pushed_at":"2022-04-24T18:03:57.000Z","size":11424,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-05T08:09:35.294Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-24T17:32:23.000Z","updated_at":"2022-04-24T17:33:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"be4458f7-4d91-4508-b7b8-b37df0a2349f","html_url":"https://github.com/sshine/lira","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Flira","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Flira/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Flira/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Flira/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshine","download_url":"https://codeload.github.com/sshine/lira/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246281217,"owners_count":20752208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T15:43:20.949Z","updated_at":"2025-03-30T05:44:38.566Z","avatar_url":"https://github.com/sshine.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Haskell](https://img.shields.io/badge/haskell-lts--18.28-blue)\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/sshine/lira/Haskell%20CI)\n![GitHub issues](https://img.shields.io/github/issues/sshine/lira.svg)\n![License](https://img.shields.io/badge/license-MIT-blue.svg)\n\n# The Lira Language\n\nLira is a declarative domain-specific language designed for expressing\nfinancial contracts that can be executed on the blockchain.\n\nLira aims at being simple and easy-to-follow allowing users with a financial\nbackground, but without extensive programming experience to simply define\nhighly complex financial contracts.\n\nLira is based on internationally recognized academic research. The language\nsemantics are formally verified by [Bahr P., Berthold J., Elsman M.\n(2015)][bahr15], and its execution on the Ethereum blockchain is covered by\n[Egelund-Müller B., Elsman M., Henglein F., Ross O. (2017)][muller17]. The\npresent implementation was initiated by Værge, T., Gram, M. (2017) and is\ncredited to various authors; see [package.yaml][pyaml].\n\n[bahr15]: https://bahr.io/pubs/entries/bahr15icfp.html\n[muller17]: https://github.com/etoroxlabs/lira/blob/master/docs/ross.pdf\n[pyaml]: ./package.yaml\n\nThis repository provides a Lira compiler that you can start using today.\nCurrently, it only compiles to EVM but it can be extended with other backends.\n\n## Table of Contents\n\u003c!--ts--\u003e\n  * [The Lira Language](#the-lira-language)\n    * [Try the Lira demo](#try-the-lira-demo---demoliraorg)\n    * [Introduction](#introduction)\n    * [Syntax](#syntax)\n    * [More examples](#more-examples)\n      * [Example 1: Future](#example-1-future)\n      * [Example 2: European put option, an Insurance Against a Drop in the ETH price](#example-2-european-put-option-an-insurance-against-a-drop-in-the-eth-price)\n    * [Application Binary Interface (ABI) of the produced contracts](#application-binary-interface-abi-of-the-produced-contracts)\n    * [Installation](#installation)\n      * [Prerequisites](#prerequisites)\n    * [Future developments](#future-developments)\n\u003c!--te--\u003e\n\n## Try the Lira demo - [demo.lira.org](https://demo.lira.org)\n\nTo demonstrate one possible integration of the language, we provide a graphical\nfront-end use-case for creating, deploying and monitoring future contracts.\nBehind the scenes, this front-end will generate corresponding Lira code which\nis subsequently compiled to EVM and deployed to Ethereum. By generating Lira\ncode, we ensure that the static guarantees of the language apply regardless of\nfront-end functionality. Additionally, the front-end makes it possible to view\nboth the generated Lira code and the compiled EVM bytecode.\n\nUsing a domain-specific language that isn't Turing-complete has several\nadvantages. In particular, expressing unintended within the contract logic\nis not possible. Further, as the semantics of the language are formally\nverified, contracts specified in the language are guaranteed to behave as\nintended and to only have a single interpretation.\n\n## Introduction\n\nLet's begin with some examples.\n\nTo transfer one unit of a tokenized asset, e.g. [`USDEX`][usdex], from Alice to Bob:\n\n```\ntransfer(USDEX, Alice, Bob)\n```\n\n[usdex]: https://www.etorox.com/exchange/us-dollar/\n\nTo transfer some other amount of an asset, a contract can be scaled:\n\n```\nscale(10, 10, transfer(USDEX, Alice, Bob))\n```\n\nThe first 10 is a constant that denotes the maximum amount of tokens that will\nbe locked in escrow before the contract is executed. The second 10 is an\nexpression calculated at run-time execution and represents the actual amount\nof tokens to transfer.\n\nThe expression can be variable at run-time by depending on *observables*, but\nit cannot exceed the maximum value known at compile-time.\n\nThis example can be extended with an observable:\n\n```\nscale(\n  9000,\n  obs(int, PriceFeed, BTCUSDEX),\n  transfer(USDEX, Alice, Bob))\n```\n\nHere a quantity of `USDEX` tokens is transferred from Alice to Bob that depends\non an external price feed, `PriceFeed`, and a `BTCUSDEX` key presumed to show\nthe price of Bitcoin, but at most 9000. If the price, upon execution, is less,\nthe remainder will be sent back to Alice, and if the price is more, only 9000\n`USDEX` is sent to Bob.\n\nTo perform two transfers in one contract:\n\n```\nboth(\n  scale(9000, obs(int, PriceFeed, BTCUSDEX), transfer(USDEX, Alice, Bob)),\n  transfer(WBTC, Bob, Alice))\n```\n\nHere, upon execution, Alice sends Bob a quantity of `USDEX` that corresponds to\nthe price of one Bitcoin, but at most USD 9000, and Bob sends Alice one `WBTC`,\nan ERC-20 wrapped Bitcoin.\n\nA contract can be executed at some relative time offset in the future:\n\n```\ntranslate(\n  days(30),\n  transfer(WBTC, Bob, Alice))\n```\n\nThis is relative to the time of contract activation.\n\nLastly, a contract can be conditional based on a predicate and a time frame.\nThe predicate may contain observables, and the time frame is also relative\nto the time of contract activation. For example:\n\n```\nscale(10, 10,\n  if obs(int, PriceFeed, BTCUSDEX) \u003e 9000 within days(7)\n    then transfer(USDEX, Alice, Bob)\n    else transfer(USDEX, Bob, Alice))\n```\n\nHere Alice and Bob each bet 10 `USDEX` on whether the price of Bitcoin will go\nabove 9000 USD within 7 days of contract activation. A one-sided variation of\nthis bet that isn't active immediately after contract activation is shown here:\n\n```\ntranslate(\n  days(7),\n  if obs(int, PriceFeed, BTCUSDEX) \u003e 9000 within days(7)\n    then scale(10, 10, transfer(USDEX, Alice, Bob))\n    else zero)\n```\n\nThe price feed isn't checked until 7 days have passed, but at that point, upon\nexecuting the contract, it will evaluate whether Alice should send Bob 10 `USDEX`\nor not for an entire week, or until the condition is true. If not, the escrow\nwill be transferred back to Alice.\n\n## Syntax\n\nBelow is a full description of Lira's syntax.\n\n```\ncontract ::=\n    'transfer(' asset ',' party ',' party ')'\n  | 'scale(' max ',' expr ',' contract ')'\n  | 'both(' contract ',' contract ')'\n  | 'translate(' time ',' contract ')'\n  | 'if' expr 'within' time 'then' contract 'else' contract\n  | 'zero'\n\nexpr ::=\n    'true'\n  | 'false'\n  | expr binop expr\n  | unop expr\n  | 'obs(' obsType ',' obsAddress ',' obsKey ')'\n  | ['0'-'9']+\n\ntime ::= 'now' | ['0'-'9']+ timeUnit\n\ntimeUnit ::= 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks'\n\nbinop ::= '+' | '-' | 'x' | '/' | '=' | 'or' | 'and' | 'min' | 'max'\n\nunop ::= 'not'\n\nobsType ::= 'int' | 'bool'\n\nobsAddress ::= address\n\nparty ::= address\n\naddress ::= '0x' ['0'-'9', 'a'-'f']{40}\n```\n\n## More examples\n\n### Example 1: Future\n\nOne of the simpler useful examples is a future contract.  The code below\ndescribes the contract, namely a legal agreement to buy or sell something at a\npredetermined price at a specified time in the future, between two parties not\nknowing each other. The contract holds a specific amount of tokens which both\nparties will receive in full amount at the maturity of the contract. The\nfunction `both\u003cc1,c2\u003e` is executing both contracts `c1` and `c2`, in this case\ntransferring the specified currencies and the specified amount to each of the\nparties.\n\n```\ntranslate(\n    seconds(\u003cTime\u003e),\n    both(\n        scale(\n            \u003cUpper limit\u003e,\n            \u003cAmount\u003e,\n            transfer(\n                \u003cCurrency\u003e,\n                \u003cme\u003e,\n                \u003cCounterparty\u003e\n            )\n        ),\n        scale(\n            \u003cUpper limit\u003e,\n            \u003cAmount to receive\u003e,\n            transfer(\n                \u003cCurrency to receive\u003e,\n                \u003cCounterparty\u003e,\n                \u003cme\u003e\n            )\n        )\n    )\n)\n```\n\n### Example 2: European put option, an Insurance Against a Drop in the ETH price\n\nScenario: Alice owns 1 wrapped ETH and would like insurance of a drop in the\nETH price below 100 USD three months from now. So Alice wants a contract whose\nvalue plus the value of ether is at least 100 USD. This can be achieved by the\nfollowing contract:\n\n```\ntranslate(\n  days(90),\n  scale(\n    100,\n    max(0, 100 - obs(int, PriceFeed, ETHUSDEX)),\n    transfer(USDEX, Bob, Alice)))\n```\n\nIf the ETH price at the strike time is 10 USD, then this contract will pay out\n90 USDEX, thus guaranteeing Alice a value of 100 USD at the maturity of the\ncontract.\n\nThe first parameter to `scale()` (the token amount to lock in escrow) is\nimportant when the second parameter (the token amount) depends on the external\nprice feed.  Without the tokens in escrow we would have no guarantee that the\ncounterparty has the asset at execution time.\n\n## Application Binary Interface (ABI) of the produced contracts\n\nThe Lira contract currently compiles into the Ethereum's ABI and has two\nmethods: `activate()` and `execute()`.\n\n * `activate()` collects the margin from the parties' accounts and starts the\n   timer. Will only succeed if the parties have allowed the Lira contract to\n   withdraw from their balance through the ERC-20 contract call `approve`.\n * `execute()` checks whether any subparts of the contracts are ready to be\n   paid out to the parties or any margins can be paid back.\n\n `activate()` and `execute()` may change the state of the deployed contract.\n\n## Installation\n\nAt the moment the only way to compile Lira contracts is to build the compiler manually.\n1. Build the compiler by running\n```\n$ stack install\n```\n2. You can now compile one of the examples by executing the following\n```\n$ mkdir build\n$ lira -o build examples/BettingExample0.lir\n```\nRemember to change the placement addresses in the examples with real ones.\n\n### Prerequisites\n\nHaskell Tool Stack is required as the development environment.\nTo install follow their [README](https://docs.haskellstack.org/en/stable/README/)\nor execute the following statement:\n```\n$ curl -sSL https://get.haskellstack.org/ | sh\n```\n\n## Future developments\n\nLira is still a work in progress and could greatly benefit from help from the\ncommunity.  The following points shows what we envision for Lira in the future.\n\n* Work with the community to get a security audit of the compiler\n* Enable fractional margin requirements into the contract language.\n  Currently, the contracts need to be fully collateralized.\n* Improve tooling by providing libraries that helps with easier startup\n* Seek funding for further research to extend the functionality of the language\n* Improve compiler documentation, both from the user's perspective and the developer's\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshine%2Flira","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshine%2Flira","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshine%2Flira/lists"}