From 296fb18d28d0f733b61d6beea7a05461f9ab794a Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 23 Jun 2025 14:07:44 +0800 Subject: [PATCH 01/24] added: spec --- .../aiken-crowdfund/README.md | 1 + .../aiken-crowdfund/aiken.lock | 26 +++++ .../aiken-crowdfund/aiken.toml | 23 ++++ .../aiken-crowdfund/plutus.json | 101 ++++++++++++++++++ .../aiken-crowdfund/specs/1_auth_token.md | 15 +++ .../aiken-crowdfund/specs/2_shares.md | 15 +++ .../aiken-crowdfund/specs/3_crowdfund.md | 50 +++++++++ .../aiken-crowdfund/specs/_scripts.md | 24 +++++ .../aiken-crowdfund/validators/placeholder.ak | 41 +++++++ .../workflows/continuous-integration.yml | 18 ++++ .../gov-crowdfund/.gitignore | 6 ++ .../gov-crowdfund/README.md | 1 + .../gov-crowdfund/aiken.toml | 18 ++++ .../gov-crowdfund/specs/1_spend.md | 69 ++++++++++++ .../gov-crowdfund/specs/2_stake.md | 15 +++ .../gov-crowdfund/specs/3_start.md | 25 +++++ .../gov-crowdfund/specs/_scripts.md | 24 +++++ .../gov-crowdfund/validators/placeholder.ak | 41 +++++++ 18 files changed, 513 insertions(+) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/README.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.lock create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.toml create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/1_auth_token.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/2_shares.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.github/workflows/continuous-integration.yml create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.gitignore create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/README.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/README.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/README.md new file mode 100644 index 000000000..e76d22490 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/README.md @@ -0,0 +1 @@ +Implement in core mesh repo `mesh-contract` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.lock b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.lock new file mode 100644 index 000000000..2e65bd164 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.lock @@ -0,0 +1,26 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +source = "github" + +[[requirements]] +name = "sidan-lab/vodka" +version = "0.1.13" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +requirements = [] +source = "github" + +[[packages]] +name = "sidan-lab/vodka" +version = "0.1.13" +requirements = [] +source = "github" + +[etags] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.toml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.toml new file mode 100644 index 000000000..62cb1af77 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.toml @@ -0,0 +1,23 @@ +name = "sidan-lab/crowdfund" +version = "0.0.0" +compiler = "v1.1.16" +plutus = "v3" +license = "Apache-2.0" +description = "Aiken contracts for project 'sidan-lab/crowdfund'" + +[repository] +user = "sidan-lab" +project = "crowdfund" +platform = "github" + +[[dependencies]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +source = "github" + +[[dependencies]] +name = "sidan-lab/vodka" +version = "0.1.13" +source = "github" + +[config] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json new file mode 100644 index 000000000..67ed61785 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json @@ -0,0 +1,101 @@ +{ + "preamble": { + "title": "sidan-lab/crowdfund", + "description": "Aiken contracts for project 'sidan-lab/crowdfund'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.16+23061c0" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "placeholder.placeholder.mint", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + }, + { + "title": "placeholder.placeholder.spend", + "datum": { + "title": "_datum", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + }, + { + "title": "placeholder.placeholder.withdraw", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + }, + { + "title": "placeholder.placeholder.publish", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + }, + { + "title": "placeholder.placeholder.vote", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + }, + { + "title": "placeholder.placeholder.propose", + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + }, + { + "title": "placeholder.placeholder.else", + "redeemer": { + "schema": {} + }, + "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", + "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + } + ], + "definitions": { + "Data": { + "title": "Data", + "description": "Any Plutus data." + } + } +} \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/1_auth_token.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/1_auth_token.md new file mode 100644 index 000000000..86a689cd0 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/1_auth_token.md @@ -0,0 +1,15 @@ +# Auth Token - One Shot + +## Parameter + +- `utxo_ref`: UTxO to be spent at minting + +## User Action + +1. Mint - Redeemer `RMint` + + - Transaction hash as parameterized is included in input + +2. Burn - Redeemer `RBurn` + + - The current policy id only has negative minting value in transaction body. diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/2_shares.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/2_shares.md new file mode 100644 index 000000000..4492912d7 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/2_shares.md @@ -0,0 +1,15 @@ +# Share Token + +## Parameter + +- `auth_token`: The policy id of `AuthToken` + +## User Action + +1. Mint - Redeemer `RMint` + + - There is input with `auth_token` with redeemer `ContributeFund` + +2. Burn - Redeemer `RBurn` + + - The current policy id only has negative minting value in transaction body. diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md new file mode 100644 index 000000000..df78c76fe --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md @@ -0,0 +1,50 @@ +# Specification - Crowdfund + +## Parameter + +- `auth_token`: The policy id of `AuthToken` + +## Datum + +- `completion_script`: ByteArray +- `share_token`: ByteArray +- `crowdfund_address`: Address +- `fundraise_target`: Int +- `current_fundraised_amount`: Int +- `allow_over_subscription`: Bool +- `deadline`: Int +- `expiry_buffer`: Int +- `fee_address`: Address +- `min_charge`: Int + +## User Action + +1. ContributeFund + + - There is only 1 input with `auth_token` from current address, and 1 output with `auth_token` and to current_address + - Not allowed other token deposit in output. Min contribution 2 ADA + - The value increase in current respending utxo equal to the increase in `current_fundraised_amount`, comparing input output datum + - If `allow_over_scription` is False, check whether `current_fundraised_amount` <= `fundraise_target` + - `deadline` is not passed + - `Shares` - Minted exactly the amount of `share_token` that lovelave contributed, with token name of `completion_script` + +2. CompleteCrowdfund + + - Any value in the current utxos - (`current_fundraised_amount` + `min_charge`) goes to `fee_address` + - `current_fundraised_amount` >= `fundraise_target` + - `completion_script` withdrawal script is exeuted + - `auth_token` from current input is burnt + +3. ContributorWithdrawal + + - Either one of below conditions + - `deadline` + `expiry_buffer` is passed + - `current_fundraised_amount` <= `fundraise_target` + - There is only 1 input with `auth_token` from current address, and 1 output with `auth_token` and to current_address + - The lovelace unlocking from `crowdfund_address` equal exactly the amount that the `share_token` with token name of `completion_script` is burnt + +4. RemoveEmptyInstance + + - `deadline` is passed + - share token with token name `completion_script` burning in current tx == `current_fundraised_amount` + - `auth_token` from current input is burnt diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md new file mode 100644 index 000000000..21e4621a5 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md @@ -0,0 +1,24 @@ +# Aiken Crowdfunding + +## 1. Auth Token + +The token that represent distinct crowdfunding campaign, attaching with distinct `completion_script` + +## 2. Shares + +The token that represents lovelace contributed to current crowdfunding campaign + +## 3. Crowdfund + +The validator that handles the crowdfunding campaign + +## Param dependency tree + +1. First layer + + - `auth_token` - no param + +2. Second layer + + - `shares` - param `auth_token` + - `crowdfund` - param `auth_token` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak new file mode 100644 index 000000000..bbf9d47d4 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak @@ -0,0 +1,41 @@ +use cardano/address.{Credential} +use cardano/assets.{PolicyId} +use cardano/certificate.{Certificate} +use cardano/governance.{ProposalProcedure, Voter} +use cardano/transaction.{Transaction, OutputReference} + +validator placeholder { + mint(_redeemer: Data, _policy_id: PolicyId, _self: Transaction) { + todo @"mint logic goes here" + } + + spend(_datum: Option, _redeemer: Data, _utxo: OutputReference, _self: Transaction) { + todo @"spend logic goes here" + } + + withdraw(_redeemer: Data, _account: Credential, _self: Transaction) { + todo @"withdraw logic goes here" + } + + publish(_redeemer: Data, _certificate: Certificate, _self: Transaction) { + todo @"publish logic goes here" + } + + vote(_redeemer: Data, _voter: Voter, _self: Transaction) { + todo @"vote logic goes here" + } + + propose(_redeemer: Data, _proposal: ProposalProcedure, _self: Transaction) { + todo @"propose logic goes here" + } + + // // If needs be, remove any of unneeded handlers above, and use: + // + // else(_ctx: ScriptContext) { + // todo @"fallback logic if none of the other purposes match" + // } + // + // // You will also need an additional import: + // // + // // use cardano/script_context.{ScriptContext} +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.github/workflows/continuous-integration.yml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.github/workflows/continuous-integration.yml new file mode 100644 index 000000000..ba419b4a2 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.github/workflows/continuous-integration.yml @@ -0,0 +1,18 @@ +name: Continuous Integration + +on: + push: + branches: ["main"] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: aiken-lang/setup-aiken@v1 + with: + version: v1.1.16 + - run: aiken fmt --check + - run: aiken check -D + - run: aiken build diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.gitignore b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.gitignore new file mode 100644 index 000000000..ff7811b15 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.gitignore @@ -0,0 +1,6 @@ +# Aiken compilation artifacts +artifacts/ +# Aiken's project working directory +build/ +# Aiken's default documentation export +docs/ diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/README.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/README.md new file mode 100644 index 000000000..de5ef005b --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/README.md @@ -0,0 +1 @@ +Implement separately & publish SDK diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml new file mode 100644 index 000000000..fba837145 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml @@ -0,0 +1,18 @@ +name = "sidan-lab/gov-crowdfund" +version = "0.0.0" +compiler = "v1.1.16" +plutus = "v3" +license = "Apache-2.0" +description = "Aiken contracts for project 'sidan-lab/gov-crowdfund'" + +[repository] +user = "sidan-lab" +project = "gov-crowdfund" +platform = "github" + +[[dependencies]] +name = "aiken-lang/stdlib" +version = "1.5.0" +source = "github" + +[config] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md new file mode 100644 index 000000000..e403685c1 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md @@ -0,0 +1,69 @@ +# Specification - Spend + +## Parameter + +- `delegate_pool_id`: ByteArray +- `gov_action`: GovernanceAction +- `proposer_key_hash`: ByteArray + +## Datum + +```rs +pub type Datum { + Init { + completion_script: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } + Proposed { + completion_script: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } + Refundable { + completion_script: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } +} +``` + +## User Action + +1. RegisterCerts + + - Only one input and output from current address + - Input datum in state of `Init` + - Output datum in state of `Proposed` + - fields exactly the same + - Registering stake cert + - Registering DRep cert + - Delegate to current own DRep + stake pool `delegate_pool_id` + - Propose gov action + - Vote on same proposal? -> if cant, create one more separate state + +2. DeregisterCerts + + - deadline is passed + - Only one input and output from current address + - Input datum in state of `Proposed` + - Output datum in state of `Refundable` + - fields exactly the same + - Deregistering both certs + - Refunds go into the output + +3. ContributorWithdrawal + + - Input datum in state of Refundable + - `deadline` is passed + - The lovelace unlocking from current equal exactly the amount that the `share_token` with token name of `completion_script` is burnt + +4. RemoveEmptyInstance + + - Input datum in state of Refundable + - `deadline` is passed + - share token with token name `completion_script` burning in current tx == `current_fundraised_amount` + - signed by `proposer_key_hash` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md new file mode 100644 index 000000000..a6b11130c --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md @@ -0,0 +1,15 @@ +# Specification - Stake + +## Parameter + +- `spend_script_hash`: The script hash of the spending part + +## User Action + +1. Register + + - Only 1 input from `spend_script_hash` with redeemer of `RegisterCerts` + +2. Deregister + + - Only 1 input from `spend_script_hash` with redeemer of `DeregisterCerts` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md new file mode 100644 index 000000000..b07a65114 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md @@ -0,0 +1,25 @@ +# Specification - Start + +## Parameter + +- `auth_token`: The policy ID of crowdfunding token +- `spend`: The script hash of the spending part of the gov system +- `stake`: The script hash of the staking part of the gov system +- `gov_action_period`: The buffer since crowdfund deadline to complete entire gov process + +## User Action + +1. Validate completion of crowdfunding + + - Only one input with `auth_token`, with inline datum + `completion_script` same as current crendential hash + - All `fundraise_target` amount of ADA is sent to address composed of `spend` and `stake` (both script hash) + - With datum: + + ```rs + Init { + completion_script: , + share_token: , + funds_controlled: , + deadline: , + } + ``` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md new file mode 100644 index 000000000..cb2f26cb4 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md @@ -0,0 +1,24 @@ +# Aiken Gov Crowdfunding + +## 1. Spend + +The spending validator that guarding the crowdfunded + +## 2. Stake + +The token that represents lovelace contributed to current crowdfunding campaign + +## 3. Start + +The withdrawal script that oversight the completion of crowdfunding (i.e. `completion_script` at crowdfunding script) + +## Param dependency tree + +1. First layer + + - `spend` - no param + - `stake` - no param + +2. Second layer + + - `start` - param `spend` and `stake` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak new file mode 100644 index 000000000..bbf9d47d4 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak @@ -0,0 +1,41 @@ +use cardano/address.{Credential} +use cardano/assets.{PolicyId} +use cardano/certificate.{Certificate} +use cardano/governance.{ProposalProcedure, Voter} +use cardano/transaction.{Transaction, OutputReference} + +validator placeholder { + mint(_redeemer: Data, _policy_id: PolicyId, _self: Transaction) { + todo @"mint logic goes here" + } + + spend(_datum: Option, _redeemer: Data, _utxo: OutputReference, _self: Transaction) { + todo @"spend logic goes here" + } + + withdraw(_redeemer: Data, _account: Credential, _self: Transaction) { + todo @"withdraw logic goes here" + } + + publish(_redeemer: Data, _certificate: Certificate, _self: Transaction) { + todo @"publish logic goes here" + } + + vote(_redeemer: Data, _voter: Voter, _self: Transaction) { + todo @"vote logic goes here" + } + + propose(_redeemer: Data, _proposal: ProposalProcedure, _self: Transaction) { + todo @"propose logic goes here" + } + + // // If needs be, remove any of unneeded handlers above, and use: + // + // else(_ctx: ScriptContext) { + // todo @"fallback logic if none of the other purposes match" + // } + // + // // You will also need an additional import: + // // + // // use cardano/script_context.{ScriptContext} +} From 1b68060faec375d6b0729aafa78b7a6bfc96c894 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 23 Jun 2025 14:38:17 +0800 Subject: [PATCH 02/24] added: auth token --- .../aiken-crowdfund/lib/types.ak | 4 ++ .../aiken-crowdfund/specs/_scripts.md | 2 +- .../validators/auth_token/mint.ak | 27 ++++++++ .../aiken-crowdfund/validators/placeholder.ak | 41 ------------ .../validators/tests/auth_token/mint.ak | 63 +++++++++++++++++++ .../aiken-crowdfund/validators/tests/utils.ak | 3 + 6 files changed, 98 insertions(+), 42 deletions(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/auth_token/mint.ak delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak new file mode 100644 index 000000000..a23a4479f --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak @@ -0,0 +1,4 @@ +pub type MintPolarity { + RMint + RBurn +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md index 21e4621a5..72da5bb9a 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md @@ -16,7 +16,7 @@ The validator that handles the crowdfunding campaign 1. First layer - - `auth_token` - no param + - `auth_token` - `utxo_ref` 2. Second layer diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/auth_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/auth_token/mint.ak new file mode 100644 index 000000000..57706664d --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/auth_token/mint.ak @@ -0,0 +1,27 @@ +use aiken/collection/dict +use aiken/collection/list +use cardano/assets.{PolicyId} +use cardano/transaction.{OutputReference, Transaction} +use types.{MintPolarity, RBurn, RMint} + +validator auth_token(utxo_ref: OutputReference) { + mint(redeemer: MintPolarity, policy_id: PolicyId, self: Transaction) { + expect [Pair(_asset_name, quantity)] = + self.mint + |> assets.tokens(policy_id) + |> dict.to_pairs() + let Transaction { inputs, .. } = self + when redeemer is { + RMint -> { + let is_output_consumed = + list.any(inputs, fn(input) { input.output_reference == utxo_ref }) + is_output_consumed? && quantity == 1 + } + RBurn -> quantity == -1 + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak deleted file mode 100644 index bbf9d47d4..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/placeholder.ak +++ /dev/null @@ -1,41 +0,0 @@ -use cardano/address.{Credential} -use cardano/assets.{PolicyId} -use cardano/certificate.{Certificate} -use cardano/governance.{ProposalProcedure, Voter} -use cardano/transaction.{Transaction, OutputReference} - -validator placeholder { - mint(_redeemer: Data, _policy_id: PolicyId, _self: Transaction) { - todo @"mint logic goes here" - } - - spend(_datum: Option, _redeemer: Data, _utxo: OutputReference, _self: Transaction) { - todo @"spend logic goes here" - } - - withdraw(_redeemer: Data, _account: Credential, _self: Transaction) { - todo @"withdraw logic goes here" - } - - publish(_redeemer: Data, _certificate: Certificate, _self: Transaction) { - todo @"publish logic goes here" - } - - vote(_redeemer: Data, _voter: Voter, _self: Transaction) { - todo @"vote logic goes here" - } - - propose(_redeemer: Data, _proposal: ProposalProcedure, _self: Transaction) { - todo @"propose logic goes here" - } - - // // If needs be, remove any of unneeded handlers above, and use: - // - // else(_ctx: ScriptContext) { - // todo @"fallback logic if none of the other purposes match" - // } - // - // // You will also need an additional import: - // // - // // use cardano/script_context.{ScriptContext} -} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak new file mode 100644 index 000000000..47de07ed7 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak @@ -0,0 +1,63 @@ +use auth_token/mint as auth_token_mint +use cardano/assets.{add, from_asset, zero} +use cardano/transaction.{Transaction, placeholder} +use mocktail.{ + complete, mint, mock_policy_id, mock_pub_key_address, mock_tx_hash, + mock_utxo_ref, mocktail_tx, tx_in, +} +use tests/utils.{mock_auth_token} +use types.{RBurn, RMint} + +test s0_mint_success_mint() { + let redeemer = RMint + let input_utxo = mock_utxo_ref(0, 1) + let policy_id = mock_auth_token + + let tx = + mocktail_tx() + |> mint(True, 1, policy_id, "") + |> tx_in(True, mock_tx_hash(0), 1, zero, mock_pub_key_address(0, None)) + |> complete() + + auth_token_mint.auth_token.mint(input_utxo, redeemer, policy_id, tx) +} + +test s0_mint_fail_mint_no_utxo_ref_supply() { + let redeemer = RMint + let policy_id = mock_auth_token + + let tx = + mocktail_tx() + |> mint(True, 1, policy_id, "") + |> tx_in(True, mock_tx_hash(0), 1, zero, mock_pub_key_address(0, None)) + |> complete() + !auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) +} + +test s0_mint_success_burn() { + let redeemer = RBurn + let policy_id = mock_auth_token + + let tx = Transaction { ..placeholder, mint: from_asset(policy_id, "", -1) } + auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) +} + +test s0_mint_success_burn_with_other_minting() { + let redeemer = RBurn + let policy_id = mock_auth_token + + let tx = + Transaction { + ..placeholder, + mint: from_asset(policy_id, "", -1) |> add(mock_policy_id(999), "", 1), + } + auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) +} + +test s0_mint_fail_burn_with_mint() { + let redeemer = RBurn + let policy_id = mock_auth_token + + let tx = Transaction { ..placeholder, mint: from_asset(policy_id, "", 1) } + !auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak new file mode 100644 index 000000000..c81269154 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak @@ -0,0 +1,3 @@ +use mocktail.{mock_policy_id} + +pub const mock_auth_token = mock_policy_id(0) From e2ca937023aaf00905d4ab701d3fa8f332fe5826 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 23 Jun 2025 16:08:41 +0800 Subject: [PATCH 03/24] added: share token --- .../aiken-crowdfund/lib/types.ak | 7 ++ .../aiken-crowdfund/lib/utils.ak | 10 ++ .../validators/share_token/mint.ak | 35 +++++++ .../validators/tests/share_token/mint.ak | 93 +++++++++++++++++++ .../aiken-crowdfund/validators/tests/utils.ak | 13 ++- 5 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/share_token/mint.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak index a23a4479f..a2bb650b8 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak @@ -2,3 +2,10 @@ pub type MintPolarity { RMint RBurn } + +pub type CrowdfundRedeemer { + ContributeFund + CompleteCrowdfund + ContributorWithdrawal + RemoveEmptyInstance +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak new file mode 100644 index 000000000..ab263997e --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak @@ -0,0 +1,10 @@ +use aiken/collection/pairs +use cardano/transaction.{Input, Redeemer, ScriptPurpose, Spend} + +pub fn redeemer_with_input( + redeemers: Pairs, + input: Input, +) -> Option { + let output_reference = input.output_reference + redeemers |> pairs.get_first(Spend(output_reference)) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/share_token/mint.ak new file mode 100644 index 000000000..01bad7385 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/share_token/mint.ak @@ -0,0 +1,35 @@ +use aiken/collection/dict +use cardano/assets.{PolicyId} +use cardano/transaction.{Transaction} +use cocktail.{inputs_with_policy} +use types.{ContributeFund, CrowdfundRedeemer, MintPolarity, RBurn, RMint} +use utils.{redeemer_with_input} + +validator share_token(auth_token: PolicyId) { + mint(redeemer: MintPolarity, policy_id: PolicyId, self: Transaction) { + expect [Pair(_asset_name, quantity)] = + self.mint + |> assets.tokens(policy_id) + |> dict.to_pairs() + let Transaction { inputs, redeemers, .. } = self + when redeemer is { + RMint -> { + expect [auth_token_input] = inputs_with_policy(inputs, auth_token) + + expect Some(auth_token_redeemer_data) = + redeemer_with_input(redeemers, auth_token_input) + + expect auth_token_redeemer: CrowdfundRedeemer = auth_token_redeemer_data + + let redeemer_check = auth_token_redeemer == ContributeFund + + redeemer_check? + } + RBurn -> quantity == -1 + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak new file mode 100644 index 000000000..e623afb0a --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak @@ -0,0 +1,93 @@ +use cardano/assets.{add, from_asset, from_lovelace} +use cardano/transaction.{OutputReference, Spend, Transaction, placeholder} +use mocktail.{ + add_redeemer, complete, mint, mock_policy_id, mock_tx_hash, mocktail_tx, tx_in, +} +use share_token/mint as share_token_mint +use tests/utils.{ + mock_auth_token, mock_completion_script, mock_crowdfund_address, + mock_share_token, +} +use types.{ContributeFund, RBurn, RMint} + +test s1_mint_success_mint() { + let redeemer = RMint + let auth_input = + from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) + + let policy_id = mock_share_token + + let auth_token_redeemer: Data = ContributeFund + let tx = + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) + |> mint(True, 1, policy_id, mock_completion_script) + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { + transaction_id: mock_tx_hash(0), + output_index: 0, + }, + ), + auth_token_redeemer, + ), + ) + + share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) +} + +test s1_mint_fail_mint_no_auth_token_input() fail { + let redeemer = RMint + let policy_id = mock_share_token + + let tx = + mocktail_tx() + |> mint(True, 1, policy_id, mock_completion_script) + |> complete() + share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) +} + +test s1_mint_fail_mint_no_auth_token_redeemer() fail { + let redeemer = RMint + let auth_input = + from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) + let policy_id = mock_share_token + + let tx = + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) + |> mint(True, 1, policy_id, mock_completion_script) + |> complete() + share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) +} + +test s1_mint_success_burn() { + let redeemer = RBurn + let policy_id = mock_share_token + + let tx = Transaction { ..placeholder, mint: from_asset(policy_id, "", -1) } + share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) +} + +test s1_mint_success_burn_with_other_minting() { + let redeemer = RBurn + let policy_id = mock_share_token + + let tx = + Transaction { + ..placeholder, + mint: from_asset(policy_id, "", -1) |> add(mock_policy_id(999), "", 1), + } + share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) +} + +test s1_mint_fail_burn_with_mint() { + let redeemer = RBurn + let policy_id = mock_share_token + + let tx = Transaction { ..placeholder, mint: from_asset(policy_id, "", 1) } + !share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak index c81269154..2ed469108 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak @@ -1,3 +1,14 @@ -use mocktail.{mock_policy_id} +use cardano/address.{from_script} +use mocktail.{mock_policy_id, mock_script_hash, mock_script_stake_key_hash} pub const mock_auth_token = mock_policy_id(0) + +pub const mock_share_token = mock_policy_id(1) + +pub const mock_completion_script = mock_script_hash(0) + +pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) + +pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) + +pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) From 181e218aeca656066a10127b5bd0c91547835d5c Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 23 Jun 2025 18:21:10 +0800 Subject: [PATCH 04/24] added: crowdfund script todo: crowdfund test case added : crowdfund test --- .../aiken-crowdfund/lib/types.ak | 15 + .../aiken-crowdfund/lib/utils.ak | 31 +- .../validators/crowdfund/spend.ak | 182 +++ .../validators/tests/crowdfund/spend.ak | 1139 +++++++++++++++++ .../aiken-crowdfund/validators/tests/utils.ak | 45 + 5 files changed, 1411 insertions(+), 1 deletion(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak index a2bb650b8..0232fc7aa 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak @@ -1,3 +1,5 @@ +use cardano/address.{Address} + pub type MintPolarity { RMint RBurn @@ -9,3 +11,16 @@ pub type CrowdfundRedeemer { ContributorWithdrawal RemoveEmptyInstance } + +pub type CrowdfundDatum { + completion_script: ByteArray, + share_token: ByteArray, + crowdfund_address: Address, + fundraise_target: Int, + current_fundraised_amount: Int, + allow_over_subscription: Bool, + deadline: Int, + expiry_buffer: Int, + fee_address: Address, + min_charge: Int, +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak index ab263997e..9216d4927 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak @@ -1,5 +1,8 @@ +use aiken/collection/list use aiken/collection/pairs -use cardano/transaction.{Input, Redeemer, ScriptPurpose, Spend} +use cardano/address.{Address} +use cardano/assets.{Value} +use cardano/transaction.{Input, Output, Redeemer, ScriptPurpose, Spend} pub fn redeemer_with_input( redeemers: Pairs, @@ -8,3 +11,29 @@ pub fn redeemer_with_input( let output_reference = input.output_reference redeemers |> pairs.get_first(Spend(output_reference)) } + +pub fn check_fundraise_target( + allow_over_subscription: Bool, + fundraise_target: Int, + current_fundraised_amount: Int, +) -> Bool { + if allow_over_subscription { + True + } else { + current_fundraised_amount <= fundraise_target + } +} + +pub fn output_at_with_value( + outputs: List, + address: Address, + value: Value, +) -> List { + list.filter( + outputs, + fn(output) { + let are_values_equal = output.value == value + are_values_equal && output.address == address + }, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak new file mode 100644 index 000000000..827b8cf86 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak @@ -0,0 +1,182 @@ +use aiken/collection/list.{delete} +use aiken/collection/pairs.{has_key} +use cardano/address.{Credential, Script} +use cardano/assets.{ + PolicyId, from_lovelace, lovelace_of, merge, policies, restricted_to, +} +use cardano/transaction.{OutputReference, Transaction, find_input} +use cocktail.{ + inputs_at_with_policy, only_minted_token, output_inline_datum, + outputs_at_with_policy, policy_only_minted_token, valid_after, valid_before, + value_length, +} +use types.{ + CompleteCrowdfund, ContributeFund, ContributorWithdrawal, CrowdfundDatum, + CrowdfundRedeemer, RemoveEmptyInstance, +} +use utils.{check_fundraise_target, output_at_with_value} + +validator crowdfund(auth_token: PolicyId) { + spend( + datum_opt: Option, + redeemer: CrowdfundRedeemer, + input: OutputReference, + self: Transaction, + ) { + let Transaction { inputs, validity_range, mint, outputs, withdrawals, .. } = + self + + expect Some(own_input) = find_input(inputs, input) + expect Some(auth_input_datum) = datum_opt + + let current_address = own_input.output.address + + // check only 1 auth toke input from current address + expect [auth_input] = + inputs_at_with_policy(inputs, current_address, auth_token) + + let CrowdfundDatum { + current_fundraised_amount, + fundraise_target, + allow_over_subscription, + deadline, + completion_script, + share_token, + min_charge, + fee_address, + expiry_buffer, + .. + } = auth_input_datum + when redeemer is { + ContributeFund -> { + expect [auth_output] = + outputs_at_with_policy(outputs, current_address, auth_token) + + let lovelace_from_auth_input = auth_input.output.value |> lovelace_of() + let lovelace_from_auth_output = auth_output.value |> lovelace_of() + expect auth_output_datum: CrowdfundDatum = + output_inline_datum(auth_output) + + let fundraise_added = + lovelace_from_auth_output - lovelace_from_auth_input + let fundraise_check = + (fundraise_added == auth_output_datum.current_fundraised_amount - current_fundraised_amount)? && (fundraise_added >= 2000000)? + + let fundraise_target_check = + check_fundraise_target( + allow_over_subscription, + fundraise_target, + auth_output_datum.current_fundraised_amount, + ) + + let validity_check = valid_before(validity_range, deadline) + + let output_datum_check = + auth_output_datum == CrowdfundDatum { + ..auth_input_datum, + current_fundraised_amount: current_fundraised_amount + fundraise_added, + } + + let is_auth_output_value_clean = value_length(auth_output.value) == 2 + fundraise_check? && fundraise_target_check? && validity_check? && output_datum_check? && is_auth_output_value_clean? && only_minted_token( + mint, + share_token, + completion_script, + fundraise_added, + )? + } + + CompleteCrowdfund -> { + let fee_value = + from_lovelace( + lovelace_of(auth_input.output.value) - current_fundraised_amount - min_charge, + ) + + let other_policy = + policies(auth_input.output.value) + |> delete(auth_token) + |> delete("") + let other_value = restricted_to(auth_input.output.value, other_policy) + + expect [_] = + output_at_with_value( + outputs, + fee_address, + merge(other_value, fee_value), + ) + + let fundraise_check = current_fundraised_amount >= fundraise_target + let completion_script_withdrawal_credential: Credential = + Script(completion_script) + let withdrawal_script_check = + withdrawals + |> has_key(completion_script_withdrawal_credential) + fundraise_check? && withdrawal_script_check? && only_minted_token( + mint, + auth_token, + completion_script, + -1, + )? + } + + ContributorWithdrawal -> { + let validity_check = + valid_after(validity_range, deadline + expiry_buffer) + let fund_check = current_fundraised_amount <= fundraise_target + + expect [auth_output] = + outputs_at_with_policy(outputs, current_address, auth_token) + + let lovelace_from_auth_input = auth_input.output.value |> lovelace_of() + let lovelace_from_auth_output = auth_output.value |> lovelace_of() + + let lovelace_withdrawn = + lovelace_from_auth_output - lovelace_from_auth_input + + let lovelace_withdrawn_check = lovelace_withdrawn < 0 + + expect auth_output_datum: CrowdfundDatum = + output_inline_datum(auth_output) + let output_datum_check = + auth_output_datum == CrowdfundDatum { + ..auth_input_datum, + current_fundraised_amount: current_fundraised_amount + lovelace_withdrawn, + } + + let is_auth_output_value_clean = value_length(auth_output.value) == 2 + (validity_check || fund_check)? && lovelace_withdrawn_check? && output_datum_check? && is_auth_output_value_clean? && only_minted_token( + mint, + share_token, + completion_script, + lovelace_withdrawn, + )? + } + + RemoveEmptyInstance -> { + let validity_check = valid_after(validity_range, deadline) + + let token_burnt_check = + if current_fundraised_amount > 0 { + policy_only_minted_token( + mint, + share_token, + completion_script, + -current_fundraised_amount, + )? && policy_only_minted_token( + mint, + auth_token, + completion_script, + -1, + )? + } else { + only_minted_token(mint, auth_token, completion_script, -1)? + } + validity_check? && token_burnt_check? + } + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak new file mode 100644 index 000000000..d1f3d7577 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak @@ -0,0 +1,1139 @@ +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{Transaction} +use crowdfund/spend as crowdfund_spend +use mocktail.{ + complete, invalid_before, invalid_hereafter, mint, mock_policy_id, + mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, + script_withdrawal, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use tests/utils.{ + mock_auth_token, mock_completion_script, mock_contribute_min_fundraised_amount, + mock_contribute_over_fundraised_amount, mock_crowdfund_address, + mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, + mock_expiry_buffer, mock_extra_fundraised_amount, mock_fee_address, + mock_fundraise_target, mock_min_charge, mock_share_token, +} +use types.{ + CompleteCrowdfund, ContributeFund, ContributorWithdrawal, RemoveEmptyInstance, +} + +type ContributeFundTestCase { + is_only_one_auth_inputed: Bool, + is_only_one_auth_outputed: Bool, + is_auth_output_datum_correct: Bool, + is_auth_output_value_clean: Bool, + is_deadline_not_passed: Bool, + is_shares_minted: Bool, +} + +fn mock_contribute_fund_tx( + test_case: ContributeFundTestCase, + current_fundraised_amount: Int, + contribute_amount: Int, + allow_over_subscription: Bool, +) -> Transaction { + let ContributeFundTestCase { + is_only_one_auth_inputed, + is_only_one_auth_outputed, + is_auth_output_datum_correct, + is_auth_output_value_clean, + is_deadline_not_passed, + is_shares_minted, + } = test_case + + let input_value = + from_lovelace(current_fundraised_amount) + |> add(mock_auth_token, mock_completion_script, 1) + + let output_value = + from_lovelace(current_fundraised_amount + contribute_amount) + |> add(mock_auth_token, mock_completion_script, 1) + + let auth_correct_output_datum = + mock_crowdfund_datum( + current_fundraised_amount + contribute_amount, + allow_over_subscription, + ) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, allow_over_subscription), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> tx_in( + True, + mock_tx_hash(1), + 0, + from_lovelace(contribute_amount), + mock_pub_key_address(0, None), + ) + |> tx_out(is_auth_output_value_clean, mock_crowdfund_address, output_value) + |> tx_out( + !is_auth_output_value_clean, + mock_crowdfund_address, + output_value |> add(mock_policy_id(999), mock_completion_script, 1), + ) + |> tx_out_inline_datum(is_auth_output_datum_correct, auth_correct_output_datum) + |> tx_out_inline_datum( + !is_auth_output_datum_correct, + mock_crowdfund_datum( + current_fundraised_amount + contribute_amount + 9999999, + allow_over_subscription, + ), + ) + |> tx_out(!is_only_one_auth_outputed, mock_crowdfund_address, output_value) + |> invalid_hereafter(is_deadline_not_passed, mock_deadline - 3600 * 24) + |> invalid_hereafter(!is_deadline_not_passed, mock_deadline + 3600 * 24) + |> mint( + is_shares_minted, + contribute_amount, + mock_share_token, + mock_completion_script, + ) + |> mint( + !is_shares_minted, + contribute_amount + 9999999, + mock_share_token, + mock_completion_script, + ) + |> complete() +} + +test s2_spend_success_contribute_fund_with_not_allow_over_subscription() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_success_contribute_fund_with_allow_over_subscription() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + True, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, True)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_success_contribute_fund_with_allow_over_subscription_and_over_fundraised() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_over_fundraised_amount, + True, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, True)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_not_allow_over_subscription_but_over_fundraised() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_over_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_over_current_fundraised() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_more_than_one_auth_inputed() fail { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: False, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_more_than_one_auth_outputed() fail { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: False, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_incorrect_auth_output_datum() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: False, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_auth_output_not_clean() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: False, + is_deadline_not_passed: True, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_deadline_passed() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: False, + is_shares_minted: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contribute_fund_with_wrong_shares_minted() { + let tx = + mock_contribute_fund_tx( + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: False, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + ContributeFund, + mock_utxo_ref(0, 0), + tx, + ) +} + +type CompleteCrowdfundTestCase { + is_only_one_auth_inputed: Bool, + is_output_to_fee_address_correct: Bool, + is_auth_burnt: Bool, + is_completion_script_executed: Bool, +} + +fn mock_complete_crowdfund_tx( + test_case: CompleteCrowdfundTestCase, + current_fundraised_amount: Int, + allow_over_subscription: Bool, +) -> Transaction { + let CompleteCrowdfundTestCase { + is_only_one_auth_inputed, + is_output_to_fee_address_correct, + is_auth_burnt, + is_completion_script_executed, + } = test_case + + let input_value = + from_lovelace( + current_fundraised_amount + mock_min_charge + mock_extra_fundraised_amount, + ) + |> add(mock_auth_token, mock_completion_script, 1) + |> add(mock_policy_id(999), mock_completion_script, 10) + + let output_value = + from_lovelace(mock_extra_fundraised_amount) + |> add(mock_policy_id(999), mock_completion_script, 10) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, allow_over_subscription), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> tx_out(is_output_to_fee_address_correct, mock_fee_address, output_value) + |> tx_out( + !is_output_to_fee_address_correct, + mock_fee_address, + from_lovelace(mock_extra_fundraised_amount - 10) + |> add(mock_policy_id(999), mock_completion_script, 10), + ) + |> script_withdrawal( + is_completion_script_executed, + mock_completion_script, + 2_000_000, + ) + |> mint(is_auth_burnt, -1, mock_auth_token, mock_completion_script) + |> complete() +} + +test s2_spend_success_complete_crowdfund_with_amount_equal_to_target() { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + }, + mock_fundraise_target, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_fundraise_target, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_success_complete_crowdfund_with_amount_larger_than_target() { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + }, + mock_contribute_over_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_complete_crowdfund_with_amount_less_than_target() { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + }, + mock_fundraise_target - 1, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_fundraise_target - 1, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_complete_crowdfund_with_more_than_one_auth_inputed() fail { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: False, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + }, + mock_fundraise_target, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_fundraise_target, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_complete_crowdfund_with_incorrect_fee_output() fail { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: False, + is_auth_burnt: True, + is_completion_script_executed: True, + }, + mock_fundraise_target, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_fundraise_target, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_complete_crowdfund_with_no_auth_burnt() { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: False, + is_completion_script_executed: True, + }, + mock_fundraise_target, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_fundraise_target, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_complete_crowdfund_with_no_completion_script_executed() { + let tx = + mock_complete_crowdfund_tx( + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: False, + }, + mock_fundraise_target, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_fundraise_target, False)), + CompleteCrowdfund, + mock_utxo_ref(0, 0), + tx, + ) +} + +type ContributorWithdrawalTestCase { + is_only_one_auth_inputed: Bool, + is_only_one_auth_outputed: Bool, + is_auth_output_datum_correct: Bool, + is_auth_output_value_clean: Bool, + is_auth_unlock_value_correct: Bool, + is_deadline_passed: Bool, + is_shares_burnt: Bool, +} + +fn mock_contributor_withdrawal_tx( + test_case: ContributorWithdrawalTestCase, + current_fundraised_amount: Int, + withdraw_amount: Int, + allow_over_subscription: Bool, +) -> Transaction { + let ContributorWithdrawalTestCase { + is_only_one_auth_inputed, + is_only_one_auth_outputed, + is_auth_output_datum_correct, + is_auth_output_value_clean, + is_auth_unlock_value_correct, + is_deadline_passed, + is_shares_burnt, + } = test_case + + let input_value = + from_lovelace(current_fundraised_amount) + |> add(mock_auth_token, mock_completion_script, 1) + + let output_value = + if is_auth_unlock_value_correct { + from_lovelace(current_fundraised_amount - withdraw_amount) + |> add(mock_auth_token, mock_completion_script, 1) + } else { + from_lovelace(current_fundraised_amount - withdraw_amount + 10) + |> add(mock_auth_token, mock_completion_script, 1) + } + + let auth_correct_output_datum = + mock_crowdfund_datum( + current_fundraised_amount - withdraw_amount, + allow_over_subscription, + ) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, allow_over_subscription), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> tx_out(True, mock_pub_key_address(0, None), from_lovelace(withdraw_amount)) + |> tx_out(is_auth_output_value_clean, mock_crowdfund_address, output_value) + |> tx_out( + !is_auth_output_value_clean, + mock_crowdfund_address, + output_value |> add(mock_policy_id(999), mock_completion_script, 1), + ) + |> tx_out_inline_datum(is_auth_output_datum_correct, auth_correct_output_datum) + |> tx_out_inline_datum( + !is_auth_output_datum_correct, + mock_crowdfund_datum( + current_fundraised_amount - withdraw_amount + 9999999, + allow_over_subscription, + ), + ) + |> tx_out(!is_only_one_auth_outputed, mock_crowdfund_address, output_value) + |> invalid_before( + is_deadline_passed, + mock_deadline + mock_expiry_buffer + 3600 * 24, + ) + |> invalid_before( + !is_deadline_passed, + mock_deadline + mock_expiry_buffer - 3600 * 24, + ) + |> mint( + is_shares_burnt, + -withdraw_amount, + mock_share_token, + mock_completion_script, + ) + |> mint( + !is_shares_burnt, + -withdraw_amount + 9999999, + mock_share_token, + mock_completion_script, + ) + |> complete() +} + +test s2_spend_success_contributor_withdraw_with_deadline_passed_but_fundraised_reach_target() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_success_contributor_withdraw_with_deadline_passed_and_fundraised_less_than_target() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount * 2, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount * 2, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_success_contributor_withdraw_with_deadline_not_passed_but_fundraised_less_than_target() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: False, + is_shares_burnt: True, + }, + mock_current_fundraised_amount * 2, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount * 2, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_deadline_not_passed_and_fundraised_reached_target() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: False, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_more_thanone_auth_inputed() fail { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: False, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_more_thanone_auth_outputed() fail { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: False, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_incorrect_output_datum() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: False, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: False, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: False, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_auth_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: False, + }, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +type RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: Bool, + is_deadline_passed: Bool, + is_shares_burnt: Bool, + is_auth_burnt: Bool, +} + +fn mock_remove_empty_instance_tx( + test_case: RemoveEmptyInstanceTestCase, + current_fundraised_amount: Int, + allow_over_subscription: Bool, +) -> Transaction { + let RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed, + is_deadline_passed, + is_shares_burnt, + is_auth_burnt, + } = test_case + + let input_value = + from_lovelace(current_fundraised_amount) + |> add(mock_auth_token, mock_completion_script, 1) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, allow_over_subscription), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> invalid_before(is_deadline_passed, mock_deadline + 3600 * 24) + |> invalid_before(!is_deadline_passed, mock_deadline - 3600 * 24) + |> mint( + is_shares_burnt, + -current_fundraised_amount, + mock_share_token, + mock_completion_script, + ) + |> mint( + !is_shares_burnt, + -current_fundraised_amount + 9999999, + mock_share_token, + mock_completion_script, + ) + |> mint(is_auth_burnt, -1, mock_auth_token, mock_completion_script) + |> complete() +} + +test s2_spend_success_remove_empty_instance_wih_zero_fund() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_auth_burnt: True, + }, + 0, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(0, False)), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_success_remove_empty_instance_wih_some_fund() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_auth_burnt: True, + }, + mock_current_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: False, + is_deadline_passed: True, + is_shares_burnt: True, + is_auth_burnt: True, + }, + mock_current_fundraised_amount, + False, + ) + + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_remove_empty_instance_wih_deadline_not_passed() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: True, + is_deadline_passed: False, + is_shares_burnt: True, + is_auth_burnt: True, + }, + mock_current_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_remove_empty_instance_wih_share_not_burnt() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: True, + is_deadline_passed: True, + is_shares_burnt: False, + is_auth_burnt: True, + }, + mock_current_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s2_spend_fail_remove_empty_instance_wih_authe_not_burnt() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_auth_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_auth_burnt: False, + }, + mock_current_fundraised_amount, + False, + ) + + !crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak index 2ed469108..a752a80c8 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak @@ -1,5 +1,6 @@ use cardano/address.{from_script} use mocktail.{mock_policy_id, mock_script_hash, mock_script_stake_key_hash} +use types.{CrowdfundDatum} pub const mock_auth_token = mock_policy_id(0) @@ -12,3 +13,47 @@ pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) + +pub const mock_fee_address = from_script("fee_address") + +pub const mock_fundraise_target = 100000000000 + +pub const mock_deadline = 1750735607 + +pub const mock_expiry_buffer = 3600 * 24 + +pub const mock_min_charge = 0 + +pub fn mock_crowdfund_datum( + current_fundraised_amount: Int, + allow_over_subscription: Bool, +) { + CrowdfundDatum { + completion_script: mock_completion_script, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount, + allow_over_subscription, + deadline: mock_deadline, + expiry_buffer: mock_expiry_buffer, + fee_address: mock_fee_address, + min_charge: mock_min_charge, + } +} + +pub const mock_current_fundraised_amount = 2000000 + +pub const mock_extra_fundraised_amount = 4000000 + +pub const mock_contribute_less_than_min_fundraised_amount = 1999999 + +pub const mock_contribute_min_fundraised_amount = 2000000 + +pub const mock_contribute_over_fundraised_amount = 100000000001 + +pub const auth_allow_over_subscription = + mock_crowdfund_datum(mock_current_fundraised_amount, True) + +pub const auth_not_allow_over_subscription = + mock_crowdfund_datum(mock_current_fundraised_amount, False) From fa467dd04e332c98d97797e0825b46dcffaa13c7 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 25 Jun 2025 14:04:32 +0800 Subject: [PATCH 05/24] added: stake --- .../aiken-crowdfund/specs/3_crowdfund.md | 2 +- .../validators/tests/auth_token/mint.ak | 10 +- .../validators/tests/crowdfund/spend.ak | 68 ++++---- .../validators/tests/share_token/mint.ak | 12 +- .../gov-crowdfund/aiken.lock | 26 +++ .../gov-crowdfund/aiken.toml | 7 +- .../gov-crowdfund/lib/types.ak | 32 ++++ .../gov-crowdfund/lib/utils.ak | 10 ++ .../gov-crowdfund/specs/1_spend.md | 1 + .../gov-crowdfund/validators/placeholder.ak | 41 ----- .../gov-crowdfund/validators/spend.ak | 0 .../gov-crowdfund/validators/stake.ak | 36 +++++ .../gov-crowdfund/validators/start.ak | 0 .../gov-crowdfund/validators/tests/stake.ak | 151 ++++++++++++++++++ .../gov-crowdfund/validators/tests/utils.ak | 10 ++ 15 files changed, 318 insertions(+), 88 deletions(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.lock create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md index df78c76fe..d63202f8e 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md @@ -32,7 +32,7 @@ - Any value in the current utxos - (`current_fundraised_amount` + `min_charge`) goes to `fee_address` - `current_fundraised_amount` >= `fundraise_target` - - `completion_script` withdrawal script is exeuted + - `completion_script` withdrawal script is executed - `auth_token` from current input is burnt 3. ContributorWithdrawal diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak index 47de07ed7..b113dd1c5 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak @@ -8,7 +8,7 @@ use mocktail.{ use tests/utils.{mock_auth_token} use types.{RBurn, RMint} -test s0_mint_success_mint() { +test s1_mint_success_mint() { let redeemer = RMint let input_utxo = mock_utxo_ref(0, 1) let policy_id = mock_auth_token @@ -22,7 +22,7 @@ test s0_mint_success_mint() { auth_token_mint.auth_token.mint(input_utxo, redeemer, policy_id, tx) } -test s0_mint_fail_mint_no_utxo_ref_supply() { +test s1_mint_fail_mint_no_utxo_ref_supply() { let redeemer = RMint let policy_id = mock_auth_token @@ -34,7 +34,7 @@ test s0_mint_fail_mint_no_utxo_ref_supply() { !auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) } -test s0_mint_success_burn() { +test s1_mint_success_burn() { let redeemer = RBurn let policy_id = mock_auth_token @@ -42,7 +42,7 @@ test s0_mint_success_burn() { auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) } -test s0_mint_success_burn_with_other_minting() { +test s1_mint_success_burn_with_other_minting() { let redeemer = RBurn let policy_id = mock_auth_token @@ -54,7 +54,7 @@ test s0_mint_success_burn_with_other_minting() { auth_token_mint.auth_token.mint(mock_utxo_ref(0, 0), redeemer, policy_id, tx) } -test s0_mint_fail_burn_with_mint() { +test s1_mint_fail_burn_with_mint() { let redeemer = RBurn let policy_id = mock_auth_token diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak index d1f3d7577..30acf36bc 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak @@ -107,7 +107,7 @@ fn mock_contribute_fund_tx( |> complete() } -test s2_spend_success_contribute_fund_with_not_allow_over_subscription() { +test s3_spend_success_contribute_fund_with_not_allow_over_subscription() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -132,7 +132,7 @@ test s2_spend_success_contribute_fund_with_not_allow_over_subscription() { ) } -test s2_spend_success_contribute_fund_with_allow_over_subscription() { +test s3_spend_success_contribute_fund_with_allow_over_subscription() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -157,7 +157,7 @@ test s2_spend_success_contribute_fund_with_allow_over_subscription() { ) } -test s2_spend_success_contribute_fund_with_allow_over_subscription_and_over_fundraised() { +test s3_spend_success_contribute_fund_with_allow_over_subscription_and_over_fundraised() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -182,7 +182,7 @@ test s2_spend_success_contribute_fund_with_allow_over_subscription_and_over_fund ) } -test s2_spend_fail_contribute_fund_with_not_allow_over_subscription_but_over_fundraised() { +test s3_spend_fail_contribute_fund_with_not_allow_over_subscription_but_over_fundraised() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -207,7 +207,7 @@ test s2_spend_fail_contribute_fund_with_not_allow_over_subscription_but_over_fun ) } -test s2_spend_fail_contribute_fund_with_over_current_fundraised() { +test s3_spend_fail_contribute_fund_with_over_current_fundraised() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -232,7 +232,7 @@ test s2_spend_fail_contribute_fund_with_over_current_fundraised() { ) } -test s2_spend_fail_contribute_fund_with_more_than_one_auth_inputed() fail { +test s3_spend_fail_contribute_fund_with_more_than_one_auth_inputed() fail { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -257,7 +257,7 @@ test s2_spend_fail_contribute_fund_with_more_than_one_auth_inputed() fail { ) } -test s2_spend_fail_contribute_fund_with_more_than_one_auth_outputed() fail { +test s3_spend_fail_contribute_fund_with_more_than_one_auth_outputed() fail { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -282,7 +282,7 @@ test s2_spend_fail_contribute_fund_with_more_than_one_auth_outputed() fail { ) } -test s2_spend_fail_contribute_fund_with_incorrect_auth_output_datum() { +test s3_spend_fail_contribute_fund_with_incorrect_auth_output_datum() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -307,7 +307,7 @@ test s2_spend_fail_contribute_fund_with_incorrect_auth_output_datum() { ) } -test s2_spend_fail_contribute_fund_with_auth_output_not_clean() { +test s3_spend_fail_contribute_fund_with_auth_output_not_clean() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -332,7 +332,7 @@ test s2_spend_fail_contribute_fund_with_auth_output_not_clean() { ) } -test s2_spend_fail_contribute_fund_with_deadline_passed() { +test s3_spend_fail_contribute_fund_with_deadline_passed() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -357,7 +357,7 @@ test s2_spend_fail_contribute_fund_with_deadline_passed() { ) } -test s2_spend_fail_contribute_fund_with_wrong_shares_minted() { +test s3_spend_fail_contribute_fund_with_wrong_shares_minted() { let tx = mock_contribute_fund_tx( ContributeFundTestCase { @@ -441,7 +441,7 @@ fn mock_complete_crowdfund_tx( |> complete() } -test s2_spend_success_complete_crowdfund_with_amount_equal_to_target() { +test s3_spend_success_complete_crowdfund_with_amount_equal_to_target() { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -463,7 +463,7 @@ test s2_spend_success_complete_crowdfund_with_amount_equal_to_target() { ) } -test s2_spend_success_complete_crowdfund_with_amount_larger_than_target() { +test s3_spend_success_complete_crowdfund_with_amount_larger_than_target() { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -485,7 +485,7 @@ test s2_spend_success_complete_crowdfund_with_amount_larger_than_target() { ) } -test s2_spend_fail_complete_crowdfund_with_amount_less_than_target() { +test s3_spend_fail_complete_crowdfund_with_amount_less_than_target() { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -507,7 +507,7 @@ test s2_spend_fail_complete_crowdfund_with_amount_less_than_target() { ) } -test s2_spend_fail_complete_crowdfund_with_more_than_one_auth_inputed() fail { +test s3_spend_fail_complete_crowdfund_with_more_than_one_auth_inputed() fail { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -529,7 +529,7 @@ test s2_spend_fail_complete_crowdfund_with_more_than_one_auth_inputed() fail { ) } -test s2_spend_fail_complete_crowdfund_with_incorrect_fee_output() fail { +test s3_spend_fail_complete_crowdfund_with_incorrect_fee_output() fail { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -551,7 +551,7 @@ test s2_spend_fail_complete_crowdfund_with_incorrect_fee_output() fail { ) } -test s2_spend_fail_complete_crowdfund_with_no_auth_burnt() { +test s3_spend_fail_complete_crowdfund_with_no_auth_burnt() { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -573,7 +573,7 @@ test s2_spend_fail_complete_crowdfund_with_no_auth_burnt() { ) } -test s2_spend_fail_complete_crowdfund_with_no_completion_script_executed() { +test s3_spend_fail_complete_crowdfund_with_no_completion_script_executed() { let tx = mock_complete_crowdfund_tx( CompleteCrowdfundTestCase { @@ -692,7 +692,7 @@ fn mock_contributor_withdrawal_tx( |> complete() } -test s2_spend_success_contributor_withdraw_with_deadline_passed_but_fundraised_reach_target() { +test s3_spend_success_contributor_withdraw_with_deadline_passed_but_fundraised_reach_target() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -718,7 +718,7 @@ test s2_spend_success_contributor_withdraw_with_deadline_passed_but_fundraised_r ) } -test s2_spend_success_contributor_withdraw_with_deadline_passed_and_fundraised_less_than_target() { +test s3_spend_success_contributor_withdraw_with_deadline_passed_and_fundraised_less_than_target() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -744,7 +744,7 @@ test s2_spend_success_contributor_withdraw_with_deadline_passed_and_fundraised_l ) } -test s2_spend_success_contributor_withdraw_with_deadline_not_passed_but_fundraised_less_than_target() { +test s3_spend_success_contributor_withdraw_with_deadline_not_passed_but_fundraised_less_than_target() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -770,7 +770,7 @@ test s2_spend_success_contributor_withdraw_with_deadline_not_passed_but_fundrais ) } -test s2_spend_fail_contributor_withdraw_with_deadline_not_passed_and_fundraised_reached_target() { +test s3_spend_fail_contributor_withdraw_with_deadline_not_passed_and_fundraised_reached_target() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -796,7 +796,7 @@ test s2_spend_fail_contributor_withdraw_with_deadline_not_passed_and_fundraised_ ) } -test s2_spend_fail_contributor_withdraw_with_more_thanone_auth_inputed() fail { +test s3_spend_fail_contributor_withdraw_with_more_thanone_auth_inputed() fail { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -822,7 +822,7 @@ test s2_spend_fail_contributor_withdraw_with_more_thanone_auth_inputed() fail { ) } -test s2_spend_fail_contributor_withdraw_with_more_thanone_auth_outputed() fail { +test s3_spend_fail_contributor_withdraw_with_more_thanone_auth_outputed() fail { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -848,7 +848,7 @@ test s2_spend_fail_contributor_withdraw_with_more_thanone_auth_outputed() fail { ) } -test s2_spend_fail_contributor_withdraw_with_incorrect_output_datum() { +test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -874,7 +874,7 @@ test s2_spend_fail_contributor_withdraw_with_incorrect_output_datum() { ) } -test s2_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { +test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -900,7 +900,7 @@ test s2_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { ) } -test s2_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { +test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -926,7 +926,7 @@ test s2_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { ) } -test s2_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { +test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1006,7 +1006,7 @@ fn mock_remove_empty_instance_tx( |> complete() } -test s2_spend_success_remove_empty_instance_wih_zero_fund() { +test s3_spend_success_remove_empty_instance_wih_zero_fund() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1028,7 +1028,7 @@ test s2_spend_success_remove_empty_instance_wih_zero_fund() { ) } -test s2_spend_success_remove_empty_instance_wih_some_fund() { +test s3_spend_success_remove_empty_instance_wih_some_fund() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1050,7 +1050,7 @@ test s2_spend_success_remove_empty_instance_wih_some_fund() { ) } -test s2_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { +test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1072,7 +1072,7 @@ test s2_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { ) } -test s2_spend_fail_remove_empty_instance_wih_deadline_not_passed() { +test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1094,7 +1094,7 @@ test s2_spend_fail_remove_empty_instance_wih_deadline_not_passed() { ) } -test s2_spend_fail_remove_empty_instance_wih_share_not_burnt() { +test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1116,7 +1116,7 @@ test s2_spend_fail_remove_empty_instance_wih_share_not_burnt() { ) } -test s2_spend_fail_remove_empty_instance_wih_authe_not_burnt() { +test s3_spend_fail_remove_empty_instance_wih_authe_not_burnt() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak index e623afb0a..6ad5a815e 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak @@ -10,7 +10,7 @@ use tests/utils.{ } use types.{ContributeFund, RBurn, RMint} -test s1_mint_success_mint() { +test s2_mint_success_mint() { let redeemer = RMint let auth_input = from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) @@ -39,7 +39,7 @@ test s1_mint_success_mint() { share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) } -test s1_mint_fail_mint_no_auth_token_input() fail { +test s2_mint_fail_mint_no_auth_token_input() fail { let redeemer = RMint let policy_id = mock_share_token @@ -50,7 +50,7 @@ test s1_mint_fail_mint_no_auth_token_input() fail { share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) } -test s1_mint_fail_mint_no_auth_token_redeemer() fail { +test s2_mint_fail_mint_no_auth_token_redeemer() fail { let redeemer = RMint let auth_input = from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) @@ -64,7 +64,7 @@ test s1_mint_fail_mint_no_auth_token_redeemer() fail { share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) } -test s1_mint_success_burn() { +test s2_mint_success_burn() { let redeemer = RBurn let policy_id = mock_share_token @@ -72,7 +72,7 @@ test s1_mint_success_burn() { share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) } -test s1_mint_success_burn_with_other_minting() { +test s2_mint_success_burn_with_other_minting() { let redeemer = RBurn let policy_id = mock_share_token @@ -84,7 +84,7 @@ test s1_mint_success_burn_with_other_minting() { share_token_mint.share_token.mint(mock_auth_token, redeemer, policy_id, tx) } -test s1_mint_fail_burn_with_mint() { +test s2_mint_fail_burn_with_mint() { let redeemer = RBurn let policy_id = mock_share_token diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.lock b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.lock new file mode 100644 index 000000000..2e65bd164 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.lock @@ -0,0 +1,26 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +source = "github" + +[[requirements]] +name = "sidan-lab/vodka" +version = "0.1.13" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +requirements = [] +source = "github" + +[[packages]] +name = "sidan-lab/vodka" +version = "0.1.13" +requirements = [] +source = "github" + +[etags] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml index fba837145..bff202272 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml @@ -12,7 +12,12 @@ platform = "github" [[dependencies]] name = "aiken-lang/stdlib" -version = "1.5.0" +version = "v2.2.0" +source = "github" + +[[dependencies]] +name = "sidan-lab/vodka" +version = "0.1.13" source = "github" [config] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak new file mode 100644 index 000000000..04220021f --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak @@ -0,0 +1,32 @@ +pub type CrowdfundRedeemer { + RegisterCerts + DeregisterCerts + ContributorWithdrawal + RemoveEmptyInstance +} + +pub type CrowdfundDatum { + Init { + completion_script: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } + Proposed { + completion_script: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } + Refundable { + completion_script: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } +} + +pub type StakeRedeemer { + Register + Deregister +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak new file mode 100644 index 000000000..ab263997e --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak @@ -0,0 +1,10 @@ +use aiken/collection/pairs +use cardano/transaction.{Input, Redeemer, ScriptPurpose, Spend} + +pub fn redeemer_with_input( + redeemers: Pairs, + input: Input, +) -> Option { + let output_reference = input.output_reference + redeemers |> pairs.get_first(Spend(output_reference)) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md index e403685c1..4ad76c581 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md @@ -44,6 +44,7 @@ pub type Datum { - Delegate to current own DRep + stake pool `delegate_pool_id` - Propose gov action - Vote on same proposal? -> if cant, create one more separate state + - todo: check 100k lock before retification correctly 2. DeregisterCerts diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak deleted file mode 100644 index bbf9d47d4..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/placeholder.ak +++ /dev/null @@ -1,41 +0,0 @@ -use cardano/address.{Credential} -use cardano/assets.{PolicyId} -use cardano/certificate.{Certificate} -use cardano/governance.{ProposalProcedure, Voter} -use cardano/transaction.{Transaction, OutputReference} - -validator placeholder { - mint(_redeemer: Data, _policy_id: PolicyId, _self: Transaction) { - todo @"mint logic goes here" - } - - spend(_datum: Option, _redeemer: Data, _utxo: OutputReference, _self: Transaction) { - todo @"spend logic goes here" - } - - withdraw(_redeemer: Data, _account: Credential, _self: Transaction) { - todo @"withdraw logic goes here" - } - - publish(_redeemer: Data, _certificate: Certificate, _self: Transaction) { - todo @"publish logic goes here" - } - - vote(_redeemer: Data, _voter: Voter, _self: Transaction) { - todo @"vote logic goes here" - } - - propose(_redeemer: Data, _proposal: ProposalProcedure, _self: Transaction) { - todo @"propose logic goes here" - } - - // // If needs be, remove any of unneeded handlers above, and use: - // - // else(_ctx: ScriptContext) { - // todo @"fallback logic if none of the other purposes match" - // } - // - // // You will also need an additional import: - // // - // // use cardano/script_context.{ScriptContext} -} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak new file mode 100644 index 000000000..e69de29bb diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak new file mode 100644 index 000000000..969dd4024 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak @@ -0,0 +1,36 @@ +use cardano/address.{from_script} +use cardano/script_context.{ScriptContext} +use cardano/transaction.{Transaction} +use cocktail.{inputs_at} +use types.{ + CrowdfundRedeemer, Deregister, DeregisterCerts, Register, RegisterCerts, + StakeRedeemer, +} +use utils.{redeemer_with_input} + +validator stake(spend_script_hash: ByteArray) { + else(ctx: ScriptContext) { + let ScriptContext { transaction, redeemer, .. } = ctx + expect stake_redeemer: StakeRedeemer = redeemer + let Transaction { inputs, redeemers, .. } = transaction + let spend_address = from_script(spend_script_hash) + expect [only_input] = inputs_at(inputs, spend_address) + expect Some(only_inpuy_redeemer_data) = + redeemer_with_input(redeemers, only_input) + + expect only_input_redeemer: CrowdfundRedeemer = only_inpuy_redeemer_data + + when stake_redeemer is { + Register -> { + let redeemer_check = only_input_redeemer == RegisterCerts + + redeemer_check? + } + Deregister -> { + let redeemer_check = only_input_redeemer == DeregisterCerts + + redeemer_check? + } + } + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak new file mode 100644 index 000000000..e69de29bb diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak new file mode 100644 index 000000000..5d5410a07 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak @@ -0,0 +1,151 @@ +use cardano/assets.{add, from_lovelace} +use cardano/certificate.{RegisterCredential} +use cardano/script_context.{Publishing, ScriptContext} +use cardano/transaction.{OutputReference, Spend, Transaction} +use mocktail.{ + add_redeemer, complete, mock_script_credential, mock_tx_hash, mocktail_tx, + tx_in, +} +use stake +use tests/utils.{ + mock_auth_token, mock_completion_script, mock_crowdfund_address, + mock_spend_script_hash, +} +use types.{Deregister, DeregisterCerts, Register, RegisterCerts} + +type StakeTestCase { + is_only_one_auth_inputed: Bool, +} + +fn mock_stake_tx( + test_case: StakeTestCase, + only_input_redeemer: Data, +) -> Transaction { + let StakeTestCase { is_only_one_auth_inputed } = test_case + let only_input = + from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_address) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + only_input, + mock_crowdfund_address, + ) + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + only_input_redeemer, + ), + ) +} + +test s2_success_stake_with_reg() { + let only_input_redeemer: Data = RegisterCerts + + let ctx = + ScriptContext { + transaction: mock_stake_tx( + StakeTestCase { is_only_one_auth_inputed: True }, + only_input_redeemer, + ), + redeemer: Register, + info: Publishing { + at: 0, + certificate: RegisterCredential { + credential: mock_script_credential(0), + deposit: Never, + }, + }, + } + stake.stake.else(mock_spend_script_hash, ctx) +} + +test s2_success_stake_with_dereg() { + let only_input_redeemer: Data = DeregisterCerts + + let ctx = + ScriptContext { + transaction: mock_stake_tx( + StakeTestCase { is_only_one_auth_inputed: True }, + only_input_redeemer, + ), + redeemer: Deregister, + info: Publishing { + at: 0, + certificate: RegisterCredential { + credential: mock_script_credential(0), + deposit: Never, + }, + }, + } + stake.stake.else(mock_spend_script_hash, ctx) +} + +test s2_fail_stake_with_reg_but_deregister_cert() { + let only_input_redeemer: Data = DeregisterCerts + + let ctx = + ScriptContext { + transaction: mock_stake_tx( + StakeTestCase { is_only_one_auth_inputed: True }, + only_input_redeemer, + ), + redeemer: Register, + info: Publishing { + at: 0, + certificate: RegisterCredential { + credential: mock_script_credential(0), + deposit: Never, + }, + }, + } + !stake.stake.else(mock_spend_script_hash, ctx) +} + +test s2_fail_stake_with_dereg_but_register_cert() { + let only_input_redeemer: Data = RegisterCerts + + let ctx = + ScriptContext { + transaction: mock_stake_tx( + StakeTestCase { is_only_one_auth_inputed: True }, + only_input_redeemer, + ), + redeemer: Deregister, + info: Publishing { + at: 0, + certificate: RegisterCredential { + credential: mock_script_credential(0), + deposit: Never, + }, + }, + } + !stake.stake.else(mock_spend_script_hash, ctx) +} + +test s2_fail_stake_with_more_than_one_input_from_hash() fail { + let only_input_redeemer: Data = RegisterCerts + + let ctx = + ScriptContext { + transaction: mock_stake_tx( + StakeTestCase { is_only_one_auth_inputed: False }, + only_input_redeemer, + ), + redeemer: Register, + info: Publishing { + at: 0, + certificate: RegisterCredential { + credential: mock_script_credential(0), + deposit: Never, + }, + }, + } + stake.stake.else(mock_spend_script_hash, ctx) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak new file mode 100644 index 000000000..f3c5c63af --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -0,0 +1,10 @@ +use cardano/address.{from_script} +use mocktail.{mock_policy_id, mock_script_hash} + +pub const mock_auth_token = mock_policy_id(0) + +pub const mock_completion_script = mock_script_hash(0) + +pub const mock_spend_script_hash = mock_script_hash(1) + +pub const mock_crowdfund_address = from_script(mock_spend_script_hash) From d9cf63487b2c94b4ad4e5da02fa8ce94dc6ddf92 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Wed, 25 Jun 2025 15:27:11 +0800 Subject: [PATCH 06/24] added: start added: check completion script --- .../gov-crowdfund/lib/types.ak | 15 ++ .../gov-crowdfund/validators/start.ak | 57 +++++ .../gov-crowdfund/validators/tests/stake.ak | 6 +- .../gov-crowdfund/validators/tests/start.ak | 206 ++++++++++++++++++ .../gov-crowdfund/validators/tests/utils.ak | 55 ++++- 5 files changed, 333 insertions(+), 6 deletions(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak index 04220021f..948ee8a32 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak @@ -1,3 +1,5 @@ +use cardano/address.{Address} + pub type CrowdfundRedeemer { RegisterCerts DeregisterCerts @@ -6,6 +8,19 @@ pub type CrowdfundRedeemer { } pub type CrowdfundDatum { + completion_script: ByteArray, + share_token: ByteArray, + crowdfund_address: Address, + fundraise_target: Int, + current_fundraised_amount: Int, + allow_over_subscription: Bool, + deadline: Int, + expiry_buffer: Int, + fee_address: Address, + min_charge: Int, +} + +pub type CrowdfundGovDatum { Init { completion_script: ByteArray, share_token: ByteArray, diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak index e69de29bb..ce4fff784 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak @@ -0,0 +1,57 @@ +use cardano/address.{Address, Credential, Inline, Script} +use cardano/assets.{PolicyId, lovelace_of} +use cardano/transaction.{Transaction} +use cocktail.{ + input_inline_datum, inputs_with_policy, output_inline_datum, outputs_at, +} +use types.{CrowdfundDatum, CrowdfundGovDatum, Init} + +validator start( + auth_token: PolicyId, + spend: ByteArray, + stake: ByteArray, + gov_action_period: Int, +) { + withdraw(_r, account: Credential, self: Transaction) { + let Transaction { inputs, outputs, .. } = self + + expect [auth_token_input] = inputs_with_policy(inputs, auth_token) + expect auth_input_datum: CrowdfundDatum = + input_inline_datum(auth_token_input) + + let CrowdfundDatum { + completion_script, + share_token, + fundraise_target, + deadline, + current_fundraised_amount, + .. + } = auth_input_datum + + let completion_script_check = Script(completion_script) == account + let gov_address = + Address { + payment_credential: Script(spend), + stake_credential: Some(Inline(Script(stake))), + } + + expect [fundraise_target_output] = outputs_at(outputs, gov_address) + + let fundraise_output_lovelace_check = + lovelace_of(fundraise_target_output.value) == fundraise_target + expect fundraise_output_datum: CrowdfundGovDatum = + output_inline_datum(fundraise_target_output) + let fundraise_output_datum_check = + fundraise_output_datum == Init { + completion_script, + share_token, + funds_controlled: current_fundraised_amount, + deadline: deadline + gov_action_period, + } + completion_script_check? && fundraise_output_lovelace_check? && fundraise_output_datum_check? + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak index 5d5410a07..18284ec4b 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak @@ -8,7 +8,7 @@ use mocktail.{ } use stake use tests/utils.{ - mock_auth_token, mock_completion_script, mock_crowdfund_address, + mock_auth_token, mock_completion_script, mock_crowdfund_gov_address, mock_spend_script_hash, } use types.{Deregister, DeregisterCerts, Register, RegisterCerts} @@ -25,13 +25,13 @@ fn mock_stake_tx( let only_input = from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) mocktail_tx() - |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_address) + |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) |> tx_in( !is_only_one_auth_inputed, mock_tx_hash(0), 1, only_input, - mock_crowdfund_address, + mock_crowdfund_gov_address, ) |> complete() |> add_redeemer( diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak new file mode 100644 index 000000000..c1215bfab --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak @@ -0,0 +1,206 @@ +use cardano/address.{Script} +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{Transaction} +use mocktail.{ + complete, mock_script_hash, mock_tx_hash, mocktail_tx, tx_in, + tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use start +use tests/utils.{ + mock_auth_token, mock_completion_script, mock_crowdfund_address, + mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, + mock_fundraise_target, mock_gov_action_period, mock_gov_address, + mock_share_token, mock_spend_script_hash, mock_stake_script_hash, +} +use types.{Init} + +type StartTestCase { + is_only_one_auth_inputed: Bool, + is_fundraise_target_sent: Bool, + is_fundraise_target_amount_correct: Bool, + is_fundraise_output_datum_correct: Bool, +} + +fn mock_stake_tx(test_case: StartTestCase) -> Transaction { + let StartTestCase { + is_only_one_auth_inputed, + is_fundraise_target_sent, + is_fundraise_target_amount_correct, + is_fundraise_output_datum_correct, + } = test_case + let auth_input = + from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) + + let fundraise_output = + if is_fundraise_target_amount_correct { + from_lovelace(mock_fundraise_target) + } else { + from_lovelace(mock_fundraise_target - 1000000) + } + + let fundraise_output_datum = + if is_fundraise_output_datum_correct { + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount + 1000000, + deadline: mock_deadline + mock_gov_action_period, + } + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(mock_current_fundraised_amount, True), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + auth_input, + mock_crowdfund_address, + ) + |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) + |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) + |> complete() +} + +test s3_withdraw_success() { + let tx = + mock_stake_tx( + StartTestCase { + is_only_one_auth_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_stake_script_hash, + mock_gov_action_period, + None, + Script(mock_completion_script), + tx, + ) +} + +test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { + let tx = + mock_stake_tx( + StartTestCase { + is_only_one_auth_inputed: False, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_stake_script_hash, + mock_gov_action_period, + None, + Script(mock_completion_script), + tx, + ) +} + +test s3_withdraw_fail_with_fundraise_target_not_sent() fail { + let tx = + mock_stake_tx( + StartTestCase { + is_only_one_auth_inputed: True, + is_fundraise_target_sent: False, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_stake_script_hash, + mock_gov_action_period, + None, + Script(mock_completion_script), + tx, + ) +} + +test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { + let tx = + mock_stake_tx( + StartTestCase { + is_only_one_auth_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: False, + is_fundraise_output_datum_correct: True, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_stake_script_hash, + mock_gov_action_period, + None, + Script(mock_completion_script), + tx, + ) +} + +test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { + let tx = + mock_stake_tx( + StartTestCase { + is_only_one_auth_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: False, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_stake_script_hash, + mock_gov_action_period, + None, + Script(mock_completion_script), + tx, + ) +} + +test s3_withdraw_fail_with_different_completion_script() { + let tx = + mock_stake_tx( + StartTestCase { + is_only_one_auth_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: False, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_stake_script_hash, + mock_gov_action_period, + None, + Script(mock_script_hash(999)), + tx, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index f3c5c63af..d26e19c0e 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -1,10 +1,59 @@ -use cardano/address.{from_script} -use mocktail.{mock_policy_id, mock_script_hash} +use cardano/address.{Address, Inline, Script, from_script} +use mocktail.{mock_policy_id, mock_script_hash, mock_script_stake_key_hash} +use types.{CrowdfundDatum} pub const mock_auth_token = mock_policy_id(0) +pub const mock_share_token = mock_policy_id(1) + pub const mock_completion_script = mock_script_hash(0) +pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) + +pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) + +pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) + +pub const mock_fee_address = from_script("fee_address") + +pub const mock_fundraise_target = 100000000000 + +pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 + +pub const mock_deadline = 1750735607 + +pub const mock_expiry_buffer = 3600 * 24 + +pub const mock_min_charge = 0 + +pub fn mock_crowdfund_datum( + current_fundraised_amount: Int, + allow_over_subscription: Bool, +) { + CrowdfundDatum { + completion_script: mock_completion_script, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount, + allow_over_subscription, + deadline: mock_deadline, + expiry_buffer: mock_expiry_buffer, + fee_address: mock_fee_address, + min_charge: mock_min_charge, + } +} + pub const mock_spend_script_hash = mock_script_hash(1) -pub const mock_crowdfund_address = from_script(mock_spend_script_hash) +pub const mock_stake_script_hash = mock_script_hash(2) + +pub const mock_crowdfund_gov_address = from_script(mock_spend_script_hash) + +pub const mock_gov_address = + Address { + payment_credential: Script(mock_spend_script_hash), + stake_credential: Some(Inline(Script(mock_stake_script_hash))), + } + +pub const mock_gov_action_period = 3600 From 24033006519ba3ca9c919e8f88b332a92cee7457 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 26 Jun 2025 13:32:18 +0800 Subject: [PATCH 07/24] added: gov spend added: gov spend test case --- .../gov-crowdfund/lib/gov.ak | 95 ++ .../gov-crowdfund/lib/utils.ak | 103 +- .../gov-crowdfund/specs/1_spend.md | 4 +- .../gov-crowdfund/validators/spend.ak | 251 +++ .../gov-crowdfund/validators/tests/spend.ak | 1369 +++++++++++++++++ .../gov-crowdfund/validators/tests/stake.ak | 8 +- .../gov-crowdfund/validators/tests/utils.ak | 39 +- 7 files changed, 1861 insertions(+), 8 deletions(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak new file mode 100644 index 000000000..215e09f88 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak @@ -0,0 +1,95 @@ +// use aiken/cbor +// use aiken/crypto.{ScriptHash} +// use aiken/math/rational.{Rational} +// use cardano/address.{Credential} +// use cardano/assets.{Lovelace} +// use cardano/governance.{ +// Constitution, GovernanceAction, GovernanceActionId, Mandate, +// ProtocolParameters, ProtocolVersion, +// } +// use cardano/governance/protocol_parameters.{ProtocolParametersUpdate} + +// pub fn to_aiken_gov_action(gov_action: VGovernanceAction) -> GovernanceAction { +// // let raw = cbor.serialise(gov_action) +// // expect Some(output): Option = cbor.deserialise(raw) +// // expect gov: GovernanceAction = output +// when gov_action is { +// VProtocolParameters { ancestor, new_parameters, guardrails } -> +// ProtocolParameters { +// ancestor, +// new_parameters: ProtocolParametersUpdate { inner: new_parameters.inner }, +// guardrails, +// } +// _ -> gov_action +// } +// } + +// type ProtocolParametersIndex = +// Int + +// pub type VProtocolParametersUpdate { +// inner: Pairs, +// } + +// pub type VGovernanceAction { +// VProtocolParameters { +// /// The last governance action of type 'ProtocolParameters'. They must all +// /// form a chain. +// ancestor: Option, +// /// The new proposed protocol parameters. Only values set to `Some` are relevant. +// new_parameters: VProtocolParametersUpdate, +// /// The optional guardrails script defined in the constitution. The script +// /// is executed by the ledger in addition to the hard-coded ledger rules. +// /// +// /// It must pass for the new protocol parameters to be deemed valid. +// guardrails: Option, +// } +// HardFork { +// /// The last governance action of type `HardFork`. They must all +// /// form a chain. +// ancestor: Option, +// /// The new proposed version. Few rules apply to proposing new versions: +// /// +// /// - The `major` component, if incremented, must be exactly one more than the current. +// /// - The `minor` component, if incremented, must be exactly one more than the current. +// /// - If the `major` component is incremented, `minor` must be set to `0`. +// /// - Neither `minor` nor `major` can be decremented. +// new_version: ProtocolVersion, +// } +// TreasuryWithdrawal { +// /// A collection of beneficiaries, which can be plain verification key +// /// hashes or script hashes (e.g. DAO). +// beneficiaries: Pairs, +// /// The optional guardrails script defined in the constitution. The script +// /// is executed by the ledger in addition to the hard-coded ledger rules. +// /// +// /// It must pass for the withdrawals to be authorized. +// guardrails: Option, +// } +// NoConfidence { +// /// The last governance action of type `NoConfidence` or +// /// `ConstitutionalCommittee`. They must all / form a chain. +// ancestor: Option, +// } +// ConstitutionalCommittee { +// /// The last governance action of type `NoConfidence` or +// /// `ConstitutionalCommittee`. They must all / form a chain. +// ancestor: Option, +// /// Constitutional members to be removed. +// evicted_members: List, +// /// Constitutional members to be added. +// added_members: Pairs, +// /// The new quorum value, as a ratio of a numerator and a denominator. The +// /// quorum specifies the threshold of 'Yes' votes necessary for the +// /// constitutional committee to accept a proposal procedure. +// quorum: Rational, +// } +// NewConstitution { +// /// The last governance action of type `Constitution` or +// /// `ConstitutionalCommittee`. They must all / form a chain. +// ancestor: Option, +// /// The new proposed constitution. +// constitution: Constitution, +// } +// NicePoll +// } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak index ab263997e..2b72369a7 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak @@ -1,5 +1,14 @@ +use aiken/collection/list use aiken/collection/pairs -use cardano/transaction.{Input, Redeemer, ScriptPurpose, Spend} +use cardano/address.{Credential} +use cardano/assets.{Lovelace, lovelace_of} +use cardano/certificate.{ + Certificate, DelegateBlockProduction, DelegateBoth, DelegateCredential, + DelegateRepresentative, DelegateVote, RegisterCredential, + RegisterDelegateRepresentative, StakePoolId, UnregisterCredential, + UnregisterDelegateRepresentative, +} +use cardano/transaction.{Input, Output, Redeemer, ScriptPurpose, Spend} pub fn redeemer_with_input( redeemers: Pairs, @@ -8,3 +17,95 @@ pub fn redeemer_with_input( let output_reference = input.output_reference redeemers |> pairs.get_first(Spend(output_reference)) } + +pub fn register_stake_certificate( + certificates: List, + credential: Credential, +) { + list.has(certificates, RegisterCredential { credential, deposit: Never }) +} + +pub fn unregister_stake_certificate( + certificates: List, + credential: Credential, +) { + list.has(certificates, UnregisterCredential { credential, refund: Never }) +} + +pub fn register_drep_certificate( + certificates: List, + credential: Credential, + deposit: Lovelace, +) { + list.has( + certificates, + RegisterDelegateRepresentative { + delegate_representative: credential, + deposit, + }, + ) +} + +pub fn unregister_drep_certificate( + certificates: List, + credential: Credential, + refund: Lovelace, +) { + list.has( + certificates, + UnregisterDelegateRepresentative { + delegate_representative: credential, + refund, + }, + ) +} + +pub fn delegate_vote_certificate( + certificates: List, + credential: Credential, + delegate_representative: DelegateRepresentative, +) { + list.has( + certificates, + DelegateCredential { + credential, + delegate: DelegateVote { delegate_representative }, + }, + ) +} + +pub fn delegate_stake_certificate( + certificates: List, + credential: Credential, + stake_pool: StakePoolId, +) { + list.has( + certificates, + DelegateCredential { + credential, + delegate: DelegateBlockProduction { stake_pool }, + }, + ) +} + +pub fn delegate_stake_and_vote_certificate( + certificates: List, + credential: Credential, + stake_pool: StakePoolId, + delegate_representative: DelegateRepresentative, +) { + list.has( + certificates, + DelegateCredential { + credential, + delegate: DelegateBoth { stake_pool, delegate_representative }, + }, + ) +} + +pub fn check_lovelace_diff(input: Input, output: Output, diff: Lovelace) { + let lovelace_from_input_output = input.output.value |> lovelace_of() + let lovelace_from_output = output.value |> lovelace_of() + + lovelace_from_output - lovelace_from_input_output == diff +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md index 4ad76c581..09e4a1977 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md @@ -5,6 +5,8 @@ - `delegate_pool_id`: ByteArray - `gov_action`: GovernanceAction - `proposer_key_hash`: ByteArray +- `stake_register_deposit`: Int +- `drep_register_deposti`: Int ## Datum @@ -44,7 +46,7 @@ pub type Datum { - Delegate to current own DRep + stake pool `delegate_pool_id` - Propose gov action - Vote on same proposal? -> if cant, create one more separate state - - todo: check 100k lock before retification correctly + - todo: check 100k lock before ratification correctly 2. DeregisterCerts diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak index e69de29bb..2c2fc36e3 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak @@ -0,0 +1,251 @@ +use aiken/collection/list +use cardano/address.{Inline} +use cardano/assets.{Lovelace, lovelace_of} +use cardano/certificate.{Registered} +use cardano/governance.{GovernanceAction, ProposalProcedure} +use cardano/transaction.{OutputReference, Transaction, find_input} +use cocktail.{ + inputs_at, key_signed, only_minted_token, output_inline_datum, outputs_at, + valid_after, value_length, +} +use types.{ + ContributorWithdrawal, CrowdfundGovDatum, CrowdfundRedeemer, DeregisterCerts, + Init, Proposed, Refundable, RegisterCerts, RemoveEmptyInstance, +} +use utils.{ + check_lovelace_diff, delegate_stake_and_vote_certificate, + delegate_stake_certificate, delegate_vote_certificate, + register_drep_certificate, register_stake_certificate, + unregister_drep_certificate, unregister_stake_certificate, +} + +validator spend( + delegate_pool_id: ByteArray, + gov_action: GovernanceAction, + proposer_key_hash: ByteArray, + stake_register_deposit: Lovelace, + drep_register_deposit: Lovelace, +) { + spend( + datum_opt: Option, + redeemer: CrowdfundRedeemer, + input: OutputReference, + self: Transaction, + ) { + let Transaction { + inputs, + validity_range, + mint, + outputs, + extra_signatories, + certificates, + proposal_procedures, + .. + } = self + + expect Some(own_input) = find_input(inputs, input) + expect Some(only_input_datum) = datum_opt + + let current_address = own_input.output.address + + // check only 1 input from current address + expect [only_input] = inputs_at(inputs, current_address) + + when redeemer is { + RegisterCerts -> + when only_input_datum is { + Init { share_token, deadline, funds_controlled, completion_script } -> { + expect Some(current_stake_credential) = + current_address.stake_credential + + expect Inline(current_credential) = current_stake_credential + + expect [only_output] = outputs_at(outputs, current_address) + + let lovelace_from_only_input = + only_input.output.value |> lovelace_of() + + let lovelace_check = + check_lovelace_diff( + only_input, + only_output, + -(stake_register_deposit + drep_register_deposit), + ) + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Proposed { + completion_script, + share_token, + funds_controlled, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 1 + + let reg_stake_cert_check = + register_stake_certificate(certificates, current_credential) + + let reg_drep_cert_check = + register_drep_certificate( + certificates, + current_credential, + drep_register_deposit, + ) + + let delegate_check = + delegate_vote_certificate( + certificates, + current_credential, + Registered(current_credential), + ) && delegate_stake_certificate( + certificates, + current_credential, + delegate_pool_id, + ) || delegate_stake_and_vote_certificate( + certificates, + current_credential, + delegate_pool_id, + Registered(current_credential), + ) + + let proposal_check = + list.has( + proposal_procedures, + ProposalProcedure { + deposit: lovelace_from_only_input - stake_register_deposit - drep_register_deposit, + return_address: current_address.payment_credential, + governance_action: gov_action, + }, + ) + lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? + } + _ -> False + } + + DeregisterCerts -> + when only_input_datum is { + Refundable { + share_token, + deadline, + funds_controlled, + completion_script, + } -> { + expect Some(current_stake_credential) = + current_address.stake_credential + + expect Inline(current_credential) = current_stake_credential + let validity_check = valid_after(validity_range, deadline) + expect [only_output] = outputs_at(outputs, current_address) + let lovelace_check = + check_lovelace_diff( + only_input, + only_output, + stake_register_deposit + drep_register_deposit, + ) + + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Refundable { + completion_script, + share_token, + funds_controlled, + deadline, + } + + let unreg_stake_cert_check = + unregister_stake_certificate(certificates, current_credential) + + let unreg_drep_cert_check = + unregister_drep_certificate( + certificates, + current_credential, + drep_register_deposit, + ) + validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? + } + + _ -> False + } + + ContributorWithdrawal -> + when only_input_datum is { + Refundable { + share_token, + deadline, + funds_controlled, + completion_script, + } -> { + let validity_check = valid_after(validity_range, deadline) + + expect [only_output] = outputs_at(outputs, current_address) + + let lovelace_from_only_input = + only_input.output.value |> lovelace_of() + let lovelace_from_only_output = only_output.value |> lovelace_of() + + let lovelace_withdrawn = + lovelace_from_only_output - lovelace_from_only_input + + let lovelace_withdrawn_check = lovelace_withdrawn < 0 + + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Refundable { + completion_script, + share_token, + funds_controlled: funds_controlled + lovelace_withdrawn, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 1 + + validity_check? && lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( + mint, + share_token, + completion_script, + lovelace_withdrawn, + )? + } + _ -> False + } + + RemoveEmptyInstance -> + when only_input_datum is { + Refundable { + share_token, + deadline, + funds_controlled, + completion_script, + } -> { + let validity_check = valid_after(validity_range, deadline) + + let token_burnt_check = + if funds_controlled > 0 { + only_minted_token( + mint, + share_token, + completion_script, + -funds_controlled, + ) + } else { + True + } + + let proposer_key_signed_check = + key_signed(extra_signatories, proposer_key_hash) + validity_check? && token_burnt_check? && proposer_key_signed_check? + } + _ -> False + } + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak new file mode 100644 index 000000000..1e5e6e438 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak @@ -0,0 +1,1369 @@ +use cardano/address.{Script} +use cardano/assets.{add, from_lovelace} +use cardano/certificate.{ + DelegateBlockProduction, DelegateCredential, DelegateVote, RegisterCredential, + RegisterDelegateRepresentative, Registered, UnregisterCredential, + UnregisterDelegateRepresentative, +} +use cardano/governance.{ProposalProcedure} +use cardano/transaction.{Transaction} +use mocktail.{ + add_certificate, add_extra_signatory, complete, invalid_before, mint, + mock_policy_id, mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, + tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use spend +use tests/utils.{ + add_proposal_procedure, mock_completion_script, + mock_contribute_min_fundraised_amount, mock_current_fundraised_amount, + mock_deadline, mock_delegate_pool_id, mock_drep_register_deposit, + mock_funds_controlled, mock_gov_action, mock_gov_action_period, + mock_gov_address, mock_proposer_key_hash, mock_share_token, + mock_spend_script_hash, mock_stake_register_deposit, mock_stake_script_hash, +} +use types.{ + ContributorWithdrawal, Init, Proposed, Refundable, RegisterCerts, + RemoveEmptyInstance, +} + +type RegisterCertsTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_output_value_correct: Bool, + is_stake_cert_register: Bool, + is_drep_cert_register: Bool, + is_drep_deposit_correct: Bool, + is_stake_delegated: Bool, + is_vote_delegated: Bool, + is_gov_proposed: Bool, +} + +fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { + let RegisterCertsTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_output_value_correct, + is_stake_cert_register, + is_drep_cert_register, + is_drep_deposit_correct, + is_stake_delegated, + is_vote_delegated, + is_gov_proposed, + } = test_case + + let input_value = from_lovelace(mock_funds_controlled) + + let input_datum = + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + } + let output_value = + if is_output_value_correct { + from_lovelace( + mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, + ) + } else { + from_lovelace( + mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit + 10, + ) + } + + let output_datum = + if is_output_datum_correct { + Proposed { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Proposed { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled + 10, + deadline: mock_deadline + mock_gov_action_period, + } + } + + let drep_deposit = + if is_drep_deposit_correct { + mock_drep_register_deposit + } else { + mock_drep_register_deposit - 1000000 + } + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_completion_script, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) + |> complete() + |> add_certificate( + is_stake_cert_register, + RegisterCredential { + credential: Script(mock_stake_script_hash), + deposit: Never, + }, + ) + |> add_certificate( + is_drep_cert_register, + RegisterDelegateRepresentative { + delegate_representative: Script(mock_stake_script_hash), + deposit: drep_deposit, + }, + ) + |> add_certificate( + is_stake_delegated, + DelegateCredential { + credential: Script(mock_stake_script_hash), + delegate: DelegateBlockProduction { + stake_pool: mock_delegate_pool_id, + }, + }, + ) + |> add_certificate( + is_vote_delegated, + DelegateCredential { + credential: Script(mock_stake_script_hash), + delegate: DelegateVote { + delegate_representative: Registered(Script(mock_stake_script_hash)), + }, + }, + ) + |> add_proposal_procedure( + is_gov_proposed, + ProposalProcedure { + deposit: mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, + return_address: Script(mock_spend_script_hash), + governance_action: mock_gov_action, + }, + ) +} + +test s3_spend_success_reg_cert() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_not_init_state() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_more_than_one_input() fail { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_more_than_one_output() fail { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_incorrect_output_datum() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_output_value_not_clean() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_incorrect_output_value() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: False, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: False, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: False, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: False, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_stake_not_delegated() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: False, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_vote_not_delegated() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: False, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_gov_not_proposed() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: False, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +type ContributorWithdrawalTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_unlock_value_correct: Bool, + is_deadline_passed: Bool, + is_shares_burnt: Bool, +} + +fn mock_contributor_withdrawal_tx( + test_case: ContributorWithdrawalTestCase, + current_fundraised_amount: Int, + withdraw_amount: Int, +) -> Transaction { + let ContributorWithdrawalTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_unlock_value_correct, + is_deadline_passed, + is_shares_burnt, + } = test_case + + let input_value = from_lovelace(current_fundraised_amount) + + let input_datum = + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + } + let output_value = + if is_unlock_value_correct { + from_lovelace(current_fundraised_amount - withdraw_amount) + } else { + from_lovelace(current_fundraised_amount - withdraw_amount + 10) + } + + let output_datum = + if is_output_datum_correct { + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount - withdraw_amount, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount - withdraw_amount + 10, + deadline: mock_deadline + mock_gov_action_period, + } + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out(True, mock_pub_key_address(0, None), from_lovelace(withdraw_amount)) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_completion_script, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) + |> invalid_before( + is_deadline_passed, + mock_deadline + mock_gov_action_period + 3600 * 24, + ) + |> invalid_before( + !is_deadline_passed, + mock_deadline + mock_gov_action_period - 3600 * 24, + ) + |> mint( + is_shares_burnt, + -withdraw_amount, + mock_share_token, + mock_completion_script, + ) + |> mint( + !is_shares_burnt, + -withdraw_amount + 9999999, + mock_share_token, + mock_completion_script, + ) + |> complete() +} + +test s3_spend_success_contributor_withdraw() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: False, + is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_deadline_not_passed() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: False, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + is_deadline_passed: True, + is_shares_burnt: False, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +type RemoveEmptyInstanceTestCase { + is_only_one_inputed: Bool, + is_deadline_passed: Bool, + is_shares_burnt: Bool, + is_proposer_signed: Bool, +} + +fn mock_remove_empty_instance_tx( + test_case: RemoveEmptyInstanceTestCase, + current_fundraised_amount: Int, +) -> Transaction { + let RemoveEmptyInstanceTestCase { + is_only_one_inputed, + is_deadline_passed, + is_shares_burnt, + is_proposer_signed, + } = test_case + + let input_value = from_lovelace(current_fundraised_amount) + + let input_datum = + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out( + True, + mock_pub_key_address(0, None), + from_lovelace(current_fundraised_amount), + ) + |> invalid_before( + is_deadline_passed, + mock_deadline + mock_gov_action_period + 3600 * 24, + ) + |> invalid_before( + !is_deadline_passed, + mock_deadline + mock_gov_action_period - 3600 * 24, + ) + |> mint( + is_shares_burnt, + -current_fundraised_amount, + mock_share_token, + mock_completion_script, + ) + |> mint( + !is_shares_burnt, + -current_fundraised_amount + 9999999, + mock_share_token, + mock_completion_script, + ) + |> complete() + |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) +} + +test s3_spend_success_remove_empty_instance_wih_zero_fund() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_proposer_signed: True, + }, + 0, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: 0, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_success_remove_empty_instance_wih_some_fund() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: False, + is_deadline_passed: True, + is_shares_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + is_deadline_passed: False, + is_shares_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + is_deadline_passed: True, + is_shares_burnt: False, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_proposer_not_signed() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + is_deadline_passed: True, + is_shares_burnt: True, + is_proposer_signed: False, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + completion_script: mock_completion_script, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak index 18284ec4b..e7188fa6a 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak @@ -1,4 +1,4 @@ -use cardano/assets.{add, from_lovelace} +use cardano/assets.{from_lovelace} use cardano/certificate.{RegisterCredential} use cardano/script_context.{Publishing, ScriptContext} use cardano/transaction.{OutputReference, Spend, Transaction} @@ -8,8 +8,7 @@ use mocktail.{ } use stake use tests/utils.{ - mock_auth_token, mock_completion_script, mock_crowdfund_gov_address, - mock_spend_script_hash, + mock_crowdfund_gov_address, mock_fundraise_target, mock_spend_script_hash, } use types.{Deregister, DeregisterCerts, Register, RegisterCerts} @@ -22,8 +21,7 @@ fn mock_stake_tx( only_input_redeemer: Data, ) -> Transaction { let StakeTestCase { is_only_one_auth_inputed } = test_case - let only_input = - from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) + let only_input = from_lovelace(mock_fundraise_target) mocktail_tx() |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) |> tx_in( diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index d26e19c0e..5278a3af4 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -1,5 +1,11 @@ +use aiken/collection/list use cardano/address.{Address, Inline, Script, from_script} -use mocktail.{mock_policy_id, mock_script_hash, mock_script_stake_key_hash} +use cardano/governance.{NoConfidence, ProposalProcedure} +use cardano/transaction.{Transaction} +use mocktail.{ + mock_policy_id, mock_pub_key_hash, mock_script_hash, + mock_script_stake_key_hash, +} use types.{CrowdfundDatum} pub const mock_auth_token = mock_policy_id(0) @@ -20,6 +26,8 @@ pub const mock_fundraise_target = 100000000000 pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 +pub const mock_contribute_min_fundraised_amount = 2000000 + pub const mock_deadline = 1750735607 pub const mock_expiry_buffer = 3600 * 24 @@ -57,3 +65,32 @@ pub const mock_gov_address = } pub const mock_gov_action_period = 3600 + +pub const mock_delegate_pool_id = mock_script_hash(3) + +pub const mock_gov_action = NoConfidence { ancestor: None } + +pub const mock_proposer_key_hash = mock_pub_key_hash(0) + +pub const mock_stake_register_deposit = 2000000 + +pub const mock_drep_register_deposit = 500000000 + +pub const mock_funds_controlled = + mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit + +pub fn add_proposal_procedure( + tx: Transaction, + condition: Bool, + proposal_procedure: ProposalProcedure, +) -> Transaction { + if !condition { + tx + } else { + Transaction { + ..tx, + proposal_procedures: tx.proposal_procedures + |> list.concat([proposal_procedure]), + } + } +} From abfe085f5ad2dc0dd5e77a0d6bd6f8e68f2f64bc Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 26 Jun 2025 18:19:41 +0800 Subject: [PATCH 08/24] updated: spec --- .../gov-crowdfund/specs/1_spend.md | 40 ++++++++----- .../gov-crowdfund/specs/2_stake.md | 15 ----- .../gov-crowdfund/specs/2_start.md | 57 +++++++++++++++++++ .../gov-crowdfund/specs/3_start.md | 25 -------- .../gov-crowdfund/specs/_scripts.md | 11 +--- 5 files changed, 87 insertions(+), 61 deletions(-) delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md index 09e4a1977..4e92d5944 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md @@ -5,27 +5,34 @@ - `delegate_pool_id`: ByteArray - `gov_action`: GovernanceAction - `proposer_key_hash`: ByteArray -- `stake_register_deposit`: Int -- `drep_register_deposti`: Int +- `stake_register_deposit`: Lovelace +- `drep_register_deposit`: Lovelace ## Datum ```rs pub type Datum { Init { - completion_script: ByteArray, + start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, deadline: Int, } Proposed { - completion_script: ByteArray, + start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, deadline: Int, } + Voted { + start_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + gov_tx_id: GovernanceActionId + deadline: Int, + } Refundable { - completion_script: ByteArray, + start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, deadline: Int, @@ -39,32 +46,39 @@ pub type Datum { - Only one input and output from current address - Input datum in state of `Init` + - Output value has deducted with 502 ADA exactly - Output datum in state of `Proposed` - fields exactly the same - Registering stake cert - - Registering DRep cert + - Registering DRep cert with drep_register_deposit - Delegate to current own DRep + stake pool `delegate_pool_id` - Propose gov action - - Vote on same proposal? -> if cant, create one more separate state - - todo: check 100k lock before ratification correctly -2. DeregisterCerts +2. VoteOnGovAction - - deadline is passed - Only one input and output from current address - Input datum in state of `Proposed` + - Check output value (deducted by 100k ADA exactly) + - Output datum in state of `Voted`, with `gov_tx_id` composed by own's input `TransactionId` + `proposal_procedure` as 0 + - fields exactly the same + +3. DeregisterCerts + + - deadline is passed + - Only one input and output from current address + - Input datum in state of `Voted` - Output datum in state of `Refundable` - fields exactly the same - Deregistering both certs - - Refunds go into the output + - Refunds (502ADA) go into the output -3. ContributorWithdrawal +4. ContributorWithdrawal - Input datum in state of Refundable - `deadline` is passed - The lovelace unlocking from current equal exactly the amount that the `share_token` with token name of `completion_script` is burnt -4. RemoveEmptyInstance +5. RemoveEmptyInstance - Input datum in state of Refundable - `deadline` is passed diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md deleted file mode 100644 index a6b11130c..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_stake.md +++ /dev/null @@ -1,15 +0,0 @@ -# Specification - Stake - -## Parameter - -- `spend_script_hash`: The script hash of the spending part - -## User Action - -1. Register - - - Only 1 input from `spend_script_hash` with redeemer of `RegisterCerts` - -2. Deregister - - - Only 1 input from `spend_script_hash` with redeemer of `DeregisterCerts` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md new file mode 100644 index 000000000..3471a3568 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md @@ -0,0 +1,57 @@ +# Specification - Start + +## Parameter + +- `auth_token`: The policy ID of crowdfunding token +- `spend`: The script hash of the spending part of the gov system +- `gov_action_period`: The buffer since crowdfund deadline to complete entire gov process + +## User Action - Withdraw + +1. Validate completion of crowdfunding + + - Only one input with `auth_token`, with inline datum + `completion_script` same as current crendential hash + - Exactly 1 token with `current_script_hash` policy is minted + - All `fundraise_target` amount of ADA + currently minted token is sent to address composed of `spend` and `current_script_hash` (both script hash) + - With datum: + + ```rs + Init { + start_hash: , + share_token: , + funds_controlled: , + deadline: , + } + ``` + +## User Action - Mint + +1. Mint - Redeemer `RMint` + + - The current token policy's equivalent withdrawal script is validated + +2. Burn - Redeemer `RBurn` + + - Only 1 input from `spend_script_hash` with redeemer of `RemoveEmptyInstance` + +## User Action - Publish + +1. Redeemer 1 - Register + + - Only 1 input from `spend_script_hash` with redeemer of `RegisterCerts` + +2. Redeemer 2 - Deregister + + - Only 1 input from `spend_script_hash` with redeemer of `DeregisterCerts` + +## User Action - Propose + +1. Propose gov action + + - Only 1 input from `spend_script_hash` with redeemer of `RegisterCerts` + +## User Action - Vote + +1. Propose gov action + + - Only 1 input from `spend_script_hash` with redeemer of `VoteOnGovAction` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md deleted file mode 100644 index b07a65114..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/3_start.md +++ /dev/null @@ -1,25 +0,0 @@ -# Specification - Start - -## Parameter - -- `auth_token`: The policy ID of crowdfunding token -- `spend`: The script hash of the spending part of the gov system -- `stake`: The script hash of the staking part of the gov system -- `gov_action_period`: The buffer since crowdfund deadline to complete entire gov process - -## User Action - -1. Validate completion of crowdfunding - - - Only one input with `auth_token`, with inline datum + `completion_script` same as current crendential hash - - All `fundraise_target` amount of ADA is sent to address composed of `spend` and `stake` (both script hash) - - With datum: - - ```rs - Init { - completion_script: , - share_token: , - funds_controlled: , - deadline: , - } - ``` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md index cb2f26cb4..94cedaeca 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md @@ -4,21 +4,16 @@ The spending validator that guarding the crowdfunded -## 2. Stake +## 2. Start -The token that represents lovelace contributed to current crowdfunding campaign - -## 3. Start - -The withdrawal script that oversight the completion of crowdfunding (i.e. `completion_script` at crowdfunding script) +The withdrawal script that oversight the completion of crowdfunding (i.e. `completion_script` at crowdfunding script). Also as the script for current campaign auth token + all gov power. ## Param dependency tree 1. First layer - `spend` - no param - - `stake` - no param 2. Second layer - - `start` - param `spend` and `stake` + - `start` - param `spend` From 6e678a6d2bebb1ac466a896a4047efc2a60ef5ea Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Thu, 26 Jun 2025 19:08:45 +0800 Subject: [PATCH 09/24] updated: start todo: start test todo: spend --- .../validators/crowdfund/spend.ak | 2 +- .../gov-crowdfund/lib/types.ak | 22 +- .../gov-crowdfund/lib/utils.ak | 20 +- .../gov-crowdfund/plutus.json | 248 ++ .../gov-crowdfund/validators/spend.ak | 502 +-- .../gov-crowdfund/validators/stake.ak | 36 - .../gov-crowdfund/validators/start.ak | 85 +- .../gov-crowdfund/validators/tests/spend.ak | 2738 ++++++++--------- .../gov-crowdfund/validators/tests/stake.ak | 274 +- .../gov-crowdfund/validators/tests/start.ak | 412 +-- .../gov-crowdfund/validators/tests/utils.ak | 140 +- 11 files changed, 2394 insertions(+), 2085 deletions(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak index 827b8cf86..017f07a62 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak @@ -111,7 +111,7 @@ validator crowdfund(auth_token: PolicyId) { let withdrawal_script_check = withdrawals |> has_key(completion_script_withdrawal_credential) - fundraise_check? && withdrawal_script_check? && only_minted_token( + fundraise_check? && withdrawal_script_check? && policy_only_minted_token( mint, auth_token, completion_script, diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak index 948ee8a32..4d53cd0de 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak @@ -1,8 +1,10 @@ use cardano/address.{Address} +use cardano/governance.{GovernanceActionId} pub type CrowdfundRedeemer { RegisterCerts DeregisterCerts + VoteOnGovAction ContributorWithdrawal RemoveEmptyInstance } @@ -22,26 +24,38 @@ pub type CrowdfundDatum { pub type CrowdfundGovDatum { Init { - completion_script: ByteArray, + start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, deadline: Int, } Proposed { - completion_script: ByteArray, + start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, deadline: Int, } + Voted { + start_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + gov_tx_id: GovernanceActionId, + deadline: Int, + } Refundable { - completion_script: ByteArray, + start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, deadline: Int, } } -pub type StakeRedeemer { +pub type MintPolarity { + RMint + RBurn +} + +pub type PublishRedeemer { Register Deregister } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak index 2b72369a7..e9d0491e3 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak @@ -1,6 +1,6 @@ use aiken/collection/list use aiken/collection/pairs -use cardano/address.{Credential} +use cardano/address.{Credential, from_script} use cardano/assets.{Lovelace, lovelace_of} use cardano/certificate.{ Certificate, DelegateBlockProduction, DelegateBoth, DelegateCredential, @@ -9,6 +9,8 @@ use cardano/certificate.{ UnregisterDelegateRepresentative, } use cardano/transaction.{Input, Output, Redeemer, ScriptPurpose, Spend} +use cocktail.{inputs_at} +use types.{CrowdfundRedeemer} pub fn redeemer_with_input( redeemers: Pairs, @@ -109,3 +111,19 @@ pub fn check_lovelace_diff(input: Input, output: Output, diff: Lovelace) { lovelace_from_output - lovelace_from_input_output == diff } + +pub fn check_spend_script_input_redeemer( + spend: ByteArray, + inputs: List, + redeemers: Pairs, + redeemer: CrowdfundRedeemer, +) { + let spend_address = from_script(spend) + expect [only_input] = inputs_at(inputs, spend_address) + expect Some(only_inpuy_redeemer_data) = + redeemer_with_input(redeemers, only_input) + + expect only_input_redeemer: CrowdfundRedeemer = only_inpuy_redeemer_data + + only_input_redeemer == redeemer +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json new file mode 100644 index 000000000..4f4bf0764 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json @@ -0,0 +1,248 @@ +{ + "preamble": { + "title": "sidan-lab/gov-crowdfund", + "description": "Aiken contracts for project 'sidan-lab/gov-crowdfund'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.7+e2fb28b" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "start.start.withdraw", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + }, + { + "title": "start.start.mint", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1MintPolarity" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + }, + { + "title": "start.start.publish", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1PublishRedeemer" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + }, + { + "title": "start.start.propose", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + }, + { + "title": "start.start.vote", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + }, + { + "title": "start.start.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + } + ], + "definitions": { + "ByteArray": { + "dataType": "bytes" + }, + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, + "Int": { + "dataType": "integer" + }, + "PolicyId": { + "title": "PolicyId", + "dataType": "bytes" + }, + "types/MintPolarity": { + "title": "MintPolarity", + "anyOf": [ + { + "title": "RMint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "RBurn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "types/PublishRedeemer": { + "title": "PublishRedeemer", + "anyOf": [ + { + "title": "Register", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Deregister", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + } + } +} \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak index 2c2fc36e3..33648a5f7 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak @@ -1,251 +1,251 @@ -use aiken/collection/list -use cardano/address.{Inline} -use cardano/assets.{Lovelace, lovelace_of} -use cardano/certificate.{Registered} -use cardano/governance.{GovernanceAction, ProposalProcedure} -use cardano/transaction.{OutputReference, Transaction, find_input} -use cocktail.{ - inputs_at, key_signed, only_minted_token, output_inline_datum, outputs_at, - valid_after, value_length, -} -use types.{ - ContributorWithdrawal, CrowdfundGovDatum, CrowdfundRedeemer, DeregisterCerts, - Init, Proposed, Refundable, RegisterCerts, RemoveEmptyInstance, -} -use utils.{ - check_lovelace_diff, delegate_stake_and_vote_certificate, - delegate_stake_certificate, delegate_vote_certificate, - register_drep_certificate, register_stake_certificate, - unregister_drep_certificate, unregister_stake_certificate, -} - -validator spend( - delegate_pool_id: ByteArray, - gov_action: GovernanceAction, - proposer_key_hash: ByteArray, - stake_register_deposit: Lovelace, - drep_register_deposit: Lovelace, -) { - spend( - datum_opt: Option, - redeemer: CrowdfundRedeemer, - input: OutputReference, - self: Transaction, - ) { - let Transaction { - inputs, - validity_range, - mint, - outputs, - extra_signatories, - certificates, - proposal_procedures, - .. - } = self - - expect Some(own_input) = find_input(inputs, input) - expect Some(only_input_datum) = datum_opt - - let current_address = own_input.output.address - - // check only 1 input from current address - expect [only_input] = inputs_at(inputs, current_address) - - when redeemer is { - RegisterCerts -> - when only_input_datum is { - Init { share_token, deadline, funds_controlled, completion_script } -> { - expect Some(current_stake_credential) = - current_address.stake_credential - - expect Inline(current_credential) = current_stake_credential - - expect [only_output] = outputs_at(outputs, current_address) - - let lovelace_from_only_input = - only_input.output.value |> lovelace_of() - - let lovelace_check = - check_lovelace_diff( - only_input, - only_output, - -(stake_register_deposit + drep_register_deposit), - ) - expect only_output_datum: CrowdfundGovDatum = - output_inline_datum(only_output) - let output_datum_check = - only_output_datum == Proposed { - completion_script, - share_token, - funds_controlled, - deadline, - } - - let is_only_output_value_clean = - value_length(only_output.value) == 1 - - let reg_stake_cert_check = - register_stake_certificate(certificates, current_credential) - - let reg_drep_cert_check = - register_drep_certificate( - certificates, - current_credential, - drep_register_deposit, - ) - - let delegate_check = - delegate_vote_certificate( - certificates, - current_credential, - Registered(current_credential), - ) && delegate_stake_certificate( - certificates, - current_credential, - delegate_pool_id, - ) || delegate_stake_and_vote_certificate( - certificates, - current_credential, - delegate_pool_id, - Registered(current_credential), - ) - - let proposal_check = - list.has( - proposal_procedures, - ProposalProcedure { - deposit: lovelace_from_only_input - stake_register_deposit - drep_register_deposit, - return_address: current_address.payment_credential, - governance_action: gov_action, - }, - ) - lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? - } - _ -> False - } - - DeregisterCerts -> - when only_input_datum is { - Refundable { - share_token, - deadline, - funds_controlled, - completion_script, - } -> { - expect Some(current_stake_credential) = - current_address.stake_credential - - expect Inline(current_credential) = current_stake_credential - let validity_check = valid_after(validity_range, deadline) - expect [only_output] = outputs_at(outputs, current_address) - let lovelace_check = - check_lovelace_diff( - only_input, - only_output, - stake_register_deposit + drep_register_deposit, - ) - - expect only_output_datum: CrowdfundGovDatum = - output_inline_datum(only_output) - let output_datum_check = - only_output_datum == Refundable { - completion_script, - share_token, - funds_controlled, - deadline, - } - - let unreg_stake_cert_check = - unregister_stake_certificate(certificates, current_credential) - - let unreg_drep_cert_check = - unregister_drep_certificate( - certificates, - current_credential, - drep_register_deposit, - ) - validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? - } - - _ -> False - } - - ContributorWithdrawal -> - when only_input_datum is { - Refundable { - share_token, - deadline, - funds_controlled, - completion_script, - } -> { - let validity_check = valid_after(validity_range, deadline) - - expect [only_output] = outputs_at(outputs, current_address) - - let lovelace_from_only_input = - only_input.output.value |> lovelace_of() - let lovelace_from_only_output = only_output.value |> lovelace_of() - - let lovelace_withdrawn = - lovelace_from_only_output - lovelace_from_only_input - - let lovelace_withdrawn_check = lovelace_withdrawn < 0 - - expect only_output_datum: CrowdfundGovDatum = - output_inline_datum(only_output) - let output_datum_check = - only_output_datum == Refundable { - completion_script, - share_token, - funds_controlled: funds_controlled + lovelace_withdrawn, - deadline, - } - - let is_only_output_value_clean = - value_length(only_output.value) == 1 - - validity_check? && lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( - mint, - share_token, - completion_script, - lovelace_withdrawn, - )? - } - _ -> False - } - - RemoveEmptyInstance -> - when only_input_datum is { - Refundable { - share_token, - deadline, - funds_controlled, - completion_script, - } -> { - let validity_check = valid_after(validity_range, deadline) - - let token_burnt_check = - if funds_controlled > 0 { - only_minted_token( - mint, - share_token, - completion_script, - -funds_controlled, - ) - } else { - True - } - - let proposer_key_signed_check = - key_signed(extra_signatories, proposer_key_hash) - validity_check? && token_burnt_check? && proposer_key_signed_check? - } - _ -> False - } - } - } - - else(_) { - fail - } -} +// use aiken/collection/list +// use cardano/address.{Inline} +// use cardano/assets.{Lovelace, lovelace_of} +// use cardano/certificate.{Registered} +// use cardano/governance.{GovernanceAction, ProposalProcedure} +// use cardano/transaction.{OutputReference, Transaction, find_input} +// use cocktail.{ +// inputs_at, key_signed, only_minted_token, output_inline_datum, outputs_at, +// valid_after, value_length, +// } +// use types.{ +// ContributorWithdrawal, CrowdfundGovDatum, CrowdfundRedeemer, DeregisterCerts, +// Init, Proposed, Refundable, RegisterCerts, RemoveEmptyInstance, +// } +// use utils.{ +// check_lovelace_diff, delegate_stake_and_vote_certificate, +// delegate_stake_certificate, delegate_vote_certificate, +// register_drep_certificate, register_stake_certificate, +// unregister_drep_certificate, unregister_stake_certificate, +// } + +// validator spend( +// delegate_pool_id: ByteArray, +// gov_action: GovernanceAction, +// proposer_key_hash: ByteArray, +// stake_register_deposit: Lovelace, +// drep_register_deposit: Lovelace, +// ) { +// spend( +// datum_opt: Option, +// redeemer: CrowdfundRedeemer, +// input: OutputReference, +// self: Transaction, +// ) { +// let Transaction { +// inputs, +// validity_range, +// mint, +// outputs, +// extra_signatories, +// certificates, +// proposal_procedures, +// .. +// } = self + +// expect Some(own_input) = find_input(inputs, input) +// expect Some(only_input_datum) = datum_opt + +// let current_address = own_input.output.address + +// // check only 1 input from current address +// expect [only_input] = inputs_at(inputs, current_address) + +// when redeemer is { +// RegisterCerts -> +// when only_input_datum is { +// Init { share_token, deadline, funds_controlled, completion_script } -> { +// expect Some(current_stake_credential) = +// current_address.stake_credential + +// expect Inline(current_credential) = current_stake_credential + +// expect [only_output] = outputs_at(outputs, current_address) + +// let lovelace_from_only_input = +// only_input.output.value |> lovelace_of() + +// let lovelace_check = +// check_lovelace_diff( +// only_input, +// only_output, +// -(stake_register_deposit + drep_register_deposit), +// ) +// expect only_output_datum: CrowdfundGovDatum = +// output_inline_datum(only_output) +// let output_datum_check = +// only_output_datum == Proposed { +// completion_script, +// share_token, +// funds_controlled, +// deadline, +// } + +// let is_only_output_value_clean = +// value_length(only_output.value) == 1 + +// let reg_stake_cert_check = +// register_stake_certificate(certificates, current_credential) + +// let reg_drep_cert_check = +// register_drep_certificate( +// certificates, +// current_credential, +// drep_register_deposit, +// ) + +// let delegate_check = +// delegate_vote_certificate( +// certificates, +// current_credential, +// Registered(current_credential), +// ) && delegate_stake_certificate( +// certificates, +// current_credential, +// delegate_pool_id, +// ) || delegate_stake_and_vote_certificate( +// certificates, +// current_credential, +// delegate_pool_id, +// Registered(current_credential), +// ) + +// let proposal_check = +// list.has( +// proposal_procedures, +// ProposalProcedure { +// deposit: lovelace_from_only_input - stake_register_deposit - drep_register_deposit, +// return_address: current_address.payment_credential, +// governance_action: gov_action, +// }, +// ) +// lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? +// } +// _ -> False +// } + +// DeregisterCerts -> +// when only_input_datum is { +// Refundable { +// share_token, +// deadline, +// funds_controlled, +// completion_script, +// } -> { +// expect Some(current_stake_credential) = +// current_address.stake_credential + +// expect Inline(current_credential) = current_stake_credential +// let validity_check = valid_after(validity_range, deadline) +// expect [only_output] = outputs_at(outputs, current_address) +// let lovelace_check = +// check_lovelace_diff( +// only_input, +// only_output, +// stake_register_deposit + drep_register_deposit, +// ) + +// expect only_output_datum: CrowdfundGovDatum = +// output_inline_datum(only_output) +// let output_datum_check = +// only_output_datum == Refundable { +// completion_script, +// share_token, +// funds_controlled, +// deadline, +// } + +// let unreg_stake_cert_check = +// unregister_stake_certificate(certificates, current_credential) + +// let unreg_drep_cert_check = +// unregister_drep_certificate( +// certificates, +// current_credential, +// drep_register_deposit, +// ) +// validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? +// } + +// _ -> False +// } + +// ContributorWithdrawal -> +// when only_input_datum is { +// Refundable { +// share_token, +// deadline, +// funds_controlled, +// completion_script, +// } -> { +// let validity_check = valid_after(validity_range, deadline) + +// expect [only_output] = outputs_at(outputs, current_address) + +// let lovelace_from_only_input = +// only_input.output.value |> lovelace_of() +// let lovelace_from_only_output = only_output.value |> lovelace_of() + +// let lovelace_withdrawn = +// lovelace_from_only_output - lovelace_from_only_input + +// let lovelace_withdrawn_check = lovelace_withdrawn < 0 + +// expect only_output_datum: CrowdfundGovDatum = +// output_inline_datum(only_output) +// let output_datum_check = +// only_output_datum == Refundable { +// completion_script, +// share_token, +// funds_controlled: funds_controlled + lovelace_withdrawn, +// deadline, +// } + +// let is_only_output_value_clean = +// value_length(only_output.value) == 1 + +// validity_check? && lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( +// mint, +// share_token, +// completion_script, +// lovelace_withdrawn, +// )? +// } +// _ -> False +// } + +// RemoveEmptyInstance -> +// when only_input_datum is { +// Refundable { +// share_token, +// deadline, +// funds_controlled, +// completion_script, +// } -> { +// let validity_check = valid_after(validity_range, deadline) + +// let token_burnt_check = +// if funds_controlled > 0 { +// only_minted_token( +// mint, +// share_token, +// completion_script, +// -funds_controlled, +// ) +// } else { +// True +// } + +// let proposer_key_signed_check = +// key_signed(extra_signatories, proposer_key_hash) +// validity_check? && token_burnt_check? && proposer_key_signed_check? +// } +// _ -> False +// } +// } +// } + +// else(_) { +// fail +// } +// } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak deleted file mode 100644 index 969dd4024..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/stake.ak +++ /dev/null @@ -1,36 +0,0 @@ -use cardano/address.{from_script} -use cardano/script_context.{ScriptContext} -use cardano/transaction.{Transaction} -use cocktail.{inputs_at} -use types.{ - CrowdfundRedeemer, Deregister, DeregisterCerts, Register, RegisterCerts, - StakeRedeemer, -} -use utils.{redeemer_with_input} - -validator stake(spend_script_hash: ByteArray) { - else(ctx: ScriptContext) { - let ScriptContext { transaction, redeemer, .. } = ctx - expect stake_redeemer: StakeRedeemer = redeemer - let Transaction { inputs, redeemers, .. } = transaction - let spend_address = from_script(spend_script_hash) - expect [only_input] = inputs_at(inputs, spend_address) - expect Some(only_inpuy_redeemer_data) = - redeemer_with_input(redeemers, only_input) - - expect only_input_redeemer: CrowdfundRedeemer = only_inpuy_redeemer_data - - when stake_redeemer is { - Register -> { - let redeemer_check = only_input_redeemer == RegisterCerts - - redeemer_check? - } - Deregister -> { - let redeemer_check = only_input_redeemer == DeregisterCerts - - redeemer_check? - } - } - } -} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak index ce4fff784..12dea9345 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak @@ -1,20 +1,25 @@ -use cardano/address.{Address, Credential, Inline, Script} +use aiken/collection/pairs.{has_key} +use cardano/address.{Address, Credential, Inline, Script, from_script} use cardano/assets.{PolicyId, lovelace_of} use cardano/transaction.{Transaction} use cocktail.{ - input_inline_datum, inputs_with_policy, output_inline_datum, outputs_at, + input_inline_datum, inputs_at, inputs_with_policy, output_inline_datum, + outputs_at_with, policy_only_minted_token, } -use types.{CrowdfundDatum, CrowdfundGovDatum, Init} +use types.{ + CrowdfundDatum, CrowdfundGovDatum, CrowdfundRedeemer, Deregister, + DeregisterCerts, Init, MintPolarity, PublishRedeemer, RBurn, RMint, Register, + RegisterCerts, RemoveEmptyInstance, VoteOnGovAction, +} +use utils.{check_spend_script_input_redeemer, redeemer_with_input} validator start( auth_token: PolicyId, spend: ByteArray, - stake: ByteArray, gov_action_period: Int, ) { withdraw(_r, account: Credential, self: Transaction) { - let Transaction { inputs, outputs, .. } = self - + let Transaction { inputs, outputs, mint, .. } = self expect [auth_token_input] = inputs_with_policy(inputs, auth_token) expect auth_input_datum: CrowdfundDatum = input_inline_datum(auth_token_input) @@ -32,10 +37,11 @@ validator start( let gov_address = Address { payment_credential: Script(spend), - stake_credential: Some(Inline(Script(stake))), + stake_credential: Some(Inline(Script(completion_script))), } - expect [fundraise_target_output] = outputs_at(outputs, gov_address) + expect [fundraise_target_output] = + outputs_at_with(outputs, gov_address, completion_script, "") let fundraise_output_lovelace_check = lovelace_of(fundraise_target_output.value) == fundraise_target @@ -43,12 +49,71 @@ validator start( output_inline_datum(fundraise_target_output) let fundraise_output_datum_check = fundraise_output_datum == Init { - completion_script, + start_hash: completion_script, share_token, funds_controlled: current_fundraised_amount, deadline: deadline + gov_action_period, } - completion_script_check? && fundraise_output_lovelace_check? && fundraise_output_datum_check? + completion_script_check? && fundraise_output_lovelace_check? && fundraise_output_datum_check? && policy_only_minted_token( + mint, + completion_script, + "", + 1, + )? + } + + mint(redeemer: MintPolarity, policy_id: PolicyId, self: Transaction) { + let Transaction { withdrawals, inputs, redeemers, .. } = self + when redeemer is { + RMint -> { + let withdrawal_credential: Credential = Script(policy_id) + let withdrawal_script_check = + withdrawals + |> has_key(withdrawal_credential) + + withdrawal_script_check? + } + RBurn -> + check_spend_script_input_redeemer( + spend, + inputs, + redeemers, + RemoveEmptyInstance, + )? + } + } + + publish(redeemer: PublishRedeemer, _c, self: Transaction) { + let Transaction { inputs, redeemers, .. } = self + let spend_address = from_script(spend) + expect [only_input] = inputs_at(inputs, spend_address) + expect Some(only_inpuy_redeemer_data) = + redeemer_with_input(redeemers, only_input) + + expect only_input_redeemer: CrowdfundRedeemer = only_inpuy_redeemer_data + + when redeemer is { + Register -> { + let redeemer_check = only_input_redeemer == RegisterCerts + + redeemer_check? + } + Deregister -> { + let redeemer_check = only_input_redeemer == DeregisterCerts + + redeemer_check? + } + } + } + + propose(_r, _p, self: Transaction) { + let Transaction { inputs, redeemers, .. } = self + check_spend_script_input_redeemer(spend, inputs, redeemers, RegisterCerts)? + } + + vote(_r, _v, self: Transaction) { + let Transaction { inputs, redeemers, .. } = self + check_spend_script_input_redeemer(spend, inputs, redeemers, VoteOnGovAction)? } else(_) { diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak index 1e5e6e438..5f3e69afd 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak @@ -1,1369 +1,1369 @@ -use cardano/address.{Script} -use cardano/assets.{add, from_lovelace} -use cardano/certificate.{ - DelegateBlockProduction, DelegateCredential, DelegateVote, RegisterCredential, - RegisterDelegateRepresentative, Registered, UnregisterCredential, - UnregisterDelegateRepresentative, -} -use cardano/governance.{ProposalProcedure} -use cardano/transaction.{Transaction} -use mocktail.{ - add_certificate, add_extra_signatory, complete, invalid_before, mint, - mock_policy_id, mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, - tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, -} -use spend -use tests/utils.{ - add_proposal_procedure, mock_completion_script, - mock_contribute_min_fundraised_amount, mock_current_fundraised_amount, - mock_deadline, mock_delegate_pool_id, mock_drep_register_deposit, - mock_funds_controlled, mock_gov_action, mock_gov_action_period, - mock_gov_address, mock_proposer_key_hash, mock_share_token, - mock_spend_script_hash, mock_stake_register_deposit, mock_stake_script_hash, -} -use types.{ - ContributorWithdrawal, Init, Proposed, Refundable, RegisterCerts, - RemoveEmptyInstance, -} - -type RegisterCertsTestCase { - is_only_one_inputed: Bool, - is_only_one_outputed: Bool, - is_output_datum_correct: Bool, - is_output_value_clean: Bool, - is_output_value_correct: Bool, - is_stake_cert_register: Bool, - is_drep_cert_register: Bool, - is_drep_deposit_correct: Bool, - is_stake_delegated: Bool, - is_vote_delegated: Bool, - is_gov_proposed: Bool, -} - -fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { - let RegisterCertsTestCase { - is_only_one_inputed, - is_only_one_outputed, - is_output_datum_correct, - is_output_value_clean, - is_output_value_correct, - is_stake_cert_register, - is_drep_cert_register, - is_drep_deposit_correct, - is_stake_delegated, - is_vote_delegated, - is_gov_proposed, - } = test_case - - let input_value = from_lovelace(mock_funds_controlled) - - let input_datum = - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - } - let output_value = - if is_output_value_correct { - from_lovelace( - mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, - ) - } else { - from_lovelace( - mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit + 10, - ) - } - - let output_datum = - if is_output_datum_correct { - Proposed { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - } - } else { - Proposed { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled + 10, - deadline: mock_deadline + mock_gov_action_period, - } - } - - let drep_deposit = - if is_drep_deposit_correct { - mock_drep_register_deposit - } else { - mock_drep_register_deposit - 1000000 - } - mocktail_tx() - |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) - |> tx_in_inline_datum(True, input_datum) - |> tx_in( - !is_only_one_inputed, - mock_tx_hash(0), - 1, - input_value, - mock_gov_address, - ) - |> tx_out(is_output_value_clean, mock_gov_address, output_value) - |> tx_out( - !is_output_value_clean, - mock_gov_address, - output_value |> add(mock_policy_id(999), mock_completion_script, 1), - ) - |> tx_out_inline_datum(True, output_datum) - |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) - |> complete() - |> add_certificate( - is_stake_cert_register, - RegisterCredential { - credential: Script(mock_stake_script_hash), - deposit: Never, - }, - ) - |> add_certificate( - is_drep_cert_register, - RegisterDelegateRepresentative { - delegate_representative: Script(mock_stake_script_hash), - deposit: drep_deposit, - }, - ) - |> add_certificate( - is_stake_delegated, - DelegateCredential { - credential: Script(mock_stake_script_hash), - delegate: DelegateBlockProduction { - stake_pool: mock_delegate_pool_id, - }, - }, - ) - |> add_certificate( - is_vote_delegated, - DelegateCredential { - credential: Script(mock_stake_script_hash), - delegate: DelegateVote { - delegate_representative: Registered(Script(mock_stake_script_hash)), - }, - }, - ) - |> add_proposal_procedure( - is_gov_proposed, - ProposalProcedure { - deposit: mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, - return_address: Script(mock_spend_script_hash), - governance_action: mock_gov_action, - }, - ) -} - -test s3_spend_success_reg_cert() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_not_init_state() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Proposed { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_more_than_one_input() fail { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: False, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_more_than_one_output() fail { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: False, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_incorrect_output_datum() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: False, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_output_value_not_clean() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: False, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_incorrect_output_value() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: False, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: False, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: False, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: False, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_stake_not_delegated() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: False, - is_vote_delegated: True, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_vote_not_delegated() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: False, - is_gov_proposed: True, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_reg_cert_with_gov_not_proposed() { - let tx = - mock_register_cert_tx( - RegisterCertsTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_output_value_correct: True, - is_stake_cert_register: True, - is_drep_cert_register: True, - is_drep_deposit_correct: True, - is_stake_delegated: True, - is_vote_delegated: True, - is_gov_proposed: False, - }, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_funds_controlled, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RegisterCerts, - mock_utxo_ref(0, 0), - tx, - ) -} - -type ContributorWithdrawalTestCase { - is_only_one_inputed: Bool, - is_only_one_outputed: Bool, - is_output_datum_correct: Bool, - is_output_value_clean: Bool, - is_unlock_value_correct: Bool, - is_deadline_passed: Bool, - is_shares_burnt: Bool, -} - -fn mock_contributor_withdrawal_tx( - test_case: ContributorWithdrawalTestCase, - current_fundraised_amount: Int, - withdraw_amount: Int, -) -> Transaction { - let ContributorWithdrawalTestCase { - is_only_one_inputed, - is_only_one_outputed, - is_output_datum_correct, - is_output_value_clean, - is_unlock_value_correct, - is_deadline_passed, - is_shares_burnt, - } = test_case - - let input_value = from_lovelace(current_fundraised_amount) - - let input_datum = - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - } - let output_value = - if is_unlock_value_correct { - from_lovelace(current_fundraised_amount - withdraw_amount) - } else { - from_lovelace(current_fundraised_amount - withdraw_amount + 10) - } - - let output_datum = - if is_output_datum_correct { - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: current_fundraised_amount - withdraw_amount, - deadline: mock_deadline + mock_gov_action_period, - } - } else { - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: current_fundraised_amount - withdraw_amount + 10, - deadline: mock_deadline + mock_gov_action_period, - } - } - - mocktail_tx() - |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) - |> tx_in_inline_datum(True, input_datum) - |> tx_in( - !is_only_one_inputed, - mock_tx_hash(0), - 1, - input_value, - mock_gov_address, - ) - |> tx_out(True, mock_pub_key_address(0, None), from_lovelace(withdraw_amount)) - |> tx_out(is_output_value_clean, mock_gov_address, output_value) - |> tx_out( - !is_output_value_clean, - mock_gov_address, - output_value |> add(mock_policy_id(999), mock_completion_script, 1), - ) - |> tx_out_inline_datum(True, output_datum) - |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) - |> invalid_before( - is_deadline_passed, - mock_deadline + mock_gov_action_period + 3600 * 24, - ) - |> invalid_before( - !is_deadline_passed, - mock_deadline + mock_gov_action_period - 3600 * 24, - ) - |> mint( - is_shares_burnt, - -withdraw_amount, - mock_share_token, - mock_completion_script, - ) - |> mint( - !is_shares_burnt, - -withdraw_amount + 9999999, - mock_share_token, - mock_completion_script, - ) - |> complete() -} - -test s3_spend_success_contributor_withdraw() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Proposed { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: False, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: False, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: False, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: False, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: False, - is_deadline_passed: True, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_deadline_not_passed() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: False, - is_shares_burnt: True, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { - let tx = - mock_contributor_withdrawal_tx( - ContributorWithdrawalTestCase { - is_only_one_inputed: True, - is_only_one_outputed: True, - is_output_datum_correct: True, - is_output_value_clean: True, - is_unlock_value_correct: True, - is_deadline_passed: True, - is_shares_burnt: False, - }, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - ContributorWithdrawal, - mock_utxo_ref(0, 0), - tx, - ) -} - -type RemoveEmptyInstanceTestCase { - is_only_one_inputed: Bool, - is_deadline_passed: Bool, - is_shares_burnt: Bool, - is_proposer_signed: Bool, -} - -fn mock_remove_empty_instance_tx( - test_case: RemoveEmptyInstanceTestCase, - current_fundraised_amount: Int, -) -> Transaction { - let RemoveEmptyInstanceTestCase { - is_only_one_inputed, - is_deadline_passed, - is_shares_burnt, - is_proposer_signed, - } = test_case - - let input_value = from_lovelace(current_fundraised_amount) - - let input_datum = - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - } - - mocktail_tx() - |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) - |> tx_in_inline_datum(True, input_datum) - |> tx_in( - !is_only_one_inputed, - mock_tx_hash(0), - 1, - input_value, - mock_gov_address, - ) - |> tx_out( - True, - mock_pub_key_address(0, None), - from_lovelace(current_fundraised_amount), - ) - |> invalid_before( - is_deadline_passed, - mock_deadline + mock_gov_action_period + 3600 * 24, - ) - |> invalid_before( - !is_deadline_passed, - mock_deadline + mock_gov_action_period - 3600 * 24, - ) - |> mint( - is_shares_burnt, - -current_fundraised_amount, - mock_share_token, - mock_completion_script, - ) - |> mint( - !is_shares_burnt, - -current_fundraised_amount + 9999999, - mock_share_token, - mock_completion_script, - ) - |> complete() - |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) -} - -test s3_spend_success_remove_empty_instance_wih_zero_fund() { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: True, - is_deadline_passed: True, - is_shares_burnt: True, - is_proposer_signed: True, - }, - 0, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: 0, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_success_remove_empty_instance_wih_some_fund() { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: True, - is_deadline_passed: True, - is_shares_burnt: True, - is_proposer_signed: True, - }, - mock_current_fundraised_amount, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: True, - is_deadline_passed: True, - is_shares_burnt: True, - is_proposer_signed: True, - }, - mock_current_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: False, - is_deadline_passed: True, - is_shares_burnt: True, - is_proposer_signed: True, - }, - mock_current_fundraised_amount, - ) - - spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: True, - is_deadline_passed: False, - is_shares_burnt: True, - is_proposer_signed: True, - }, - mock_current_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: True, - is_deadline_passed: True, - is_shares_burnt: False, - is_proposer_signed: True, - }, - mock_current_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} - -test s3_spend_fail_remove_empty_instance_wih_proposer_not_signed() { - let tx = - mock_remove_empty_instance_tx( - RemoveEmptyInstanceTestCase { - is_only_one_inputed: True, - is_deadline_passed: True, - is_shares_burnt: True, - is_proposer_signed: False, - }, - mock_current_fundraised_amount, - ) - - !spend.spend.spend( - mock_delegate_pool_id, - mock_gov_action, - mock_proposer_key_hash, - mock_stake_register_deposit, - mock_drep_register_deposit, - Some( - Refundable { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - }, - ), - RemoveEmptyInstance, - mock_utxo_ref(0, 0), - tx, - ) -} +// use cardano/address.{Script} +// use cardano/assets.{add, from_lovelace} +// use cardano/certificate.{ +// DelegateBlockProduction, DelegateCredential, DelegateVote, RegisterCredential, +// RegisterDelegateRepresentative, Registered, UnregisterCredential, +// UnregisterDelegateRepresentative, +// } +// use cardano/governance.{ProposalProcedure} +// use cardano/transaction.{Transaction} +// use mocktail.{ +// add_certificate, add_extra_signatory, complete, invalid_before, mint, +// mock_policy_id, mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, +// tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +// } +// use spend +// use tests/utils.{ +// add_proposal_procedure, mock_completion_script, +// mock_contribute_min_fundraised_amount, mock_current_fundraised_amount, +// mock_deadline, mock_delegate_pool_id, mock_drep_register_deposit, +// mock_funds_controlled, mock_gov_action, mock_gov_action_period, +// mock_gov_address, mock_proposer_key_hash, mock_share_token, +// mock_spend_script_hash, mock_stake_register_deposit, mock_stake_script_hash, +// } +// use types.{ +// ContributorWithdrawal, Init, Proposed, Refundable, RegisterCerts, +// RemoveEmptyInstance, +// } + +// type RegisterCertsTestCase { +// is_only_one_inputed: Bool, +// is_only_one_outputed: Bool, +// is_output_datum_correct: Bool, +// is_output_value_clean: Bool, +// is_output_value_correct: Bool, +// is_stake_cert_register: Bool, +// is_drep_cert_register: Bool, +// is_drep_deposit_correct: Bool, +// is_stake_delegated: Bool, +// is_vote_delegated: Bool, +// is_gov_proposed: Bool, +// } + +// fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { +// let RegisterCertsTestCase { +// is_only_one_inputed, +// is_only_one_outputed, +// is_output_datum_correct, +// is_output_value_clean, +// is_output_value_correct, +// is_stake_cert_register, +// is_drep_cert_register, +// is_drep_deposit_correct, +// is_stake_delegated, +// is_vote_delegated, +// is_gov_proposed, +// } = test_case + +// let input_value = from_lovelace(mock_funds_controlled) + +// let input_datum = +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// } +// let output_value = +// if is_output_value_correct { +// from_lovelace( +// mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, +// ) +// } else { +// from_lovelace( +// mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit + 10, +// ) +// } + +// let output_datum = +// if is_output_datum_correct { +// Proposed { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// } +// } else { +// Proposed { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled + 10, +// deadline: mock_deadline + mock_gov_action_period, +// } +// } + +// let drep_deposit = +// if is_drep_deposit_correct { +// mock_drep_register_deposit +// } else { +// mock_drep_register_deposit - 1000000 +// } +// mocktail_tx() +// |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) +// |> tx_in_inline_datum(True, input_datum) +// |> tx_in( +// !is_only_one_inputed, +// mock_tx_hash(0), +// 1, +// input_value, +// mock_gov_address, +// ) +// |> tx_out(is_output_value_clean, mock_gov_address, output_value) +// |> tx_out( +// !is_output_value_clean, +// mock_gov_address, +// output_value |> add(mock_policy_id(999), mock_completion_script, 1), +// ) +// |> tx_out_inline_datum(True, output_datum) +// |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) +// |> complete() +// |> add_certificate( +// is_stake_cert_register, +// RegisterCredential { +// credential: Script(mock_stake_script_hash), +// deposit: Never, +// }, +// ) +// |> add_certificate( +// is_drep_cert_register, +// RegisterDelegateRepresentative { +// delegate_representative: Script(mock_stake_script_hash), +// deposit: drep_deposit, +// }, +// ) +// |> add_certificate( +// is_stake_delegated, +// DelegateCredential { +// credential: Script(mock_stake_script_hash), +// delegate: DelegateBlockProduction { +// stake_pool: mock_delegate_pool_id, +// }, +// }, +// ) +// |> add_certificate( +// is_vote_delegated, +// DelegateCredential { +// credential: Script(mock_stake_script_hash), +// delegate: DelegateVote { +// delegate_representative: Registered(Script(mock_stake_script_hash)), +// }, +// }, +// ) +// |> add_proposal_procedure( +// is_gov_proposed, +// ProposalProcedure { +// deposit: mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, +// return_address: Script(mock_spend_script_hash), +// governance_action: mock_gov_action, +// }, +// ) +// } + +// test s3_spend_success_reg_cert() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_not_init_state() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Proposed { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_more_than_one_input() fail { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: False, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_more_than_one_output() fail { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: False, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_incorrect_output_datum() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: False, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_output_value_not_clean() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: False, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_incorrect_output_value() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: False, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: False, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: False, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: False, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_stake_not_delegated() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: False, +// is_vote_delegated: True, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_vote_not_delegated() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: False, +// is_gov_proposed: True, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_reg_cert_with_gov_not_proposed() { +// let tx = +// mock_register_cert_tx( +// RegisterCertsTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_output_value_correct: True, +// is_stake_cert_register: True, +// is_drep_cert_register: True, +// is_drep_deposit_correct: True, +// is_stake_delegated: True, +// is_vote_delegated: True, +// is_gov_proposed: False, +// }, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_funds_controlled, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RegisterCerts, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// type ContributorWithdrawalTestCase { +// is_only_one_inputed: Bool, +// is_only_one_outputed: Bool, +// is_output_datum_correct: Bool, +// is_output_value_clean: Bool, +// is_unlock_value_correct: Bool, +// is_deadline_passed: Bool, +// is_shares_burnt: Bool, +// } + +// fn mock_contributor_withdrawal_tx( +// test_case: ContributorWithdrawalTestCase, +// current_fundraised_amount: Int, +// withdraw_amount: Int, +// ) -> Transaction { +// let ContributorWithdrawalTestCase { +// is_only_one_inputed, +// is_only_one_outputed, +// is_output_datum_correct, +// is_output_value_clean, +// is_unlock_value_correct, +// is_deadline_passed, +// is_shares_burnt, +// } = test_case + +// let input_value = from_lovelace(current_fundraised_amount) + +// let input_datum = +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// } +// let output_value = +// if is_unlock_value_correct { +// from_lovelace(current_fundraised_amount - withdraw_amount) +// } else { +// from_lovelace(current_fundraised_amount - withdraw_amount + 10) +// } + +// let output_datum = +// if is_output_datum_correct { +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: current_fundraised_amount - withdraw_amount, +// deadline: mock_deadline + mock_gov_action_period, +// } +// } else { +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: current_fundraised_amount - withdraw_amount + 10, +// deadline: mock_deadline + mock_gov_action_period, +// } +// } + +// mocktail_tx() +// |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) +// |> tx_in_inline_datum(True, input_datum) +// |> tx_in( +// !is_only_one_inputed, +// mock_tx_hash(0), +// 1, +// input_value, +// mock_gov_address, +// ) +// |> tx_out(True, mock_pub_key_address(0, None), from_lovelace(withdraw_amount)) +// |> tx_out(is_output_value_clean, mock_gov_address, output_value) +// |> tx_out( +// !is_output_value_clean, +// mock_gov_address, +// output_value |> add(mock_policy_id(999), mock_completion_script, 1), +// ) +// |> tx_out_inline_datum(True, output_datum) +// |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) +// |> invalid_before( +// is_deadline_passed, +// mock_deadline + mock_gov_action_period + 3600 * 24, +// ) +// |> invalid_before( +// !is_deadline_passed, +// mock_deadline + mock_gov_action_period - 3600 * 24, +// ) +// |> mint( +// is_shares_burnt, +// -withdraw_amount, +// mock_share_token, +// mock_completion_script, +// ) +// |> mint( +// !is_shares_burnt, +// -withdraw_amount + 9999999, +// mock_share_token, +// mock_completion_script, +// ) +// |> complete() +// } + +// test s3_spend_success_contributor_withdraw() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Proposed { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: False, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: False, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: False, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: False, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: False, +// is_deadline_passed: True, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_deadline_not_passed() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: False, +// is_shares_burnt: True, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { +// let tx = +// mock_contributor_withdrawal_tx( +// ContributorWithdrawalTestCase { +// is_only_one_inputed: True, +// is_only_one_outputed: True, +// is_output_datum_correct: True, +// is_output_value_clean: True, +// is_unlock_value_correct: True, +// is_deadline_passed: True, +// is_shares_burnt: False, +// }, +// mock_current_fundraised_amount, +// mock_contribute_min_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// ContributorWithdrawal, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// type RemoveEmptyInstanceTestCase { +// is_only_one_inputed: Bool, +// is_deadline_passed: Bool, +// is_shares_burnt: Bool, +// is_proposer_signed: Bool, +// } + +// fn mock_remove_empty_instance_tx( +// test_case: RemoveEmptyInstanceTestCase, +// current_fundraised_amount: Int, +// ) -> Transaction { +// let RemoveEmptyInstanceTestCase { +// is_only_one_inputed, +// is_deadline_passed, +// is_shares_burnt, +// is_proposer_signed, +// } = test_case + +// let input_value = from_lovelace(current_fundraised_amount) + +// let input_datum = +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// } + +// mocktail_tx() +// |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) +// |> tx_in_inline_datum(True, input_datum) +// |> tx_in( +// !is_only_one_inputed, +// mock_tx_hash(0), +// 1, +// input_value, +// mock_gov_address, +// ) +// |> tx_out( +// True, +// mock_pub_key_address(0, None), +// from_lovelace(current_fundraised_amount), +// ) +// |> invalid_before( +// is_deadline_passed, +// mock_deadline + mock_gov_action_period + 3600 * 24, +// ) +// |> invalid_before( +// !is_deadline_passed, +// mock_deadline + mock_gov_action_period - 3600 * 24, +// ) +// |> mint( +// is_shares_burnt, +// -current_fundraised_amount, +// mock_share_token, +// mock_completion_script, +// ) +// |> mint( +// !is_shares_burnt, +// -current_fundraised_amount + 9999999, +// mock_share_token, +// mock_completion_script, +// ) +// |> complete() +// |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) +// } + +// test s3_spend_success_remove_empty_instance_wih_zero_fund() { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// is_proposer_signed: True, +// }, +// 0, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: 0, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_success_remove_empty_instance_wih_some_fund() { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// is_proposer_signed: True, +// }, +// mock_current_fundraised_amount, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// is_proposer_signed: True, +// }, +// mock_current_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: False, +// is_deadline_passed: True, +// is_shares_burnt: True, +// is_proposer_signed: True, +// }, +// mock_current_fundraised_amount, +// ) + +// spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: True, +// is_deadline_passed: False, +// is_shares_burnt: True, +// is_proposer_signed: True, +// }, +// mock_current_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: True, +// is_deadline_passed: True, +// is_shares_burnt: False, +// is_proposer_signed: True, +// }, +// mock_current_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } + +// test s3_spend_fail_remove_empty_instance_wih_proposer_not_signed() { +// let tx = +// mock_remove_empty_instance_tx( +// RemoveEmptyInstanceTestCase { +// is_only_one_inputed: True, +// is_deadline_passed: True, +// is_shares_burnt: True, +// is_proposer_signed: False, +// }, +// mock_current_fundraised_amount, +// ) + +// !spend.spend.spend( +// mock_delegate_pool_id, +// mock_gov_action, +// mock_proposer_key_hash, +// mock_stake_register_deposit, +// mock_drep_register_deposit, +// Some( +// Refundable { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// }, +// ), +// RemoveEmptyInstance, +// mock_utxo_ref(0, 0), +// tx, +// ) +// } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak index e7188fa6a..327822a1e 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak @@ -1,149 +1,149 @@ -use cardano/assets.{from_lovelace} -use cardano/certificate.{RegisterCredential} -use cardano/script_context.{Publishing, ScriptContext} -use cardano/transaction.{OutputReference, Spend, Transaction} -use mocktail.{ - add_redeemer, complete, mock_script_credential, mock_tx_hash, mocktail_tx, - tx_in, -} -use stake -use tests/utils.{ - mock_crowdfund_gov_address, mock_fundraise_target, mock_spend_script_hash, -} -use types.{Deregister, DeregisterCerts, Register, RegisterCerts} +// use cardano/assets.{from_lovelace} +// use cardano/certificate.{RegisterCredential} +// use cardano/script_context.{Publishing, ScriptContext} +// use cardano/transaction.{OutputReference, Spend, Transaction} +// use mocktail.{ +// add_redeemer, complete, mock_script_credential, mock_tx_hash, mocktail_tx, +// tx_in, +// } +// use stake +// use tests/utils.{ +// mock_crowdfund_gov_address, mock_fundraise_target, mock_spend_script_hash, +// } +// use types.{Deregister, DeregisterCerts, Register, RegisterCerts} -type StakeTestCase { - is_only_one_auth_inputed: Bool, -} +// type StakeTestCase { +// is_only_one_auth_inputed: Bool, +// } -fn mock_stake_tx( - test_case: StakeTestCase, - only_input_redeemer: Data, -) -> Transaction { - let StakeTestCase { is_only_one_auth_inputed } = test_case - let only_input = from_lovelace(mock_fundraise_target) - mocktail_tx() - |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) - |> tx_in( - !is_only_one_auth_inputed, - mock_tx_hash(0), - 1, - only_input, - mock_crowdfund_gov_address, - ) - |> complete() - |> add_redeemer( - True, - Pair( - Spend( - OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, - ), - only_input_redeemer, - ), - ) -} +// fn mock_stake_tx( +// test_case: StakeTestCase, +// only_input_redeemer: Data, +// ) -> Transaction { +// let StakeTestCase { is_only_one_auth_inputed } = test_case +// let only_input = from_lovelace(mock_fundraise_target) +// mocktail_tx() +// |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) +// |> tx_in( +// !is_only_one_auth_inputed, +// mock_tx_hash(0), +// 1, +// only_input, +// mock_crowdfund_gov_address, +// ) +// |> complete() +// |> add_redeemer( +// True, +// Pair( +// Spend( +// OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, +// ), +// only_input_redeemer, +// ), +// ) +// } -test s2_success_stake_with_reg() { - let only_input_redeemer: Data = RegisterCerts +// test s2_success_stake_with_reg() { +// let only_input_redeemer: Data = RegisterCerts - let ctx = - ScriptContext { - transaction: mock_stake_tx( - StakeTestCase { is_only_one_auth_inputed: True }, - only_input_redeemer, - ), - redeemer: Register, - info: Publishing { - at: 0, - certificate: RegisterCredential { - credential: mock_script_credential(0), - deposit: Never, - }, - }, - } - stake.stake.else(mock_spend_script_hash, ctx) -} +// let ctx = +// ScriptContext { +// transaction: mock_stake_tx( +// StakeTestCase { is_only_one_auth_inputed: True }, +// only_input_redeemer, +// ), +// redeemer: Register, +// info: Publishing { +// at: 0, +// certificate: RegisterCredential { +// credential: mock_script_credential(0), +// deposit: Never, +// }, +// }, +// } +// stake.stake.else(mock_spend_script_hash, ctx) +// } -test s2_success_stake_with_dereg() { - let only_input_redeemer: Data = DeregisterCerts +// test s2_success_stake_with_dereg() { +// let only_input_redeemer: Data = DeregisterCerts - let ctx = - ScriptContext { - transaction: mock_stake_tx( - StakeTestCase { is_only_one_auth_inputed: True }, - only_input_redeemer, - ), - redeemer: Deregister, - info: Publishing { - at: 0, - certificate: RegisterCredential { - credential: mock_script_credential(0), - deposit: Never, - }, - }, - } - stake.stake.else(mock_spend_script_hash, ctx) -} +// let ctx = +// ScriptContext { +// transaction: mock_stake_tx( +// StakeTestCase { is_only_one_auth_inputed: True }, +// only_input_redeemer, +// ), +// redeemer: Deregister, +// info: Publishing { +// at: 0, +// certificate: RegisterCredential { +// credential: mock_script_credential(0), +// deposit: Never, +// }, +// }, +// } +// stake.stake.else(mock_spend_script_hash, ctx) +// } -test s2_fail_stake_with_reg_but_deregister_cert() { - let only_input_redeemer: Data = DeregisterCerts +// test s2_fail_stake_with_reg_but_deregister_cert() { +// let only_input_redeemer: Data = DeregisterCerts - let ctx = - ScriptContext { - transaction: mock_stake_tx( - StakeTestCase { is_only_one_auth_inputed: True }, - only_input_redeemer, - ), - redeemer: Register, - info: Publishing { - at: 0, - certificate: RegisterCredential { - credential: mock_script_credential(0), - deposit: Never, - }, - }, - } - !stake.stake.else(mock_spend_script_hash, ctx) -} +// let ctx = +// ScriptContext { +// transaction: mock_stake_tx( +// StakeTestCase { is_only_one_auth_inputed: True }, +// only_input_redeemer, +// ), +// redeemer: Register, +// info: Publishing { +// at: 0, +// certificate: RegisterCredential { +// credential: mock_script_credential(0), +// deposit: Never, +// }, +// }, +// } +// !stake.stake.else(mock_spend_script_hash, ctx) +// } -test s2_fail_stake_with_dereg_but_register_cert() { - let only_input_redeemer: Data = RegisterCerts +// test s2_fail_stake_with_dereg_but_register_cert() { +// let only_input_redeemer: Data = RegisterCerts - let ctx = - ScriptContext { - transaction: mock_stake_tx( - StakeTestCase { is_only_one_auth_inputed: True }, - only_input_redeemer, - ), - redeemer: Deregister, - info: Publishing { - at: 0, - certificate: RegisterCredential { - credential: mock_script_credential(0), - deposit: Never, - }, - }, - } - !stake.stake.else(mock_spend_script_hash, ctx) -} +// let ctx = +// ScriptContext { +// transaction: mock_stake_tx( +// StakeTestCase { is_only_one_auth_inputed: True }, +// only_input_redeemer, +// ), +// redeemer: Deregister, +// info: Publishing { +// at: 0, +// certificate: RegisterCredential { +// credential: mock_script_credential(0), +// deposit: Never, +// }, +// }, +// } +// !stake.stake.else(mock_spend_script_hash, ctx) +// } -test s2_fail_stake_with_more_than_one_input_from_hash() fail { - let only_input_redeemer: Data = RegisterCerts +// test s2_fail_stake_with_more_than_one_input_from_hash() fail { +// let only_input_redeemer: Data = RegisterCerts - let ctx = - ScriptContext { - transaction: mock_stake_tx( - StakeTestCase { is_only_one_auth_inputed: False }, - only_input_redeemer, - ), - redeemer: Register, - info: Publishing { - at: 0, - certificate: RegisterCredential { - credential: mock_script_credential(0), - deposit: Never, - }, - }, - } - stake.stake.else(mock_spend_script_hash, ctx) -} +// let ctx = +// ScriptContext { +// transaction: mock_stake_tx( +// StakeTestCase { is_only_one_auth_inputed: False }, +// only_input_redeemer, +// ), +// redeemer: Register, +// info: Publishing { +// at: 0, +// certificate: RegisterCredential { +// credential: mock_script_credential(0), +// deposit: Never, +// }, +// }, +// } +// stake.stake.else(mock_spend_script_hash, ctx) +// } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak index c1215bfab..89646ea10 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak @@ -1,206 +1,206 @@ -use cardano/address.{Script} -use cardano/assets.{add, from_lovelace} -use cardano/transaction.{Transaction} -use mocktail.{ - complete, mock_script_hash, mock_tx_hash, mocktail_tx, tx_in, - tx_in_inline_datum, tx_out, tx_out_inline_datum, -} -use start -use tests/utils.{ - mock_auth_token, mock_completion_script, mock_crowdfund_address, - mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, - mock_fundraise_target, mock_gov_action_period, mock_gov_address, - mock_share_token, mock_spend_script_hash, mock_stake_script_hash, -} -use types.{Init} - -type StartTestCase { - is_only_one_auth_inputed: Bool, - is_fundraise_target_sent: Bool, - is_fundraise_target_amount_correct: Bool, - is_fundraise_output_datum_correct: Bool, -} - -fn mock_stake_tx(test_case: StartTestCase) -> Transaction { - let StartTestCase { - is_only_one_auth_inputed, - is_fundraise_target_sent, - is_fundraise_target_amount_correct, - is_fundraise_output_datum_correct, - } = test_case - let auth_input = - from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) - - let fundraise_output = - if is_fundraise_target_amount_correct { - from_lovelace(mock_fundraise_target) - } else { - from_lovelace(mock_fundraise_target - 1000000) - } - - let fundraise_output_datum = - if is_fundraise_output_datum_correct { - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount, - deadline: mock_deadline + mock_gov_action_period, - } - } else { - Init { - completion_script: mock_completion_script, - share_token: mock_share_token, - funds_controlled: mock_current_fundraised_amount + 1000000, - deadline: mock_deadline + mock_gov_action_period, - } - } - - mocktail_tx() - |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) - |> tx_in_inline_datum( - True, - mock_crowdfund_datum(mock_current_fundraised_amount, True), - ) - |> tx_in( - !is_only_one_auth_inputed, - mock_tx_hash(0), - 1, - auth_input, - mock_crowdfund_address, - ) - |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) - |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) - |> complete() -} - -test s3_withdraw_success() { - let tx = - mock_stake_tx( - StartTestCase { - is_only_one_auth_inputed: True, - is_fundraise_target_sent: True, - is_fundraise_target_amount_correct: True, - is_fundraise_output_datum_correct: True, - }, - ) - - start.start.withdraw( - mock_auth_token, - mock_spend_script_hash, - mock_stake_script_hash, - mock_gov_action_period, - None, - Script(mock_completion_script), - tx, - ) -} - -test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { - let tx = - mock_stake_tx( - StartTestCase { - is_only_one_auth_inputed: False, - is_fundraise_target_sent: True, - is_fundraise_target_amount_correct: True, - is_fundraise_output_datum_correct: True, - }, - ) - - start.start.withdraw( - mock_auth_token, - mock_spend_script_hash, - mock_stake_script_hash, - mock_gov_action_period, - None, - Script(mock_completion_script), - tx, - ) -} - -test s3_withdraw_fail_with_fundraise_target_not_sent() fail { - let tx = - mock_stake_tx( - StartTestCase { - is_only_one_auth_inputed: True, - is_fundraise_target_sent: False, - is_fundraise_target_amount_correct: True, - is_fundraise_output_datum_correct: True, - }, - ) - - start.start.withdraw( - mock_auth_token, - mock_spend_script_hash, - mock_stake_script_hash, - mock_gov_action_period, - None, - Script(mock_completion_script), - tx, - ) -} - -test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { - let tx = - mock_stake_tx( - StartTestCase { - is_only_one_auth_inputed: True, - is_fundraise_target_sent: True, - is_fundraise_target_amount_correct: False, - is_fundraise_output_datum_correct: True, - }, - ) - - !start.start.withdraw( - mock_auth_token, - mock_spend_script_hash, - mock_stake_script_hash, - mock_gov_action_period, - None, - Script(mock_completion_script), - tx, - ) -} - -test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { - let tx = - mock_stake_tx( - StartTestCase { - is_only_one_auth_inputed: True, - is_fundraise_target_sent: True, - is_fundraise_target_amount_correct: True, - is_fundraise_output_datum_correct: False, - }, - ) - - !start.start.withdraw( - mock_auth_token, - mock_spend_script_hash, - mock_stake_script_hash, - mock_gov_action_period, - None, - Script(mock_completion_script), - tx, - ) -} - -test s3_withdraw_fail_with_different_completion_script() { - let tx = - mock_stake_tx( - StartTestCase { - is_only_one_auth_inputed: True, - is_fundraise_target_sent: True, - is_fundraise_target_amount_correct: True, - is_fundraise_output_datum_correct: False, - }, - ) - - !start.start.withdraw( - mock_auth_token, - mock_spend_script_hash, - mock_stake_script_hash, - mock_gov_action_period, - None, - Script(mock_script_hash(999)), - tx, - ) -} +// use cardano/address.{Script} +// use cardano/assets.{add, from_lovelace} +// use cardano/transaction.{Transaction} +// use mocktail.{ +// complete, mock_script_hash, mock_tx_hash, mocktail_tx, tx_in, +// tx_in_inline_datum, tx_out, tx_out_inline_datum, +// } +// use start +// use tests/utils.{ +// mock_auth_token, mock_completion_script, mock_crowdfund_address, +// mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, +// mock_fundraise_target, mock_gov_action_period, mock_gov_address, +// mock_share_token, mock_spend_script_hash, mock_stake_script_hash, +// } +// use types.{Init} + +// type StartTestCase { +// is_only_one_auth_inputed: Bool, +// is_fundraise_target_sent: Bool, +// is_fundraise_target_amount_correct: Bool, +// is_fundraise_output_datum_correct: Bool, +// } + +// fn mock_stake_tx(test_case: StartTestCase) -> Transaction { +// let StartTestCase { +// is_only_one_auth_inputed, +// is_fundraise_target_sent, +// is_fundraise_target_amount_correct, +// is_fundraise_output_datum_correct, +// } = test_case +// let auth_input = +// from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) + +// let fundraise_output = +// if is_fundraise_target_amount_correct { +// from_lovelace(mock_fundraise_target) +// } else { +// from_lovelace(mock_fundraise_target - 1000000) +// } + +// let fundraise_output_datum = +// if is_fundraise_output_datum_correct { +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount, +// deadline: mock_deadline + mock_gov_action_period, +// } +// } else { +// Init { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// funds_controlled: mock_current_fundraised_amount + 1000000, +// deadline: mock_deadline + mock_gov_action_period, +// } +// } + +// mocktail_tx() +// |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) +// |> tx_in_inline_datum( +// True, +// mock_crowdfund_datum(mock_current_fundraised_amount, True), +// ) +// |> tx_in( +// !is_only_one_auth_inputed, +// mock_tx_hash(0), +// 1, +// auth_input, +// mock_crowdfund_address, +// ) +// |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) +// |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) +// |> complete() +// } + +// test s3_withdraw_success() { +// let tx = +// mock_stake_tx( +// StartTestCase { +// is_only_one_auth_inputed: True, +// is_fundraise_target_sent: True, +// is_fundraise_target_amount_correct: True, +// is_fundraise_output_datum_correct: True, +// }, +// ) + +// start.start.withdraw( +// mock_auth_token, +// mock_spend_script_hash, +// mock_stake_script_hash, +// mock_gov_action_period, +// None, +// Script(mock_completion_script), +// tx, +// ) +// } + +// test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { +// let tx = +// mock_stake_tx( +// StartTestCase { +// is_only_one_auth_inputed: False, +// is_fundraise_target_sent: True, +// is_fundraise_target_amount_correct: True, +// is_fundraise_output_datum_correct: True, +// }, +// ) + +// start.start.withdraw( +// mock_auth_token, +// mock_spend_script_hash, +// mock_stake_script_hash, +// mock_gov_action_period, +// None, +// Script(mock_completion_script), +// tx, +// ) +// } + +// test s3_withdraw_fail_with_fundraise_target_not_sent() fail { +// let tx = +// mock_stake_tx( +// StartTestCase { +// is_only_one_auth_inputed: True, +// is_fundraise_target_sent: False, +// is_fundraise_target_amount_correct: True, +// is_fundraise_output_datum_correct: True, +// }, +// ) + +// start.start.withdraw( +// mock_auth_token, +// mock_spend_script_hash, +// mock_stake_script_hash, +// mock_gov_action_period, +// None, +// Script(mock_completion_script), +// tx, +// ) +// } + +// test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { +// let tx = +// mock_stake_tx( +// StartTestCase { +// is_only_one_auth_inputed: True, +// is_fundraise_target_sent: True, +// is_fundraise_target_amount_correct: False, +// is_fundraise_output_datum_correct: True, +// }, +// ) + +// !start.start.withdraw( +// mock_auth_token, +// mock_spend_script_hash, +// mock_stake_script_hash, +// mock_gov_action_period, +// None, +// Script(mock_completion_script), +// tx, +// ) +// } + +// test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { +// let tx = +// mock_stake_tx( +// StartTestCase { +// is_only_one_auth_inputed: True, +// is_fundraise_target_sent: True, +// is_fundraise_target_amount_correct: True, +// is_fundraise_output_datum_correct: False, +// }, +// ) + +// !start.start.withdraw( +// mock_auth_token, +// mock_spend_script_hash, +// mock_stake_script_hash, +// mock_gov_action_period, +// None, +// Script(mock_completion_script), +// tx, +// ) +// } + +// test s3_withdraw_fail_with_different_completion_script() { +// let tx = +// mock_stake_tx( +// StartTestCase { +// is_only_one_auth_inputed: True, +// is_fundraise_target_sent: True, +// is_fundraise_target_amount_correct: True, +// is_fundraise_output_datum_correct: False, +// }, +// ) + +// !start.start.withdraw( +// mock_auth_token, +// mock_spend_script_hash, +// mock_stake_script_hash, +// mock_gov_action_period, +// None, +// Script(mock_script_hash(999)), +// tx, +// ) +// } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index 5278a3af4..b7a0b3cb7 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -1,96 +1,96 @@ -use aiken/collection/list -use cardano/address.{Address, Inline, Script, from_script} -use cardano/governance.{NoConfidence, ProposalProcedure} -use cardano/transaction.{Transaction} -use mocktail.{ - mock_policy_id, mock_pub_key_hash, mock_script_hash, - mock_script_stake_key_hash, -} -use types.{CrowdfundDatum} +// use aiken/collection/list +// use cardano/address.{Address, Inline, Script, from_script} +// use cardano/governance.{NoConfidence, ProposalProcedure} +// use cardano/transaction.{Transaction} +// use mocktail.{ +// mock_policy_id, mock_pub_key_hash, mock_script_hash, +// mock_script_stake_key_hash, +// } +// use types.{CrowdfundDatum} -pub const mock_auth_token = mock_policy_id(0) +// pub const mock_auth_token = mock_policy_id(0) -pub const mock_share_token = mock_policy_id(1) +// pub const mock_share_token = mock_policy_id(1) -pub const mock_completion_script = mock_script_hash(0) +// pub const mock_completion_script = mock_script_hash(0) -pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) +// pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) -pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) +// pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) -pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) +// pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) -pub const mock_fee_address = from_script("fee_address") +// pub const mock_fee_address = from_script("fee_address") -pub const mock_fundraise_target = 100000000000 +// pub const mock_fundraise_target = 100000000000 -pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 +// pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 -pub const mock_contribute_min_fundraised_amount = 2000000 +// pub const mock_contribute_min_fundraised_amount = 2000000 -pub const mock_deadline = 1750735607 +// pub const mock_deadline = 1750735607 -pub const mock_expiry_buffer = 3600 * 24 +// pub const mock_expiry_buffer = 3600 * 24 -pub const mock_min_charge = 0 +// pub const mock_min_charge = 0 -pub fn mock_crowdfund_datum( - current_fundraised_amount: Int, - allow_over_subscription: Bool, -) { - CrowdfundDatum { - completion_script: mock_completion_script, - share_token: mock_share_token, - crowdfund_address: mock_crowdfund_address, - fundraise_target: mock_fundraise_target, - current_fundraised_amount, - allow_over_subscription, - deadline: mock_deadline, - expiry_buffer: mock_expiry_buffer, - fee_address: mock_fee_address, - min_charge: mock_min_charge, - } -} +// pub fn mock_crowdfund_datum( +// current_fundraised_amount: Int, +// allow_over_subscription: Bool, +// ) { +// CrowdfundDatum { +// completion_script: mock_completion_script, +// share_token: mock_share_token, +// crowdfund_address: mock_crowdfund_address, +// fundraise_target: mock_fundraise_target, +// current_fundraised_amount, +// allow_over_subscription, +// deadline: mock_deadline, +// expiry_buffer: mock_expiry_buffer, +// fee_address: mock_fee_address, +// min_charge: mock_min_charge, +// } +// } -pub const mock_spend_script_hash = mock_script_hash(1) +// pub const mock_spend_script_hash = mock_script_hash(1) -pub const mock_stake_script_hash = mock_script_hash(2) +// pub const mock_stake_script_hash = mock_script_hash(2) -pub const mock_crowdfund_gov_address = from_script(mock_spend_script_hash) +// pub const mock_crowdfund_gov_address = from_script(mock_spend_script_hash) -pub const mock_gov_address = - Address { - payment_credential: Script(mock_spend_script_hash), - stake_credential: Some(Inline(Script(mock_stake_script_hash))), - } +// pub const mock_gov_address = +// Address { +// payment_credential: Script(mock_spend_script_hash), +// stake_credential: Some(Inline(Script(mock_stake_script_hash))), +// } -pub const mock_gov_action_period = 3600 +// pub const mock_gov_action_period = 3600 -pub const mock_delegate_pool_id = mock_script_hash(3) +// pub const mock_delegate_pool_id = mock_script_hash(3) -pub const mock_gov_action = NoConfidence { ancestor: None } +// pub const mock_gov_action = NoConfidence { ancestor: None } -pub const mock_proposer_key_hash = mock_pub_key_hash(0) +// pub const mock_proposer_key_hash = mock_pub_key_hash(0) -pub const mock_stake_register_deposit = 2000000 +// pub const mock_stake_register_deposit = 2000000 -pub const mock_drep_register_deposit = 500000000 +// pub const mock_drep_register_deposit = 500000000 -pub const mock_funds_controlled = - mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit +// pub const mock_funds_controlled = +// mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit -pub fn add_proposal_procedure( - tx: Transaction, - condition: Bool, - proposal_procedure: ProposalProcedure, -) -> Transaction { - if !condition { - tx - } else { - Transaction { - ..tx, - proposal_procedures: tx.proposal_procedures - |> list.concat([proposal_procedure]), - } - } -} +// pub fn add_proposal_procedure( +// tx: Transaction, +// condition: Bool, +// proposal_procedure: ProposalProcedure, +// ) -> Transaction { +// if !condition { +// tx +// } else { +// Transaction { +// ..tx, +// proposal_procedures: tx.proposal_procedures +// |> list.concat([proposal_procedure]), +// } +// } +// } From 6b1c6a1528ece72aff0cf0967ea239db16356a22 Mon Sep 17 00:00:00 2001 From: kenlau666 Date: Fri, 27 Jun 2025 01:25:30 +0800 Subject: [PATCH 10/24] updated: spend todo: start and spend tests --- .../gov-crowdfund/validators/spend.ak | 520 +++++++++--------- 1 file changed, 269 insertions(+), 251 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak index 33648a5f7..3f96addb5 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak @@ -1,251 +1,269 @@ -// use aiken/collection/list -// use cardano/address.{Inline} -// use cardano/assets.{Lovelace, lovelace_of} -// use cardano/certificate.{Registered} -// use cardano/governance.{GovernanceAction, ProposalProcedure} -// use cardano/transaction.{OutputReference, Transaction, find_input} -// use cocktail.{ -// inputs_at, key_signed, only_minted_token, output_inline_datum, outputs_at, -// valid_after, value_length, -// } -// use types.{ -// ContributorWithdrawal, CrowdfundGovDatum, CrowdfundRedeemer, DeregisterCerts, -// Init, Proposed, Refundable, RegisterCerts, RemoveEmptyInstance, -// } -// use utils.{ -// check_lovelace_diff, delegate_stake_and_vote_certificate, -// delegate_stake_certificate, delegate_vote_certificate, -// register_drep_certificate, register_stake_certificate, -// unregister_drep_certificate, unregister_stake_certificate, -// } - -// validator spend( -// delegate_pool_id: ByteArray, -// gov_action: GovernanceAction, -// proposer_key_hash: ByteArray, -// stake_register_deposit: Lovelace, -// drep_register_deposit: Lovelace, -// ) { -// spend( -// datum_opt: Option, -// redeemer: CrowdfundRedeemer, -// input: OutputReference, -// self: Transaction, -// ) { -// let Transaction { -// inputs, -// validity_range, -// mint, -// outputs, -// extra_signatories, -// certificates, -// proposal_procedures, -// .. -// } = self - -// expect Some(own_input) = find_input(inputs, input) -// expect Some(only_input_datum) = datum_opt - -// let current_address = own_input.output.address - -// // check only 1 input from current address -// expect [only_input] = inputs_at(inputs, current_address) - -// when redeemer is { -// RegisterCerts -> -// when only_input_datum is { -// Init { share_token, deadline, funds_controlled, completion_script } -> { -// expect Some(current_stake_credential) = -// current_address.stake_credential - -// expect Inline(current_credential) = current_stake_credential - -// expect [only_output] = outputs_at(outputs, current_address) - -// let lovelace_from_only_input = -// only_input.output.value |> lovelace_of() - -// let lovelace_check = -// check_lovelace_diff( -// only_input, -// only_output, -// -(stake_register_deposit + drep_register_deposit), -// ) -// expect only_output_datum: CrowdfundGovDatum = -// output_inline_datum(only_output) -// let output_datum_check = -// only_output_datum == Proposed { -// completion_script, -// share_token, -// funds_controlled, -// deadline, -// } - -// let is_only_output_value_clean = -// value_length(only_output.value) == 1 - -// let reg_stake_cert_check = -// register_stake_certificate(certificates, current_credential) - -// let reg_drep_cert_check = -// register_drep_certificate( -// certificates, -// current_credential, -// drep_register_deposit, -// ) - -// let delegate_check = -// delegate_vote_certificate( -// certificates, -// current_credential, -// Registered(current_credential), -// ) && delegate_stake_certificate( -// certificates, -// current_credential, -// delegate_pool_id, -// ) || delegate_stake_and_vote_certificate( -// certificates, -// current_credential, -// delegate_pool_id, -// Registered(current_credential), -// ) - -// let proposal_check = -// list.has( -// proposal_procedures, -// ProposalProcedure { -// deposit: lovelace_from_only_input - stake_register_deposit - drep_register_deposit, -// return_address: current_address.payment_credential, -// governance_action: gov_action, -// }, -// ) -// lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? -// } -// _ -> False -// } - -// DeregisterCerts -> -// when only_input_datum is { -// Refundable { -// share_token, -// deadline, -// funds_controlled, -// completion_script, -// } -> { -// expect Some(current_stake_credential) = -// current_address.stake_credential - -// expect Inline(current_credential) = current_stake_credential -// let validity_check = valid_after(validity_range, deadline) -// expect [only_output] = outputs_at(outputs, current_address) -// let lovelace_check = -// check_lovelace_diff( -// only_input, -// only_output, -// stake_register_deposit + drep_register_deposit, -// ) - -// expect only_output_datum: CrowdfundGovDatum = -// output_inline_datum(only_output) -// let output_datum_check = -// only_output_datum == Refundable { -// completion_script, -// share_token, -// funds_controlled, -// deadline, -// } - -// let unreg_stake_cert_check = -// unregister_stake_certificate(certificates, current_credential) - -// let unreg_drep_cert_check = -// unregister_drep_certificate( -// certificates, -// current_credential, -// drep_register_deposit, -// ) -// validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? -// } - -// _ -> False -// } - -// ContributorWithdrawal -> -// when only_input_datum is { -// Refundable { -// share_token, -// deadline, -// funds_controlled, -// completion_script, -// } -> { -// let validity_check = valid_after(validity_range, deadline) - -// expect [only_output] = outputs_at(outputs, current_address) - -// let lovelace_from_only_input = -// only_input.output.value |> lovelace_of() -// let lovelace_from_only_output = only_output.value |> lovelace_of() - -// let lovelace_withdrawn = -// lovelace_from_only_output - lovelace_from_only_input - -// let lovelace_withdrawn_check = lovelace_withdrawn < 0 - -// expect only_output_datum: CrowdfundGovDatum = -// output_inline_datum(only_output) -// let output_datum_check = -// only_output_datum == Refundable { -// completion_script, -// share_token, -// funds_controlled: funds_controlled + lovelace_withdrawn, -// deadline, -// } - -// let is_only_output_value_clean = -// value_length(only_output.value) == 1 - -// validity_check? && lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( -// mint, -// share_token, -// completion_script, -// lovelace_withdrawn, -// )? -// } -// _ -> False -// } - -// RemoveEmptyInstance -> -// when only_input_datum is { -// Refundable { -// share_token, -// deadline, -// funds_controlled, -// completion_script, -// } -> { -// let validity_check = valid_after(validity_range, deadline) - -// let token_burnt_check = -// if funds_controlled > 0 { -// only_minted_token( -// mint, -// share_token, -// completion_script, -// -funds_controlled, -// ) -// } else { -// True -// } - -// let proposer_key_signed_check = -// key_signed(extra_signatories, proposer_key_hash) -// validity_check? && token_burnt_check? && proposer_key_signed_check? -// } -// _ -> False -// } -// } -// } - -// else(_) { -// fail -// } -// } +use aiken/collection/list +use cardano/address.{Inline} +use cardano/assets.{Lovelace, lovelace_of} +use cardano/certificate.{Registered} +use cardano/governance.{GovernanceAction, GovernanceActionId, ProposalProcedure} +use cardano/transaction.{OutputReference, Transaction, find_input} +use cocktail.{ + inputs_at, key_signed, only_minted_token, output_inline_datum, outputs_at, + policy_only_minted_token, valid_after, value_length, +} +use types.{ + ContributorWithdrawal, CrowdfundGovDatum, CrowdfundRedeemer, DeregisterCerts, + Init, Proposed, Refundable, RegisterCerts, RemoveEmptyInstance, + VoteOnGovAction, Voted, +} +use utils.{ + check_lovelace_diff, delegate_stake_and_vote_certificate, + delegate_stake_certificate, delegate_vote_certificate, + register_drep_certificate, register_stake_certificate, + unregister_drep_certificate, unregister_stake_certificate, +} + +validator spend( + delegate_pool_id: ByteArray, + gov_action: GovernanceAction, + proposer_key_hash: ByteArray, + stake_register_deposit: Lovelace, + drep_register_deposit: Lovelace, +) { + spend( + datum_opt: Option, + redeemer: CrowdfundRedeemer, + input: OutputReference, + self: Transaction, + ) { + let Transaction { + inputs, + validity_range, + mint, + outputs, + extra_signatories, + certificates, + proposal_procedures, + .. + } = self + + expect Some(own_input) = find_input(inputs, input) + expect Some(only_input_datum) = datum_opt + + let current_address = own_input.output.address + + // check only 1 input from current address + expect [only_input] = inputs_at(inputs, current_address) + + when redeemer is { + RegisterCerts -> + when only_input_datum is { + Init { start_hash, share_token, funds_controlled, deadline } -> { + expect Some(current_stake_credential) = + current_address.stake_credential + + expect Inline(current_credential) = current_stake_credential + + expect [only_output] = outputs_at(outputs, current_address) + + let lovelace_from_only_input = + only_input.output.value |> lovelace_of() + + let lovelace_check = + check_lovelace_diff( + only_input, + only_output, + -(stake_register_deposit + drep_register_deposit), + ) + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Proposed { + start_hash, + share_token, + funds_controlled, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + + let reg_stake_cert_check = + register_stake_certificate(certificates, current_credential) + + let reg_drep_cert_check = + register_drep_certificate( + certificates, + current_credential, + drep_register_deposit, + ) + + let delegate_check = + delegate_vote_certificate( + certificates, + current_credential, + Registered(current_credential), + ) && delegate_stake_certificate( + certificates, + current_credential, + delegate_pool_id, + ) || delegate_stake_and_vote_certificate( + certificates, + current_credential, + delegate_pool_id, + Registered(current_credential), + ) + + let proposal_check = + list.has( + proposal_procedures, + ProposalProcedure { + deposit: lovelace_from_only_input - stake_register_deposit - drep_register_deposit, + return_address: current_address.payment_credential, + governance_action: gov_action, + }, + ) + lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? + } + _ -> False + } + VoteOnGovAction -> + when only_input_datum is { + Proposed { start_hash, share_token, funds_controlled, deadline } -> { + expect [only_output] = outputs_at(outputs, current_address) + + let lovelace_check = + check_lovelace_diff(only_input, only_output, -100000000000) + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Voted { + start_hash, + share_token, + funds_controlled, + gov_tx_id: GovernanceActionId { + transaction: own_input.output_reference.transaction_id, + proposal_procedure: 0, + }, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + + lovelace_check? && output_datum_check? && is_only_output_value_clean? + } + _ -> False + } + DeregisterCerts -> + when only_input_datum is { + Voted { start_hash, share_token, funds_controlled, deadline, .. } -> { + expect Some(current_stake_credential) = + current_address.stake_credential + + expect Inline(current_credential) = current_stake_credential + let validity_check = valid_after(validity_range, deadline) + expect [only_output] = outputs_at(outputs, current_address) + let lovelace_check = + check_lovelace_diff( + only_input, + only_output, + stake_register_deposit + drep_register_deposit, + ) + + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Refundable { + start_hash, + share_token, + funds_controlled, + deadline, + } + + let unreg_stake_cert_check = + unregister_stake_certificate(certificates, current_credential) + + let unreg_drep_cert_check = + unregister_drep_certificate( + certificates, + current_credential, + drep_register_deposit, + ) + validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? + } + + _ -> False + } + + ContributorWithdrawal -> + when only_input_datum is { + Refundable { start_hash, share_token, funds_controlled, deadline } -> { + let validity_check = valid_after(validity_range, deadline) + + expect [only_output] = outputs_at(outputs, current_address) + + let lovelace_from_only_input = + only_input.output.value |> lovelace_of() + let lovelace_from_only_output = only_output.value |> lovelace_of() + + let lovelace_withdrawn = + lovelace_from_only_output - lovelace_from_only_input + + let lovelace_withdrawn_check = lovelace_withdrawn < 0 + + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Refundable { + start_hash, + share_token, + funds_controlled: funds_controlled + lovelace_withdrawn, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + + validity_check? && lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( + mint, + share_token, + start_hash, + lovelace_withdrawn, + )? + } + _ -> False + } + + RemoveEmptyInstance -> + when only_input_datum is { + Refundable { start_hash, share_token, funds_controlled, deadline } -> { + let validity_check = valid_after(validity_range, deadline) + + let token_burnt_check = + if funds_controlled > 0 { + policy_only_minted_token( + mint, + share_token, + start_hash, + -funds_controlled, + ) + } else { + True + } + + let proposer_key_signed_check = + key_signed(extra_signatories, proposer_key_hash) + validity_check? && token_burnt_check? && proposer_key_signed_check? && policy_only_minted_token( + mint, + start_hash, + "", + -1, + )? + } + _ -> False + } + } + } + + else(_) { + fail + } +} From 8458bc45c8542d2c711a7485b7f155e764137e1d Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 27 Jun 2025 11:47:32 +0800 Subject: [PATCH 11/24] updated: start test --- .../gov-crowdfund/validators/tests/stake.ak | 149 ---- .../gov-crowdfund/validators/tests/start.ak | 773 +++++++++++++----- .../gov-crowdfund/validators/tests/utils.ak | 140 ++-- 3 files changed, 637 insertions(+), 425 deletions(-) delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak deleted file mode 100644 index 327822a1e..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/stake.ak +++ /dev/null @@ -1,149 +0,0 @@ -// use cardano/assets.{from_lovelace} -// use cardano/certificate.{RegisterCredential} -// use cardano/script_context.{Publishing, ScriptContext} -// use cardano/transaction.{OutputReference, Spend, Transaction} -// use mocktail.{ -// add_redeemer, complete, mock_script_credential, mock_tx_hash, mocktail_tx, -// tx_in, -// } -// use stake -// use tests/utils.{ -// mock_crowdfund_gov_address, mock_fundraise_target, mock_spend_script_hash, -// } -// use types.{Deregister, DeregisterCerts, Register, RegisterCerts} - -// type StakeTestCase { -// is_only_one_auth_inputed: Bool, -// } - -// fn mock_stake_tx( -// test_case: StakeTestCase, -// only_input_redeemer: Data, -// ) -> Transaction { -// let StakeTestCase { is_only_one_auth_inputed } = test_case -// let only_input = from_lovelace(mock_fundraise_target) -// mocktail_tx() -// |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) -// |> tx_in( -// !is_only_one_auth_inputed, -// mock_tx_hash(0), -// 1, -// only_input, -// mock_crowdfund_gov_address, -// ) -// |> complete() -// |> add_redeemer( -// True, -// Pair( -// Spend( -// OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, -// ), -// only_input_redeemer, -// ), -// ) -// } - -// test s2_success_stake_with_reg() { -// let only_input_redeemer: Data = RegisterCerts - -// let ctx = -// ScriptContext { -// transaction: mock_stake_tx( -// StakeTestCase { is_only_one_auth_inputed: True }, -// only_input_redeemer, -// ), -// redeemer: Register, -// info: Publishing { -// at: 0, -// certificate: RegisterCredential { -// credential: mock_script_credential(0), -// deposit: Never, -// }, -// }, -// } -// stake.stake.else(mock_spend_script_hash, ctx) -// } - -// test s2_success_stake_with_dereg() { -// let only_input_redeemer: Data = DeregisterCerts - -// let ctx = -// ScriptContext { -// transaction: mock_stake_tx( -// StakeTestCase { is_only_one_auth_inputed: True }, -// only_input_redeemer, -// ), -// redeemer: Deregister, -// info: Publishing { -// at: 0, -// certificate: RegisterCredential { -// credential: mock_script_credential(0), -// deposit: Never, -// }, -// }, -// } -// stake.stake.else(mock_spend_script_hash, ctx) -// } - -// test s2_fail_stake_with_reg_but_deregister_cert() { -// let only_input_redeemer: Data = DeregisterCerts - -// let ctx = -// ScriptContext { -// transaction: mock_stake_tx( -// StakeTestCase { is_only_one_auth_inputed: True }, -// only_input_redeemer, -// ), -// redeemer: Register, -// info: Publishing { -// at: 0, -// certificate: RegisterCredential { -// credential: mock_script_credential(0), -// deposit: Never, -// }, -// }, -// } -// !stake.stake.else(mock_spend_script_hash, ctx) -// } - -// test s2_fail_stake_with_dereg_but_register_cert() { -// let only_input_redeemer: Data = RegisterCerts - -// let ctx = -// ScriptContext { -// transaction: mock_stake_tx( -// StakeTestCase { is_only_one_auth_inputed: True }, -// only_input_redeemer, -// ), -// redeemer: Deregister, -// info: Publishing { -// at: 0, -// certificate: RegisterCredential { -// credential: mock_script_credential(0), -// deposit: Never, -// }, -// }, -// } -// !stake.stake.else(mock_spend_script_hash, ctx) -// } - -// test s2_fail_stake_with_more_than_one_input_from_hash() fail { -// let only_input_redeemer: Data = RegisterCerts - -// let ctx = -// ScriptContext { -// transaction: mock_stake_tx( -// StakeTestCase { is_only_one_auth_inputed: False }, -// only_input_redeemer, -// ), -// redeemer: Register, -// info: Publishing { -// at: 0, -// certificate: RegisterCredential { -// credential: mock_script_credential(0), -// deposit: Never, -// }, -// }, -// } -// stake.stake.else(mock_spend_script_hash, ctx) -// } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak index 89646ea10..60a2d5521 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak @@ -1,206 +1,567 @@ -// use cardano/address.{Script} -// use cardano/assets.{add, from_lovelace} -// use cardano/transaction.{Transaction} -// use mocktail.{ -// complete, mock_script_hash, mock_tx_hash, mocktail_tx, tx_in, -// tx_in_inline_datum, tx_out, tx_out_inline_datum, -// } -// use start -// use tests/utils.{ -// mock_auth_token, mock_completion_script, mock_crowdfund_address, -// mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, -// mock_fundraise_target, mock_gov_action_period, mock_gov_address, -// mock_share_token, mock_spend_script_hash, mock_stake_script_hash, -// } -// use types.{Init} - -// type StartTestCase { -// is_only_one_auth_inputed: Bool, -// is_fundraise_target_sent: Bool, -// is_fundraise_target_amount_correct: Bool, -// is_fundraise_output_datum_correct: Bool, -// } - -// fn mock_stake_tx(test_case: StartTestCase) -> Transaction { -// let StartTestCase { -// is_only_one_auth_inputed, -// is_fundraise_target_sent, -// is_fundraise_target_amount_correct, -// is_fundraise_output_datum_correct, -// } = test_case -// let auth_input = -// from_lovelace(20000000) |> add(mock_auth_token, mock_completion_script, 1) - -// let fundraise_output = -// if is_fundraise_target_amount_correct { -// from_lovelace(mock_fundraise_target) -// } else { -// from_lovelace(mock_fundraise_target - 1000000) -// } - -// let fundraise_output_datum = -// if is_fundraise_output_datum_correct { -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// } -// } else { -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount + 1000000, -// deadline: mock_deadline + mock_gov_action_period, -// } -// } - -// mocktail_tx() -// |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) -// |> tx_in_inline_datum( -// True, -// mock_crowdfund_datum(mock_current_fundraised_amount, True), -// ) -// |> tx_in( -// !is_only_one_auth_inputed, -// mock_tx_hash(0), -// 1, -// auth_input, -// mock_crowdfund_address, -// ) -// |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) -// |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) -// |> complete() -// } - -// test s3_withdraw_success() { -// let tx = -// mock_stake_tx( -// StartTestCase { -// is_only_one_auth_inputed: True, -// is_fundraise_target_sent: True, -// is_fundraise_target_amount_correct: True, -// is_fundraise_output_datum_correct: True, -// }, -// ) - -// start.start.withdraw( -// mock_auth_token, -// mock_spend_script_hash, -// mock_stake_script_hash, -// mock_gov_action_period, -// None, -// Script(mock_completion_script), -// tx, -// ) -// } - -// test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { -// let tx = -// mock_stake_tx( -// StartTestCase { -// is_only_one_auth_inputed: False, -// is_fundraise_target_sent: True, -// is_fundraise_target_amount_correct: True, -// is_fundraise_output_datum_correct: True, -// }, -// ) - -// start.start.withdraw( -// mock_auth_token, -// mock_spend_script_hash, -// mock_stake_script_hash, -// mock_gov_action_period, -// None, -// Script(mock_completion_script), -// tx, -// ) -// } - -// test s3_withdraw_fail_with_fundraise_target_not_sent() fail { -// let tx = -// mock_stake_tx( -// StartTestCase { -// is_only_one_auth_inputed: True, -// is_fundraise_target_sent: False, -// is_fundraise_target_amount_correct: True, -// is_fundraise_output_datum_correct: True, -// }, -// ) - -// start.start.withdraw( -// mock_auth_token, -// mock_spend_script_hash, -// mock_stake_script_hash, -// mock_gov_action_period, -// None, -// Script(mock_completion_script), -// tx, -// ) -// } - -// test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { -// let tx = -// mock_stake_tx( -// StartTestCase { -// is_only_one_auth_inputed: True, -// is_fundraise_target_sent: True, -// is_fundraise_target_amount_correct: False, -// is_fundraise_output_datum_correct: True, -// }, -// ) - -// !start.start.withdraw( -// mock_auth_token, -// mock_spend_script_hash, -// mock_stake_script_hash, -// mock_gov_action_period, -// None, -// Script(mock_completion_script), -// tx, -// ) -// } - -// test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { -// let tx = -// mock_stake_tx( -// StartTestCase { -// is_only_one_auth_inputed: True, -// is_fundraise_target_sent: True, -// is_fundraise_target_amount_correct: True, -// is_fundraise_output_datum_correct: False, -// }, -// ) - -// !start.start.withdraw( -// mock_auth_token, -// mock_spend_script_hash, -// mock_stake_script_hash, -// mock_gov_action_period, -// None, -// Script(mock_completion_script), -// tx, -// ) -// } - -// test s3_withdraw_fail_with_different_completion_script() { -// let tx = -// mock_stake_tx( -// StartTestCase { -// is_only_one_auth_inputed: True, -// is_fundraise_target_sent: True, -// is_fundraise_target_amount_correct: True, -// is_fundraise_output_datum_correct: False, -// }, -// ) - -// !start.start.withdraw( -// mock_auth_token, -// mock_spend_script_hash, -// mock_stake_script_hash, -// mock_gov_action_period, -// None, -// Script(mock_script_hash(999)), -// tx, -// ) -// } +use cardano/address.{Script} +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{OutputReference, Spend, Transaction} +use mocktail.{ + add_redeemer, complete, mint, mock_script_hash, mock_tx_hash, mocktail_tx, + script_withdrawal, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use start +use tests/utils.{ + mock_auth_token, mock_crowdfund_address, mock_crowdfund_datum, + mock_crowdfund_gov_address, mock_current_fundraised_amount, mock_deadline, + mock_fundraise_target, mock_gov_action_period, mock_gov_address, + mock_share_token, mock_spend_script_hash, mock_start_hash, +} +use types.{ + Deregister, DeregisterCerts, Init, RBurn, RMint, Register, RegisterCerts, + RemoveEmptyInstance, VoteOnGovAction, +} + +type WithdrawTestCase { + is_only_one_spend_inputed: Bool, + is_fundraise_target_sent: Bool, + is_fundraise_target_amount_correct: Bool, + is_fundraise_output_datum_correct: Bool, + is_token_minted: Bool, +} + +fn mock_withdraw_tx(test_case: WithdrawTestCase) -> Transaction { + let WithdrawTestCase { + is_only_one_spend_inputed, + is_fundraise_target_sent, + is_fundraise_target_amount_correct, + is_fundraise_output_datum_correct, + is_token_minted, + } = test_case + let auth_input = + from_lovelace(20000000) |> add(mock_auth_token, mock_start_hash, 1) + + let fundraise_output = + if is_fundraise_target_amount_correct { + from_lovelace(mock_fundraise_target) |> add(mock_start_hash, "", 1) + } else { + from_lovelace(mock_fundraise_target - 1000000) + |> add(mock_start_hash, "", 1) + } + + let fundraise_output_datum = + if is_fundraise_output_datum_correct { + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount + 1000000, + deadline: mock_deadline + mock_gov_action_period, + } + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, auth_input, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(mock_current_fundraised_amount, True), + ) + |> tx_in( + !is_only_one_spend_inputed, + mock_tx_hash(0), + 1, + auth_input, + mock_crowdfund_address, + ) + |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) + |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) + |> mint(is_token_minted, 1, mock_start_hash, "") + |> complete() +} + +test s3_withdraw_success() { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + +test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: False, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + +test s3_withdraw_fail_with_fundraise_target_not_sent() fail { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: False, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + +test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: False, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + +test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: False, + is_token_minted: True, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + +test s3_withdraw_fail_with_token_not_minted() { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: False, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + +test s3_withdraw_fail_with_different_start_hash() { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + }, + ) + + !start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_script_hash(999)), + tx, + ) +} + +test s2_success_mint() { + let tx = + mocktail_tx() + |> script_withdrawal(True, mock_start_hash, 2_000_000) + |> complete() + + start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RMint, + mock_start_hash, + tx, + ) +} + +test s2_fail_mint_with_no_withdraw() { + let tx = + mocktail_tx() + |> script_withdrawal(False, mock_start_hash, 2_000_000) + |> complete() + + !start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RMint, + mock_start_hash, + tx, + ) +} + +test s2_fail_mint_with_other_withdraw() { + let tx = + mocktail_tx() + |> script_withdrawal(True, mock_script_hash(999), 2_000_000) + |> complete() + + !start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RMint, + mock_start_hash, + tx, + ) +} + +type StartTestCase { + is_only_one_spend_inputed: Bool, +} + +fn mock_start_tx( + test_case: StartTestCase, + only_input_redeemer: Data, +) -> Transaction { + let StartTestCase { is_only_one_spend_inputed } = test_case + let only_input = + from_lovelace(mock_fundraise_target) |> add(mock_start_hash, "", 1) + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) + |> tx_in( + !is_only_one_spend_inputed, + mock_tx_hash(0), + 1, + only_input, + mock_crowdfund_gov_address, + ) + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + only_input_redeemer, + ), + ) +} + +test s2_success_burn() { + let only_input_redeemer: Data = RemoveEmptyInstance + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RBurn, + mock_start_hash, + tx, + ) +} + +test s2_fail_burn_with_wrong_redeemer() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RBurn, + mock_start_hash, + tx, + ) +} + +test s2_fail_burn_with_more_than_one_inputed() fail { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RBurn, + mock_start_hash, + tx, + ) +} + +test s2_success_publish_with_reg() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + start.start.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Register, + None, + tx, + ) +} + +test s2_success_publish_with_dereg() { + let only_input_redeemer: Data = DeregisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + start.start.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Deregister, + None, + tx, + ) +} + +test s2_fail_publish_with_reg_but_deregister_cert() { + let only_input_redeemer: Data = DeregisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !start.start.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Register, + None, + tx, + ) +} + +test s2_fail_publish_with_dereg_but_register_cert() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !start.start.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Deregister, + None, + tx, + ) +} + +test s2_fail_publish_with_more_than_one_input_from_hash() fail { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + start.start.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Register, + None, + tx, + ) +} + +test s2_success_propose() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + start.start.propose( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_propose_with_wrong_redeemer() { + let only_input_redeemer: Data = VoteOnGovAction + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !start.start.propose( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_propose_with_more_than_one_inputed() fail { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + start.start.propose( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_success_vote() { + let only_input_redeemer: Data = VoteOnGovAction + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + start.start.vote( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_vote_with_wrong_redeemer() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !start.start.vote( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_vote_with_more_than_one_inputed() fail { + let only_input_redeemer: Data = VoteOnGovAction + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + start.start.vote( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index b7a0b3cb7..516b3055c 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -1,96 +1,96 @@ -// use aiken/collection/list -// use cardano/address.{Address, Inline, Script, from_script} -// use cardano/governance.{NoConfidence, ProposalProcedure} -// use cardano/transaction.{Transaction} -// use mocktail.{ -// mock_policy_id, mock_pub_key_hash, mock_script_hash, -// mock_script_stake_key_hash, -// } -// use types.{CrowdfundDatum} +use aiken/collection/list +use cardano/address.{Address, Inline, Script, from_script} +use cardano/governance.{NoConfidence, ProposalProcedure} +use cardano/transaction.{Transaction} +use mocktail.{ + mock_policy_id, mock_pub_key_hash, mock_script_hash, + mock_script_stake_key_hash, +} +use types.{CrowdfundDatum} -// pub const mock_auth_token = mock_policy_id(0) +pub const mock_auth_token = mock_policy_id(0) -// pub const mock_share_token = mock_policy_id(1) +pub const mock_share_token = mock_policy_id(1) -// pub const mock_completion_script = mock_script_hash(0) +pub const mock_completion_script = mock_script_hash(0) -// pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) +pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) -// pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) +pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) -// pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) +pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) -// pub const mock_fee_address = from_script("fee_address") +pub const mock_fee_address = from_script("fee_address") -// pub const mock_fundraise_target = 100000000000 +pub const mock_fundraise_target = 100000000000 -// pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 +pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 -// pub const mock_contribute_min_fundraised_amount = 2000000 +pub const mock_contribute_min_fundraised_amount = 2000000 -// pub const mock_deadline = 1750735607 +pub const mock_deadline = 1750735607 -// pub const mock_expiry_buffer = 3600 * 24 +pub const mock_expiry_buffer = 3600 * 24 -// pub const mock_min_charge = 0 +pub const mock_min_charge = 0 -// pub fn mock_crowdfund_datum( -// current_fundraised_amount: Int, -// allow_over_subscription: Bool, -// ) { -// CrowdfundDatum { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// crowdfund_address: mock_crowdfund_address, -// fundraise_target: mock_fundraise_target, -// current_fundraised_amount, -// allow_over_subscription, -// deadline: mock_deadline, -// expiry_buffer: mock_expiry_buffer, -// fee_address: mock_fee_address, -// min_charge: mock_min_charge, -// } -// } +pub fn mock_crowdfund_datum( + current_fundraised_amount: Int, + allow_over_subscription: Bool, +) { + CrowdfundDatum { + completion_script: mock_completion_script, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount, + allow_over_subscription, + deadline: mock_deadline, + expiry_buffer: mock_expiry_buffer, + fee_address: mock_fee_address, + min_charge: mock_min_charge, + } +} -// pub const mock_spend_script_hash = mock_script_hash(1) +pub const mock_start_hash = mock_script_hash(0) -// pub const mock_stake_script_hash = mock_script_hash(2) +pub const mock_spend_script_hash = mock_script_hash(1) -// pub const mock_crowdfund_gov_address = from_script(mock_spend_script_hash) +pub const mock_crowdfund_gov_address = from_script(mock_spend_script_hash) -// pub const mock_gov_address = -// Address { -// payment_credential: Script(mock_spend_script_hash), -// stake_credential: Some(Inline(Script(mock_stake_script_hash))), -// } +pub const mock_gov_address = + Address { + payment_credential: Script(mock_spend_script_hash), + stake_credential: Some(Inline(Script(mock_start_hash))), + } -// pub const mock_gov_action_period = 3600 +pub const mock_gov_action_period = 3600 -// pub const mock_delegate_pool_id = mock_script_hash(3) +pub const mock_delegate_pool_id = mock_script_hash(3) -// pub const mock_gov_action = NoConfidence { ancestor: None } +pub const mock_gov_action = NoConfidence { ancestor: None } -// pub const mock_proposer_key_hash = mock_pub_key_hash(0) +pub const mock_proposer_key_hash = mock_pub_key_hash(0) -// pub const mock_stake_register_deposit = 2000000 +pub const mock_stake_register_deposit = 2000000 -// pub const mock_drep_register_deposit = 500000000 +pub const mock_drep_register_deposit = 500000000 -// pub const mock_funds_controlled = -// mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit +pub const mock_funds_controlled = + mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit -// pub fn add_proposal_procedure( -// tx: Transaction, -// condition: Bool, -// proposal_procedure: ProposalProcedure, -// ) -> Transaction { -// if !condition { -// tx -// } else { -// Transaction { -// ..tx, -// proposal_procedures: tx.proposal_procedures -// |> list.concat([proposal_procedure]), -// } -// } -// } +pub fn add_proposal_procedure( + tx: Transaction, + condition: Bool, + proposal_procedure: ProposalProcedure, +) -> Transaction { + if !condition { + tx + } else { + Transaction { + ..tx, + proposal_procedures: tx.proposal_procedures + |> list.concat([proposal_procedure]), + } + } +} From 713b113a0153db7b6885f28255d4691044abd67e Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 27 Jun 2025 17:44:28 +0800 Subject: [PATCH 12/24] added: spend test --- .../gov-crowdfund/lib/gov.ak | 166 +- .../gov-crowdfund/lib/types.ak | 3 +- .../gov-crowdfund/lib/utils.ak | 41 +- .../gov-crowdfund/validators/spend.ak | 103 +- .../gov-crowdfund/validators/tests/spend.ak | 3386 ++++++++++------- .../gov-crowdfund/validators/tests/start.ak | 14 +- .../gov-crowdfund/validators/tests/utils.ak | 26 +- 7 files changed, 2287 insertions(+), 1452 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak index 215e09f88..b50730be8 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak @@ -1,95 +1,77 @@ -// use aiken/cbor -// use aiken/crypto.{ScriptHash} -// use aiken/math/rational.{Rational} -// use cardano/address.{Credential} -// use cardano/assets.{Lovelace} -// use cardano/governance.{ -// Constitution, GovernanceAction, GovernanceActionId, Mandate, -// ProtocolParameters, ProtocolVersion, -// } -// use cardano/governance/protocol_parameters.{ProtocolParametersUpdate} +use aiken/crypto.{ScriptHash} +use aiken/math/rational.{Rational} +use cardano/address.{Credential} +use cardano/assets.{Lovelace} +use cardano/governance.{ + Constitution, GovernanceActionId, Mandate, ProtocolVersion, +} -// pub fn to_aiken_gov_action(gov_action: VGovernanceAction) -> GovernanceAction { -// // let raw = cbor.serialise(gov_action) -// // expect Some(output): Option = cbor.deserialise(raw) -// // expect gov: GovernanceAction = output -// when gov_action is { -// VProtocolParameters { ancestor, new_parameters, guardrails } -> -// ProtocolParameters { -// ancestor, -// new_parameters: ProtocolParametersUpdate { inner: new_parameters.inner }, -// guardrails, -// } -// _ -> gov_action -// } -// } +type ProtocolParametersIndex = + Int -// type ProtocolParametersIndex = -// Int +pub type VProtocolParametersUpdate { + inner: Pairs, +} -// pub type VProtocolParametersUpdate { -// inner: Pairs, -// } - -// pub type VGovernanceAction { -// VProtocolParameters { -// /// The last governance action of type 'ProtocolParameters'. They must all -// /// form a chain. -// ancestor: Option, -// /// The new proposed protocol parameters. Only values set to `Some` are relevant. -// new_parameters: VProtocolParametersUpdate, -// /// The optional guardrails script defined in the constitution. The script -// /// is executed by the ledger in addition to the hard-coded ledger rules. -// /// -// /// It must pass for the new protocol parameters to be deemed valid. -// guardrails: Option, -// } -// HardFork { -// /// The last governance action of type `HardFork`. They must all -// /// form a chain. -// ancestor: Option, -// /// The new proposed version. Few rules apply to proposing new versions: -// /// -// /// - The `major` component, if incremented, must be exactly one more than the current. -// /// - The `minor` component, if incremented, must be exactly one more than the current. -// /// - If the `major` component is incremented, `minor` must be set to `0`. -// /// - Neither `minor` nor `major` can be decremented. -// new_version: ProtocolVersion, -// } -// TreasuryWithdrawal { -// /// A collection of beneficiaries, which can be plain verification key -// /// hashes or script hashes (e.g. DAO). -// beneficiaries: Pairs, -// /// The optional guardrails script defined in the constitution. The script -// /// is executed by the ledger in addition to the hard-coded ledger rules. -// /// -// /// It must pass for the withdrawals to be authorized. -// guardrails: Option, -// } -// NoConfidence { -// /// The last governance action of type `NoConfidence` or -// /// `ConstitutionalCommittee`. They must all / form a chain. -// ancestor: Option, -// } -// ConstitutionalCommittee { -// /// The last governance action of type `NoConfidence` or -// /// `ConstitutionalCommittee`. They must all / form a chain. -// ancestor: Option, -// /// Constitutional members to be removed. -// evicted_members: List, -// /// Constitutional members to be added. -// added_members: Pairs, -// /// The new quorum value, as a ratio of a numerator and a denominator. The -// /// quorum specifies the threshold of 'Yes' votes necessary for the -// /// constitutional committee to accept a proposal procedure. -// quorum: Rational, -// } -// NewConstitution { -// /// The last governance action of type `Constitution` or -// /// `ConstitutionalCommittee`. They must all / form a chain. -// ancestor: Option, -// /// The new proposed constitution. -// constitution: Constitution, -// } -// NicePoll -// } +pub type VGovernanceAction { + VProtocolParameters { + /// The last governance action of type 'ProtocolParameters'. They must all + /// form a chain. + ancestor: Option, + /// The new proposed protocol parameters. Only values set to `Some` are relevant. + new_parameters: VProtocolParametersUpdate, + /// The optional guardrails script defined in the constitution. The script + /// is executed by the ledger in addition to the hard-coded ledger rules. + /// + /// It must pass for the new protocol parameters to be deemed valid. + guardrails: Option, + } + HardFork { + /// The last governance action of type `HardFork`. They must all + /// form a chain. + ancestor: Option, + /// The new proposed version. Few rules apply to proposing new versions: + /// + /// - The `major` component, if incremented, must be exactly one more than the current. + /// - The `minor` component, if incremented, must be exactly one more than the current. + /// - If the `major` component is incremented, `minor` must be set to `0`. + /// - Neither `minor` nor `major` can be decremented. + new_version: ProtocolVersion, + } + TreasuryWithdrawal { + /// A collection of beneficiaries, which can be plain verification key + /// hashes or script hashes (e.g. DAO). + beneficiaries: Pairs, + /// The optional guardrails script defined in the constitution. The script + /// is executed by the ledger in addition to the hard-coded ledger rules. + /// + /// It must pass for the withdrawals to be authorized. + guardrails: Option, + } + NoConfidence { + /// The last governance action of type `NoConfidence` or + /// `ConstitutionalCommittee`. They must all / form a chain. + ancestor: Option, + } + ConstitutionalCommittee { + /// The last governance action of type `NoConfidence` or + /// `ConstitutionalCommittee`. They must all / form a chain. + ancestor: Option, + /// Constitutional members to be removed. + evicted_members: List, + /// Constitutional members to be added. + added_members: Pairs, + /// The new quorum value, as a ratio of a numerator and a denominator. The + /// quorum specifies the threshold of 'Yes' votes necessary for the + /// constitutional committee to accept a proposal procedure. + quorum: Rational, + } + NewConstitution { + /// The last governance action of type `Constitution` or + /// `ConstitutionalCommittee`. They must all / form a chain. + ancestor: Option, + /// The new proposed constitution. + constitution: Constitution, + } + NicePoll +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak index 4d53cd0de..90eb956d5 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak @@ -3,8 +3,8 @@ use cardano/governance.{GovernanceActionId} pub type CrowdfundRedeemer { RegisterCerts - DeregisterCerts VoteOnGovAction + DeregisterCerts ContributorWithdrawal RemoveEmptyInstance } @@ -46,7 +46,6 @@ pub type CrowdfundGovDatum { start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, - deadline: Int, } } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak index e9d0491e3..0d66337fe 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak @@ -1,5 +1,6 @@ +use aiken/cbor use aiken/collection/list -use aiken/collection/pairs +use aiken/collection/pairs.{get_first} use cardano/address.{Credential, from_script} use cardano/assets.{Lovelace, lovelace_of} use cardano/certificate.{ @@ -8,8 +9,12 @@ use cardano/certificate.{ RegisterDelegateRepresentative, StakePoolId, UnregisterCredential, UnregisterDelegateRepresentative, } +use cardano/governance.{ + GovernanceAction, GovernanceActionId, ProposalProcedure, Vote, Voter, Yes, +} use cardano/transaction.{Input, Output, Redeemer, ScriptPurpose, Spend} use cocktail.{inputs_at} +use gov.{VGovernanceAction} use types.{CrowdfundRedeemer} pub fn redeemer_with_input( @@ -127,3 +132,37 @@ pub fn check_spend_script_input_redeemer( only_input_redeemer == redeemer } + +pub fn compare_gov_action(agov: GovernanceAction, vgov: VGovernanceAction) { + let se_agov = cbor.serialise(agov) + let se_vgov = cbor.serialise(vgov) + se_agov == se_vgov +} + +pub fn check_proposal_procedure( + proposal_procedures: List, + deposit: Lovelace, + return_address: Credential, + vgovernance_action: VGovernanceAction, +) { + list.count( + proposal_procedures, + fn(proposal_procedure) { + proposal_procedure.deposit == deposit && proposal_procedure.return_address == return_address && compare_gov_action( + proposal_procedure.governance_action, + vgovernance_action, + ) + }, + ) == 1 +} + +pub fn check_vote( + votes: Pairs>, + drep: Voter, + gov_tx_id: GovernanceActionId, +) { + let value_list = get_first(votes, drep) + + expect Some(gov_pair) = value_list + list.has(gov_pair, Pair(gov_tx_id, Yes)) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak index 3f96addb5..59343009a 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak @@ -1,28 +1,29 @@ -use aiken/collection/list -use cardano/address.{Inline} +use cardano/address.{Inline, Script} use cardano/assets.{Lovelace, lovelace_of} use cardano/certificate.{Registered} -use cardano/governance.{GovernanceAction, GovernanceActionId, ProposalProcedure} +use cardano/governance.{DelegateRepresentative, GovernanceActionId} use cardano/transaction.{OutputReference, Transaction, find_input} use cocktail.{ - inputs_at, key_signed, only_minted_token, output_inline_datum, outputs_at, - policy_only_minted_token, valid_after, value_length, + inputs_at_with, key_signed, only_minted_token, output_inline_datum, + outputs_at_with, policy_only_minted_token, valid_after, value_length, } +use gov.{VGovernanceAction} use types.{ ContributorWithdrawal, CrowdfundGovDatum, CrowdfundRedeemer, DeregisterCerts, Init, Proposed, Refundable, RegisterCerts, RemoveEmptyInstance, VoteOnGovAction, Voted, } use utils.{ - check_lovelace_diff, delegate_stake_and_vote_certificate, - delegate_stake_certificate, delegate_vote_certificate, - register_drep_certificate, register_stake_certificate, - unregister_drep_certificate, unregister_stake_certificate, + check_lovelace_diff, check_proposal_procedure, check_vote, + delegate_stake_and_vote_certificate, delegate_stake_certificate, + delegate_vote_certificate, register_drep_certificate, + register_stake_certificate, unregister_drep_certificate, + unregister_stake_certificate, } validator spend( delegate_pool_id: ByteArray, - gov_action: GovernanceAction, + gov_action: VGovernanceAction, proposer_key_hash: ByteArray, stake_register_deposit: Lovelace, drep_register_deposit: Lovelace, @@ -41,6 +42,7 @@ validator spend( extra_signatories, certificates, proposal_procedures, + votes, .. } = self @@ -49,28 +51,26 @@ validator spend( let current_address = own_input.output.address - // check only 1 input from current address - expect [only_input] = inputs_at(inputs, current_address) - when redeemer is { RegisterCerts -> when only_input_datum is { Init { start_hash, share_token, funds_controlled, deadline } -> { + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, start_hash, "") expect Some(current_stake_credential) = current_address.stake_credential expect Inline(current_credential) = current_stake_credential - expect [only_output] = outputs_at(outputs, current_address) - - let lovelace_from_only_input = - only_input.output.value |> lovelace_of() + expect [only_output] = + outputs_at_with(outputs, current_address, start_hash, "") let lovelace_check = check_lovelace_diff( only_input, only_output, - -(stake_register_deposit + drep_register_deposit), + -(stake_register_deposit + drep_register_deposit + 100000000000), ) expect only_output_datum: CrowdfundGovDatum = output_inline_datum(only_output) @@ -112,13 +112,11 @@ validator spend( ) let proposal_check = - list.has( + check_proposal_procedure( proposal_procedures, - ProposalProcedure { - deposit: lovelace_from_only_input - stake_register_deposit - drep_register_deposit, - return_address: current_address.payment_credential, - governance_action: gov_action, - }, + 100000000000, + current_address.payment_credential, + gov_action, ) lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? } @@ -127,40 +125,53 @@ validator spend( VoteOnGovAction -> when only_input_datum is { Proposed { start_hash, share_token, funds_controlled, deadline } -> { - expect [only_output] = outputs_at(outputs, current_address) + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, start_hash, "") + expect [only_output] = + outputs_at_with(outputs, current_address, start_hash, "") - let lovelace_check = - check_lovelace_diff(only_input, only_output, -100000000000) + let value_check = only_input.output.value == only_output.value expect only_output_datum: CrowdfundGovDatum = output_inline_datum(only_output) + let gov_tx_id = + GovernanceActionId { + transaction: own_input.output_reference.transaction_id, + proposal_procedure: 0, + } let output_datum_check = only_output_datum == Voted { start_hash, share_token, funds_controlled, - gov_tx_id: GovernanceActionId { - transaction: own_input.output_reference.transaction_id, - proposal_procedure: 0, - }, + gov_tx_id, deadline, } let is_only_output_value_clean = value_length(only_output.value) == 2 - lovelace_check? && output_datum_check? && is_only_output_value_clean? + value_check? && output_datum_check? && is_only_output_value_clean? && check_vote( + votes, + DelegateRepresentative(Script(start_hash)), + gov_tx_id, + ) } _ -> False } DeregisterCerts -> when only_input_datum is { Voted { start_hash, share_token, funds_controlled, deadline, .. } -> { + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, start_hash, "") expect Some(current_stake_credential) = current_address.stake_credential expect Inline(current_credential) = current_stake_credential let validity_check = valid_after(validity_range, deadline) - expect [only_output] = outputs_at(outputs, current_address) + expect [only_output] = + outputs_at_with(outputs, current_address, start_hash, "") let lovelace_check = check_lovelace_diff( only_input, @@ -175,7 +186,6 @@ validator spend( start_hash, share_token, funds_controlled, - deadline, } let unreg_stake_cert_check = @@ -187,7 +197,10 @@ validator spend( current_credential, drep_register_deposit, ) - validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? && is_only_output_value_clean? } _ -> False @@ -195,10 +208,13 @@ validator spend( ContributorWithdrawal -> when only_input_datum is { - Refundable { start_hash, share_token, funds_controlled, deadline } -> { - let validity_check = valid_after(validity_range, deadline) + Refundable { start_hash, share_token, funds_controlled } -> { + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, start_hash, "") - expect [only_output] = outputs_at(outputs, current_address) + expect [only_output] = + outputs_at_with(outputs, current_address, start_hash, "") let lovelace_from_only_input = only_input.output.value |> lovelace_of() @@ -216,13 +232,12 @@ validator spend( start_hash, share_token, funds_controlled: funds_controlled + lovelace_withdrawn, - deadline, } let is_only_output_value_clean = value_length(only_output.value) == 2 - validity_check? && lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( + lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( mint, share_token, start_hash, @@ -234,9 +249,9 @@ validator spend( RemoveEmptyInstance -> when only_input_datum is { - Refundable { start_hash, share_token, funds_controlled, deadline } -> { - let validity_check = valid_after(validity_range, deadline) - + Refundable { start_hash, share_token, funds_controlled } -> { + // check only 1 input with token from current address + expect [_] = inputs_at_with(inputs, current_address, start_hash, "") let token_burnt_check = if funds_controlled > 0 { policy_only_minted_token( @@ -251,7 +266,7 @@ validator spend( let proposer_key_signed_check = key_signed(extra_signatories, proposer_key_hash) - validity_check? && token_burnt_check? && proposer_key_signed_check? && policy_only_minted_token( + token_burnt_check? && proposer_key_signed_check? && policy_only_minted_token( mint, start_hash, "", diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak index 5f3e69afd..32e69ea13 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak @@ -1,1009 +1,1756 @@ -// use cardano/address.{Script} -// use cardano/assets.{add, from_lovelace} -// use cardano/certificate.{ -// DelegateBlockProduction, DelegateCredential, DelegateVote, RegisterCredential, -// RegisterDelegateRepresentative, Registered, UnregisterCredential, -// UnregisterDelegateRepresentative, -// } -// use cardano/governance.{ProposalProcedure} -// use cardano/transaction.{Transaction} -// use mocktail.{ -// add_certificate, add_extra_signatory, complete, invalid_before, mint, -// mock_policy_id, mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, -// tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, -// } -// use spend -// use tests/utils.{ -// add_proposal_procedure, mock_completion_script, -// mock_contribute_min_fundraised_amount, mock_current_fundraised_amount, -// mock_deadline, mock_delegate_pool_id, mock_drep_register_deposit, -// mock_funds_controlled, mock_gov_action, mock_gov_action_period, -// mock_gov_address, mock_proposer_key_hash, mock_share_token, -// mock_spend_script_hash, mock_stake_register_deposit, mock_stake_script_hash, -// } -// use types.{ -// ContributorWithdrawal, Init, Proposed, Refundable, RegisterCerts, -// RemoveEmptyInstance, -// } - -// type RegisterCertsTestCase { -// is_only_one_inputed: Bool, -// is_only_one_outputed: Bool, -// is_output_datum_correct: Bool, -// is_output_value_clean: Bool, -// is_output_value_correct: Bool, -// is_stake_cert_register: Bool, -// is_drep_cert_register: Bool, -// is_drep_deposit_correct: Bool, -// is_stake_delegated: Bool, -// is_vote_delegated: Bool, -// is_gov_proposed: Bool, -// } - -// fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { -// let RegisterCertsTestCase { -// is_only_one_inputed, -// is_only_one_outputed, -// is_output_datum_correct, -// is_output_value_clean, -// is_output_value_correct, -// is_stake_cert_register, -// is_drep_cert_register, -// is_drep_deposit_correct, -// is_stake_delegated, -// is_vote_delegated, -// is_gov_proposed, -// } = test_case - -// let input_value = from_lovelace(mock_funds_controlled) - -// let input_datum = -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// } -// let output_value = -// if is_output_value_correct { -// from_lovelace( -// mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, -// ) -// } else { -// from_lovelace( -// mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit + 10, -// ) -// } - -// let output_datum = -// if is_output_datum_correct { -// Proposed { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// } -// } else { -// Proposed { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled + 10, -// deadline: mock_deadline + mock_gov_action_period, -// } -// } - -// let drep_deposit = -// if is_drep_deposit_correct { -// mock_drep_register_deposit -// } else { -// mock_drep_register_deposit - 1000000 -// } -// mocktail_tx() -// |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) -// |> tx_in_inline_datum(True, input_datum) -// |> tx_in( -// !is_only_one_inputed, -// mock_tx_hash(0), -// 1, -// input_value, -// mock_gov_address, -// ) -// |> tx_out(is_output_value_clean, mock_gov_address, output_value) -// |> tx_out( -// !is_output_value_clean, -// mock_gov_address, -// output_value |> add(mock_policy_id(999), mock_completion_script, 1), -// ) -// |> tx_out_inline_datum(True, output_datum) -// |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) -// |> complete() -// |> add_certificate( -// is_stake_cert_register, -// RegisterCredential { -// credential: Script(mock_stake_script_hash), -// deposit: Never, -// }, -// ) -// |> add_certificate( -// is_drep_cert_register, -// RegisterDelegateRepresentative { -// delegate_representative: Script(mock_stake_script_hash), -// deposit: drep_deposit, -// }, -// ) -// |> add_certificate( -// is_stake_delegated, -// DelegateCredential { -// credential: Script(mock_stake_script_hash), -// delegate: DelegateBlockProduction { -// stake_pool: mock_delegate_pool_id, -// }, -// }, -// ) -// |> add_certificate( -// is_vote_delegated, -// DelegateCredential { -// credential: Script(mock_stake_script_hash), -// delegate: DelegateVote { -// delegate_representative: Registered(Script(mock_stake_script_hash)), -// }, -// }, -// ) -// |> add_proposal_procedure( -// is_gov_proposed, -// ProposalProcedure { -// deposit: mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit, -// return_address: Script(mock_spend_script_hash), -// governance_action: mock_gov_action, -// }, -// ) -// } - -// test s3_spend_success_reg_cert() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_not_init_state() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Proposed { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_more_than_one_input() fail { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: False, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_more_than_one_output() fail { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: False, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_incorrect_output_datum() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: False, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_output_value_not_clean() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: False, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_incorrect_output_value() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: False, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: False, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: False, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: False, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_stake_not_delegated() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: False, -// is_vote_delegated: True, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_vote_not_delegated() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: False, -// is_gov_proposed: True, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_reg_cert_with_gov_not_proposed() { -// let tx = -// mock_register_cert_tx( -// RegisterCertsTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_output_value_correct: True, -// is_stake_cert_register: True, -// is_drep_cert_register: True, -// is_drep_deposit_correct: True, -// is_stake_delegated: True, -// is_vote_delegated: True, -// is_gov_proposed: False, -// }, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_funds_controlled, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RegisterCerts, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// type ContributorWithdrawalTestCase { -// is_only_one_inputed: Bool, -// is_only_one_outputed: Bool, -// is_output_datum_correct: Bool, -// is_output_value_clean: Bool, -// is_unlock_value_correct: Bool, -// is_deadline_passed: Bool, -// is_shares_burnt: Bool, -// } - -// fn mock_contributor_withdrawal_tx( -// test_case: ContributorWithdrawalTestCase, -// current_fundraised_amount: Int, -// withdraw_amount: Int, -// ) -> Transaction { -// let ContributorWithdrawalTestCase { -// is_only_one_inputed, -// is_only_one_outputed, -// is_output_datum_correct, -// is_output_value_clean, -// is_unlock_value_correct, -// is_deadline_passed, -// is_shares_burnt, -// } = test_case - -// let input_value = from_lovelace(current_fundraised_amount) - -// let input_datum = -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// } -// let output_value = -// if is_unlock_value_correct { -// from_lovelace(current_fundraised_amount - withdraw_amount) -// } else { -// from_lovelace(current_fundraised_amount - withdraw_amount + 10) -// } - -// let output_datum = -// if is_output_datum_correct { -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: current_fundraised_amount - withdraw_amount, -// deadline: mock_deadline + mock_gov_action_period, -// } -// } else { -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: current_fundraised_amount - withdraw_amount + 10, -// deadline: mock_deadline + mock_gov_action_period, -// } -// } - -// mocktail_tx() -// |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) -// |> tx_in_inline_datum(True, input_datum) -// |> tx_in( -// !is_only_one_inputed, -// mock_tx_hash(0), -// 1, -// input_value, -// mock_gov_address, -// ) -// |> tx_out(True, mock_pub_key_address(0, None), from_lovelace(withdraw_amount)) -// |> tx_out(is_output_value_clean, mock_gov_address, output_value) -// |> tx_out( -// !is_output_value_clean, -// mock_gov_address, -// output_value |> add(mock_policy_id(999), mock_completion_script, 1), -// ) -// |> tx_out_inline_datum(True, output_datum) -// |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) -// |> invalid_before( -// is_deadline_passed, -// mock_deadline + mock_gov_action_period + 3600 * 24, -// ) -// |> invalid_before( -// !is_deadline_passed, -// mock_deadline + mock_gov_action_period - 3600 * 24, -// ) -// |> mint( -// is_shares_burnt, -// -withdraw_amount, -// mock_share_token, -// mock_completion_script, -// ) -// |> mint( -// !is_shares_burnt, -// -withdraw_amount + 9999999, -// mock_share_token, -// mock_completion_script, -// ) -// |> complete() -// } - -// test s3_spend_success_contributor_withdraw() { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Proposed { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: False, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: False, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: False, -// is_output_value_clean: True, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: False, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_unlock_value_correct: False, -// is_deadline_passed: True, -// is_shares_burnt: True, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } +use cardano/address.{Script} +use cardano/assets.{add, from_lovelace} +use cardano/certificate.{ + DelegateBlockProduction, DelegateCredential, DelegateVote, RegisterCredential, + RegisterDelegateRepresentative, Registered, UnregisterCredential, + UnregisterDelegateRepresentative, +} +use cardano/governance.{ + DelegateRepresentative, GovernanceActionId, NoConfidence, ProposalProcedure, + Yes, +} +use cardano/transaction.{Transaction} +use mocktail.{ + add_certificate, add_extra_signatory, complete, invalid_before, mint, + mock_policy_id, mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, + tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use spend +use tests/utils.{ + add_proposal_procedure, add_vote, mock_contribute_min_fundraised_amount, + mock_current_fundraised_amount, mock_deadline, mock_delegate_pool_id, + mock_drep_register_deposit, mock_fundraise_target, mock_funds_controlled, + mock_gov_action, mock_gov_action_id, mock_gov_action_period, mock_gov_address, + mock_proposer_key_hash, mock_share_token, mock_spend_script_hash, + mock_stake_register_deposit, mock_start_hash, +} +use types.{ + ContributorWithdrawal, DeregisterCerts, Init, Proposed, Refundable, + RegisterCerts, RemoveEmptyInstance, VoteOnGovAction, Voted, +} + +type RegisterCertsTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_output_value_correct: Bool, + is_stake_cert_register: Bool, + is_drep_cert_register: Bool, + is_drep_deposit_correct: Bool, + is_stake_delegated: Bool, + is_vote_delegated: Bool, + is_gov_proposed: Bool, +} + +fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { + let RegisterCertsTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_output_value_correct, + is_stake_cert_register, + is_drep_cert_register, + is_drep_deposit_correct, + is_stake_delegated, + is_vote_delegated, + is_gov_proposed, + } = test_case + + let input_value = + from_lovelace(mock_funds_controlled) |> add(mock_start_hash, "", 1) + + let input_datum = + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + } + let output_value = + if is_output_value_correct { + from_lovelace( + mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit - mock_fundraise_target, + ) + |> add(mock_start_hash, "", 1) + } else { + from_lovelace( + mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit + 10 - mock_fundraise_target, + ) + |> add(mock_start_hash, "", 1) + } + + let output_datum = + if is_output_datum_correct { + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled + 10, + deadline: mock_deadline + mock_gov_action_period, + } + } + + let drep_deposit = + if is_drep_deposit_correct { + mock_drep_register_deposit + } else { + mock_drep_register_deposit - 1000000 + } + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_start_hash, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) + |> complete() + |> add_certificate( + is_stake_cert_register, + RegisterCredential { + credential: Script(mock_start_hash), + deposit: Never, + }, + ) + |> add_certificate( + is_drep_cert_register, + RegisterDelegateRepresentative { + delegate_representative: Script(mock_start_hash), + deposit: drep_deposit, + }, + ) + |> add_certificate( + is_stake_delegated, + DelegateCredential { + credential: Script(mock_start_hash), + delegate: DelegateBlockProduction { + stake_pool: mock_delegate_pool_id, + }, + }, + ) + |> add_certificate( + is_vote_delegated, + DelegateCredential { + credential: Script(mock_start_hash), + delegate: DelegateVote { + delegate_representative: Registered(Script(mock_start_hash)), + }, + }, + ) + |> add_proposal_procedure( + is_gov_proposed, + ProposalProcedure { + deposit: mock_fundraise_target, + return_address: Script(mock_spend_script_hash), + governance_action: NoConfidence { ancestor: None }, + }, + ) +} + +test s3_spend_success_reg_cert() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_not_init_state() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_more_than_one_input() fail { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_more_than_one_output() fail { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_incorrect_output_datum() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_output_value_not_clean() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_incorrect_output_value() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: False, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: False, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: False, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: False, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_stake_not_delegated() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: False, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_vote_not_delegated() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: False, + is_gov_proposed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_reg_cert_with_gov_not_proposed() { + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: False, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +type VoteOnGovActionTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_output_value_same: Bool, + is_voted_by_drep: Bool, +} + +fn mock_vote_on_gov_action_tx(test_case: VoteOnGovActionTestCase) -> Transaction { + let VoteOnGovActionTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_output_value_same, + is_voted_by_drep, + } = test_case + + let input_value = + from_lovelace(mock_current_fundraised_amount) |> add(mock_start_hash, "", 1) + + let input_datum = + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + } + let output_value = + if is_output_value_same { + from_lovelace(mock_current_fundraised_amount) + |> add(mock_start_hash, "", 1) + } else { + from_lovelace(mock_current_fundraised_amount + 10) + |> add(mock_start_hash, "", 1) + } + + let output_datum = + if is_output_datum_correct { + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + gov_tx_id: mock_gov_action_id, + } + } else { + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + gov_tx_id: GovernanceActionId { + transaction: mock_tx_hash(0), + proposal_procedure: 1, + }, + } + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out( + True, + mock_pub_key_address(0, None), + from_lovelace(mock_fundraise_target), + ) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_start_hash, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) + |> complete() + |> add_vote( + is_voted_by_drep, + Pair( + DelegateRepresentative(Script(mock_start_hash)), + [Pair(mock_gov_action_id, Yes)], + ), + ) +} + +test s3_spend_success_vote_on_gov_action() { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_same: True, + is_voted_by_drep: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_vote_on_gov_action_with_more_than_one_inputed() fail { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_same: True, + is_voted_by_drep: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_vote_on_gov_action_with_more_than_one_outputed() fail { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_same: True, + is_voted_by_drep: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_vote_on_gov_action_with_output_datum_wrong() { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_output_value_same: True, + is_voted_by_drep: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_vote_on_gov_action_with_output_value_not_clean() { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_output_value_same: True, + is_voted_by_drep: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_vote_on_gov_action_with_incorrect_output_value() { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_same: False, + is_voted_by_drep: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_vote_on_gov_action_with_no_vote() fail { + let tx = + mock_vote_on_gov_action_tx( + VoteOnGovActionTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_same: True, + is_voted_by_drep: False, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + VoteOnGovAction, + mock_utxo_ref(0, 0), + tx, + ) +} + +type DeregisterCertsTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_output_value_correct: Bool, + is_stake_cert_deregister: Bool, + is_drep_cert_deregister: Bool, + is_deadline_passed: Bool, +} + +fn mock_deregister_cert_tx(test_case: DeregisterCertsTestCase) -> Transaction { + let DeregisterCertsTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_output_value_correct, + is_stake_cert_deregister, + is_drep_cert_deregister, + is_deadline_passed, + } = test_case + + let input_value = + from_lovelace(mock_funds_controlled) |> add(mock_start_hash, "", 1) + + let input_datum = + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + } + let output_value = + if is_output_value_correct { + from_lovelace( + mock_funds_controlled + mock_stake_register_deposit + mock_drep_register_deposit, + ) + |> add(mock_start_hash, "", 1) + } else { + from_lovelace( + mock_funds_controlled + mock_stake_register_deposit + mock_drep_register_deposit - 10, + ) + |> add(mock_start_hash, "", 1) + } + + let output_datum = + if is_output_datum_correct { + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + } + } else { + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled + 10, + } + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_start_hash, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) + |> invalid_before( + is_deadline_passed, + mock_deadline + mock_gov_action_period + 3600 * 24, + ) + |> invalid_before( + !is_deadline_passed, + mock_deadline + mock_gov_action_period - 3600 * 24, + ) + |> complete() + |> add_certificate( + is_stake_cert_deregister, + UnregisterCredential { + credential: Script(mock_start_hash), + refund: Never, + }, + ) + |> add_certificate( + is_drep_cert_deregister, + UnregisterDelegateRepresentative { + delegate_representative: Script(mock_start_hash), + refund: mock_drep_register_deposit, + }, + ) +} + +test s3_spend_success_unregister_certs() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_more_than_one_inputed() fail { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_more_than_one_outputed() fail { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_output_datum_incorrect() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_output_value_not_clean() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_output_value_incorrect() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: False, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_stake_not_unregister() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: False, + is_drep_cert_deregister: True, + is_deadline_passed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_drep_not_unregister() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: False, + is_deadline_passed: True, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_unregister_certs_with_deadline_not_passed() { + let tx = + mock_deregister_cert_tx( + DeregisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_deregister: True, + is_drep_cert_deregister: True, + is_deadline_passed: False, + }, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Voted { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + gov_tx_id: mock_gov_action_id, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + DeregisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +type ContributorWithdrawalTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_unlock_value_correct: Bool, + // is_deadline_passed: Bool, + is_shares_burnt: Bool, +} + +fn mock_contributor_withdrawal_tx( + test_case: ContributorWithdrawalTestCase, + current_fundraised_amount: Int, + withdraw_amount: Int, +) -> Transaction { + let ContributorWithdrawalTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_unlock_value_correct, + is_shares_burnt, + } = test_case + + let input_value = + from_lovelace(current_fundraised_amount) |> add(mock_start_hash, "", 1) + + let input_datum = + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount, + } + let output_value = + if is_unlock_value_correct { + from_lovelace(current_fundraised_amount - withdraw_amount) + |> add(mock_start_hash, "", 1) + } else { + from_lovelace(current_fundraised_amount - withdraw_amount + 10) + |> add(mock_start_hash, "", 1) + } + + let output_datum = + if is_output_datum_correct { + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount - withdraw_amount, + } + } else { + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount - withdraw_amount + 10, + } + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out(True, mock_pub_key_address(0, None), from_lovelace(withdraw_amount)) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_start_hash, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) // |> invalid_before( + // is_deadline_passed, + // mock_deadline + mock_gov_action_period + 3600 * 24, + // ) + // |> invalid_before( + // !is_deadline_passed, + // mock_deadline + mock_gov_action_period - 3600 * 24, + // ) + + |> mint(is_shares_burnt, -withdraw_amount, mock_share_token, mock_start_hash) + |> mint( + !is_shares_burnt, + -withdraw_amount + 9999999, + mock_share_token, + mock_start_hash, + ) + |> complete() +} + +test s3_spend_success_contributor_withdraw() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Proposed { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: False, + // is_deadline_passed: True, + is_shares_burnt: True, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} // test s3_spend_fail_contributor_withdraw_with_deadline_not_passed() { // let tx = @@ -1029,10 +1776,9 @@ // mock_drep_register_deposit, // Some( // Refundable { -// completion_script: mock_completion_script, +// start_hash: mock_start_hash, // share_token: mock_share_token, // funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, // }, // ), // ContributorWithdrawal, @@ -1041,236 +1787,238 @@ // ) // } -// test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { -// let tx = -// mock_contributor_withdrawal_tx( -// ContributorWithdrawalTestCase { -// is_only_one_inputed: True, -// is_only_one_outputed: True, -// is_output_datum_correct: True, -// is_output_value_clean: True, -// is_unlock_value_correct: True, -// is_deadline_passed: True, -// is_shares_burnt: False, -// }, -// mock_current_fundraised_amount, -// mock_contribute_min_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// ContributorWithdrawal, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// type RemoveEmptyInstanceTestCase { -// is_only_one_inputed: Bool, -// is_deadline_passed: Bool, -// is_shares_burnt: Bool, -// is_proposer_signed: Bool, -// } - -// fn mock_remove_empty_instance_tx( -// test_case: RemoveEmptyInstanceTestCase, -// current_fundraised_amount: Int, -// ) -> Transaction { -// let RemoveEmptyInstanceTestCase { -// is_only_one_inputed, -// is_deadline_passed, -// is_shares_burnt, -// is_proposer_signed, -// } = test_case - -// let input_value = from_lovelace(current_fundraised_amount) - -// let input_datum = -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// } - -// mocktail_tx() -// |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) -// |> tx_in_inline_datum(True, input_datum) -// |> tx_in( -// !is_only_one_inputed, -// mock_tx_hash(0), -// 1, -// input_value, -// mock_gov_address, -// ) -// |> tx_out( -// True, -// mock_pub_key_address(0, None), -// from_lovelace(current_fundraised_amount), -// ) -// |> invalid_before( -// is_deadline_passed, -// mock_deadline + mock_gov_action_period + 3600 * 24, -// ) -// |> invalid_before( -// !is_deadline_passed, -// mock_deadline + mock_gov_action_period - 3600 * 24, -// ) -// |> mint( -// is_shares_burnt, -// -current_fundraised_amount, -// mock_share_token, -// mock_completion_script, -// ) -// |> mint( -// !is_shares_burnt, -// -current_fundraised_amount + 9999999, -// mock_share_token, -// mock_completion_script, -// ) -// |> complete() -// |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) -// } - -// test s3_spend_success_remove_empty_instance_wih_zero_fund() { -// let tx = -// mock_remove_empty_instance_tx( -// RemoveEmptyInstanceTestCase { -// is_only_one_inputed: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// is_proposer_signed: True, -// }, -// 0, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: 0, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RemoveEmptyInstance, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_success_remove_empty_instance_wih_some_fund() { -// let tx = -// mock_remove_empty_instance_tx( -// RemoveEmptyInstanceTestCase { -// is_only_one_inputed: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// is_proposer_signed: True, -// }, -// mock_current_fundraised_amount, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RemoveEmptyInstance, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { -// let tx = -// mock_remove_empty_instance_tx( -// RemoveEmptyInstanceTestCase { -// is_only_one_inputed: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// is_proposer_signed: True, -// }, -// mock_current_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Init { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RemoveEmptyInstance, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { -// let tx = -// mock_remove_empty_instance_tx( -// RemoveEmptyInstanceTestCase { -// is_only_one_inputed: False, -// is_deadline_passed: True, -// is_shares_burnt: True, -// is_proposer_signed: True, -// }, -// mock_current_fundraised_amount, -// ) - -// spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RemoveEmptyInstance, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } +test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { + let tx = + mock_contributor_withdrawal_tx( + ContributorWithdrawalTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_unlock_value_correct: True, + // is_deadline_passed: True, + is_shares_burnt: False, + }, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + ContributorWithdrawal, + mock_utxo_ref(0, 0), + tx, + ) +} + +type RemoveEmptyInstanceTestCase { + is_only_one_inputed: Bool, + // is_deadline_passed: Bool, + is_shares_burnt: Bool, + is_token_burnt: Bool, + is_proposer_signed: Bool, +} + +fn mock_remove_empty_instance_tx( + test_case: RemoveEmptyInstanceTestCase, + current_fundraised_amount: Int, +) -> Transaction { + let RemoveEmptyInstanceTestCase { + is_only_one_inputed, + is_shares_burnt, + is_token_burnt, + is_proposer_signed, + } = test_case + + let input_value = + from_lovelace(current_fundraised_amount) |> add(mock_start_hash, "", 1) + + let input_datum = + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount, + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out( + True, + mock_pub_key_address(0, None), + from_lovelace(current_fundraised_amount), + ) // |> invalid_before( + // is_deadline_passed, + // mock_deadline + mock_gov_action_period + 3600 * 24, + // ) + // |> invalid_before( + // !is_deadline_passed, + // mock_deadline + mock_gov_action_period - 3600 * 24, + // ) + + |> mint( + is_shares_burnt, + -current_fundraised_amount, + mock_share_token, + mock_start_hash, + ) + |> mint( + !is_shares_burnt, + -current_fundraised_amount + 9999999, + mock_share_token, + mock_start_hash, + ) + |> mint(is_token_burnt, -1, mock_start_hash, "") + |> complete() + |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) +} + +test s3_spend_success_remove_empty_instance_wih_zero_fund() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + // is_deadline_passed: True, + is_shares_burnt: True, + is_token_burnt: True, + is_proposer_signed: True, + }, + 0, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: 0, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_success_remove_empty_instance_wih_some_fund() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + // is_deadline_passed: True, + is_shares_burnt: True, + is_token_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + // is_deadline_passed: True, + is_shares_burnt: True, + is_token_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: False, + // is_deadline_passed: True, + is_shares_burnt: True, + is_token_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} // test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { // let tx = @@ -1279,6 +2027,7 @@ // is_only_one_inputed: True, // is_deadline_passed: False, // is_shares_burnt: True, +// is_token_burnt: True, // is_proposer_signed: True, // }, // mock_current_fundraised_amount, @@ -1292,42 +2041,9 @@ // mock_drep_register_deposit, // Some( // Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RemoveEmptyInstance, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } - -// test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { -// let tx = -// mock_remove_empty_instance_tx( -// RemoveEmptyInstanceTestCase { -// is_only_one_inputed: True, -// is_deadline_passed: True, -// is_shares_burnt: False, -// is_proposer_signed: True, -// }, -// mock_current_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, +// start_hash: mock_start_hash, // share_token: mock_share_token, // funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, // }, // ), // RemoveEmptyInstance, @@ -1336,34 +2052,98 @@ // ) // } -// test s3_spend_fail_remove_empty_instance_wih_proposer_not_signed() { -// let tx = -// mock_remove_empty_instance_tx( -// RemoveEmptyInstanceTestCase { -// is_only_one_inputed: True, -// is_deadline_passed: True, -// is_shares_burnt: True, -// is_proposer_signed: False, -// }, -// mock_current_fundraised_amount, -// ) - -// !spend.spend.spend( -// mock_delegate_pool_id, -// mock_gov_action, -// mock_proposer_key_hash, -// mock_stake_register_deposit, -// mock_drep_register_deposit, -// Some( -// Refundable { -// completion_script: mock_completion_script, -// share_token: mock_share_token, -// funds_controlled: mock_current_fundraised_amount, -// deadline: mock_deadline + mock_gov_action_period, -// }, -// ), -// RemoveEmptyInstance, -// mock_utxo_ref(0, 0), -// tx, -// ) -// } +test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + // is_deadline_passed: True, + is_shares_burnt: False, + is_token_burnt: True, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_token_not_burnt() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + // is_deadline_passed: True, + is_shares_burnt: True, + is_token_burnt: False, + is_proposer_signed: True, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s3_spend_fail_remove_empty_instance_wih_proposer_not_signed() { + let tx = + mock_remove_empty_instance_tx( + RemoveEmptyInstanceTestCase { + is_only_one_inputed: True, + // is_deadline_passed: True, + is_shares_burnt: True, + is_token_burnt: True, + is_proposer_signed: False, + }, + mock_current_fundraised_amount, + ) + + !spend.spend.spend( + mock_delegate_pool_id, + mock_gov_action, + mock_proposer_key_hash, + mock_stake_register_deposit, + mock_drep_register_deposit, + Some( + Refundable { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: mock_current_fundraised_amount, + }, + ), + RemoveEmptyInstance, + mock_utxo_ref(0, 0), + tx, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak index 60a2d5521..2313b8147 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak @@ -80,7 +80,7 @@ fn mock_withdraw_tx(test_case: WithdrawTestCase) -> Transaction { |> complete() } -test s3_withdraw_success() { +test s2_withdraw_success() { let tx = mock_withdraw_tx( WithdrawTestCase { @@ -102,7 +102,7 @@ test s3_withdraw_success() { ) } -test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { +test s2_withdraw_fail_with_more_than_one_auth_inputed() fail { let tx = mock_withdraw_tx( WithdrawTestCase { @@ -124,7 +124,7 @@ test s3_withdraw_fail_with_more_than_one_auth_inputed() fail { ) } -test s3_withdraw_fail_with_fundraise_target_not_sent() fail { +test s2_withdraw_fail_with_fundraise_target_not_sent() fail { let tx = mock_withdraw_tx( WithdrawTestCase { @@ -146,7 +146,7 @@ test s3_withdraw_fail_with_fundraise_target_not_sent() fail { ) } -test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { +test s2_withdraw_fail_with_incorrect_fundraise_target_output_amount() { let tx = mock_withdraw_tx( WithdrawTestCase { @@ -168,7 +168,7 @@ test s3_withdraw_fail_with_incorrect_fundraise_target_output_amount() { ) } -test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { +test s2_withdraw_fail_with_incorrect_fundraise_target_output_datum() { let tx = mock_withdraw_tx( WithdrawTestCase { @@ -190,7 +190,7 @@ test s3_withdraw_fail_with_incorrect_fundraise_target_output_datum() { ) } -test s3_withdraw_fail_with_token_not_minted() { +test s2_withdraw_fail_with_token_not_minted() { let tx = mock_withdraw_tx( WithdrawTestCase { @@ -212,7 +212,7 @@ test s3_withdraw_fail_with_token_not_minted() { ) } -test s3_withdraw_fail_with_different_start_hash() { +test s2_withdraw_fail_with_different_start_hash() { let tx = mock_withdraw_tx( WithdrawTestCase { diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index 516b3055c..caac96b94 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -1,10 +1,11 @@ use aiken/collection/list use cardano/address.{Address, Inline, Script, from_script} -use cardano/governance.{NoConfidence, ProposalProcedure} +use cardano/governance.{GovernanceActionId, ProposalProcedure, Vote, Voter} use cardano/transaction.{Transaction} +use gov.{NoConfidence} use mocktail.{ mock_policy_id, mock_pub_key_hash, mock_script_hash, - mock_script_stake_key_hash, + mock_script_stake_key_hash, mock_tx_hash, } use types.{CrowdfundDatum} @@ -77,7 +78,10 @@ pub const mock_stake_register_deposit = 2000000 pub const mock_drep_register_deposit = 500000000 pub const mock_funds_controlled = - mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit + mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit + 1000000 + +pub const mock_gov_action_id = + GovernanceActionId { transaction: mock_tx_hash(0), proposal_procedure: 0 } pub fn add_proposal_procedure( tx: Transaction, @@ -94,3 +98,19 @@ pub fn add_proposal_procedure( } } } + +pub fn add_vote( + tx: Transaction, + condition: Bool, + vote: Pair>, +) -> Transaction { + if !condition { + tx + } else { + Transaction { + ..tx, + votes: tx.votes + |> list.concat([vote]), + } + } +} From 43ade5386a6a459563fd747b8e6e0ba0af66f7d3 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Fri, 27 Jun 2025 17:51:28 +0800 Subject: [PATCH 13/24] fixed: opaque type --- .../gov-crowdfund/lib/gov.ak | 8 +- .../gov-crowdfund/plutus.json | 596 +++++++++++++++++- 2 files changed, 590 insertions(+), 14 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak index b50730be8..d29db7b58 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak @@ -1,5 +1,4 @@ use aiken/crypto.{ScriptHash} -use aiken/math/rational.{Rational} use cardano/address.{Credential} use cardano/assets.{Lovelace} use cardano/governance.{ @@ -13,6 +12,11 @@ pub type VProtocolParametersUpdate { inner: Pairs, } +pub type VRational { + numerator: Int, + denominator: Int, +} + pub type VGovernanceAction { VProtocolParameters { /// The last governance action of type 'ProtocolParameters'. They must all @@ -64,7 +68,7 @@ pub type VGovernanceAction { /// The new quorum value, as a ratio of a numerator and a denominator. The /// quorum specifies the threshold of 'Yes' votes necessary for the /// constitutional committee to accept a proposal procedure. - quorum: Rational, + quorum: VRational, } NewConstitution { /// The last governance action of type `Constitution` or diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json index 4f4bf0764..0b930888d 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json @@ -11,6 +11,95 @@ "license": "Apache-2.0" }, "validators": [ + { + "title": "spend.spend.spend", + "datum": { + "title": "datum_opt", + "schema": { + "$ref": "#/definitions/types~1CrowdfundGovDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1CrowdfundRedeemer" + } + }, + "parameters": [ + { + "title": "delegate_pool_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action", + "schema": { + "$ref": "#/definitions/gov~1VGovernanceAction" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "stake_register_deposit", + "schema": { + "$ref": "#/definitions/Lovelace" + } + }, + { + "title": "drep_register_deposit", + "schema": { + "$ref": "#/definitions/Lovelace" + } + } + ], + "compiledCode": "591a430101003232323232323223222322322322533300b323232323253323301130013012375400426466446464646464a66603260080022a66603860366ea802c0085854ccc064c02400454ccc070c06cdd50058010b0a99980c98028008a99980e180d9baa00b002161533301930030011533301c301b37540160042c2a66603266e1d20080011533301c301b37540160042c2c60326ea80284c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0a4c050c0a8dd50008992999815180a98159baa0171323232323232323232325323232333037302200a1533303730223038375401a2646464666644446464a666086608c004264a666082605860846ea80044c94ccc108c0b4c10cdd5000899191929998241825801099191980c800899191919191929998268040a9998268030a9998268028a9998268020a9998268018a99982680108008a5014a029405280a5014a064607a646600200205244a6660a400229000099912999828a99982899b87375a605660a66ea80092080a0b787e905153330513375e604c60a66ea80080144cdc79bb3305630573057305337540046ecc1385280a501301b001100130540013300200230550013026304e3754040a666096a66609666030054602e6609e0126609e602c6609e60486609e01297ae04bd7025eb804cc0600a8c05ccc13c024cc13cc090cc13cdd4824a5eb812f5c0294052889980c015180b9982780499827980b998279ba90493304f30243304f0094bd7025eb812f5c06602e05266e9520083304e0083304e375008297ae03301602830223304d0073304d4c103d87a80004bd70181a1929998260008a4000264602864a66609c004290000980a9980080098288011129998278008a40002602c6600400460a4002609e00264660020026eacc078c12cdd50029129998268008a5eb804c8c8c8c8cc004004dd5982800211299982900088018991982a1ba733054375200a660a860a2002660a860a400297ae03300300330560023054001330040043052003375c6098002609e00266ebc004c048cc12cdd4806998259ba900c3304b3750016660966ea00292f5c064a66608e606660906ea80044c130c124dd50008b18259826182618241baa00233301300600133702900019b803370007c0789040505bc3f4828b182480099198008008129129998240008a5eb804cc894ccc11d4ccc11ccdd7982618249baa00201b130373253330483038304937540022900009bad304d304a375400264a666090607060926ea80045300103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e301f0031533304e301e0031302733052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c098cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c1380045280998258011980200200089980200200098250009825800982398221baa001163046304337540022c602a60846ea805058c110004c8cc004004084894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd51823982418221baa002016130323253330433033304437540022900009bad30483045375400264a666086606660886ea80045300103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e604e0142a66606e604e60706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c8c94ccc114c1200084c8c8cc0580044c8c8c94ccc11c01454ccc11c00854ccc11c0044c8c94ccc124c0d0c128dd50008999119198008008019129998280008a5013322533304f3375e6e98cc14c0092f5bded8c06e98cc14c0152f5bded8c029444cc010010004c148004c14c004dd5982718259baa0013376000a980103d87a800016323300100102522533304d00114c0103d87a8000132333222533304e3375e00e0062604e660a46e980092f5c026600c00c00260980026eacc134004c144008c13c004c048cc12cc048cc12cdd4806a5eb812f5c029405280a50303232533304a0011480004c8c048c94ccc130008520001301333001001304f00222533304d0011480004c050cc008008c140004c134004c8cc004004dd5980e18249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd78011808998249ba900b330493752014660926ea0024cc124004cc124dd400425eb80c074cc120c078c118dd5180f18231baa01b330484c010100004bd70192999822181818229baa00113049304637540022c609060926092608a6ea8008cdd7980b98221baa301730443754006602e60886ea800458c118004c8cc004004088894ccc11400452f5c026644a666088a66608866ebcc124c118dd500100c0981a192999822981a98231baa0011480004dd6982518239baa0013253330453035304637540022980103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b301c0031533304b301b003130243304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00322533304900114c103d87a8000132333222533304a337220200062a66609466e3c04000c4c08ccc138dd300125eb80530103d87a8000133006006001375c60900026eacc124004c134008c12c00452809982400119802002000899802002000982380098240008b182200099198008008109129998218008a5eb804cc894ccc1094ccc108cdd7982398221baa304730483044375400402c2606464a666086606660886ea8004520001375a6090608a6ea8004c94ccc10cc0ccc110dd50008a6103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e60460142a66606e604660706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c94ccc104c0b0c108dd50008992999821181698219baa0011323232325333049304c002132323301a001132323232533304c0091533304c0061533304c0041533304c0031533304c002100114a029405280a5014a0606e64a66609e00229000099180b9929998288010a4000260306600200260a800444a6660a4002290000980c99801001182a800982900099198008009bab3021304e375400e44a6660a0002297ae013232323233001001375660a600844a6660aa0022006264660ae6e9ccc15cdd48029982b982a0009982b982a800a5eb80cc00c00cc164008c15c004cc010010c15400cdd7182780098290009980b81499ba548030cc138020cc138dd4020a5eb80cc0580a0c050cc13401ccc13530103d87a80004bd7019baf0013374a9003198261ba900e3304c375201a660986ea00312f5c064a666090606860926ea80044c134c128dd50008b18261826982698249baa0023330140070013370007e07a2c6094002646600200204c44a666092002297ae013322533304853330483375e609a60946ea80080704c0e0c94ccc124c0e4c128dd50008a400026eb4c138c12cdd5000992999824981c98251baa00114c0103d87a8000132330010013756609e60986ea8008894ccc138004530103d87a8000132333222533304f30200031533304f301f0031302833053375000497ae014c103d87a8000133006006001375c609a0026eb4c138004c148008c140004c8cc004004dd59827182798259baa00322533304d00114c103d87a8000132333222533304e337220280062a66609c66e3c05000c4c09ccc148dd300125eb80530103d87a8000133006006001375c60980026eacc134004c144008c13c00452809982600119802002000899802002000982580098260009919192999823181b18239baa0011533304630363047375460966098004266e20024dd6982598241baa0011337120126eb4c12cc120dd50008a50304a001330483049001330483330443034304537546092609400298103d87a80004c0103d87980004bd7018229baa304830453754042608e60886ea800458c118c10cdd50008b180a98211baa014163044001323300100102122533304300114bd70099912999821299982119baf304730443754608e609060886ea80080584c0c8c94ccc10cc0ccc110dd50008a400026eb4c120c114dd5000992999821981998221baa00114c0103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f98201820000981f800981f000981c9baa00d14a02a66606e60420142a66606e604260706ea80344c8c8ccc888c8c94ccc104c1100084c8c94ccc10cc1180084c8c8c8cc0540044c8c94ccc11401054ccc11400854ccc1140044c8c94ccc12800400854ccc128c1340044c8c8ccc8894ccc130cdc78018090a99982619b8f00201313370e00201829405281bae304e002375c609c0026eb4c138c13c004c138004dd6182600080119198008008139129998258008a5eb804c8c8c8c8cc004004dd598270021129998280008801899198291ba733052375200a660a4609e002660a460a000297ae03300300330540023052001330040043050003375c6094002609a00229405280a5014a0606064a6660900022900009918081929998250010a40002602266002002609a00444a6660960022900009809198010011827000982580099198008009bab301a3047375400c44a666092002297ae0132323232330010013756609800844a66609c0022006264660a06e9ccc140dd4802998281826800998281827000a5eb80cc00c00cc148008c140004cc010010c13800cdd71824000982580099baf0013374a9003198239ba900a3304737520126608e6ea0cdc0004001a5eb80c94ccc10cc0bcc110dd50008982418229baa001163047304830483044375400666e20005200033702601e6eacc054c108dd500098079bab301530423754602a60846ea800c58c110004c8cc004004080894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd500100b09819192999821981998221baa0011480004dd6982418229baa001325333043303330443754002298103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa00322533304700114c103d87a800013233322253330483372201e0062a66609066e3c03c00c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230008b1821000991980080080f9129998208008a5eb804cc894ccc1014ccc100cdd7982298211baa30453046304237540040282606064a666082606260846ea8004520001375a608c60866ea8004c94ccc104c0c4c108dd50008a6103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c00452809982200119802002000899802002000982180098220009bae303e002375c607c0026eb4c0f8c0fc004c0f8004c0e4dd50068a501533303730213038375401a26464666444a66607e6084646600200203e44a666082002297ae013322533304053330403375e608a60846ea8c114c118c108dd500100a09818192999820981898211baa0011480004dd6982318219baa001325333041303130423754002298103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c0045280998220011980200200089980200200098218009822000899299981ea99981e99b88480000084c8c8c94ccc10c00400854ccc10cc1180044c8cc894ccc10ccdc7801005099b8700100614a06eb8c118004dd69823182380098231bac30450010023233001001323300100102122533304500114bd70099191919198008009bab304800422533304a00110031323304c374e660986ea4014cc130c124004cc130c1280052f5c066006006609c00460980026600800860940066eb8c110004c11c004894ccc11000452f5c026644a66608666e3cdd718240010048998239ba7002330040040011330040040013758608c002608e0022940cdc0a4000004294454ccc0f40044c8c94ccc10800400854ccc108c1140044c8cc894ccc108c0480084cdc3800a40022940dd718228009bad304530460013045375860880020046466002002646600200204044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230009129998218008a5eb804cc894ccc108cdc79bae3047002009133046374e004660080080022660080080026eb0c114004c1180045280a5014a0646600200203444a66608200229404cc894ccc100cdc780101d8a51133004004001375c608600260880022c6eb8c0f8008dd7181f0009bad303e303f001303e0013039375401a2940dc0240046e952002374a900211191980080080191299981d0008a501332253330393375e00400a29444cc010010004c0f0004c0f4004888cdc399b81300437566014606e6ea8008c010dd59805181b9baa300a30373754006002464a666066604660686ea8004520001375a6070606a6ea8004c94ccc0ccc08cc0d0dd50008a60103d87a80001323300100137566072606c6ea8008894ccc0e0004530103d87a80001323332225333039300a003153330393009003130123303d375000497ae014c103d87a8000133006006001375c606e0026eb4c0e0004c0f0008c0e8004c8cc004004008894ccc0dc0045300103d87a800013233322253330383009003153330383008003130113303c374c00497ae014c103d87a8000133006006001375c606c0026eacc0dc004c0ec008c0e4004dc7a4500372291010022325333031301c00113232323232323232533303c303f00200a16375a607a002607a0046eb4c0ec004c0ec008dd7181c800981c8011bae3037001303337540062a666062604200226464646464646464a666078607e0040142c6eb4c0f4004c0f4008dd6981d800981d8011bae30390013039002375c606e00260666ea800c54ccc0c4c0740044c8c8c8c8c8c8c8c8c8c94ccc0f8c10400854ccc0ecc098c0f0dd5001899191919299982118228010080b1bad30430013043002375c6082002607a6ea800c5858dd6981f800981f801181e800981e8011bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018a999818980d8008991919191919299981d181e8010040b1bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018b18189baa002302e375403e600c605c6ea8c004c0b8dd5001918189819000981798161baa01716302e302b37540022c646600200201644a66605a002298103d87a800013322533302c3375e600c605c6ea80080684c014cc0c00092f5c0266008008002605e00260600026e9520002302c0013758605460560106eacc0a401cdd6181400398138039bac30260073756604a00e6eb0c09001cdd6181180398119811981198118009811000981098108009810000980f980f800980f180f000980c9baa00a370e90031b8748000dc3a4008602e002602e603000260266ea8008dc3a40042c6028602a006602600460240046024002601a6ea800452613656375a0026eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d11", + "hash": "b77e4f80ee4d5887de1f3954470f392f455198ff4372c4c7d0d6480c" + }, + { + "title": "spend.spend.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "delegate_pool_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action", + "schema": { + "$ref": "#/definitions/gov~1VGovernanceAction" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "stake_register_deposit", + "schema": { + "$ref": "#/definitions/Lovelace" + } + }, + { + "title": "drep_register_deposit", + "schema": { + "$ref": "#/definitions/Lovelace" + } + } + ], + "compiledCode": "591a430101003232323232323223222322322322533300b323232323253323301130013012375400426466446464646464a66603260080022a66603860366ea802c0085854ccc064c02400454ccc070c06cdd50058010b0a99980c98028008a99980e180d9baa00b002161533301930030011533301c301b37540160042c2a66603266e1d20080011533301c301b37540160042c2c60326ea80284c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0a4c050c0a8dd50008992999815180a98159baa0171323232323232323232325323232333037302200a1533303730223038375401a2646464666644446464a666086608c004264a666082605860846ea80044c94ccc108c0b4c10cdd5000899191929998241825801099191980c800899191919191929998268040a9998268030a9998268028a9998268020a9998268018a99982680108008a5014a029405280a5014a064607a646600200205244a6660a400229000099912999828a99982899b87375a605660a66ea80092080a0b787e905153330513375e604c60a66ea80080144cdc79bb3305630573057305337540046ecc1385280a501301b001100130540013300200230550013026304e3754040a666096a66609666030054602e6609e0126609e602c6609e60486609e01297ae04bd7025eb804cc0600a8c05ccc13c024cc13cc090cc13cdd4824a5eb812f5c0294052889980c015180b9982780499827980b998279ba90493304f30243304f0094bd7025eb812f5c06602e05266e9520083304e0083304e375008297ae03301602830223304d0073304d4c103d87a80004bd70181a1929998260008a4000264602864a66609c004290000980a9980080098288011129998278008a40002602c6600400460a4002609e00264660020026eacc078c12cdd50029129998268008a5eb804c8c8c8c8cc004004dd5982800211299982900088018991982a1ba733054375200a660a860a2002660a860a400297ae03300300330560023054001330040043052003375c6098002609e00266ebc004c048cc12cdd4806998259ba900c3304b3750016660966ea00292f5c064a66608e606660906ea80044c130c124dd50008b18259826182618241baa00233301300600133702900019b803370007c0789040505bc3f4828b182480099198008008129129998240008a5eb804cc894ccc11d4ccc11ccdd7982618249baa00201b130373253330483038304937540022900009bad304d304a375400264a666090607060926ea80045300103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e301f0031533304e301e0031302733052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c098cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c1380045280998258011980200200089980200200098250009825800982398221baa001163046304337540022c602a60846ea805058c110004c8cc004004084894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd51823982418221baa002016130323253330433033304437540022900009bad30483045375400264a666086606660886ea80045300103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e604e0142a66606e604e60706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c8c94ccc114c1200084c8c8cc0580044c8c8c94ccc11c01454ccc11c00854ccc11c0044c8c94ccc124c0d0c128dd50008999119198008008019129998280008a5013322533304f3375e6e98cc14c0092f5bded8c06e98cc14c0152f5bded8c029444cc010010004c148004c14c004dd5982718259baa0013376000a980103d87a800016323300100102522533304d00114c0103d87a8000132333222533304e3375e00e0062604e660a46e980092f5c026600c00c00260980026eacc134004c144008c13c004c048cc12cc048cc12cdd4806a5eb812f5c029405280a50303232533304a0011480004c8c048c94ccc130008520001301333001001304f00222533304d0011480004c050cc008008c140004c134004c8cc004004dd5980e18249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd78011808998249ba900b330493752014660926ea0024cc124004cc124dd400425eb80c074cc120c078c118dd5180f18231baa01b330484c010100004bd70192999822181818229baa00113049304637540022c609060926092608a6ea8008cdd7980b98221baa301730443754006602e60886ea800458c118004c8cc004004088894ccc11400452f5c026644a666088a66608866ebcc124c118dd500100c0981a192999822981a98231baa0011480004dd6982518239baa0013253330453035304637540022980103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b301c0031533304b301b003130243304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00322533304900114c103d87a8000132333222533304a337220200062a66609466e3c04000c4c08ccc138dd300125eb80530103d87a8000133006006001375c60900026eacc124004c134008c12c00452809982400119802002000899802002000982380098240008b182200099198008008109129998218008a5eb804cc894ccc1094ccc108cdd7982398221baa304730483044375400402c2606464a666086606660886ea8004520001375a6090608a6ea8004c94ccc10cc0ccc110dd50008a6103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e60460142a66606e604660706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c94ccc104c0b0c108dd50008992999821181698219baa0011323232325333049304c002132323301a001132323232533304c0091533304c0061533304c0041533304c0031533304c002100114a029405280a5014a0606e64a66609e00229000099180b9929998288010a4000260306600200260a800444a6660a4002290000980c99801001182a800982900099198008009bab3021304e375400e44a6660a0002297ae013232323233001001375660a600844a6660aa0022006264660ae6e9ccc15cdd48029982b982a0009982b982a800a5eb80cc00c00cc164008c15c004cc010010c15400cdd7182780098290009980b81499ba548030cc138020cc138dd4020a5eb80cc0580a0c050cc13401ccc13530103d87a80004bd7019baf0013374a9003198261ba900e3304c375201a660986ea00312f5c064a666090606860926ea80044c134c128dd50008b18261826982698249baa0023330140070013370007e07a2c6094002646600200204c44a666092002297ae013322533304853330483375e609a60946ea80080704c0e0c94ccc124c0e4c128dd50008a400026eb4c138c12cdd5000992999824981c98251baa00114c0103d87a8000132330010013756609e60986ea8008894ccc138004530103d87a8000132333222533304f30200031533304f301f0031302833053375000497ae014c103d87a8000133006006001375c609a0026eb4c138004c148008c140004c8cc004004dd59827182798259baa00322533304d00114c103d87a8000132333222533304e337220280062a66609c66e3c05000c4c09ccc148dd300125eb80530103d87a8000133006006001375c60980026eacc134004c144008c13c00452809982600119802002000899802002000982580098260009919192999823181b18239baa0011533304630363047375460966098004266e20024dd6982598241baa0011337120126eb4c12cc120dd50008a50304a001330483049001330483330443034304537546092609400298103d87a80004c0103d87980004bd7018229baa304830453754042608e60886ea800458c118c10cdd50008b180a98211baa014163044001323300100102122533304300114bd70099912999821299982119baf304730443754608e609060886ea80080584c0c8c94ccc10cc0ccc110dd50008a400026eb4c120c114dd5000992999821981998221baa00114c0103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f98201820000981f800981f000981c9baa00d14a02a66606e60420142a66606e604260706ea80344c8c8ccc888c8c94ccc104c1100084c8c94ccc10cc1180084c8c8c8cc0540044c8c94ccc11401054ccc11400854ccc1140044c8c94ccc12800400854ccc128c1340044c8c8ccc8894ccc130cdc78018090a99982619b8f00201313370e00201829405281bae304e002375c609c0026eb4c138c13c004c138004dd6182600080119198008008139129998258008a5eb804c8c8c8c8cc004004dd598270021129998280008801899198291ba733052375200a660a4609e002660a460a000297ae03300300330540023052001330040043050003375c6094002609a00229405280a5014a0606064a6660900022900009918081929998250010a40002602266002002609a00444a6660960022900009809198010011827000982580099198008009bab301a3047375400c44a666092002297ae0132323232330010013756609800844a66609c0022006264660a06e9ccc140dd4802998281826800998281827000a5eb80cc00c00cc148008c140004cc010010c13800cdd71824000982580099baf0013374a9003198239ba900a3304737520126608e6ea0cdc0004001a5eb80c94ccc10cc0bcc110dd50008982418229baa001163047304830483044375400666e20005200033702601e6eacc054c108dd500098079bab301530423754602a60846ea800c58c110004c8cc004004080894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd500100b09819192999821981998221baa0011480004dd6982418229baa001325333043303330443754002298103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa00322533304700114c103d87a800013233322253330483372201e0062a66609066e3c03c00c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230008b1821000991980080080f9129998208008a5eb804cc894ccc1014ccc100cdd7982298211baa30453046304237540040282606064a666082606260846ea8004520001375a608c60866ea8004c94ccc104c0c4c108dd50008a6103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c00452809982200119802002000899802002000982180098220009bae303e002375c607c0026eb4c0f8c0fc004c0f8004c0e4dd50068a501533303730213038375401a26464666444a66607e6084646600200203e44a666082002297ae013322533304053330403375e608a60846ea8c114c118c108dd500100a09818192999820981898211baa0011480004dd6982318219baa001325333041303130423754002298103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c0045280998220011980200200089980200200098218009822000899299981ea99981e99b88480000084c8c8c94ccc10c00400854ccc10cc1180044c8cc894ccc10ccdc7801005099b8700100614a06eb8c118004dd69823182380098231bac30450010023233001001323300100102122533304500114bd70099191919198008009bab304800422533304a00110031323304c374e660986ea4014cc130c124004cc130c1280052f5c066006006609c00460980026600800860940066eb8c110004c11c004894ccc11000452f5c026644a66608666e3cdd718240010048998239ba7002330040040011330040040013758608c002608e0022940cdc0a4000004294454ccc0f40044c8c94ccc10800400854ccc108c1140044c8cc894ccc108c0480084cdc3800a40022940dd718228009bad304530460013045375860880020046466002002646600200204044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230009129998218008a5eb804cc894ccc108cdc79bae3047002009133046374e004660080080022660080080026eb0c114004c1180045280a5014a0646600200203444a66608200229404cc894ccc100cdc780101d8a51133004004001375c608600260880022c6eb8c0f8008dd7181f0009bad303e303f001303e0013039375401a2940dc0240046e952002374a900211191980080080191299981d0008a501332253330393375e00400a29444cc010010004c0f0004c0f4004888cdc399b81300437566014606e6ea8008c010dd59805181b9baa300a30373754006002464a666066604660686ea8004520001375a6070606a6ea8004c94ccc0ccc08cc0d0dd50008a60103d87a80001323300100137566072606c6ea8008894ccc0e0004530103d87a80001323332225333039300a003153330393009003130123303d375000497ae014c103d87a8000133006006001375c606e0026eb4c0e0004c0f0008c0e8004c8cc004004008894ccc0dc0045300103d87a800013233322253330383009003153330383008003130113303c374c00497ae014c103d87a8000133006006001375c606c0026eacc0dc004c0ec008c0e4004dc7a4500372291010022325333031301c00113232323232323232533303c303f00200a16375a607a002607a0046eb4c0ec004c0ec008dd7181c800981c8011bae3037001303337540062a666062604200226464646464646464a666078607e0040142c6eb4c0f4004c0f4008dd6981d800981d8011bae30390013039002375c606e00260666ea800c54ccc0c4c0740044c8c8c8c8c8c8c8c8c8c94ccc0f8c10400854ccc0ecc098c0f0dd5001899191919299982118228010080b1bad30430013043002375c6082002607a6ea800c5858dd6981f800981f801181e800981e8011bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018a999818980d8008991919191919299981d181e8010040b1bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018b18189baa002302e375403e600c605c6ea8c004c0b8dd5001918189819000981798161baa01716302e302b37540022c646600200201644a66605a002298103d87a800013322533302c3375e600c605c6ea80080684c014cc0c00092f5c0266008008002605e00260600026e9520002302c0013758605460560106eacc0a401cdd6181400398138039bac30260073756604a00e6eb0c09001cdd6181180398119811981198118009811000981098108009810000980f980f800980f180f000980c9baa00a370e90031b8748000dc3a4008602e002602e603000260266ea8008dc3a40042c6028602a006602600460240046024002601a6ea800452613656375a0026eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d11", + "hash": "b77e4f80ee4d5887de1f3954470f392f455198ff4372c4c7d0d6480c" + }, { "title": "start.start.withdraw", "redeemer": { @@ -39,8 +128,8 @@ } } ], - "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" }, { "title": "start.start.mint", @@ -70,8 +159,8 @@ } } ], - "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" }, { "title": "start.start.publish", @@ -101,8 +190,8 @@ } } ], - "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" }, { "title": "start.start.propose", @@ -132,8 +221,8 @@ } } ], - "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" }, { "title": "start.start.vote", @@ -163,8 +252,8 @@ } } ], - "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" }, { "title": "start.start.else", @@ -191,8 +280,8 @@ } } ], - "compiledCode": "590be6010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa00315333044303300113232323232323232533304f305200200a16375a60a000260a00046eb4c138004c138008dd7182600098260011bae304a001304637540062c60886ea80084c94ccc10c02054ccc10c00c54ccc10c0044c8c94ccc12000400854ccc120c12c0044c8cc894ccc120c02c0084c0e40045281bae304b001375a6096609800260966eb0c128004008c8cc004004c8cc0040040b8894ccc12800452f5c0264646464660020026eacc134010894ccc13c004400c4c8cc144dd3998289ba900533051304e00133051304f0014bd7019801801982980118288009980200218278019bae3049001304c00122533304900114bd7009991299982419b8f375c609a0040242660986e9c008cc0100100044cc010010004dd6182580098260008a5014a0294052819baf00130303304637520186608c6ea402ccc118dd4004998231ba83370001007897ae03253330423032304337540022608e60886ea800458c118c11cc11cc10cdd500119b873253330413032304237540022900009bad30463043375400264a666082606460846ea80045300103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87a80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87b8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "21fdcd57e8d9b595b36d777501ba22ae06d2a7dcdf379b53f5552dd6" + "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" } ], "definitions": { @@ -203,13 +292,496 @@ "title": "Data", "description": "Any Plutus data." }, + "Index": { + "title": "Index", + "dataType": "integer" + }, "Int": { "dataType": "integer" }, + "List$cardano/address/Credential": { + "dataType": "list", + "items": { + "$ref": "#/definitions/cardano~1address~1Credential" + } + }, + "Lovelace": { + "title": "Lovelace", + "dataType": "integer" + }, + "Mandate": { + "title": "Mandate", + "dataType": "integer" + }, + "Option$ScriptHash": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/ScriptHash" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$cardano/governance/GovernanceActionId": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Pairs$ProtocolParametersIndex_Data": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/ProtocolParametersIndex" + }, + "values": { + "$ref": "#/definitions/Data" + } + }, + "Pairs$cardano/address/Credential_Lovelace": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/cardano~1address~1Credential" + }, + "values": { + "$ref": "#/definitions/Lovelace" + } + }, + "Pairs$cardano/address/Credential_Mandate": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/cardano~1address~1Credential" + }, + "values": { + "$ref": "#/definitions/Mandate" + } + }, "PolicyId": { "title": "PolicyId", "dataType": "bytes" }, + "ProtocolParametersIndex": { + "title": "ProtocolParametersIndex", + "dataType": "integer" + }, + "ScriptHash": { + "title": "ScriptHash", + "dataType": "bytes" + }, + "TransactionId": { + "title": "TransactionId", + "dataType": "bytes" + }, + "VerificationKeyHash": { + "title": "VerificationKeyHash", + "dataType": "bytes" + }, + "cardano/address/Credential": { + "title": "Credential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/ScriptHash" + } + ] + } + ] + }, + "cardano/governance/Constitution": { + "title": "Constitution", + "anyOf": [ + { + "title": "Constitution", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "guardrails", + "$ref": "#/definitions/Option$ScriptHash" + } + ] + } + ] + }, + "cardano/governance/GovernanceActionId": { + "title": "GovernanceActionId", + "anyOf": [ + { + "title": "GovernanceActionId", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction", + "$ref": "#/definitions/TransactionId" + }, + { + "title": "proposal_procedure", + "$ref": "#/definitions/Index" + } + ] + } + ] + }, + "cardano/governance/ProtocolVersion": { + "title": "ProtocolVersion", + "anyOf": [ + { + "title": "ProtocolVersion", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "major", + "$ref": "#/definitions/Int" + }, + { + "title": "minor", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "gov/VGovernanceAction": { + "title": "VGovernanceAction", + "anyOf": [ + { + "title": "VProtocolParameters", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type 'ProtocolParameters'. They must all\n form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "new_parameters", + "description": "The new proposed protocol parameters. Only values set to `Some` are relevant.", + "$ref": "#/definitions/gov~1VProtocolParametersUpdate" + }, + { + "title": "guardrails", + "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the new protocol parameters to be deemed valid.", + "$ref": "#/definitions/Option$ScriptHash" + } + ] + }, + { + "title": "HardFork", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `HardFork`. They must all\n form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "new_version", + "description": "The new proposed version. Few rules apply to proposing new versions:\n\n - The `major` component, if incremented, must be exactly one more than the current.\n - The `minor` component, if incremented, must be exactly one more than the current.\n - If the `major` component is incremented, `minor` must be set to `0`.\n - Neither `minor` nor `major` can be decremented.", + "$ref": "#/definitions/cardano~1governance~1ProtocolVersion" + } + ] + }, + { + "title": "TreasuryWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "title": "beneficiaries", + "description": "A collection of beneficiaries, which can be plain verification key\n hashes or script hashes (e.g. DAO).", + "$ref": "#/definitions/Pairs$cardano~1address~1Credential_Lovelace" + }, + { + "title": "guardrails", + "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the withdrawals to be authorized.", + "$ref": "#/definitions/Option$ScriptHash" + } + ] + }, + { + "title": "NoConfidence", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + } + ] + }, + { + "title": "ConstitutionalCommittee", + "dataType": "constructor", + "index": 4, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "evicted_members", + "description": "Constitutional members to be removed.", + "$ref": "#/definitions/List$cardano~1address~1Credential" + }, + { + "title": "added_members", + "description": "Constitutional members to be added.", + "$ref": "#/definitions/Pairs$cardano~1address~1Credential_Mandate" + }, + { + "title": "quorum", + "description": "The new quorum value, as a ratio of a numerator and a denominator. The\n quorum specifies the threshold of 'Yes' votes necessary for the\n constitutional committee to accept a proposal procedure.", + "$ref": "#/definitions/gov~1VRational" + } + ] + }, + { + "title": "NewConstitution", + "dataType": "constructor", + "index": 5, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `Constitution` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "constitution", + "description": "The new proposed constitution.", + "$ref": "#/definitions/cardano~1governance~1Constitution" + } + ] + }, + { + "title": "NicePoll", + "dataType": "constructor", + "index": 6, + "fields": [] + } + ] + }, + "gov/VProtocolParametersUpdate": { + "title": "VProtocolParametersUpdate", + "anyOf": [ + { + "title": "VProtocolParametersUpdate", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "inner", + "$ref": "#/definitions/Pairs$ProtocolParametersIndex_Data" + } + ] + } + ] + }, + "gov/VRational": { + "title": "VRational", + "anyOf": [ + { + "title": "VRational", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "numerator", + "$ref": "#/definitions/Int" + }, + { + "title": "denominator", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundGovDatum": { + "title": "CrowdfundGovDatum", + "anyOf": [ + { + "title": "Init", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Proposed", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Voted", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "gov_tx_id", + "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Refundable", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundRedeemer": { + "title": "CrowdfundRedeemer", + "anyOf": [ + { + "title": "RegisterCerts", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "VoteOnGovAction", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "DeregisterCerts", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "ContributorWithdrawal", + "dataType": "constructor", + "index": 3, + "fields": [] + }, + { + "title": "RemoveEmptyInstance", + "dataType": "constructor", + "index": 4, + "fields": [] + } + ] + }, "types/MintPolarity": { "title": "MintPolarity", "anyOf": [ From 12620c412fe4089ee2c43068408381e6a65a42f8 Mon Sep 17 00:00:00 2001 From: kenlau666 Date: Sat, 28 Jun 2025 18:50:55 +0800 Subject: [PATCH 14/24] added: contribute fund integration test --- .../tests/integration_test/contribute_fund.ak | 385 ++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak new file mode 100644 index 000000000..4284bd939 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak @@ -0,0 +1,385 @@ +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{OutputReference, Spend, Transaction} +use crowdfund/spend as crowdfund_spend +use mocktail.{ + add_redeemer, complete, invalid_hereafter, mint, mock_policy_id, + mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, tx_in, + tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use share_token/mint as share_token_mint +use tests/utils.{ + mock_auth_token, mock_completion_script, mock_contribute_min_fundraised_amount, + mock_contribute_over_fundraised_amount, mock_crowdfund_address, + mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, + mock_share_token, +} +use types.{CompleteCrowdfund, ContributeFund, CrowdfundRedeemer, RMint} + +type ContributeFundTestCase { + is_only_one_auth_inputed: Bool, + is_only_one_auth_outputed: Bool, + is_auth_output_datum_correct: Bool, + is_auth_output_value_clean: Bool, + is_deadline_not_passed: Bool, + is_shares_minted: Bool, +} + +fn mock_contribute_fund_tx( + test_case: ContributeFundTestCase, + current_fundraised_amount: Int, + contribute_amount: Int, + allow_over_subscription: Bool, + auth_token_redeemer: CrowdfundRedeemer, +) -> Transaction { + let ContributeFundTestCase { + is_only_one_auth_inputed, + is_only_one_auth_outputed, + is_auth_output_datum_correct, + is_auth_output_value_clean, + is_deadline_not_passed, + is_shares_minted, + } = test_case + let auth_token_redeemer_data: Data = auth_token_redeemer + + let input_value = + from_lovelace(current_fundraised_amount) + |> add(mock_auth_token, mock_completion_script, 1) + + let output_value = + from_lovelace(current_fundraised_amount + contribute_amount) + |> add(mock_auth_token, mock_completion_script, 1) + + let auth_correct_output_datum = + mock_crowdfund_datum( + current_fundraised_amount + contribute_amount, + allow_over_subscription, + ) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, allow_over_subscription), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> tx_in( + True, + mock_tx_hash(1), + 0, + from_lovelace(contribute_amount), + mock_pub_key_address(0, None), + ) + |> tx_out(is_auth_output_value_clean, mock_crowdfund_address, output_value) + |> tx_out( + !is_auth_output_value_clean, + mock_crowdfund_address, + output_value |> add(mock_policy_id(999), mock_completion_script, 1), + ) + |> tx_out_inline_datum(is_auth_output_datum_correct, auth_correct_output_datum) + |> tx_out_inline_datum( + !is_auth_output_datum_correct, + mock_crowdfund_datum( + current_fundraised_amount + contribute_amount + 9999999, + allow_over_subscription, + ), + ) + |> tx_out(!is_only_one_auth_outputed, mock_crowdfund_address, output_value) + |> invalid_hereafter(is_deadline_not_passed, mock_deadline - 3600 * 24) + |> invalid_hereafter(!is_deadline_not_passed, mock_deadline + 3600 * 24) + |> mint( + is_shares_minted, + contribute_amount, + mock_share_token, + mock_completion_script, + ) + |> mint( + !is_shares_minted, + contribute_amount + 9999999, + mock_share_token, + mock_completion_script, + ) + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + auth_token_redeemer_data, + ), + ) +} + +fn check_all_scripts( + test_case: ContributeFundTestCase, + current_fundraised_amount: Int, + contribute_amount: Int, + allow_over_subscription: Bool, + auth_token_redeemer: CrowdfundRedeemer, +) { + let tx = + mock_contribute_fund_tx( + test_case, + current_fundraised_amount, + contribute_amount, + allow_over_subscription, + auth_token_redeemer, + ) + + let check_auth_spend = + crowdfund_spend.crowdfund.spend( + mock_auth_token, + Some( + mock_crowdfund_datum( + mock_current_fundraised_amount, + allow_over_subscription, + ), + ), + auth_token_redeemer, + mock_utxo_ref(0, 0), + tx, + ) + let check_share_mint = + share_token_mint.share_token.mint( + mock_auth_token, + RMint, + mock_share_token, + tx, + ) + + check_auth_spend? && check_share_mint? +} + +test contribute_fund_success_with_not_allow_over_subscription() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_success_with_allow_over_subscription() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + True, + ContributeFund, + ) +} + +test contribute_fund_success_with_allow_over_subscription_and_over_fundraised() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_over_fundraised_amount, + True, + ContributeFund, + ) +} + +test contribute_fund_fail_with_not_allow_over_subscription_but_over_fundraised() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_over_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_over_current_fundraised() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + !check_all_scripts( + test_case, + mock_contribute_over_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_wrong_redeemer() fail { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + CompleteCrowdfund, + ) +} + +test contribute_fund_fail_with_more_than_one_auth_inputed() fail { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: False, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_more_than_one_auth_outputed() fail { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: False, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_incorrect_auth_output_datum() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: False, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: True, + } + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_auth_output_not_clean() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: False, + is_deadline_not_passed: True, + is_shares_minted: True, + } + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_deadline_passed() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: False, + is_shares_minted: True, + } + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} + +test contribute_fund_fail_with_wrong_shares_minted() { + let test_case = + ContributeFundTestCase { + is_only_one_auth_inputed: True, + is_only_one_auth_outputed: True, + is_auth_output_datum_correct: True, + is_auth_output_value_clean: True, + is_deadline_not_passed: True, + is_shares_minted: False, + } + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + mock_contribute_min_fundraised_amount, + False, + ContributeFund, + ) +} From 2db35e7445abf84f5ca4eb860cffc643e016fb85 Mon Sep 17 00:00:00 2001 From: kenlau666 Date: Sun, 29 Jun 2025 02:23:49 +0800 Subject: [PATCH 15/24] added: complete fund integration test --- .../tests/integration_test/contribute_fund.ak | 57 --- .../gov-crowdfund/validators/crowdfund.ak | 211 +++++++++ .../intergration_test/complete_crowdfund.ak | 439 ++++++++++++++++++ .../gov-crowdfund/validators/tests/utils.ak | 12 +- 4 files changed, 659 insertions(+), 60 deletions(-) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak index 4284bd939..ba13be51e 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak @@ -156,63 +156,6 @@ fn check_all_scripts( check_auth_spend? && check_share_mint? } -test contribute_fund_success_with_not_allow_over_subscription() { - let test_case = - ContributeFundTestCase { - is_only_one_auth_inputed: True, - is_only_one_auth_outputed: True, - is_auth_output_datum_correct: True, - is_auth_output_value_clean: True, - is_deadline_not_passed: True, - is_shares_minted: True, - } - check_all_scripts( - test_case, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - False, - ContributeFund, - ) -} - -test contribute_fund_success_with_allow_over_subscription() { - let test_case = - ContributeFundTestCase { - is_only_one_auth_inputed: True, - is_only_one_auth_outputed: True, - is_auth_output_datum_correct: True, - is_auth_output_value_clean: True, - is_deadline_not_passed: True, - is_shares_minted: True, - } - check_all_scripts( - test_case, - mock_current_fundraised_amount, - mock_contribute_min_fundraised_amount, - True, - ContributeFund, - ) -} - -test contribute_fund_success_with_allow_over_subscription_and_over_fundraised() { - let test_case = - ContributeFundTestCase { - is_only_one_auth_inputed: True, - is_only_one_auth_outputed: True, - is_auth_output_datum_correct: True, - is_auth_output_value_clean: True, - is_deadline_not_passed: True, - is_shares_minted: True, - } - check_all_scripts( - test_case, - mock_current_fundraised_amount, - mock_contribute_over_fundraised_amount, - True, - ContributeFund, - ) -} - test contribute_fund_fail_with_not_allow_over_subscription_but_over_fundraised() { let test_case = ContributeFundTestCase { diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak new file mode 100644 index 000000000..fb60cf331 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak @@ -0,0 +1,211 @@ +use aiken/collection/list.{delete} +use aiken/collection/pairs.{has_key} +use cardano/address.{Address, Credential, Script} +use cardano/assets.{ + PolicyId, Value, from_lovelace, lovelace_of, merge, policies, restricted_to, +} +use cardano/transaction.{Output, OutputReference, Transaction, find_input} +use cocktail.{ + inputs_at_with_policy, only_minted_token, output_inline_datum, + outputs_at_with_policy, policy_only_minted_token, valid_after, valid_before, + value_length, +} +use types.{CrowdfundDatum} + +pub type CrowdfundRedeemer { + ContributeFund + CompleteCrowdfund + ContributorWithdrawal + RemoveEmptyInstance +} + +fn check_fundraise_target( + allow_over_subscription: Bool, + fundraise_target: Int, + current_fundraised_amount: Int, +) -> Bool { + if allow_over_subscription { + True + } else { + current_fundraised_amount <= fundraise_target + } +} + +fn output_at_with_value( + outputs: List, + address: Address, + value: Value, +) -> List { + list.filter( + outputs, + fn(output) { + let are_values_equal = output.value == value + are_values_equal && output.address == address + }, + ) +} + +validator crowdfund(auth_token: PolicyId) { + spend( + datum_opt: Option, + redeemer: CrowdfundRedeemer, + input: OutputReference, + self: Transaction, + ) { + let Transaction { inputs, validity_range, mint, outputs, withdrawals, .. } = + self + + expect Some(own_input) = find_input(inputs, input) + expect Some(auth_input_datum) = datum_opt + + let current_address = own_input.output.address + + // check only 1 auth toke input from current address + expect [auth_input] = + inputs_at_with_policy(inputs, current_address, auth_token) + + let CrowdfundDatum { + current_fundraised_amount, + fundraise_target, + allow_over_subscription, + deadline, + completion_script, + share_token, + min_charge, + fee_address, + expiry_buffer, + .. + } = auth_input_datum + when redeemer is { + ContributeFund -> { + expect [auth_output] = + outputs_at_with_policy(outputs, current_address, auth_token) + + let lovelace_from_auth_input = auth_input.output.value |> lovelace_of() + let lovelace_from_auth_output = auth_output.value |> lovelace_of() + expect auth_output_datum: CrowdfundDatum = + output_inline_datum(auth_output) + + let fundraise_added = + lovelace_from_auth_output - lovelace_from_auth_input + let fundraise_check = + (fundraise_added == auth_output_datum.current_fundraised_amount - current_fundraised_amount)? && (fundraise_added >= 2000000)? + + let fundraise_target_check = + check_fundraise_target( + allow_over_subscription, + fundraise_target, + auth_output_datum.current_fundraised_amount, + ) + + let validity_check = valid_before(validity_range, deadline) + + let output_datum_check = + auth_output_datum == CrowdfundDatum { + ..auth_input_datum, + current_fundraised_amount: current_fundraised_amount + fundraise_added, + } + + let is_auth_output_value_clean = value_length(auth_output.value) == 2 + fundraise_check? && fundraise_target_check? && validity_check? && output_datum_check? && is_auth_output_value_clean? && only_minted_token( + mint, + share_token, + completion_script, + fundraise_added, + )? + } + + CompleteCrowdfund -> { + let fee_value = + from_lovelace( + lovelace_of(auth_input.output.value) - current_fundraised_amount - min_charge, + ) + + let other_policy = + policies(auth_input.output.value) + |> delete(auth_token) + |> delete("") + let other_value = restricted_to(auth_input.output.value, other_policy) + + expect [_] = + output_at_with_value( + outputs, + fee_address, + merge(other_value, fee_value), + ) + + let fundraise_check = current_fundraised_amount >= fundraise_target + let completion_script_withdrawal_credential: Credential = + Script(completion_script) + let withdrawal_script_check = + withdrawals + |> has_key(completion_script_withdrawal_credential) + fundraise_check? && withdrawal_script_check? && policy_only_minted_token( + mint, + auth_token, + completion_script, + -1, + )? + } + + ContributorWithdrawal -> { + let validity_check = + valid_after(validity_range, deadline + expiry_buffer) + let fund_check = current_fundraised_amount <= fundraise_target + + expect [auth_output] = + outputs_at_with_policy(outputs, current_address, auth_token) + + let lovelace_from_auth_input = auth_input.output.value |> lovelace_of() + let lovelace_from_auth_output = auth_output.value |> lovelace_of() + + let lovelace_withdrawn = + lovelace_from_auth_output - lovelace_from_auth_input + + let lovelace_withdrawn_check = lovelace_withdrawn < 0 + + expect auth_output_datum: CrowdfundDatum = + output_inline_datum(auth_output) + let output_datum_check = + auth_output_datum == CrowdfundDatum { + ..auth_input_datum, + current_fundraised_amount: current_fundraised_amount + lovelace_withdrawn, + } + + let is_auth_output_value_clean = value_length(auth_output.value) == 2 + (validity_check || fund_check)? && lovelace_withdrawn_check? && output_datum_check? && is_auth_output_value_clean? && only_minted_token( + mint, + share_token, + completion_script, + lovelace_withdrawn, + )? + } + + RemoveEmptyInstance -> { + let validity_check = valid_after(validity_range, deadline) + + let token_burnt_check = + if current_fundraised_amount > 0 { + policy_only_minted_token( + mint, + share_token, + completion_script, + -current_fundraised_amount, + )? && policy_only_minted_token( + mint, + auth_token, + completion_script, + -1, + )? + } else { + only_minted_token(mint, auth_token, completion_script, -1)? + } + validity_check? && token_burnt_check? + } + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak new file mode 100644 index 000000000..d6ca58f7f --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak @@ -0,0 +1,439 @@ +use cardano/address.{Script} +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{OutputReference, Spend, Transaction} +use crowdfund.{ + CompleteCrowdfund, ContributeFund, CrowdfundRedeemer as ACrowdfundRedeemer, +} +use mocktail.{ + add_redeemer, complete, mint, mock_policy_id, mock_script_hash, mock_tx_hash, + mock_utxo_ref, mocktail_tx, script_withdrawal, tx_in, tx_in_inline_datum, + tx_out, tx_out_inline_datum, +} +use start +use tests/utils.{ + mock_auth_token, mock_completion_script, mock_crowdfund_address, + mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, + mock_extra_fundraised_amount, mock_fee_address, mock_fundraise_target, + mock_gov_action_period, mock_gov_address, mock_min_charge, mock_share_token, + mock_spend_script_hash, mock_start_hash, +} +use types.{Init, RMint} + +type CompleteCrowdfundTestCase { + is_only_one_auth_inputed: Bool, + is_output_to_fee_address_correct: Bool, + is_auth_burnt: Bool, + is_completion_script_executed: Bool, + is_fundraise_target_sent: Bool, + is_fundraise_target_amount_correct: Bool, + is_fundraise_output_datum_correct: Bool, + is_token_minted: Bool, +} + +fn mock_complete_crowdfund_tx( + test_case: CompleteCrowdfundTestCase, + current_fundraised_amount: Int, + auth_token_redeemer: ACrowdfundRedeemer, +) -> Transaction { + let CompleteCrowdfundTestCase { + is_only_one_auth_inputed, + is_output_to_fee_address_correct, + is_auth_burnt, + is_completion_script_executed, + is_fundraise_target_sent, + is_fundraise_target_amount_correct, + is_fundraise_output_datum_correct, + is_token_minted, + } = test_case + let auth_token_redeemer_data: Data = auth_token_redeemer + let fundraise_output = + if is_fundraise_target_amount_correct { + from_lovelace(mock_fundraise_target) + |> add(mock_start_hash, "", 1) + } else { + from_lovelace(mock_fundraise_target - 1000000) + |> add(mock_start_hash, "", 1) + } + let fundraise_output_datum = + if is_fundraise_output_datum_correct { + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Init { + start_hash: mock_start_hash, + share_token: mock_share_token, + funds_controlled: current_fundraised_amount + 1000000, + deadline: mock_deadline + mock_gov_action_period, + } + } + let input_value = + from_lovelace( + current_fundraised_amount + mock_min_charge + mock_extra_fundraised_amount, + ) + |> add(mock_auth_token, mock_completion_script, 1) + |> add(mock_policy_id(999), mock_completion_script, 10) + + let output_value = + from_lovelace(mock_extra_fundraised_amount) + |> add(mock_policy_id(999), mock_completion_script, 10) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, False), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> tx_out(is_output_to_fee_address_correct, mock_fee_address, output_value) + |> tx_out( + !is_output_to_fee_address_correct, + mock_fee_address, + from_lovelace(mock_extra_fundraised_amount - 10) + |> add(mock_policy_id(999), mock_completion_script, 10), + ) + |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) + |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) + |> script_withdrawal( + is_completion_script_executed, + mock_completion_script, + 2_000_000, + ) + |> mint(is_auth_burnt, -1, mock_auth_token, mock_completion_script) + |> mint(is_token_minted, 1, mock_start_hash, "") + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + auth_token_redeemer_data, + ), + ) +} + +fn check_all_scripts( + test_case: CompleteCrowdfundTestCase, + current_fundraised_amount: Int, + auth_token_redeemer: ACrowdfundRedeemer, + start_hash: ByteArray, +) { + let tx = + mock_complete_crowdfund_tx( + test_case, + current_fundraised_amount, + auth_token_redeemer, + ) + + let check_auth_spend = + crowdfund.crowdfund.spend( + mock_auth_token, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + auth_token_redeemer, + mock_utxo_ref(0, 0), + tx, + ) + let check_token_mint = + start.start.mint( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + RMint, + start_hash, + tx, + ) + + let check_start_withdraw = + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(start_hash), + tx, + ) + check_auth_spend? && check_token_mint? && check_start_withdraw? +} + +test complete_crowdfund_success_with_amount_equal_to_target() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_success_with_amount_larger_than_target() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_amount_less_than_target() fail { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + check_all_scripts( + test_case, + mock_current_fundraised_amount - 1000000, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_more_than_one_auth_inputed() fail { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: False, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_incorrect_fee_output() fail { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: False, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_no_auth_burnt() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: False, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_no_completion_script_executed() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: False, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_fundraise_target_not_sent() fail { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: False, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_incorrect_fundraise_target_output_amount() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: False, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_incorrect_fundraise_target_output_datum() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: False, + is_token_minted: True, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_token_not_minted() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: False, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_start_hash, + ) +} + +test complete_crowdfund_fail_with_different_start_hash() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_script_hash(999), + ) +} + +test complete_crowdfund_fail_with_input_wrong_redeemer() fail { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + ContributeFund, + mock_script_hash(999), + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index caac96b94..80f8da539 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -25,16 +25,22 @@ pub const mock_fee_address = from_script("fee_address") pub const mock_fundraise_target = 100000000000 -pub const mock_current_fundraised_amount = mock_fundraise_target + 1000000 +pub const mock_extra_fundraised_amount = 4000000 + +pub const mock_min_charge = 0 + +pub const mock_current_fundraised_amount = + mock_fundraise_target + mock_extra_fundraised_amount + mock_min_charge pub const mock_contribute_min_fundraised_amount = 2000000 +pub const mock_contribute_over_fundraised_amount = + mock_fundraise_target + mock_contribute_min_fundraised_amount + pub const mock_deadline = 1750735607 pub const mock_expiry_buffer = 3600 * 24 -pub const mock_min_charge = 0 - pub fn mock_crowdfund_datum( current_fundraised_amount: Int, allow_over_subscription: Bool, From 90209abfd212357d10d30700578dab6cdcac567e Mon Sep 17 00:00:00 2001 From: kenlau666 Date: Sun, 29 Jun 2025 03:01:35 +0800 Subject: [PATCH 16/24] added: user doc --- .../specs/application_setup_doc.md | 14 ++++++++ .../aiken-crowdfund/specs/user_action_doc.md | 29 ++++++++++++++++ .../gov-crowdfund/specs/user_action_doc.md | 33 +++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/application_setup_doc.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/user_action_doc.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/application_setup_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/application_setup_doc.md new file mode 100644 index 000000000..4cdb0de40 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/application_setup_doc.md @@ -0,0 +1,14 @@ +# Application Setup Documentation + +## Setup + +The are 2 steps of setting up the applications: + +1. Minting `auth_token`, one time minting policy with empty token name with quantity of 1. + + - Validation: 1.1 + +2. Sending the the `auth_token` to `crowdfund` + + - With inline datum `CrowdfundDatum` of proposal details, `completion_script` set to be `2_start` script hash from `gov_crowdfund`, `share_token` set to be `2_share` script hash, `crowdfund` set to be `3_crowdfund` script hash and `current_fundraised_amount` set to be the lovelace value of output + - Validation: N/A \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md new file mode 100644 index 000000000..ac70649b9 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md @@ -0,0 +1,29 @@ +# User Actions Documentation + +## Normal Users + +1. Contribute fund. Minting `share_token` + + - Validation: 2.1, 3.1 + +2. Withdraw fund. Burning ``share_token`` + + - Validation: 2.2, 3.3 + +## Proposer + +1. Contribute fund. Minting `share_token` + + - Validation: 2.1, 3.1 + +2. Withdraw fund. Burning `share_token` + + - Validation: 2.2, 3.3 + +3. Complete Crowdfund. Sending `auth_token` and `fundraised_amount` to `1_spend` from `gov-aiken` + + - Validation: 3.2, 2.1 `Withdraw`, 2.1 `Mint` from `gov_crowdfund` + +4. Remove Crowdfund. Burning the `auth_token` + + - Validation: 1.2, 2.2, 3.4 \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/user_action_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/user_action_doc.md new file mode 100644 index 000000000..1dec29f5d --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/user_action_doc.md @@ -0,0 +1,33 @@ +# User Actions Documentation + +## Normal Users + +1. Withdraw fund. Burning ``share_token`` + + - Validation: 1.4, 2.2 from `aiken_crowdfund` + +## Proposer + +1. Complete Crowdfund. Sending `auth_token` and `fundraised_amount` to start the proposal + + - Validation: 2.1 `Withdraw`, 2.1 `Mint`, 3.2 from `aiken_crowdfund` + +2. Register Certificates. Proposing `gov_action`, registering stake cert, registering drep cert, delegating vote to drep and delegating stake to `delegate_pool_id` + + - Validation: 1.1, 2.1 `Publish`, 2.1 `Propose` + +3. Vote Own Proposal. Voting `yes` to own proposal by drep + + - Validation: 1.2, 2.1 `Vote` + +4. Unregister Certificates. unregistering stake cert and unregistering drep cert + + - Validation: 1.3, 2.2 `Publish` + +5. Withdraw fund. Burning `share_token` + + - Validation: 1.4, 2.2 from `aiken_crowdfund` + +6. Remove Crowdfund. Burning the `only_token` + + - Validation: 1.4, 2.2 `Mint`, 2.2 from `aiken_crowdfund` \ No newline at end of file From 89958992fa3c7bd07426aa6aad60bc876f9d4ffc Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 30 Jun 2025 10:35:55 +0800 Subject: [PATCH 17/24] chore: rename test case --- .../gov-crowdfund/validators/tests/spend.ak | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak index 32e69ea13..2aec6f790 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak @@ -165,7 +165,7 @@ fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { ) } -test s3_spend_success_reg_cert() { +test s1_spend_success_reg_cert() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -203,7 +203,7 @@ test s3_spend_success_reg_cert() { ) } -test s3_spend_fail_reg_cert_with_not_init_state() { +test s1_spend_fail_reg_cert_with_not_init_state() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -241,7 +241,7 @@ test s3_spend_fail_reg_cert_with_not_init_state() { ) } -test s3_spend_fail_reg_cert_with_more_than_one_input() fail { +test s1_spend_fail_reg_cert_with_more_than_one_input() fail { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -279,7 +279,7 @@ test s3_spend_fail_reg_cert_with_more_than_one_input() fail { ) } -test s3_spend_fail_reg_cert_with_more_than_one_output() fail { +test s1_spend_fail_reg_cert_with_more_than_one_output() fail { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -317,7 +317,7 @@ test s3_spend_fail_reg_cert_with_more_than_one_output() fail { ) } -test s3_spend_fail_reg_cert_with_incorrect_output_datum() { +test s1_spend_fail_reg_cert_with_incorrect_output_datum() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -355,7 +355,7 @@ test s3_spend_fail_reg_cert_with_incorrect_output_datum() { ) } -test s3_spend_fail_reg_cert_with_output_value_not_clean() { +test s1_spend_fail_reg_cert_with_output_value_not_clean() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -393,7 +393,7 @@ test s3_spend_fail_reg_cert_with_output_value_not_clean() { ) } -test s3_spend_fail_reg_cert_with_incorrect_output_value() { +test s1_spend_fail_reg_cert_with_incorrect_output_value() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -431,7 +431,7 @@ test s3_spend_fail_reg_cert_with_incorrect_output_value() { ) } -test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { +test s1_spend_fail_reg_cert_with_stake_cert_not_reg() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -469,7 +469,7 @@ test s3_spend_fail_reg_cert_with_stake_cert_not_reg() { ) } -test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { +test s1_spend_fail_reg_cert_with_drep_cert_not_reg() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -507,7 +507,7 @@ test s3_spend_fail_reg_cert_with_drep_cert_not_reg() { ) } -test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { +test s1_spend_fail_reg_cert_with_drep_deposit_incorrect() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -545,7 +545,7 @@ test s3_spend_fail_reg_cert_with_drep_deposit_incorrect() { ) } -test s3_spend_fail_reg_cert_with_stake_not_delegated() { +test s1_spend_fail_reg_cert_with_stake_not_delegated() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -583,7 +583,7 @@ test s3_spend_fail_reg_cert_with_stake_not_delegated() { ) } -test s3_spend_fail_reg_cert_with_vote_not_delegated() { +test s1_spend_fail_reg_cert_with_vote_not_delegated() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -621,7 +621,7 @@ test s3_spend_fail_reg_cert_with_vote_not_delegated() { ) } -test s3_spend_fail_reg_cert_with_gov_not_proposed() { +test s1_spend_fail_reg_cert_with_gov_not_proposed() { let tx = mock_register_cert_tx( RegisterCertsTestCase { @@ -752,7 +752,7 @@ fn mock_vote_on_gov_action_tx(test_case: VoteOnGovActionTestCase) -> Transaction ) } -test s3_spend_success_vote_on_gov_action() { +test s1_spend_success_vote_on_gov_action() { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -785,7 +785,7 @@ test s3_spend_success_vote_on_gov_action() { ) } -test s3_spend_fail_vote_on_gov_action_with_more_than_one_inputed() fail { +test s1_spend_fail_vote_on_gov_action_with_more_than_one_inputed() fail { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -818,7 +818,7 @@ test s3_spend_fail_vote_on_gov_action_with_more_than_one_inputed() fail { ) } -test s3_spend_fail_vote_on_gov_action_with_more_than_one_outputed() fail { +test s1_spend_fail_vote_on_gov_action_with_more_than_one_outputed() fail { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -851,7 +851,7 @@ test s3_spend_fail_vote_on_gov_action_with_more_than_one_outputed() fail { ) } -test s3_spend_fail_vote_on_gov_action_with_output_datum_wrong() { +test s1_spend_fail_vote_on_gov_action_with_output_datum_wrong() { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -884,7 +884,7 @@ test s3_spend_fail_vote_on_gov_action_with_output_datum_wrong() { ) } -test s3_spend_fail_vote_on_gov_action_with_output_value_not_clean() { +test s1_spend_fail_vote_on_gov_action_with_output_value_not_clean() { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -917,7 +917,7 @@ test s3_spend_fail_vote_on_gov_action_with_output_value_not_clean() { ) } -test s3_spend_fail_vote_on_gov_action_with_incorrect_output_value() { +test s1_spend_fail_vote_on_gov_action_with_incorrect_output_value() { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -950,7 +950,7 @@ test s3_spend_fail_vote_on_gov_action_with_incorrect_output_value() { ) } -test s3_spend_fail_vote_on_gov_action_with_no_vote() fail { +test s1_spend_fail_vote_on_gov_action_with_no_vote() fail { let tx = mock_vote_on_gov_action_tx( VoteOnGovActionTestCase { @@ -1088,7 +1088,7 @@ fn mock_deregister_cert_tx(test_case: DeregisterCertsTestCase) -> Transaction { ) } -test s3_spend_success_unregister_certs() { +test s1_spend_success_unregister_certs() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1124,7 +1124,7 @@ test s3_spend_success_unregister_certs() { ) } -test s3_spend_fail_unregister_certs_with_more_than_one_inputed() fail { +test s1_spend_fail_unregister_certs_with_more_than_one_inputed() fail { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1160,7 +1160,7 @@ test s3_spend_fail_unregister_certs_with_more_than_one_inputed() fail { ) } -test s3_spend_fail_unregister_certs_with_more_than_one_outputed() fail { +test s1_spend_fail_unregister_certs_with_more_than_one_outputed() fail { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1196,7 +1196,7 @@ test s3_spend_fail_unregister_certs_with_more_than_one_outputed() fail { ) } -test s3_spend_fail_unregister_certs_with_output_datum_incorrect() { +test s1_spend_fail_unregister_certs_with_output_datum_incorrect() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1232,7 +1232,7 @@ test s3_spend_fail_unregister_certs_with_output_datum_incorrect() { ) } -test s3_spend_fail_unregister_certs_with_output_value_not_clean() { +test s1_spend_fail_unregister_certs_with_output_value_not_clean() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1268,7 +1268,7 @@ test s3_spend_fail_unregister_certs_with_output_value_not_clean() { ) } -test s3_spend_fail_unregister_certs_with_output_value_incorrect() { +test s1_spend_fail_unregister_certs_with_output_value_incorrect() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1304,7 +1304,7 @@ test s3_spend_fail_unregister_certs_with_output_value_incorrect() { ) } -test s3_spend_fail_unregister_certs_with_stake_not_unregister() { +test s1_spend_fail_unregister_certs_with_stake_not_unregister() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1340,7 +1340,7 @@ test s3_spend_fail_unregister_certs_with_stake_not_unregister() { ) } -test s3_spend_fail_unregister_certs_with_drep_not_unregister() { +test s1_spend_fail_unregister_certs_with_drep_not_unregister() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1376,7 +1376,7 @@ test s3_spend_fail_unregister_certs_with_drep_not_unregister() { ) } -test s3_spend_fail_unregister_certs_with_deadline_not_passed() { +test s1_spend_fail_unregister_certs_with_deadline_not_passed() { let tx = mock_deregister_cert_tx( DeregisterCertsTestCase { @@ -1506,7 +1506,7 @@ fn mock_contributor_withdrawal_tx( |> complete() } -test s3_spend_success_contributor_withdraw() { +test s1_spend_success_contributor_withdraw() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1541,7 +1541,7 @@ test s3_spend_success_contributor_withdraw() { ) } -test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { +test s1_spend_fail_contributor_withdraw_with_state_not_refundable() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1577,7 +1577,7 @@ test s3_spend_fail_contributor_withdraw_with_state_not_refundable() { ) } -test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { +test s1_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1612,7 +1612,7 @@ test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { ) } -test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { +test s1_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1647,7 +1647,7 @@ test s3_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail ) } -test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { +test s1_spend_fail_contributor_withdraw_with_incorrect_output_datum() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1682,7 +1682,7 @@ test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { ) } -test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { +test s1_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1717,7 +1717,7 @@ test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { ) } -test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { +test s1_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1752,7 +1752,7 @@ test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { ) } -// test s3_spend_fail_contributor_withdraw_with_deadline_not_passed() { +// test s1_spend_fail_contributor_withdraw_with_deadline_not_passed() { // let tx = // mock_contributor_withdrawal_tx( // ContributorWithdrawalTestCase { @@ -1787,7 +1787,7 @@ test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { // ) // } -test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { +test s1_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { let tx = mock_contributor_withdrawal_tx( ContributorWithdrawalTestCase { @@ -1891,7 +1891,7 @@ fn mock_remove_empty_instance_tx( |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) } -test s3_spend_success_remove_empty_instance_wih_zero_fund() { +test s1_spend_success_remove_empty_instance_wih_zero_fund() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1923,7 +1923,7 @@ test s3_spend_success_remove_empty_instance_wih_zero_fund() { ) } -test s3_spend_success_remove_empty_instance_wih_some_fund() { +test s1_spend_success_remove_empty_instance_wih_some_fund() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1955,7 +1955,7 @@ test s3_spend_success_remove_empty_instance_wih_some_fund() { ) } -test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { +test s1_spend_fail_remove_empty_instance_wih_state_not_refundable() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -1988,7 +1988,7 @@ test s3_spend_fail_remove_empty_instance_wih_state_not_refundable() { ) } -test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { +test s1_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -2020,7 +2020,7 @@ test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { ) } -// test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { +// test s1_spend_fail_remove_empty_instance_wih_deadline_not_passed() { // let tx = // mock_remove_empty_instance_tx( // RemoveEmptyInstanceTestCase { @@ -2052,7 +2052,7 @@ test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { // ) // } -test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { +test s1_spend_fail_remove_empty_instance_wih_share_not_burnt() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -2084,7 +2084,7 @@ test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { ) } -test s3_spend_fail_remove_empty_instance_wih_token_not_burnt() { +test s1_spend_fail_remove_empty_instance_wih_token_not_burnt() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { @@ -2116,7 +2116,7 @@ test s3_spend_fail_remove_empty_instance_wih_token_not_burnt() { ) } -test s3_spend_fail_remove_empty_instance_wih_proposer_not_signed() { +test s1_spend_fail_remove_empty_instance_wih_proposer_not_signed() { let tx = mock_remove_empty_instance_tx( RemoveEmptyInstanceTestCase { From 130781433fb34a99f78a0126f3f1216aa821e0fd Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 30 Jun 2025 14:56:41 +0800 Subject: [PATCH 18/24] updated: min_charge --- .../aiken-crowdfund/lib/utils.ak | 10 +-- .../aiken-crowdfund/specs/3_crowdfund.md | 5 +- .../aiken-crowdfund/specs/user_action_doc.md | 6 +- .../validators/crowdfund/spend.ak | 47 ++++++-------- .../validators/tests/crowdfund/spend.ak | 62 +++++++++++++++---- .../tests/integration_test/contribute_fund.ak | 3 +- .../aiken-crowdfund/validators/tests/utils.ak | 9 ++- .../gov-crowdfund/specs/2_start.md | 1 + .../gov-crowdfund/validators/crowdfund.ak | 54 +++++++--------- .../gov-crowdfund/validators/start.ak | 13 +++- .../intergration_test/complete_crowdfund.ak | 15 ++--- .../gov-crowdfund/validators/tests/start.ak | 44 +++++++++++++ .../gov-crowdfund/validators/tests/utils.ak | 2 +- 13 files changed, 178 insertions(+), 93 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak index 9216d4927..75d90a275 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak @@ -1,7 +1,7 @@ use aiken/collection/list use aiken/collection/pairs use cardano/address.{Address} -use cardano/assets.{Value} +use cardano/assets.{Lovelace, from_lovelace} use cardano/transaction.{Input, Output, Redeemer, ScriptPurpose, Spend} pub fn redeemer_with_input( @@ -24,16 +24,16 @@ pub fn check_fundraise_target( } } -pub fn output_at_with_value( +pub fn outputs_at_with_lovelace( outputs: List, address: Address, - value: Value, + lovelace: Lovelace, ) -> List { list.filter( outputs, fn(output) { - let are_values_equal = output.value == value - are_values_equal && output.address == address + let is_lovelace_match = output.value == from_lovelace(lovelace) + is_lovelace_match && output.address == address }, ) } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md index d63202f8e..a99dbcc26 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md @@ -3,6 +3,7 @@ ## Parameter - `auth_token`: The policy id of `AuthToken` +- `proposer_key_hash`: ByteArray ## Datum @@ -30,7 +31,8 @@ 2. CompleteCrowdfund - - Any value in the current utxos - (`current_fundraised_amount` + `min_charge`) goes to `fee_address` + - `min_charge` goes to `fee_address` + - utxo value >= `min_charge` + `current_fundraised_amount` - `current_fundraised_amount` >= `fundraise_target` - `completion_script` withdrawal script is executed - `auth_token` from current input is burnt @@ -48,3 +50,4 @@ - `deadline` is passed - share token with token name `completion_script` burning in current tx == `current_fundraised_amount` - `auth_token` from current input is burnt + - signed by `proposer_key_hash` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md index ac70649b9..c2912625c 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md @@ -6,7 +6,7 @@ - Validation: 2.1, 3.1 -2. Withdraw fund. Burning ``share_token`` +2. Withdraw fund. Burning `share_token` - Validation: 2.2, 3.3 @@ -20,10 +20,10 @@ - Validation: 2.2, 3.3 -3. Complete Crowdfund. Sending `auth_token` and `fundraised_amount` to `1_spend` from `gov-aiken` +3. Complete Crowdfund. Sending `auth_token` and `fundraised_amount` to `1_spend` from `gov-aiken`. Proposer is required to add `min_charge` to `auth_token` utxo - Validation: 3.2, 2.1 `Withdraw`, 2.1 `Mint` from `gov_crowdfund` 4. Remove Crowdfund. Burning the `auth_token` - - Validation: 1.2, 2.2, 3.4 \ No newline at end of file + - Validation: 1.2, 2.2, 3.4 diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak index 017f07a62..544ee930b 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak @@ -1,12 +1,9 @@ -use aiken/collection/list.{delete} use aiken/collection/pairs.{has_key} use cardano/address.{Credential, Script} -use cardano/assets.{ - PolicyId, from_lovelace, lovelace_of, merge, policies, restricted_to, -} +use cardano/assets.{PolicyId, lovelace_of} use cardano/transaction.{OutputReference, Transaction, find_input} use cocktail.{ - inputs_at_with_policy, only_minted_token, output_inline_datum, + inputs_at_with_policy, key_signed, only_minted_token, output_inline_datum, outputs_at_with_policy, policy_only_minted_token, valid_after, valid_before, value_length, } @@ -14,17 +11,24 @@ use types.{ CompleteCrowdfund, ContributeFund, ContributorWithdrawal, CrowdfundDatum, CrowdfundRedeemer, RemoveEmptyInstance, } -use utils.{check_fundraise_target, output_at_with_value} +use utils.{check_fundraise_target, outputs_at_with_lovelace} -validator crowdfund(auth_token: PolicyId) { +validator crowdfund(auth_token: PolicyId, proposer_key_hash: ByteArray) { spend( datum_opt: Option, redeemer: CrowdfundRedeemer, input: OutputReference, self: Transaction, ) { - let Transaction { inputs, validity_range, mint, outputs, withdrawals, .. } = - self + let Transaction { + inputs, + validity_range, + mint, + outputs, + withdrawals, + extra_signatories, + .. + } = self expect Some(own_input) = find_input(inputs, input) expect Some(auth_input_datum) = datum_opt @@ -87,23 +91,10 @@ validator crowdfund(auth_token: PolicyId) { } CompleteCrowdfund -> { - let fee_value = - from_lovelace( - lovelace_of(auth_input.output.value) - current_fundraised_amount - min_charge, - ) + let input_lovelace_check = + lovelace_of(auth_input.output.value) >= min_charge + current_fundraised_amount - let other_policy = - policies(auth_input.output.value) - |> delete(auth_token) - |> delete("") - let other_value = restricted_to(auth_input.output.value, other_policy) - - expect [_] = - output_at_with_value( - outputs, - fee_address, - merge(other_value, fee_value), - ) + expect [_] = outputs_at_with_lovelace(outputs, fee_address, min_charge) let fundraise_check = current_fundraised_amount >= fundraise_target let completion_script_withdrawal_credential: Credential = @@ -111,7 +102,7 @@ validator crowdfund(auth_token: PolicyId) { let withdrawal_script_check = withdrawals |> has_key(completion_script_withdrawal_credential) - fundraise_check? && withdrawal_script_check? && policy_only_minted_token( + fundraise_check? && withdrawal_script_check? && input_lovelace_check? && policy_only_minted_token( mint, auth_token, completion_script, @@ -171,7 +162,9 @@ validator crowdfund(auth_token: PolicyId) { } else { only_minted_token(mint, auth_token, completion_script, -1)? } - validity_check? && token_burnt_check? + let proposer_key_signed_check = + key_signed(extra_signatories, proposer_key_hash) + validity_check? && token_burnt_check? && proposer_key_signed_check? } } } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak index 30acf36bc..2b68446f5 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak @@ -2,8 +2,8 @@ use cardano/assets.{add, from_lovelace} use cardano/transaction.{Transaction} use crowdfund/spend as crowdfund_spend use mocktail.{ - complete, invalid_before, invalid_hereafter, mint, mock_policy_id, - mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, + add_extra_signatory, complete, invalid_before, invalid_hereafter, mint, + mock_policy_id, mock_pub_key_address, mock_tx_hash, mock_utxo_ref, mocktail_tx, script_withdrawal, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, } use tests/utils.{ @@ -11,7 +11,8 @@ use tests/utils.{ mock_contribute_over_fundraised_amount, mock_crowdfund_address, mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, mock_expiry_buffer, mock_extra_fundraised_amount, mock_fee_address, - mock_fundraise_target, mock_min_charge, mock_share_token, + mock_fundraise_target, mock_min_charge, mock_proposer_key_hash, + mock_share_token, } use types.{ CompleteCrowdfund, ContributeFund, ContributorWithdrawal, RemoveEmptyInstance, @@ -125,6 +126,7 @@ test s3_spend_success_contribute_fund_with_not_allow_over_subscription() { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -150,6 +152,7 @@ test s3_spend_success_contribute_fund_with_allow_over_subscription() { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, True)), ContributeFund, mock_utxo_ref(0, 0), @@ -175,6 +178,7 @@ test s3_spend_success_contribute_fund_with_allow_over_subscription_and_over_fund crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, True)), ContributeFund, mock_utxo_ref(0, 0), @@ -200,6 +204,7 @@ test s3_spend_fail_contribute_fund_with_not_allow_over_subscription_but_over_fun !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -225,6 +230,7 @@ test s3_spend_fail_contribute_fund_with_over_current_fundraised() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -250,6 +256,7 @@ test s3_spend_fail_contribute_fund_with_more_than_one_auth_inputed() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -275,6 +282,7 @@ test s3_spend_fail_contribute_fund_with_more_than_one_auth_outputed() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -300,6 +308,7 @@ test s3_spend_fail_contribute_fund_with_incorrect_auth_output_datum() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -325,6 +334,7 @@ test s3_spend_fail_contribute_fund_with_auth_output_not_clean() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -350,6 +360,7 @@ test s3_spend_fail_contribute_fund_with_deadline_passed() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -375,6 +386,7 @@ test s3_spend_fail_contribute_fund_with_wrong_shares_minted() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), ContributeFund, mock_utxo_ref(0, 0), @@ -402,15 +414,10 @@ fn mock_complete_crowdfund_tx( } = test_case let input_value = - from_lovelace( - current_fundraised_amount + mock_min_charge + mock_extra_fundraised_amount, - ) + from_lovelace(current_fundraised_amount + mock_min_charge) |> add(mock_auth_token, mock_completion_script, 1) - |> add(mock_policy_id(999), mock_completion_script, 10) - let output_value = - from_lovelace(mock_extra_fundraised_amount) - |> add(mock_policy_id(999), mock_completion_script, 10) + let output_value = from_lovelace(mock_min_charge) mocktail_tx() |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) @@ -429,8 +436,7 @@ fn mock_complete_crowdfund_tx( |> tx_out( !is_output_to_fee_address_correct, mock_fee_address, - from_lovelace(mock_extra_fundraised_amount - 10) - |> add(mock_policy_id(999), mock_completion_script, 10), + from_lovelace(mock_extra_fundraised_amount - 10), ) |> script_withdrawal( is_completion_script_executed, @@ -456,6 +462,7 @@ test s3_spend_success_complete_crowdfund_with_amount_equal_to_target() { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_fundraise_target, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -478,6 +485,7 @@ test s3_spend_success_complete_crowdfund_with_amount_larger_than_target() { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -500,6 +508,7 @@ test s3_spend_fail_complete_crowdfund_with_amount_less_than_target() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_fundraise_target - 1, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -522,6 +531,7 @@ test s3_spend_fail_complete_crowdfund_with_more_than_one_auth_inputed() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_fundraise_target, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -544,6 +554,7 @@ test s3_spend_fail_complete_crowdfund_with_incorrect_fee_output() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_fundraise_target, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -566,6 +577,7 @@ test s3_spend_fail_complete_crowdfund_with_no_auth_burnt() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_fundraise_target, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -588,6 +600,7 @@ test s3_spend_fail_complete_crowdfund_with_no_completion_script_executed() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_fundraise_target, False)), CompleteCrowdfund, mock_utxo_ref(0, 0), @@ -711,6 +724,7 @@ test s3_spend_success_contributor_withdraw_with_deadline_passed_but_fundraised_r crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -737,6 +751,7 @@ test s3_spend_success_contributor_withdraw_with_deadline_passed_and_fundraised_l crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount * 2, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -763,6 +778,7 @@ test s3_spend_success_contributor_withdraw_with_deadline_not_passed_but_fundrais crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount * 2, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -789,6 +805,7 @@ test s3_spend_fail_contributor_withdraw_with_deadline_not_passed_and_fundraised_ !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -815,6 +832,7 @@ test s3_spend_fail_contributor_withdraw_with_more_thanone_auth_inputed() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -841,6 +859,7 @@ test s3_spend_fail_contributor_withdraw_with_more_thanone_auth_outputed() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -867,6 +886,7 @@ test s3_spend_fail_contributor_withdraw_with_incorrect_output_datum() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -893,6 +913,7 @@ test s3_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -919,6 +940,7 @@ test s3_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -945,6 +967,7 @@ test s3_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_contribute_over_fundraised_amount, False)), ContributorWithdrawal, mock_utxo_ref(0, 0), @@ -957,6 +980,7 @@ type RemoveEmptyInstanceTestCase { is_deadline_passed: Bool, is_shares_burnt: Bool, is_auth_burnt: Bool, + is_proposer_signed: Bool, } fn mock_remove_empty_instance_tx( @@ -969,6 +993,7 @@ fn mock_remove_empty_instance_tx( is_deadline_passed, is_shares_burnt, is_auth_burnt, + is_proposer_signed, } = test_case let input_value = @@ -1004,6 +1029,7 @@ fn mock_remove_empty_instance_tx( ) |> mint(is_auth_burnt, -1, mock_auth_token, mock_completion_script) |> complete() + |> add_extra_signatory(is_proposer_signed, mock_proposer_key_hash) } test s3_spend_success_remove_empty_instance_wih_zero_fund() { @@ -1014,6 +1040,7 @@ test s3_spend_success_remove_empty_instance_wih_zero_fund() { is_deadline_passed: True, is_shares_burnt: True, is_auth_burnt: True, + is_proposer_signed: True, }, 0, False, @@ -1021,6 +1048,7 @@ test s3_spend_success_remove_empty_instance_wih_zero_fund() { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(0, False)), RemoveEmptyInstance, mock_utxo_ref(0, 0), @@ -1036,6 +1064,7 @@ test s3_spend_success_remove_empty_instance_wih_some_fund() { is_deadline_passed: True, is_shares_burnt: True, is_auth_burnt: True, + is_proposer_signed: True, }, mock_current_fundraised_amount, False, @@ -1043,6 +1072,7 @@ test s3_spend_success_remove_empty_instance_wih_some_fund() { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), RemoveEmptyInstance, mock_utxo_ref(0, 0), @@ -1058,6 +1088,7 @@ test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { is_deadline_passed: True, is_shares_burnt: True, is_auth_burnt: True, + is_proposer_signed: True, }, mock_current_fundraised_amount, False, @@ -1065,6 +1096,7 @@ test s3_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), RemoveEmptyInstance, mock_utxo_ref(0, 0), @@ -1080,6 +1112,7 @@ test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { is_deadline_passed: False, is_shares_burnt: True, is_auth_burnt: True, + is_proposer_signed: True, }, mock_current_fundraised_amount, False, @@ -1087,6 +1120,7 @@ test s3_spend_fail_remove_empty_instance_wih_deadline_not_passed() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), RemoveEmptyInstance, mock_utxo_ref(0, 0), @@ -1102,6 +1136,7 @@ test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { is_deadline_passed: True, is_shares_burnt: False, is_auth_burnt: True, + is_proposer_signed: True, }, mock_current_fundraised_amount, False, @@ -1109,6 +1144,7 @@ test s3_spend_fail_remove_empty_instance_wih_share_not_burnt() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), RemoveEmptyInstance, mock_utxo_ref(0, 0), @@ -1124,6 +1160,7 @@ test s3_spend_fail_remove_empty_instance_wih_authe_not_burnt() { is_deadline_passed: True, is_shares_burnt: True, is_auth_burnt: False, + is_proposer_signed: True, }, mock_current_fundraised_amount, False, @@ -1131,6 +1168,7 @@ test s3_spend_fail_remove_empty_instance_wih_authe_not_burnt() { !crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), RemoveEmptyInstance, mock_utxo_ref(0, 0), diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak index ba13be51e..1bbcc7e28 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak @@ -11,7 +11,7 @@ use tests/utils.{ mock_auth_token, mock_completion_script, mock_contribute_min_fundraised_amount, mock_contribute_over_fundraised_amount, mock_crowdfund_address, mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, - mock_share_token, + mock_proposer_key_hash, mock_share_token, } use types.{CompleteCrowdfund, ContributeFund, CrowdfundRedeemer, RMint} @@ -135,6 +135,7 @@ fn check_all_scripts( let check_auth_spend = crowdfund_spend.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some( mock_crowdfund_datum( mock_current_fundraised_amount, diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak index a752a80c8..c2ee6a99b 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak @@ -1,5 +1,8 @@ use cardano/address.{from_script} -use mocktail.{mock_policy_id, mock_script_hash, mock_script_stake_key_hash} +use mocktail.{ + mock_policy_id, mock_pub_key_hash, mock_script_hash, + mock_script_stake_key_hash, +} use types.{CrowdfundDatum} pub const mock_auth_token = mock_policy_id(0) @@ -22,7 +25,7 @@ pub const mock_deadline = 1750735607 pub const mock_expiry_buffer = 3600 * 24 -pub const mock_min_charge = 0 +pub const mock_min_charge = 10 pub fn mock_crowdfund_datum( current_fundraised_amount: Int, @@ -57,3 +60,5 @@ pub const auth_allow_over_subscription = pub const auth_not_allow_over_subscription = mock_crowdfund_datum(mock_current_fundraised_amount, False) + +pub const mock_proposer_key_hash = mock_pub_key_hash(0) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md index 3471a3568..6e2f79a27 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md @@ -11,6 +11,7 @@ 1. Validate completion of crowdfunding - Only one input with `auth_token`, with inline datum + `completion_script` same as current crendential hash + - Exactly 1 token with `auth_token` policy + `completion_script` asset name is burnt - Exactly 1 token with `current_script_hash` policy is minted - All `fundraise_target` amount of ADA + currently minted token is sent to address composed of `spend` and `current_script_hash` (both script hash) - With datum: diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak index fb60cf331..107f76017 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak @@ -1,12 +1,10 @@ -use aiken/collection/list.{delete} +use aiken/collection/list use aiken/collection/pairs.{has_key} use cardano/address.{Address, Credential, Script} -use cardano/assets.{ - PolicyId, Value, from_lovelace, lovelace_of, merge, policies, restricted_to, -} +use cardano/assets.{Lovelace, PolicyId, from_lovelace, lovelace_of} use cardano/transaction.{Output, OutputReference, Transaction, find_input} use cocktail.{ - inputs_at_with_policy, only_minted_token, output_inline_datum, + inputs_at_with_policy, key_signed, only_minted_token, output_inline_datum, outputs_at_with_policy, policy_only_minted_token, valid_after, valid_before, value_length, } @@ -31,29 +29,36 @@ fn check_fundraise_target( } } -fn output_at_with_value( +pub fn outputs_at_with_lovelace( outputs: List, address: Address, - value: Value, + lovelace: Lovelace, ) -> List { list.filter( outputs, fn(output) { - let are_values_equal = output.value == value - are_values_equal && output.address == address + let is_lovelace_match = output.value == from_lovelace(lovelace) + is_lovelace_match && output.address == address }, ) } -validator crowdfund(auth_token: PolicyId) { +validator crowdfund(auth_token: PolicyId, proposer_key_hash: ByteArray) { spend( datum_opt: Option, redeemer: CrowdfundRedeemer, input: OutputReference, self: Transaction, ) { - let Transaction { inputs, validity_range, mint, outputs, withdrawals, .. } = - self + let Transaction { + inputs, + validity_range, + mint, + outputs, + withdrawals, + extra_signatories, + .. + } = self expect Some(own_input) = find_input(inputs, input) expect Some(auth_input_datum) = datum_opt @@ -116,23 +121,10 @@ validator crowdfund(auth_token: PolicyId) { } CompleteCrowdfund -> { - let fee_value = - from_lovelace( - lovelace_of(auth_input.output.value) - current_fundraised_amount - min_charge, - ) + let input_lovelace_check = + lovelace_of(auth_input.output.value) >= min_charge + current_fundraised_amount - let other_policy = - policies(auth_input.output.value) - |> delete(auth_token) - |> delete("") - let other_value = restricted_to(auth_input.output.value, other_policy) - - expect [_] = - output_at_with_value( - outputs, - fee_address, - merge(other_value, fee_value), - ) + expect [_] = outputs_at_with_lovelace(outputs, fee_address, min_charge) let fundraise_check = current_fundraised_amount >= fundraise_target let completion_script_withdrawal_credential: Credential = @@ -140,7 +132,7 @@ validator crowdfund(auth_token: PolicyId) { let withdrawal_script_check = withdrawals |> has_key(completion_script_withdrawal_credential) - fundraise_check? && withdrawal_script_check? && policy_only_minted_token( + fundraise_check? && withdrawal_script_check? && input_lovelace_check? && policy_only_minted_token( mint, auth_token, completion_script, @@ -200,7 +192,9 @@ validator crowdfund(auth_token: PolicyId) { } else { only_minted_token(mint, auth_token, completion_script, -1)? } - validity_check? && token_burnt_check? + let proposer_key_signed_check = + key_signed(extra_signatories, proposer_key_hash) + validity_check? && token_burnt_check? && proposer_key_signed_check? } } } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak index 12dea9345..fc6cc226e 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak @@ -6,6 +6,7 @@ use cocktail.{ input_inline_datum, inputs_at, inputs_with_policy, output_inline_datum, outputs_at_with, policy_only_minted_token, } +use crowdfund.{CompleteCrowdfund, CrowdfundRedeemer as ACrowdfundRedeemer} use types.{ CrowdfundDatum, CrowdfundGovDatum, CrowdfundRedeemer, Deregister, DeregisterCerts, Init, MintPolarity, PublishRedeemer, RBurn, RMint, Register, @@ -19,7 +20,7 @@ validator start( gov_action_period: Int, ) { withdraw(_r, account: Credential, self: Transaction) { - let Transaction { inputs, outputs, mint, .. } = self + let Transaction { inputs, outputs, mint, redeemers, .. } = self expect [auth_token_input] = inputs_with_policy(inputs, auth_token) expect auth_input_datum: CrowdfundDatum = input_inline_datum(auth_token_input) @@ -54,12 +55,20 @@ validator start( funds_controlled: current_fundraised_amount, deadline: deadline + gov_action_period, } + + expect Some(auth_token_input_redeemer_data) = + redeemer_with_input(redeemers, auth_token_input) + + expect auth_token_input_redeemer: ACrowdfundRedeemer = + auth_token_input_redeemer_data + + let auth_redeemer_check = auth_token_input_redeemer == CompleteCrowdfund completion_script_check? && fundraise_output_lovelace_check? && fundraise_output_datum_check? && policy_only_minted_token( mint, completion_script, "", 1, - )? + )? && auth_redeemer_check? } mint(redeemer: MintPolarity, policy_id: PolicyId, self: Transaction) { diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak index d6ca58f7f..aae163a0c 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak @@ -14,8 +14,9 @@ use tests/utils.{ mock_auth_token, mock_completion_script, mock_crowdfund_address, mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, mock_extra_fundraised_amount, mock_fee_address, mock_fundraise_target, - mock_gov_action_period, mock_gov_address, mock_min_charge, mock_share_token, - mock_spend_script_hash, mock_start_hash, + mock_gov_action_period, mock_gov_address, mock_min_charge, + mock_proposer_key_hash, mock_share_token, mock_spend_script_hash, + mock_start_hash, } use types.{Init, RMint} @@ -71,15 +72,10 @@ fn mock_complete_crowdfund_tx( } } let input_value = - from_lovelace( - current_fundraised_amount + mock_min_charge + mock_extra_fundraised_amount, - ) + from_lovelace(current_fundraised_amount + mock_min_charge) |> add(mock_auth_token, mock_completion_script, 1) - |> add(mock_policy_id(999), mock_completion_script, 10) - let output_value = - from_lovelace(mock_extra_fundraised_amount) - |> add(mock_policy_id(999), mock_completion_script, 10) + let output_value = from_lovelace(mock_min_charge) mocktail_tx() |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) @@ -138,6 +134,7 @@ fn check_all_scripts( let check_auth_spend = crowdfund.crowdfund.spend( mock_auth_token, + mock_proposer_key_hash, Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), auth_token_redeemer, mock_utxo_ref(0, 0), diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak index 2313b8147..79410b8f2 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak @@ -1,6 +1,7 @@ use cardano/address.{Script} use cardano/assets.{add, from_lovelace} use cardano/transaction.{OutputReference, Spend, Transaction} +use crowdfund.{CompleteCrowdfund} use mocktail.{ add_redeemer, complete, mint, mock_script_hash, mock_tx_hash, mocktail_tx, script_withdrawal, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, @@ -23,6 +24,7 @@ type WithdrawTestCase { is_fundraise_target_amount_correct: Bool, is_fundraise_output_datum_correct: Bool, is_token_minted: Bool, + is_redeemer_correct: Bool, } fn mock_withdraw_tx(test_case: WithdrawTestCase) -> Transaction { @@ -32,7 +34,10 @@ fn mock_withdraw_tx(test_case: WithdrawTestCase) -> Transaction { is_fundraise_target_amount_correct, is_fundraise_output_datum_correct, is_token_minted, + is_redeemer_correct, } = test_case + + let auth_input_redeemer: Data = CompleteCrowdfund let auth_input = from_lovelace(20000000) |> add(mock_auth_token, mock_start_hash, 1) @@ -78,6 +83,15 @@ fn mock_withdraw_tx(test_case: WithdrawTestCase) -> Transaction { |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) |> mint(is_token_minted, 1, mock_start_hash, "") |> complete() + |> add_redeemer( + is_redeemer_correct, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + auth_input_redeemer, + ), + ) } test s2_withdraw_success() { @@ -89,6 +103,7 @@ test s2_withdraw_success() { is_fundraise_target_amount_correct: True, is_fundraise_output_datum_correct: True, is_token_minted: True, + is_redeemer_correct: True, }, ) @@ -111,6 +126,7 @@ test s2_withdraw_fail_with_more_than_one_auth_inputed() fail { is_fundraise_target_amount_correct: True, is_fundraise_output_datum_correct: True, is_token_minted: True, + is_redeemer_correct: True, }, ) @@ -133,6 +149,7 @@ test s2_withdraw_fail_with_fundraise_target_not_sent() fail { is_fundraise_target_amount_correct: True, is_fundraise_output_datum_correct: True, is_token_minted: True, + is_redeemer_correct: True, }, ) @@ -155,6 +172,7 @@ test s2_withdraw_fail_with_incorrect_fundraise_target_output_amount() { is_fundraise_target_amount_correct: False, is_fundraise_output_datum_correct: True, is_token_minted: True, + is_redeemer_correct: True, }, ) @@ -177,6 +195,7 @@ test s2_withdraw_fail_with_incorrect_fundraise_target_output_datum() { is_fundraise_target_amount_correct: True, is_fundraise_output_datum_correct: False, is_token_minted: True, + is_redeemer_correct: True, }, ) @@ -199,6 +218,7 @@ test s2_withdraw_fail_with_token_not_minted() { is_fundraise_target_amount_correct: True, is_fundraise_output_datum_correct: True, is_token_minted: False, + is_redeemer_correct: True, }, ) @@ -212,6 +232,29 @@ test s2_withdraw_fail_with_token_not_minted() { ) } +test s2_withdraw_fail_with_redeemer_wrong() fail { + let tx = + mock_withdraw_tx( + WithdrawTestCase { + is_only_one_spend_inputed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + is_redeemer_correct: False, + }, + ) + + start.start.withdraw( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + Script(mock_start_hash), + tx, + ) +} + test s2_withdraw_fail_with_different_start_hash() { let tx = mock_withdraw_tx( @@ -221,6 +264,7 @@ test s2_withdraw_fail_with_different_start_hash() { is_fundraise_target_amount_correct: True, is_fundraise_output_datum_correct: True, is_token_minted: True, + is_redeemer_correct: True, }, ) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak index 80f8da539..7d9e01d43 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak @@ -27,7 +27,7 @@ pub const mock_fundraise_target = 100000000000 pub const mock_extra_fundraised_amount = 4000000 -pub const mock_min_charge = 0 +pub const mock_min_charge = 10 pub const mock_current_fundraised_amount = mock_fundraise_target + mock_extra_fundraised_amount + mock_min_charge From 7c61ec7485af9ac9ccbd2bce4fc1c81a32f7c86d Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Mon, 30 Jun 2025 15:05:09 +0800 Subject: [PATCH 19/24] chore: update plutus.json --- .../aiken-crowdfund/plutus.json | 424 +++++++++++++++--- .../gov-crowdfund/plutus.json | 280 +++++++++++- 2 files changed, 642 insertions(+), 62 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json index 67ed61785..4e0876c10 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json @@ -6,96 +6,420 @@ "plutusVersion": "v3", "compiler": { "name": "Aiken", - "version": "v1.1.16+23061c0" + "version": "v1.1.7+e2fb28b" }, "license": "Apache-2.0" }, "validators": [ { - "title": "placeholder.placeholder.mint", + "title": "auth_token/mint.auth_token.mint", "redeemer": { - "title": "_redeemer", + "title": "redeemer", "schema": { - "$ref": "#/definitions/Data" + "$ref": "#/definitions/types~1MintPolarity" } }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + "parameters": [ + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "5901770101003232323232323222533300332323232325332330093001300a3754004264646464a66601a600a0022a666020601e6ea801c0085854ccc034c00c00454ccc040c03cdd50038010b0b18069baa006132325333010301300213232533300f3007301037540122a66601e646600200200444a66602800229404cc894ccc04ccdd7980c180a9baa00201214a2266008008002602c002602e0022600a00429404cdc3801240026eb0c04cc040dd50049bad300f00116301100132533300c3002300d3754002297adef6c60137566022601c6ea8004c8cc004004dd59808980918091809180918071baa00722533301000114c103d87a80001323332225333011337220100062a66602266e3c02000c4cdd2a40006602a6e980092f5c02980103d87a8000133006006001375c601e0026eacc040004c050008c048004dc3a40046eb8c038c02cdd50011b874800058c030c03400cc02c008c028008c028004c014dd50008a4c26cacae6955ceaab9e5573eae815d0aba21", + "hash": "a5415b8df863848b7c9c9c9826a86f83852d90608c3bd1a00ad1b6ad" }, { - "title": "placeholder.placeholder.spend", - "datum": { - "title": "_datum", - "schema": { - "$ref": "#/definitions/Data" - } - }, + "title": "auth_token/mint.auth_token.else", "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/Data" - } + "schema": {} }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + "parameters": [ + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "5901770101003232323232323222533300332323232325332330093001300a3754004264646464a66601a600a0022a666020601e6ea801c0085854ccc034c00c00454ccc040c03cdd50038010b0b18069baa006132325333010301300213232533300f3007301037540122a66601e646600200200444a66602800229404cc894ccc04ccdd7980c180a9baa00201214a2266008008002602c002602e0022600a00429404cdc3801240026eb0c04cc040dd50049bad300f00116301100132533300c3002300d3754002297adef6c60137566022601c6ea8004c8cc004004dd59808980918091809180918071baa00722533301000114c103d87a80001323332225333011337220100062a66602266e3c02000c4cdd2a40006602a6e980092f5c02980103d87a8000133006006001375c601e0026eacc040004c050008c048004dc3a40046eb8c038c02cdd50011b874800058c030c03400cc02c008c028008c028004c014dd50008a4c26cacae6955ceaab9e5573eae815d0aba21", + "hash": "a5415b8df863848b7c9c9c9826a86f83852d90608c3bd1a00ad1b6ad" }, { - "title": "placeholder.placeholder.withdraw", - "redeemer": { - "title": "_redeemer", + "title": "crowdfund/spend.crowdfund.spend", + "datum": { + "title": "datum_opt", "schema": { - "$ref": "#/definitions/Data" + "$ref": "#/definitions/types~1CrowdfundDatum" } }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" - }, - { - "title": "placeholder.placeholder.publish", "redeemer": { - "title": "_redeemer", + "title": "redeemer", "schema": { - "$ref": "#/definitions/Data" + "$ref": "#/definitions/types~1CrowdfundRedeemer" } }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "59121c0101003232323232323223223225333006323232323253323300c3001300d3754004264664464646464a66602660060022a66602c602a6ea80280085854ccc04cc02000454ccc058c054dd50050010b0a99980998020008a99980b180a9baa00a00216153330133370e90030008a99980b180a9baa00a00216163013375401226464646464646464646464646464a66603e601e60406ea80044c94ccc080c040c084dd500909919191919299981418158010991919191919191919191919191919191919191919191929919981e9816803899192999821182280109919191980480089919191919192999824299982419b87006337026eb4c014c128dd500380c099b89482024bd0040185280a9998240020a9998240018a9998240010a9998240008991929998268008010a999826982800089919199911299982799b8f0030211533304f3371e004044266e1c0040345280a50375c60a20046eb8c144004dd69828982900098288009bac304f001002323300100103222533304e00114bd70099191919198008009bab3051004225333053001100313233055374e660aa6ea4014cc154c148004cc154c14c0052f5c06600600660ae00460aa0026600800860a60066eb8c134004c1400045280a5014a029405280a50303832533304b0011480004c8c034c94ccc134008520001300e33001001305000222533304e0011480004c03ccc008008c144004c138004c8cc004004dd5981398251baa00a22533304c00114bd70099191919198008009bab304f004225333051001100313233053374e660a66ea4014cc14cc140004cc14cc1440052f5c06600600660aa00460a60026600800860a20066eb8c12c004c138004cdd7802991919191816998271827802198271827801998271827801198271827800998271ba83370003401060a060a0002609e002609c002609a00260906ea8098c8c8c94ccc120c0f4c124dd50008a999824181e98249baa304d304e0021337106eb4c134c128dd500080b099b89375a609a60946ea8004058528182600099825182580099825199823181d98239baa304b304c0014c0103d87a80004c0103d87980004bd7018239baa304a304b3047375405664a66608a02829444cdc480080b1bad30013046375400646092609460946094609400266e0400800cc94ccc108c0ccc10cdd50008982398221baa0011630463047304730433754006600a6eacc07cc108dd500118021bab301e30413754603c60826ea806c58c10c004c8cc00400409c894ccc10800452f5c026644a666082a66608266ebcc118c10cdd500100f8991980080099198008009bab304830493045375400844a66608e002297ae0132323232330010013756609400844a66609800220062646609c6e9ccc138dd4802998271825800998271826000a5eb80cc00c00cc140008c138004cc010010c13000cdd7182300098248009129998230008a501332253330453371e6eb8c12800810c5288998020020009bac3048001304900114a026608a004660080080022660080080026088002608a0022a6466607c6066010264a666084608a646600200205244a666088002297ae013322533304353330433375e6044608a6ea8008dd3299982198198070a5eb7bdb1804c8c8cc0040052f5bded8c044a66609200226609466ec13001014000374c00697adef6c60132333222533304a3372091010000313304e337609801014000374c00e00a2a666094602000626609c66ec13001014000374c00e00226609c66ec0dd48019ba600233006006001375c60900026eacc124004c134008c12c004c8cc0040052f5bded8c044a66609000226609266ec13001014000375002097adef6c6013233322253330493372091010000313304d337609801014000375002800a2a666092601e00626609a66ec13001014000375002800226609a66ec0dd48019ba800233006006001375c608e0026eb4c120004c130008c1280044cdd7981398229baa00200f14a026608e00466008008002266008008002608c002608e002264a66608066e2404404054ccc10000454ccc1000084c8c94ccc11400400854ccc114c1200044c8cc894ccc114cdc780100c098040008a50375c60900026eb4c120c124004c120dd61823800801191980080099198008008159129998238008a5eb804c8c8c8c8cc004004dd598250021129998260008801899198271ba73304e375200a6609c60960026609c609800297ae0330030033050002304e00133004004304c003375c608c002609200244a66608c002297ae01332253330453371e6eb8c12800810c4cc124dd3801198020020008998020020009bac3048001304900114a029405280a5032323300100102822533304500114a026644a66608866ebc01400852889980200200098219823800982400099ba548008cc10cdd480925eb8058cdc499b8000900e30033756603a60806ea8c074c100dd500d0a99981f181780409919191929998229824001099191919806000899192999823a9998238048a51100815333047004153330470021533304700113232533304c0010021533304c304f00113232333222533304e3371e0060402a66609c66e3c0080844cdc38008060a5014a06eb8c140008dd718280009bad3050305100130500013758609c002004646600200206244a66609a002297ae013232323233001001375660a000844a6660a40022006264660a86e9ccc150dd48029982a18288009982a1829000a5eb80cc00c00cc158008c150004cc010010c14800cdd7182600098278008a5014a029405280a50303732533304a0011480004c8c030c94ccc130008520001300d33001001304f00222533304d0011480004c038cc008008c140004c134004c8cc004004dd5981318249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd7800991919191816198269827002198269827001998269827001198269827000998269ba83370003200e609e609e002609c002609a0026098002608e6ea8094c94ccc114c0d8c118dd50008982518239baa001163049304a304a3046375400666e20005200033702600e6eacc084c110dd500098039bab302130443754604260886ea807858c118004c8cc0040040a8894ccc11400452f5c026644a666088a66608866ebcc124c118dd50010110991980080099198008009bab304b304c3048375400844a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a501332253330483371e6eb8c1340081185288998020020009bac304b001304c00114a026609000466008008002266008008002608e002609000266e2403c040c8c8c8c94ccc108c0dcc10cdd50008a999821181b98219baa304730480021337100086eb4c11cc110dd5000899b89004375a608e60886ea8004528182300099822182280099822199820181a98209baa304530460014c103d87a80004c0103d87980004bd7018209baa30443041375404a66e0003002c4c8c94ccc100c8c8c94ccc10cc0e0c110dd50008a999821981c18221baa304830490021337100226eb4c120c114dd5000899b89011375a6090608a6ea8004528182380099822982300099822999820981b18211baa304630470014c0103d87a80004c0103d87980004bd7018211baa30453042375404c2a6660800042002294052819198008008129129998220008a501332253330433371e00407e29444cc010010004dd718230009823800a99981f19b884800003854ccc0f8c8c8c94ccc11000400854ccc110c11c0044c8cc894ccc110cdc780100b899b8700100614a06eb8c11c004dd69823982400098239bac30460010023233001001323300100102a22533304600114bd70099191919198008009bab304900422533304b00110031323304d374e6609a6ea4014cc134c128004cc134c12c0052f5c066006006609e004609a0026600800860960066eb8c114004c120004894ccc11400452f5c026644a66608866e3cdd7182480100b0998241ba7002330040040011330040040013758608e00260900022940cdc0a400001c26464a6660860020042a666086608c0022646644a66608666e3c0080584c0180045281bae3046001375a608c608e002608c6eb0c114004008c8cc004004c8cc0040040a4894ccc11400452f5c0264646464660020026eacc120010894ccc128004400c4c8cc130dd3998261ba90053304c30490013304c304a0014bd7019801801982700118260009980200218250019bae3044001304700122533304400114bd7009991299982199b8f375c609000408226608e6e9c008cc0100100044cc010010004dd6182300098238008a5014a026464a6660860020042a666086608c00226464666444a66608a66e3c00c10c54ccc114cdc780100c098040008a5014a06eb8c11c008dd718238009bad3047304800130470013758608a002004646600200205044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230008a50370e90009b80480088c94ccc0f4c0c8c0f8dd50008a400026eb4c108c0fcdd500099299981e9819181f1baa00114c0103d87a8000132330010013756608660806ea8008894ccc108004530103d87a8000132333222533304333722911000031533304330090031302633047375000497ae014c103d87a8000133006006001375c60820026eb4c108004c118008c110004c8cc004004008894ccc1040045300103d87a8000132333222533304233722911000031533304230080031302533046374c00497ae014c103d87a8000133006006001375c60800026eacc104004c114008c10c004dc7a450022533303b302b303c375400426464646464646464646464646464646464646464a6660a460aa00426602e01e26602e00602a2c6eb4c14c004c14c008c144004c144008dd6982780098278011bad304d001304d00232533304a30490011533304733712900218240008b0981e18240008b1baa304b001304b002375a609200260920046eb4c11c004c11c008c114004c114008dd7182180098218011bae3041001303d37540042c44a666074605460766ea80084c8c8c8c94ccc104c1100084cc01c00c4c94ccc0fcc0bc0044c8c94ccc110c11c0084c94ccc108c0c80044c8c94ccc11cc1280084cc03400402c58c120004c110dd50010a999821181b8008991919191919299982598270010078b1bad304c001304c002375a609400260940046eb4c120004c110dd50010b18211baa001163045001304137540042a66607e60680022a66608460826ea80080185858c0fcdd50008b182100098210011820000981e1baa002162232533303a302a00113232533303f304200200416375c608000260786ea800c54ccc0e8c0bc0044c8c94ccc0fcc10800801058dd71820000981e1baa00316303a3754004606e6ea80b4dd6981d181d804981c8041bad3038008375a606e010604c60646ea8c0d8020dd6981a8041bad3034008375c60660106eb8c0c8020c0c8004c0c4004c0c0004c0bc004c0b8004c0b4c0b4004c0b0004c09cdd50028b181480099198008008071129998140008a5eb804cc894ccc09d4ccc09ccdd7981618149baa302c302d3029375400400a2646600200264660020026eacc0b8c0bcc0acdd51817181798159baa00422533302d00114bd70099191919198008009bab3030004225333032001100313233034374e660686ea4014cc0d0c0c4004cc0d0c0c80052f5c066006006606c00460680026600800860640066eb8c0b0004c0bc004894ccc0b000452809991299981599b8f375c606000405229444cc010010004dd6181700098178008a5013302b00233004004001133004004001302a001302b001300630243754600260486ea800c8c09cc0a0004c094c088dd50090b181218109baa00116323300100100922533302300114c103d87a80001332253330223375e600c60486ea80080544c014cc0980092f5c0266008008002604a002604c0026e9520002302200137586040604200c603e00a6eacc078014dd5980e8029bac301c0053758603600a603600260346034002603260320026030603000260266ea8024dc3a40006e1d2004301200130123013001300e37540046e1d200216300f3010003300e002300d002300d0013008375400229309b2b1bae001375c002ae6955ceaab9e5573eae815d0aba201", + "hash": "c0f352bf5856e696038a0449a91382f35ba4a5741946736ca1480382" }, { - "title": "placeholder.placeholder.vote", + "title": "crowdfund/spend.crowdfund.else", "redeemer": { - "title": "_redeemer", - "schema": { - "$ref": "#/definitions/Data" - } + "schema": {} }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "59121c0101003232323232323223223225333006323232323253323300c3001300d3754004264664464646464a66602660060022a66602c602a6ea80280085854ccc04cc02000454ccc058c054dd50050010b0a99980998020008a99980b180a9baa00a00216153330133370e90030008a99980b180a9baa00a00216163013375401226464646464646464646464646464a66603e601e60406ea80044c94ccc080c040c084dd500909919191919299981418158010991919191919191919191919191919191919191919191929919981e9816803899192999821182280109919191980480089919191919192999824299982419b87006337026eb4c014c128dd500380c099b89482024bd0040185280a9998240020a9998240018a9998240010a9998240008991929998268008010a999826982800089919199911299982799b8f0030211533304f3371e004044266e1c0040345280a50375c60a20046eb8c144004dd69828982900098288009bac304f001002323300100103222533304e00114bd70099191919198008009bab3051004225333053001100313233055374e660aa6ea4014cc154c148004cc154c14c0052f5c06600600660ae00460aa0026600800860a60066eb8c134004c1400045280a5014a029405280a50303832533304b0011480004c8c034c94ccc134008520001300e33001001305000222533304e0011480004c03ccc008008c144004c138004c8cc004004dd5981398251baa00a22533304c00114bd70099191919198008009bab304f004225333051001100313233053374e660a66ea4014cc14cc140004cc14cc1440052f5c06600600660aa00460a60026600800860a20066eb8c12c004c138004cdd7802991919191816998271827802198271827801998271827801198271827800998271ba83370003401060a060a0002609e002609c002609a00260906ea8098c8c8c94ccc120c0f4c124dd50008a999824181e98249baa304d304e0021337106eb4c134c128dd500080b099b89375a609a60946ea8004058528182600099825182580099825199823181d98239baa304b304c0014c0103d87a80004c0103d87980004bd7018239baa304a304b3047375405664a66608a02829444cdc480080b1bad30013046375400646092609460946094609400266e0400800cc94ccc108c0ccc10cdd50008982398221baa0011630463047304730433754006600a6eacc07cc108dd500118021bab301e30413754603c60826ea806c58c10c004c8cc00400409c894ccc10800452f5c026644a666082a66608266ebcc118c10cdd500100f8991980080099198008009bab304830493045375400844a66608e002297ae0132323232330010013756609400844a66609800220062646609c6e9ccc138dd4802998271825800998271826000a5eb80cc00c00cc140008c138004cc010010c13000cdd7182300098248009129998230008a501332253330453371e6eb8c12800810c5288998020020009bac3048001304900114a026608a004660080080022660080080026088002608a0022a6466607c6066010264a666084608a646600200205244a666088002297ae013322533304353330433375e6044608a6ea8008dd3299982198198070a5eb7bdb1804c8c8cc0040052f5bded8c044a66609200226609466ec13001014000374c00697adef6c60132333222533304a3372091010000313304e337609801014000374c00e00a2a666094602000626609c66ec13001014000374c00e00226609c66ec0dd48019ba600233006006001375c60900026eacc124004c134008c12c004c8cc0040052f5bded8c044a66609000226609266ec13001014000375002097adef6c6013233322253330493372091010000313304d337609801014000375002800a2a666092601e00626609a66ec13001014000375002800226609a66ec0dd48019ba800233006006001375c608e0026eb4c120004c130008c1280044cdd7981398229baa00200f14a026608e00466008008002266008008002608c002608e002264a66608066e2404404054ccc10000454ccc1000084c8c94ccc11400400854ccc114c1200044c8cc894ccc114cdc780100c098040008a50375c60900026eb4c120c124004c120dd61823800801191980080099198008008159129998238008a5eb804c8c8c8c8cc004004dd598250021129998260008801899198271ba73304e375200a6609c60960026609c609800297ae0330030033050002304e00133004004304c003375c608c002609200244a66608c002297ae01332253330453371e6eb8c12800810c4cc124dd3801198020020008998020020009bac3048001304900114a029405280a5032323300100102822533304500114a026644a66608866ebc01400852889980200200098219823800982400099ba548008cc10cdd480925eb8058cdc499b8000900e30033756603a60806ea8c074c100dd500d0a99981f181780409919191929998229824001099191919806000899192999823a9998238048a51100815333047004153330470021533304700113232533304c0010021533304c304f00113232333222533304e3371e0060402a66609c66e3c0080844cdc38008060a5014a06eb8c140008dd718280009bad3050305100130500013758609c002004646600200206244a66609a002297ae013232323233001001375660a000844a6660a40022006264660a86e9ccc150dd48029982a18288009982a1829000a5eb80cc00c00cc158008c150004cc010010c14800cdd7182600098278008a5014a029405280a50303732533304a0011480004c8c030c94ccc130008520001300d33001001304f00222533304d0011480004c038cc008008c140004c134004c8cc004004dd5981318249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd7800991919191816198269827002198269827001998269827001198269827000998269ba83370003200e609e609e002609c002609a0026098002608e6ea8094c94ccc114c0d8c118dd50008982518239baa001163049304a304a3046375400666e20005200033702600e6eacc084c110dd500098039bab302130443754604260886ea807858c118004c8cc0040040a8894ccc11400452f5c026644a666088a66608866ebcc124c118dd50010110991980080099198008009bab304b304c3048375400844a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a501332253330483371e6eb8c1340081185288998020020009bac304b001304c00114a026609000466008008002266008008002608e002609000266e2403c040c8c8c8c94ccc108c0dcc10cdd50008a999821181b98219baa304730480021337100086eb4c11cc110dd5000899b89004375a608e60886ea8004528182300099822182280099822199820181a98209baa304530460014c103d87a80004c0103d87980004bd7018209baa30443041375404a66e0003002c4c8c94ccc100c8c8c94ccc10cc0e0c110dd50008a999821981c18221baa304830490021337100226eb4c120c114dd5000899b89011375a6090608a6ea8004528182380099822982300099822999820981b18211baa304630470014c0103d87a80004c0103d87980004bd7018211baa30453042375404c2a6660800042002294052819198008008129129998220008a501332253330433371e00407e29444cc010010004dd718230009823800a99981f19b884800003854ccc0f8c8c8c94ccc11000400854ccc110c11c0044c8cc894ccc110cdc780100b899b8700100614a06eb8c11c004dd69823982400098239bac30460010023233001001323300100102a22533304600114bd70099191919198008009bab304900422533304b00110031323304d374e6609a6ea4014cc134c128004cc134c12c0052f5c066006006609e004609a0026600800860960066eb8c114004c120004894ccc11400452f5c026644a66608866e3cdd7182480100b0998241ba7002330040040011330040040013758608e00260900022940cdc0a400001c26464a6660860020042a666086608c0022646644a66608666e3c0080584c0180045281bae3046001375a608c608e002608c6eb0c114004008c8cc004004c8cc0040040a4894ccc11400452f5c0264646464660020026eacc120010894ccc128004400c4c8cc130dd3998261ba90053304c30490013304c304a0014bd7019801801982700118260009980200218250019bae3044001304700122533304400114bd7009991299982199b8f375c609000408226608e6e9c008cc0100100044cc010010004dd6182300098238008a5014a026464a6660860020042a666086608c00226464666444a66608a66e3c00c10c54ccc114cdc780100c098040008a5014a06eb8c11c008dd718238009bad3047304800130470013758608a002004646600200205044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230008a50370e90009b80480088c94ccc0f4c0c8c0f8dd50008a400026eb4c108c0fcdd500099299981e9819181f1baa00114c0103d87a8000132330010013756608660806ea8008894ccc108004530103d87a8000132333222533304333722911000031533304330090031302633047375000497ae014c103d87a8000133006006001375c60820026eb4c108004c118008c110004c8cc004004008894ccc1040045300103d87a8000132333222533304233722911000031533304230080031302533046374c00497ae014c103d87a8000133006006001375c60800026eacc104004c114008c10c004dc7a450022533303b302b303c375400426464646464646464646464646464646464646464a6660a460aa00426602e01e26602e00602a2c6eb4c14c004c14c008c144004c144008dd6982780098278011bad304d001304d00232533304a30490011533304733712900218240008b0981e18240008b1baa304b001304b002375a609200260920046eb4c11c004c11c008c114004c114008dd7182180098218011bae3041001303d37540042c44a666074605460766ea80084c8c8c8c94ccc104c1100084cc01c00c4c94ccc0fcc0bc0044c8c94ccc110c11c0084c94ccc108c0c80044c8c94ccc11cc1280084cc03400402c58c120004c110dd50010a999821181b8008991919191919299982598270010078b1bad304c001304c002375a609400260940046eb4c120004c110dd50010b18211baa001163045001304137540042a66607e60680022a66608460826ea80080185858c0fcdd50008b182100098210011820000981e1baa002162232533303a302a00113232533303f304200200416375c608000260786ea800c54ccc0e8c0bc0044c8c94ccc0fcc10800801058dd71820000981e1baa00316303a3754004606e6ea80b4dd6981d181d804981c8041bad3038008375a606e010604c60646ea8c0d8020dd6981a8041bad3034008375c60660106eb8c0c8020c0c8004c0c4004c0c0004c0bc004c0b8004c0b4c0b4004c0b0004c09cdd50028b181480099198008008071129998140008a5eb804cc894ccc09d4ccc09ccdd7981618149baa302c302d3029375400400a2646600200264660020026eacc0b8c0bcc0acdd51817181798159baa00422533302d00114bd70099191919198008009bab3030004225333032001100313233034374e660686ea4014cc0d0c0c4004cc0d0c0c80052f5c066006006606c00460680026600800860640066eb8c0b0004c0bc004894ccc0b000452809991299981599b8f375c606000405229444cc010010004dd6181700098178008a5013302b00233004004001133004004001302a001302b001300630243754600260486ea800c8c09cc0a0004c094c088dd50090b181218109baa00116323300100100922533302300114c103d87a80001332253330223375e600c60486ea80080544c014cc0980092f5c0266008008002604a002604c0026e9520002302200137586040604200c603e00a6eacc078014dd5980e8029bac301c0053758603600a603600260346034002603260320026030603000260266ea8024dc3a40006e1d2004301200130123013001300e37540046e1d200216300f3010003300e002300d002300d0013008375400229309b2b1bae001375c002ae6955ceaab9e5573eae815d0aba201", + "hash": "c0f352bf5856e696038a0449a91382f35ba4a5741946736ca1480382" }, { - "title": "placeholder.placeholder.propose", + "title": "share_token/mint.share_token.mint", "redeemer": { - "title": "_redeemer", + "title": "redeemer", "schema": { - "$ref": "#/definitions/Data" + "$ref": "#/definitions/types~1MintPolarity" } }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + } + ], + "compiledCode": "5903020101003232323232323223225333004323232323253323300a3001300b3754004264646464a66601c600a0022a66602260206ea801c0085854ccc038c00c00454ccc044c040dd50038010b0b18071baa0061323253330113014002132323232533301230093013375401626464a66602e6034004264a66602a6018602c6ea80044c8c8c94ccc060c03c00454ccc06cc068dd50018010b0a99980c18068008a99980d980d1baa00300216153330183370e90020008a99980d980d1baa00300216153330183370e90030008a99980d980d1baa003002161630183754004266ebc005300103d8798000301a301737540022c64646600200200a44a666034002298103d87a8000132333222533301b3375e00e006266e9520003301f0024bd70099803003000980c800980d000980f001180e00099ba548008cc060c064c058dd5000a5eb8058c060004c8cc00400400c894ccc05c00452f5c026644a66602c646600200264660020026eacc074c078c068dd5180e980f180d1baa00422533301c00114bd70099191919198008009bab301f004225333021001100313233023374e660466ea4014cc08cc080004cc08cc0840052f5c066006006604a00460460026600800860420066eb8c06c004c078004894ccc06c00452809991299980d19b8f375c603e00403029444cc010010004dd6180e800980f00089980d00119802002000899802002000980c800980d000899b8700448004dd5980b180b980b980b980b980b980b980b980b980b8011bac3015001301137540126eb4c04000458c048004c94ccc034c008c038dd50008a5eb7bdb1804dd5980918079baa0013233001001375660246026602660266026601e6ea801c894ccc0440045300103d87a80001323332225333012337220100062a66602466e3c02000c4cdd2a40006602c6e980092f5c02980103d87a8000133006006001375c60200026eacc044004c054008c04c004dc3a40046eb8c03cc030dd50011b874800058c034c03800cc030008c02c008c02c004c018dd50008a4c26cac6eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "203a21ede4281a3cd5b9ea4e88b1ca32b5296dca9a715601632fbd4b" }, { - "title": "placeholder.placeholder.else", + "title": "share_token/mint.share_token.else", "redeemer": { "schema": {} }, - "compiledCode": "58d001010029800aba2aba1aab9eaab9dab9a48888966002646465300130053754003300700398038012444b30013370e9000001c4c98dd7180518049baa0048acc004cdc3a400400713233226300b001300b300c0013009375400915980099b874801000e264c601460126ea80122b30013370e9003001c4c8cc898dd698058009805980600098049baa0048acc004cdc3a40100071326300a3009375400913233226375a60160026016601800260126ea8011007200e401c80390070c018c01c004c018004c00cdd5003452689b2b20021", - "hash": "f2388d136606a27c4a531d0040c3e12e07eb95cd5011793c160707dc" + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + } + ], + "compiledCode": "5903020101003232323232323223225333004323232323253323300a3001300b3754004264646464a66601c600a0022a66602260206ea801c0085854ccc038c00c00454ccc044c040dd50038010b0b18071baa0061323253330113014002132323232533301230093013375401626464a66602e6034004264a66602a6018602c6ea80044c8c8c94ccc060c03c00454ccc06cc068dd50018010b0a99980c18068008a99980d980d1baa00300216153330183370e90020008a99980d980d1baa00300216153330183370e90030008a99980d980d1baa003002161630183754004266ebc005300103d8798000301a301737540022c64646600200200a44a666034002298103d87a8000132333222533301b3375e00e006266e9520003301f0024bd70099803003000980c800980d000980f001180e00099ba548008cc060c064c058dd5000a5eb8058c060004c8cc00400400c894ccc05c00452f5c026644a66602c646600200264660020026eacc074c078c068dd5180e980f180d1baa00422533301c00114bd70099191919198008009bab301f004225333021001100313233023374e660466ea4014cc08cc080004cc08cc0840052f5c066006006604a00460460026600800860420066eb8c06c004c078004894ccc06c00452809991299980d19b8f375c603e00403029444cc010010004dd6180e800980f00089980d00119802002000899802002000980c800980d000899b8700448004dd5980b180b980b980b980b980b980b980b980b980b8011bac3015001301137540126eb4c04000458c048004c94ccc034c008c038dd50008a5eb7bdb1804dd5980918079baa0013233001001375660246026602660266026601e6ea801c894ccc0440045300103d87a80001323332225333012337220100062a66602466e3c02000c4cdd2a40006602c6e980092f5c02980103d87a8000133006006001375c60200026eacc044004c054008c04c004dc3a40046eb8c03cc030dd50011b874800058c034c03800cc030008c02c008c02c004c018dd50008a4c26cac6eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "203a21ede4281a3cd5b9ea4e88b1ca32b5296dca9a715601632fbd4b" } ], "definitions": { - "Data": { - "title": "Data", - "description": "Any Plutus data." + "Bool": { + "title": "Bool", + "anyOf": [ + { + "title": "False", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "True", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "ByteArray": { + "dataType": "bytes" + }, + "Int": { + "dataType": "integer" + }, + "Option$StakeCredential": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/StakeCredential" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "PaymentCredential": { + "title": "PaymentCredential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/ScriptHash" + } + ] + } + ] + }, + "PolicyId": { + "title": "PolicyId", + "dataType": "bytes" + }, + "ScriptHash": { + "title": "ScriptHash", + "dataType": "bytes" + }, + "StakeCredential": { + "title": "StakeCredential", + "description": "Represent a type of object that can be represented either inline (by hash)\n or via a reference (i.e. a pointer to an on-chain location).\n\n This is mainly use for capturing pointers to a stake credential\n registration certificate in the case of so-called pointer addresses.", + "anyOf": [ + { + "title": "Inline", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1address~1Credential" + } + ] + }, + { + "title": "Pointer", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "slot_number", + "$ref": "#/definitions/Int" + }, + { + "title": "transaction_index", + "$ref": "#/definitions/Int" + }, + { + "title": "certificate_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "VerificationKeyHash": { + "title": "VerificationKeyHash", + "dataType": "bytes" + }, + "cardano/address/Address": { + "title": "Address", + "description": "A Cardano `Address` typically holding one or two credential references.\n\n Note that legacy bootstrap addresses (a.k.a. 'Byron addresses') are\n completely excluded from Plutus contexts. Thus, from an on-chain\n perspective only exists addresses of type 00, 01, ..., 07 as detailed\n in [CIP-0019 :: Shelley Addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019/#shelley-addresses).", + "anyOf": [ + { + "title": "Address", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "payment_credential", + "$ref": "#/definitions/PaymentCredential" + }, + { + "title": "stake_credential", + "$ref": "#/definitions/Option$StakeCredential" + } + ] + } + ] + }, + "cardano/address/Credential": { + "title": "Credential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/ScriptHash" + } + ] + } + ] + }, + "cardano/transaction/OutputReference": { + "title": "OutputReference", + "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", + "anyOf": [ + { + "title": "OutputReference", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction_id", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "output_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundDatum": { + "title": "CrowdfundDatum", + "anyOf": [ + { + "title": "CrowdfundDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "completion_script", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "crowdfund_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "fundraise_target", + "$ref": "#/definitions/Int" + }, + { + "title": "current_fundraised_amount", + "$ref": "#/definitions/Int" + }, + { + "title": "allow_over_subscription", + "$ref": "#/definitions/Bool" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + }, + { + "title": "expiry_buffer", + "$ref": "#/definitions/Int" + }, + { + "title": "fee_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "min_charge", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundRedeemer": { + "title": "CrowdfundRedeemer", + "anyOf": [ + { + "title": "ContributeFund", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "CompleteCrowdfund", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "ContributorWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "RemoveEmptyInstance", + "dataType": "constructor", + "index": 3, + "fields": [] + } + ] + }, + "types/MintPolarity": { + "title": "MintPolarity", + "anyOf": [ + { + "title": "RMint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "RBurn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] } } } \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json index 0b930888d..3c9d7328d 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json @@ -11,6 +11,59 @@ "license": "Apache-2.0" }, "validators": [ + { + "title": "crowdfund.crowdfund.spend", + "datum": { + "title": "datum_opt", + "schema": { + "$ref": "#/definitions/types~1CrowdfundDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/crowdfund~1CrowdfundRedeemer" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "59121c0101003232323232323223223225333006323232323253323300c3001300d3754004264664464646464a66602660060022a66602c602a6ea80280085854ccc04cc02000454ccc058c054dd50050010b0a99980998020008a99980b180a9baa00a00216153330133370e90030008a99980b180a9baa00a00216163013375401226464646464646464646464646464a66603e601e60406ea80044c94ccc080c040c084dd500909919191919299981418158010991919191919191919191919191919191919191919191929919981e9816803899192999821182280109919191980480089919191919192999824299982419b87006337026eb4c014c128dd500380c099b89482024bd0040185280a9998240020a9998240018a9998240010a9998240008991929998268008010a999826982800089919199911299982799b8f0030211533304f3371e004044266e1c0040345280a50375c60a20046eb8c144004dd69828982900098288009bac304f001002323300100103222533304e00114bd70099191919198008009bab3051004225333053001100313233055374e660aa6ea4014cc154c148004cc154c14c0052f5c06600600660ae00460aa0026600800860a60066eb8c134004c1400045280a5014a029405280a50303832533304b0011480004c8c034c94ccc134008520001300e33001001305000222533304e0011480004c03ccc008008c144004c138004c8cc004004dd5981398251baa00a22533304c00114bd70099191919198008009bab304f004225333051001100313233053374e660a66ea4014cc14cc140004cc14cc1440052f5c06600600660aa00460a60026600800860a20066eb8c12c004c138004cdd7802991919191816998271827802198271827801998271827801198271827800998271ba83370003401060a060a0002609e002609c002609a00260906ea8098c8c8c94ccc120c0f4c124dd50008a999824181e98249baa304d304e0021337106eb4c134c128dd500080b099b89375a609a60946ea8004058528182600099825182580099825199823181d98239baa304b304c0014c0103d87a80004c0103d87980004bd7018239baa304a304b3047375405664a66608a02829444cdc480080b1bad30013046375400646092609460946094609400266e0400800cc94ccc108c0ccc10cdd50008982398221baa0011630463047304730433754006600a6eacc07cc108dd500118021bab301e30413754603c60826ea806c58c10c004c8cc00400409c894ccc10800452f5c026644a666082a66608266ebcc118c10cdd500100f8991980080099198008009bab304830493045375400844a66608e002297ae0132323232330010013756609400844a66609800220062646609c6e9ccc138dd4802998271825800998271826000a5eb80cc00c00cc140008c138004cc010010c13000cdd7182300098248009129998230008a501332253330453371e6eb8c12800810c5288998020020009bac3048001304900114a026608a004660080080022660080080026088002608a0022a6466607c6066010264a666084608a646600200205244a666088002297ae013322533304353330433375e6044608a6ea8008dd3299982198198070a5eb7bdb1804c8c8cc0040052f5bded8c044a66609200226609466ec13001014000374c00697adef6c60132333222533304a3372091010000313304e337609801014000374c00e00a2a666094602000626609c66ec13001014000374c00e00226609c66ec0dd48019ba600233006006001375c60900026eacc124004c134008c12c004c8cc0040052f5bded8c044a66609000226609266ec13001014000375002097adef6c6013233322253330493372091010000313304d337609801014000375002800a2a666092601e00626609a66ec13001014000375002800226609a66ec0dd48019ba800233006006001375c608e0026eb4c120004c130008c1280044cdd7981398229baa00200f14a026608e00466008008002266008008002608c002608e002264a66608066e2404404054ccc10000454ccc1000084c8c94ccc11400400854ccc114c1200044c8cc894ccc114cdc780100c098040008a50375c60900026eb4c120c124004c120dd61823800801191980080099198008008159129998238008a5eb804c8c8c8c8cc004004dd598250021129998260008801899198271ba73304e375200a6609c60960026609c609800297ae0330030033050002304e00133004004304c003375c608c002609200244a66608c002297ae01332253330453371e6eb8c12800810c4cc124dd3801198020020008998020020009bac3048001304900114a029405280a5032323300100102822533304500114a026644a66608866ebc01400852889980200200098219823800982400099ba548008cc10cdd480925eb8058cdc499b8000900e30033756603a60806ea8c074c100dd500d0a99981f181780409919191929998229824001099191919806000899192999823a9998238048a51100815333047004153330470021533304700113232533304c0010021533304c304f00113232333222533304e3371e0060402a66609c66e3c0080844cdc38008060a5014a06eb8c140008dd718280009bad3050305100130500013758609c002004646600200206244a66609a002297ae013232323233001001375660a000844a6660a40022006264660a86e9ccc150dd48029982a18288009982a1829000a5eb80cc00c00cc158008c150004cc010010c14800cdd7182600098278008a5014a029405280a50303732533304a0011480004c8c030c94ccc130008520001300d33001001304f00222533304d0011480004c038cc008008c140004c134004c8cc004004dd5981318249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd7800991919191816198269827002198269827001998269827001198269827000998269ba83370003200e609e609e002609c002609a0026098002608e6ea8094c94ccc114c0d8c118dd50008982518239baa001163049304a304a3046375400666e20005200033702600e6eacc084c110dd500098039bab302130443754604260886ea807858c118004c8cc0040040a8894ccc11400452f5c026644a666088a66608866ebcc124c118dd50010110991980080099198008009bab304b304c3048375400844a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a501332253330483371e6eb8c1340081185288998020020009bac304b001304c00114a026609000466008008002266008008002608e002609000266e2403c040c8c8c8c94ccc108c0dcc10cdd50008a999821181b98219baa304730480021337100086eb4c11cc110dd5000899b89004375a608e60886ea8004528182300099822182280099822199820181a98209baa304530460014c103d87a80004c0103d87980004bd7018209baa30443041375404a66e0003002c4c8c94ccc100c8c8c94ccc10cc0e0c110dd50008a999821981c18221baa304830490021337100226eb4c120c114dd5000899b89011375a6090608a6ea8004528182380099822982300099822999820981b18211baa304630470014c0103d87a80004c0103d87980004bd7018211baa30453042375404c2a6660800042002294052819198008008129129998220008a501332253330433371e00407e29444cc010010004dd718230009823800a99981f19b884800003854ccc0f8c8c8c94ccc11000400854ccc110c11c0044c8cc894ccc110cdc780100b899b8700100614a06eb8c11c004dd69823982400098239bac30460010023233001001323300100102a22533304600114bd70099191919198008009bab304900422533304b00110031323304d374e6609a6ea4014cc134c128004cc134c12c0052f5c066006006609e004609a0026600800860960066eb8c114004c120004894ccc11400452f5c026644a66608866e3cdd7182480100b0998241ba7002330040040011330040040013758608e00260900022940cdc0a400001c26464a6660860020042a666086608c0022646644a66608666e3c0080584c0180045281bae3046001375a608c608e002608c6eb0c114004008c8cc004004c8cc0040040a4894ccc11400452f5c0264646464660020026eacc120010894ccc128004400c4c8cc130dd3998261ba90053304c30490013304c304a0014bd7019801801982700118260009980200218250019bae3044001304700122533304400114bd7009991299982199b8f375c609000408226608e6e9c008cc0100100044cc010010004dd6182300098238008a5014a026464a6660860020042a666086608c00226464666444a66608a66e3c00c10c54ccc114cdc780100c098040008a5014a06eb8c11c008dd718238009bad3047304800130470013758608a002004646600200205044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230008a50370e90009b80480088c94ccc0f4c0c8c0f8dd50008a400026eb4c108c0fcdd500099299981e9819181f1baa00114c0103d87a8000132330010013756608660806ea8008894ccc108004530103d87a8000132333222533304333722911000031533304330090031302633047375000497ae014c103d87a8000133006006001375c60820026eb4c108004c118008c110004c8cc004004008894ccc1040045300103d87a8000132333222533304233722911000031533304230080031302533046374c00497ae014c103d87a8000133006006001375c60800026eacc104004c114008c10c004dc7a450022533303b302b303c375400426464646464646464646464646464646464646464a6660a460aa00426602e01e26602e00602a2c6eb4c14c004c14c008c144004c144008dd6982780098278011bad304d001304d00232533304a30490011533304733712900218240008b0981e18240008b1baa304b001304b002375a609200260920046eb4c11c004c11c008c114004c114008dd7182180098218011bae3041001303d37540042c44a666074605460766ea80084c8c8c8c94ccc104c1100084cc01c00c4c94ccc0fcc0bc0044c8c94ccc110c11c0084c94ccc108c0c80044c8c94ccc11cc1280084cc03400402c58c120004c110dd50010a999821181b8008991919191919299982598270010078b1bad304c001304c002375a609400260940046eb4c120004c110dd50010b18211baa001163045001304137540042a66607e60680022a66608460826ea80080185858c0fcdd50008b182100098210011820000981e1baa002162232533303a302a00113232533303f304200200416375c608000260786ea800c54ccc0e8c0bc0044c8c94ccc0fcc10800801058dd71820000981e1baa00316303a3754004606e6ea80b4dd6981d181d804981c8041bad3038008375a606e010604c60646ea8c0d8020dd6981a8041bad3034008375c60660106eb8c0c8020c0c8004c0c4004c0c0004c0bc004c0b8004c0b4c0b4004c0b0004c09cdd50028b181480099198008008071129998140008a5eb804cc894ccc09d4ccc09ccdd7981618149baa302c302d3029375400400a2646600200264660020026eacc0b8c0bcc0acdd51817181798159baa00422533302d00114bd70099191919198008009bab3030004225333032001100313233034374e660686ea4014cc0d0c0c4004cc0d0c0c80052f5c066006006606c00460680026600800860640066eb8c0b0004c0bc004894ccc0b000452809991299981599b8f375c606000405229444cc010010004dd6181700098178008a5013302b00233004004001133004004001302a001302b001300630243754600260486ea800c8c09cc0a0004c094c088dd50090b181218109baa00116323300100100922533302300114c103d87a80001332253330223375e600c60486ea80080544c014cc0980092f5c0266008008002604a002604c0026e9520002302200137586040604200c603e00a6eacc078014dd5980e8029bac301c0053758603600a603600260346034002603260320026030603000260266ea8024dc3a40006e1d2004301200130123013001300e37540046e1d200216300f3010003300e002300d002300d0013008375400229309b2b1bae001375c002ae6955ceaab9e5573eae815d0aba201", + "hash": "c0f352bf5856e696038a0449a91382f35ba4a5741946736ca1480382" + }, + { + "title": "crowdfund.crowdfund.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "59121c0101003232323232323223223225333006323232323253323300c3001300d3754004264664464646464a66602660060022a66602c602a6ea80280085854ccc04cc02000454ccc058c054dd50050010b0a99980998020008a99980b180a9baa00a00216153330133370e90030008a99980b180a9baa00a00216163013375401226464646464646464646464646464a66603e601e60406ea80044c94ccc080c040c084dd500909919191919299981418158010991919191919191919191919191919191919191919191929919981e9816803899192999821182280109919191980480089919191919192999824299982419b87006337026eb4c014c128dd500380c099b89482024bd0040185280a9998240020a9998240018a9998240010a9998240008991929998268008010a999826982800089919199911299982799b8f0030211533304f3371e004044266e1c0040345280a50375c60a20046eb8c144004dd69828982900098288009bac304f001002323300100103222533304e00114bd70099191919198008009bab3051004225333053001100313233055374e660aa6ea4014cc154c148004cc154c14c0052f5c06600600660ae00460aa0026600800860a60066eb8c134004c1400045280a5014a029405280a50303832533304b0011480004c8c034c94ccc134008520001300e33001001305000222533304e0011480004c03ccc008008c144004c138004c8cc004004dd5981398251baa00a22533304c00114bd70099191919198008009bab304f004225333051001100313233053374e660a66ea4014cc14cc140004cc14cc1440052f5c06600600660aa00460a60026600800860a20066eb8c12c004c138004cdd7802991919191816998271827802198271827801998271827801198271827800998271ba83370003401060a060a0002609e002609c002609a00260906ea8098c8c8c94ccc120c0f4c124dd50008a999824181e98249baa304d304e0021337106eb4c134c128dd500080b099b89375a609a60946ea8004058528182600099825182580099825199823181d98239baa304b304c0014c0103d87a80004c0103d87980004bd7018239baa304a304b3047375405664a66608a02829444cdc480080b1bad30013046375400646092609460946094609400266e0400800cc94ccc108c0ccc10cdd50008982398221baa0011630463047304730433754006600a6eacc07cc108dd500118021bab301e30413754603c60826ea806c58c10c004c8cc00400409c894ccc10800452f5c026644a666082a66608266ebcc118c10cdd500100f8991980080099198008009bab304830493045375400844a66608e002297ae0132323232330010013756609400844a66609800220062646609c6e9ccc138dd4802998271825800998271826000a5eb80cc00c00cc140008c138004cc010010c13000cdd7182300098248009129998230008a501332253330453371e6eb8c12800810c5288998020020009bac3048001304900114a026608a004660080080022660080080026088002608a0022a6466607c6066010264a666084608a646600200205244a666088002297ae013322533304353330433375e6044608a6ea8008dd3299982198198070a5eb7bdb1804c8c8cc0040052f5bded8c044a66609200226609466ec13001014000374c00697adef6c60132333222533304a3372091010000313304e337609801014000374c00e00a2a666094602000626609c66ec13001014000374c00e00226609c66ec0dd48019ba600233006006001375c60900026eacc124004c134008c12c004c8cc0040052f5bded8c044a66609000226609266ec13001014000375002097adef6c6013233322253330493372091010000313304d337609801014000375002800a2a666092601e00626609a66ec13001014000375002800226609a66ec0dd48019ba800233006006001375c608e0026eb4c120004c130008c1280044cdd7981398229baa00200f14a026608e00466008008002266008008002608c002608e002264a66608066e2404404054ccc10000454ccc1000084c8c94ccc11400400854ccc114c1200044c8cc894ccc114cdc780100c098040008a50375c60900026eb4c120c124004c120dd61823800801191980080099198008008159129998238008a5eb804c8c8c8c8cc004004dd598250021129998260008801899198271ba73304e375200a6609c60960026609c609800297ae0330030033050002304e00133004004304c003375c608c002609200244a66608c002297ae01332253330453371e6eb8c12800810c4cc124dd3801198020020008998020020009bac3048001304900114a029405280a5032323300100102822533304500114a026644a66608866ebc01400852889980200200098219823800982400099ba548008cc10cdd480925eb8058cdc499b8000900e30033756603a60806ea8c074c100dd500d0a99981f181780409919191929998229824001099191919806000899192999823a9998238048a51100815333047004153330470021533304700113232533304c0010021533304c304f00113232333222533304e3371e0060402a66609c66e3c0080844cdc38008060a5014a06eb8c140008dd718280009bad3050305100130500013758609c002004646600200206244a66609a002297ae013232323233001001375660a000844a6660a40022006264660a86e9ccc150dd48029982a18288009982a1829000a5eb80cc00c00cc158008c150004cc010010c14800cdd7182600098278008a5014a029405280a50303732533304a0011480004c8c030c94ccc130008520001300d33001001304f00222533304d0011480004c038cc008008c140004c134004c8cc004004dd5981318249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd7800991919191816198269827002198269827001998269827001198269827000998269ba83370003200e609e609e002609c002609a0026098002608e6ea8094c94ccc114c0d8c118dd50008982518239baa001163049304a304a3046375400666e20005200033702600e6eacc084c110dd500098039bab302130443754604260886ea807858c118004c8cc0040040a8894ccc11400452f5c026644a666088a66608866ebcc124c118dd50010110991980080099198008009bab304b304c3048375400844a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a501332253330483371e6eb8c1340081185288998020020009bac304b001304c00114a026609000466008008002266008008002608e002609000266e2403c040c8c8c8c94ccc108c0dcc10cdd50008a999821181b98219baa304730480021337100086eb4c11cc110dd5000899b89004375a608e60886ea8004528182300099822182280099822199820181a98209baa304530460014c103d87a80004c0103d87980004bd7018209baa30443041375404a66e0003002c4c8c94ccc100c8c8c94ccc10cc0e0c110dd50008a999821981c18221baa304830490021337100226eb4c120c114dd5000899b89011375a6090608a6ea8004528182380099822982300099822999820981b18211baa304630470014c0103d87a80004c0103d87980004bd7018211baa30453042375404c2a6660800042002294052819198008008129129998220008a501332253330433371e00407e29444cc010010004dd718230009823800a99981f19b884800003854ccc0f8c8c8c94ccc11000400854ccc110c11c0044c8cc894ccc110cdc780100b899b8700100614a06eb8c11c004dd69823982400098239bac30460010023233001001323300100102a22533304600114bd70099191919198008009bab304900422533304b00110031323304d374e6609a6ea4014cc134c128004cc134c12c0052f5c066006006609e004609a0026600800860960066eb8c114004c120004894ccc11400452f5c026644a66608866e3cdd7182480100b0998241ba7002330040040011330040040013758608e00260900022940cdc0a400001c26464a6660860020042a666086608c0022646644a66608666e3c0080584c0180045281bae3046001375a608c608e002608c6eb0c114004008c8cc004004c8cc0040040a4894ccc11400452f5c0264646464660020026eacc120010894ccc128004400c4c8cc130dd3998261ba90053304c30490013304c304a0014bd7019801801982700118260009980200218250019bae3044001304700122533304400114bd7009991299982199b8f375c609000408226608e6e9c008cc0100100044cc010010004dd6182300098238008a5014a026464a6660860020042a666086608c00226464666444a66608a66e3c00c10c54ccc114cdc780100c098040008a5014a06eb8c11c008dd718238009bad3047304800130470013758608a002004646600200205044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230008a50370e90009b80480088c94ccc0f4c0c8c0f8dd50008a400026eb4c108c0fcdd500099299981e9819181f1baa00114c0103d87a8000132330010013756608660806ea8008894ccc108004530103d87a8000132333222533304333722911000031533304330090031302633047375000497ae014c103d87a8000133006006001375c60820026eb4c108004c118008c110004c8cc004004008894ccc1040045300103d87a8000132333222533304233722911000031533304230080031302533046374c00497ae014c103d87a8000133006006001375c60800026eacc104004c114008c10c004dc7a450022533303b302b303c375400426464646464646464646464646464646464646464a6660a460aa00426602e01e26602e00602a2c6eb4c14c004c14c008c144004c144008dd6982780098278011bad304d001304d00232533304a30490011533304733712900218240008b0981e18240008b1baa304b001304b002375a609200260920046eb4c11c004c11c008c114004c114008dd7182180098218011bae3041001303d37540042c44a666074605460766ea80084c8c8c8c94ccc104c1100084cc01c00c4c94ccc0fcc0bc0044c8c94ccc110c11c0084c94ccc108c0c80044c8c94ccc11cc1280084cc03400402c58c120004c110dd50010a999821181b8008991919191919299982598270010078b1bad304c001304c002375a609400260940046eb4c120004c110dd50010b18211baa001163045001304137540042a66607e60680022a66608460826ea80080185858c0fcdd50008b182100098210011820000981e1baa002162232533303a302a00113232533303f304200200416375c608000260786ea800c54ccc0e8c0bc0044c8c94ccc0fcc10800801058dd71820000981e1baa00316303a3754004606e6ea80b4dd6981d181d804981c8041bad3038008375a606e010604c60646ea8c0d8020dd6981a8041bad3034008375c60660106eb8c0c8020c0c8004c0c4004c0c0004c0bc004c0b8004c0b4c0b4004c0b0004c09cdd50028b181480099198008008071129998140008a5eb804cc894ccc09d4ccc09ccdd7981618149baa302c302d3029375400400a2646600200264660020026eacc0b8c0bcc0acdd51817181798159baa00422533302d00114bd70099191919198008009bab3030004225333032001100313233034374e660686ea4014cc0d0c0c4004cc0d0c0c80052f5c066006006606c00460680026600800860640066eb8c0b0004c0bc004894ccc0b000452809991299981599b8f375c606000405229444cc010010004dd6181700098178008a5013302b00233004004001133004004001302a001302b001300630243754600260486ea800c8c09cc0a0004c094c088dd50090b181218109baa00116323300100100922533302300114c103d87a80001332253330223375e600c60486ea80080544c014cc0980092f5c0266008008002604a002604c0026e9520002302200137586040604200c603e00a6eacc078014dd5980e8029bac301c0053758603600a603600260346034002603260320026030603000260266ea8024dc3a40006e1d2004301200130123013001300e37540046e1d200216300f3010003300e002300d002300d0013008375400229309b2b1bae001375c002ae6955ceaab9e5573eae815d0aba201", + "hash": "c0f352bf5856e696038a0449a91382f35ba4a5741946736ca1480382" + }, { "title": "spend.spend.spend", "datum": { @@ -128,8 +181,8 @@ } } ], - "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" + "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" }, { "title": "start.start.mint", @@ -159,8 +212,8 @@ } } ], - "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" + "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" }, { "title": "start.start.publish", @@ -190,8 +243,8 @@ } } ], - "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" + "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" }, { "title": "start.start.propose", @@ -221,8 +274,8 @@ } } ], - "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" + "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" }, { "title": "start.start.vote", @@ -252,8 +305,8 @@ } } ], - "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" + "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" }, { "title": "start.start.else", @@ -280,11 +333,28 @@ } } ], - "compiledCode": "590bdb010100323232323232322322322322533300832323232323253232323232323330143004007132323232323232533301e30210021323232533301e3010301f375400626464646464646464646464646464646464646464a66606a607000426602a01e26602a00626464646464646464646464646464a666086608c004264646464a666088606c00226464646464646464a66609e60a40040142c6eb4c140004c140008dd6982700098270011bae304c001304c002375c6094002608c6ea800c54ccc110c0d40044c8c8c8c8c8c8c8c94ccc13cc14800802858dd6982800098280011bad304e001304e002375c609800260980046eb8c128004c118dd50018a999822181a0008991919191919191919192999828982a0010a999827182018279baa0031323232325333055305800201016375a60ac00260ac0046eb8c150004c140dd50018b0b1bad3052001305200230500013050002375a609c002609c0046eb8c130004c130008dd7182500098231baa0031533304430330011323232323232533304d305000200816375a609c002609c0046eb8c130004c130008dd7182500098231baa0031630443754004264a6660860102a6660860062a66608600226464a6660900020042a66609060960022646644a6660906016004260720022940dd718258009bad304b304c001304b375860940020046466002002646600200205c44a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a5eb804cc894ccc120cdc79bae304d00201213304c374e004660080080022660080080026eb0c12c004c1300045280a5014a02940cdd78009818198231ba900c3304637520166608c6ea0024cc118dd419b8000803c4bd70192999821181918219baa00113047304437540022c608c608e608e60866ea8008cdc3992999820981918211baa0011480004dd6982318219baa0013253330413032304237540022980103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a80001323332225333047300b00315333047300a003130353304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa00222533304500114c103d87a80001323332225333046300a003153330463009003130343304a374c00497ae014c103d87a8000133006006001375c60880026eacc114004c124008c11c00402058c110004c8c8cc0040040a4894ccc11000452f5c026644a666086a66608666ebcc120c114dd50010028981a192999822181a98229baa0011480004dd6982498231baa001325333044303530453754002298103d87a80001323300100137566094608e6ea8008894ccc124004530103d87a8000132333222533304a300e0031533304a300d003130383304e375000497ae014c103d87a8000133006006001375c60900026eb4c124004c134008c12c004c8cc004004dd59824982518231baa00322533304800114c103d87a80001323332225333049337220260062a66609266e3c04c00c4c0dccc134dd300125eb80530103d87a8000133006006001375c608e0026eacc120004c130008c12800452809982380119802002000899802002000982300098238009816198211815998211ba903a4bd70198211816198211816198211815998211ba90084bd7025eb812f5c097ae0371e9110037229101003375e60506607e6ea40152f5c004e6eb4c0fcc100c100014dd6981f0021bad303d004375c60780086eb8c0ec010c0ec004c0e8c0e8004c0e4004c0d0dd500b8b1bad3036001303600230340013034002375a606400260640046eb4c0c0004c0c0008c94ccc0b4c0b000454ccc0a8cdc4a400860560022c2603660560022c6ea8c0b8004c0b8008dd6981600098160011bad302a001302a00230280013028002375c604c002604c0046eb8c090004c080dd50018b11299980f980898101baa0021323232325333026302900213300700313253330243016001132325333029302c0021325333027301900113232533302c302f00213300d00100b16302d001302937540042a66604e60300022646464646464a666060606600401e2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302937540042c604e6ea800458c0a8004c098dd50010a999812180a8008a99981398131baa0020061616302437540022c604e002604e004604a00260426ea80085888c94ccc07cc0440044c8c94ccc090c09c00801058dd7181280098109baa0031533301f3010001132325333024302700200416375c604a00260426ea800c58c07cdd500119299980e1806180e9baa00113021301e37540022c604060426042603a6ea8c080c084c074dd50008b180f80099198008009bac301f00522533301e00114bd7009991299980e991980080099198008009bab30243025302137546048604a60426ea8010894ccc08c00452f5c0264646464660020026eacc098010894ccc0a0004400c4c8cc0a8dd3998151ba90053302a30270013302a30280014bd7019801801981600118150009980200218140019bae3022001302500122533302200114a026644a66604266e3cdd7181300100f8a5113300400400137586048002604a00226604200466008008002266008008002604000260420026eacc074c078c078008dd6180e000980e180e000980b9baa00b301930163754010264646464a66603060140162646464a666036601a0022a66603c603a6ea80400085854ccc06cc03000454ccc078c074dd50080010b0b180d9baa00f13232323232533301e3010301f3754026264646600200200844a66604800229404cc894ccc08ccdd78028010a51133004004001302230260013027001300b33022375200c97ae01333300701a0030014c0103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc02c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300901937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919804800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd5001002899812001198020020008998020020009811800981200098038021119299980c98058008a99980e180d9baa0030021615333019300a0011533301c301b37540060042c2a66603260120022a66603860366ea800c0085854ccc064c02000454ccc070c06cdd50018010b0a99980c99b874802000454ccc070c06cdd50018010b0b180c9baa0022232323300100100422533301d00114c103d87a8000132333222533301e3375e00e006260186604400497ae0133006006001301c001301d0013021002301f00130043301b301c3019375400297ae02300333019300233019375200297ae0330194c0103d87a80004bd701ba548008dd2a40006e1d2006370e90021b8748008dc3a4000601c6ea8004c044c04800cc040008c03c008c03c004c028dd50008a4c26cac6eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d101", - "hash": "eaf3b4c500aa3f149b863085350a2b0f2a8dba7e8bcd69e2e4eada34" + "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", + "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" } ], "definitions": { + "Bool": { + "title": "Bool", + "anyOf": [ + { + "title": "False", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "True", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, "ByteArray": { "dataType": "bytes" }, @@ -336,6 +406,29 @@ } ] }, + "Option$StakeCredential": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/StakeCredential" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, "Option$cardano/governance/GovernanceActionId": { "title": "Option", "anyOf": [ @@ -389,6 +482,32 @@ "$ref": "#/definitions/Mandate" } }, + "PaymentCredential": { + "title": "PaymentCredential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/ScriptHash" + } + ] + } + ] + }, "PolicyId": { "title": "PolicyId", "dataType": "bytes" @@ -401,6 +520,41 @@ "title": "ScriptHash", "dataType": "bytes" }, + "StakeCredential": { + "title": "StakeCredential", + "description": "Represent a type of object that can be represented either inline (by hash)\n or via a reference (i.e. a pointer to an on-chain location).\n\n This is mainly use for capturing pointers to a stake credential\n registration certificate in the case of so-called pointer addresses.", + "anyOf": [ + { + "title": "Inline", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1address~1Credential" + } + ] + }, + { + "title": "Pointer", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "slot_number", + "$ref": "#/definitions/Int" + }, + { + "title": "transaction_index", + "$ref": "#/definitions/Int" + }, + { + "title": "certificate_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, "TransactionId": { "title": "TransactionId", "dataType": "bytes" @@ -409,6 +563,27 @@ "title": "VerificationKeyHash", "dataType": "bytes" }, + "cardano/address/Address": { + "title": "Address", + "description": "A Cardano `Address` typically holding one or two credential references.\n\n Note that legacy bootstrap addresses (a.k.a. 'Byron addresses') are\n completely excluded from Plutus contexts. Thus, from an on-chain\n perspective only exists addresses of type 00, 01, ..., 07 as detailed\n in [CIP-0019 :: Shelley Addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019/#shelley-addresses).", + "anyOf": [ + { + "title": "Address", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "payment_credential", + "$ref": "#/definitions/PaymentCredential" + }, + { + "title": "stake_credential", + "$ref": "#/definitions/Option$StakeCredential" + } + ] + } + ] + }, "cardano/address/Credential": { "title": "Credential", "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", @@ -491,6 +666,35 @@ } ] }, + "crowdfund/CrowdfundRedeemer": { + "title": "CrowdfundRedeemer", + "anyOf": [ + { + "title": "ContributeFund", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "CompleteCrowdfund", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "ContributorWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "RemoveEmptyInstance", + "dataType": "constructor", + "index": 3, + "fields": [] + } + ] + }, "gov/VGovernanceAction": { "title": "VGovernanceAction", "anyOf": [ @@ -650,6 +854,58 @@ } ] }, + "types/CrowdfundDatum": { + "title": "CrowdfundDatum", + "anyOf": [ + { + "title": "CrowdfundDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "completion_script", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "crowdfund_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "fundraise_target", + "$ref": "#/definitions/Int" + }, + { + "title": "current_fundraised_amount", + "$ref": "#/definitions/Int" + }, + { + "title": "allow_over_subscription", + "$ref": "#/definitions/Bool" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + }, + { + "title": "expiry_buffer", + "$ref": "#/definitions/Int" + }, + { + "title": "fee_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "min_charge", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, "types/CrowdfundGovDatum": { "title": "CrowdfundGovDatum", "anyOf": [ From b7f77950e420c859657faedb3eece5955b5a1e27 Mon Sep 17 00:00:00 2001 From: Ken Lau Date: Tue, 8 Jul 2025 18:20:47 +0800 Subject: [PATCH 20/24] fixed: gov target in para and deposit return --- .../gov-crowdfund/specs/1_spend.md | 24 ++++----- .../gov-crowdfund/validators/spend.ak | 9 ++-- .../gov-crowdfund/validators/tests/spend.ak | 54 +++++++++++++++++-- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md index 4e92d5944..f3a7776d0 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md @@ -3,10 +3,11 @@ ## Parameter - `delegate_pool_id`: ByteArray -- `gov_action`: GovernanceAction +- `gov_action`: VGovernanceAction - `proposer_key_hash`: ByteArray - `stake_register_deposit`: Lovelace - `drep_register_deposit`: Lovelace +- `gov_deposit`: Lovelace ## Datum @@ -35,7 +36,6 @@ pub type Datum { start_hash: ByteArray, share_token: ByteArray, funds_controlled: Int, - deadline: Int, } } ``` @@ -43,10 +43,9 @@ pub type Datum { ## User Action 1. RegisterCerts - - - Only one input and output from current address + - Only one input and output from current address with token of policy `start_hash` - Input datum in state of `Init` - - Output value has deducted with 502 ADA exactly + - Output value has deducted with 502 + 100k ADA exactly - Output datum in state of `Proposed` - fields exactly the same - Registering stake cert @@ -55,17 +54,16 @@ pub type Datum { - Propose gov action 2. VoteOnGovAction - - - Only one input and output from current address + - Only one input and output from current address with token of policy `start_hash` - Input datum in state of `Proposed` - - Check output value (deducted by 100k ADA exactly) - Output datum in state of `Voted`, with `gov_tx_id` composed by own's input `TransactionId` + `proposal_procedure` as 0 - fields exactly the same + - Voted yes by drep 3. DeregisterCerts - + - collecting 100k ada from reward address to spending address - deadline is passed - - Only one input and output from current address + - Only one input and output from current address with token of policy `start_hash` - Input datum in state of `Voted` - Output datum in state of `Refundable` - fields exactly the same @@ -73,14 +71,12 @@ pub type Datum { - Refunds (502ADA) go into the output 4. ContributorWithdrawal - + - Input with token of policy `start_hash` - Input datum in state of Refundable - - `deadline` is passed - The lovelace unlocking from current equal exactly the amount that the `share_token` with token name of `completion_script` is burnt 5. RemoveEmptyInstance - + - Input with token of policy `start_hash`, which is burnt - Input datum in state of Refundable - - `deadline` is passed - share token with token name `completion_script` burning in current tx == `current_fundraised_amount` - signed by `proposer_key_hash` diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak index 59343009a..3314e3410 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak @@ -27,6 +27,7 @@ validator spend( proposer_key_hash: ByteArray, stake_register_deposit: Lovelace, drep_register_deposit: Lovelace, + gov_deposit: Lovelace, ) { spend( datum_opt: Option, @@ -70,7 +71,7 @@ validator spend( check_lovelace_diff( only_input, only_output, - -(stake_register_deposit + drep_register_deposit + 100000000000), + -(stake_register_deposit + drep_register_deposit + gov_deposit), ) expect only_output_datum: CrowdfundGovDatum = output_inline_datum(only_output) @@ -114,8 +115,8 @@ validator spend( let proposal_check = check_proposal_procedure( proposal_procedures, - 100000000000, - current_address.payment_credential, + gov_deposit, + Script(start_hash), gov_action, ) lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? @@ -176,7 +177,7 @@ validator spend( check_lovelace_diff( only_input, only_output, - stake_register_deposit + drep_register_deposit, + stake_register_deposit + drep_register_deposit + gov_deposit, ) expect only_output_datum: CrowdfundGovDatum = diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak index 2aec6f790..00e5aa4ad 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak @@ -21,8 +21,8 @@ use tests/utils.{ mock_current_fundraised_amount, mock_deadline, mock_delegate_pool_id, mock_drep_register_deposit, mock_fundraise_target, mock_funds_controlled, mock_gov_action, mock_gov_action_id, mock_gov_action_period, mock_gov_address, - mock_proposer_key_hash, mock_share_token, mock_spend_script_hash, - mock_stake_register_deposit, mock_start_hash, + mock_proposer_key_hash, mock_share_token, mock_stake_register_deposit, + mock_start_hash, } use types.{ ContributorWithdrawal, DeregisterCerts, Init, Proposed, Refundable, @@ -159,7 +159,7 @@ fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { is_gov_proposed, ProposalProcedure { deposit: mock_fundraise_target, - return_address: Script(mock_spend_script_hash), + return_address: Script(mock_start_hash), governance_action: NoConfidence { ancestor: None }, }, ) @@ -189,6 +189,7 @@ test s1_spend_success_reg_cert() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -227,6 +228,7 @@ test s1_spend_fail_reg_cert_with_not_init_state() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -265,6 +267,7 @@ test s1_spend_fail_reg_cert_with_more_than_one_input() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -303,6 +306,7 @@ test s1_spend_fail_reg_cert_with_more_than_one_output() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -341,6 +345,7 @@ test s1_spend_fail_reg_cert_with_incorrect_output_datum() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -379,6 +384,7 @@ test s1_spend_fail_reg_cert_with_output_value_not_clean() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -417,6 +423,7 @@ test s1_spend_fail_reg_cert_with_incorrect_output_value() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -455,6 +462,7 @@ test s1_spend_fail_reg_cert_with_stake_cert_not_reg() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -493,6 +501,7 @@ test s1_spend_fail_reg_cert_with_drep_cert_not_reg() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -531,6 +540,7 @@ test s1_spend_fail_reg_cert_with_drep_deposit_incorrect() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -569,6 +579,7 @@ test s1_spend_fail_reg_cert_with_stake_not_delegated() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -607,6 +618,7 @@ test s1_spend_fail_reg_cert_with_vote_not_delegated() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -645,6 +657,7 @@ test s1_spend_fail_reg_cert_with_gov_not_proposed() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -771,6 +784,7 @@ test s1_spend_success_vote_on_gov_action() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -804,6 +818,7 @@ test s1_spend_fail_vote_on_gov_action_with_more_than_one_inputed() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -837,6 +852,7 @@ test s1_spend_fail_vote_on_gov_action_with_more_than_one_outputed() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -870,6 +886,7 @@ test s1_spend_fail_vote_on_gov_action_with_output_datum_wrong() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -903,6 +920,7 @@ test s1_spend_fail_vote_on_gov_action_with_output_value_not_clean() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -936,6 +954,7 @@ test s1_spend_fail_vote_on_gov_action_with_incorrect_output_value() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -969,6 +988,7 @@ test s1_spend_fail_vote_on_gov_action_with_no_vote() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -1020,12 +1040,12 @@ fn mock_deregister_cert_tx(test_case: DeregisterCertsTestCase) -> Transaction { let output_value = if is_output_value_correct { from_lovelace( - mock_funds_controlled + mock_stake_register_deposit + mock_drep_register_deposit, + mock_funds_controlled + mock_stake_register_deposit + mock_drep_register_deposit + mock_fundraise_target, ) |> add(mock_start_hash, "", 1) } else { from_lovelace( - mock_funds_controlled + mock_stake_register_deposit + mock_drep_register_deposit - 10, + mock_funds_controlled + mock_stake_register_deposit + mock_drep_register_deposit + mock_fundraise_target - 10, ) |> add(mock_start_hash, "", 1) } @@ -1109,6 +1129,7 @@ test s1_spend_success_unregister_certs() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1145,6 +1166,7 @@ test s1_spend_fail_unregister_certs_with_more_than_one_inputed() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1181,6 +1203,7 @@ test s1_spend_fail_unregister_certs_with_more_than_one_outputed() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1217,6 +1240,7 @@ test s1_spend_fail_unregister_certs_with_output_datum_incorrect() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1253,6 +1277,7 @@ test s1_spend_fail_unregister_certs_with_output_value_not_clean() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1289,6 +1314,7 @@ test s1_spend_fail_unregister_certs_with_output_value_incorrect() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1325,6 +1351,7 @@ test s1_spend_fail_unregister_certs_with_stake_not_unregister() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1361,6 +1388,7 @@ test s1_spend_fail_unregister_certs_with_drep_not_unregister() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1397,6 +1425,7 @@ test s1_spend_fail_unregister_certs_with_deadline_not_passed() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Voted { start_hash: mock_start_hash, @@ -1528,6 +1557,7 @@ test s1_spend_success_contributor_withdraw() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1563,6 +1593,7 @@ test s1_spend_fail_contributor_withdraw_with_state_not_refundable() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Proposed { start_hash: mock_start_hash, @@ -1599,6 +1630,7 @@ test s1_spend_fail_contributor_withdraw_with_more_than_one_auth_inputed() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1634,6 +1666,7 @@ test s1_spend_fail_contributor_withdraw_with_more_than_one_auth_outputed() fail mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1669,6 +1702,7 @@ test s1_spend_fail_contributor_withdraw_with_incorrect_output_datum() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1704,6 +1738,7 @@ test s1_spend_fail_contributor_withdraw_with_auth_output_value_not_clean() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1739,6 +1774,7 @@ test s1_spend_fail_contributor_withdraw_with_incorrect_auth_unlock_value() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1809,6 +1845,7 @@ test s1_spend_fail_contributor_withdraw_with_incorrect_shares_burnt() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1910,6 +1947,7 @@ test s1_spend_success_remove_empty_instance_wih_zero_fund() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1942,6 +1980,7 @@ test s1_spend_success_remove_empty_instance_wih_some_fund() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -1974,6 +2013,7 @@ test s1_spend_fail_remove_empty_instance_wih_state_not_refundable() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Init { start_hash: mock_start_hash, @@ -2007,6 +2047,7 @@ test s1_spend_fail_remove_empty_instance_wih_more_than_one_auth_inputed() fail { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -2071,6 +2112,7 @@ test s1_spend_fail_remove_empty_instance_wih_share_not_burnt() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -2103,6 +2145,7 @@ test s1_spend_fail_remove_empty_instance_wih_token_not_burnt() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, @@ -2135,6 +2178,7 @@ test s1_spend_fail_remove_empty_instance_wih_proposer_not_signed() { mock_proposer_key_hash, mock_stake_register_deposit, mock_drep_register_deposit, + mock_fundraise_target, Some( Refundable { start_hash: mock_start_hash, From 29202a43bda0c13870a86ce174ac19c4c44935e8 Mon Sep 17 00:00:00 2001 From: twwu123 Date: Wed, 12 Nov 2025 14:44:49 +0100 Subject: [PATCH 21/24] update fee checks --- .../gov-crowdfund/lib/gov.ak | 6 ++++++ .../gov-crowdfund/validators/crowdfund.ak | 19 ++++++++++++++++--- .../intergration_test/complete_crowdfund.ak | 16 +++++++--------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak index d29db7b58..a1cf32eed 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak @@ -1,3 +1,4 @@ +use aiken/cbor use aiken/crypto.{ScriptHash} use cardano/address.{Credential} use cardano/assets.{Lovelace} @@ -79,3 +80,8 @@ pub type VGovernanceAction { } NicePoll } + +test action_test() { + trace cbor.serialise(NicePoll) + "" == "" +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak index 107f76017..7a0ad8d0b 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak @@ -1,7 +1,9 @@ use aiken/collection/list use aiken/collection/pairs.{has_key} use cardano/address.{Address, Credential, Script} -use cardano/assets.{Lovelace, PolicyId, from_lovelace, lovelace_of} +use cardano/assets.{ + Lovelace, PolicyId, from_lovelace, is_zero, lovelace_of, without_lovelace, +} use cardano/transaction.{Output, OutputReference, Transaction, find_input} use cocktail.{ inputs_at_with_policy, key_signed, only_minted_token, output_inline_datum, @@ -124,7 +126,18 @@ validator crowdfund(auth_token: PolicyId, proposer_key_hash: ByteArray) { let input_lovelace_check = lovelace_of(auth_input.output.value) >= min_charge + current_fundraised_amount - expect [_] = outputs_at_with_lovelace(outputs, fee_address, min_charge) + let fee_output_check = + when min_charge is { + 0 -> True + _ -> { + expect [fee_output] = + outputs + |> list.filter(fn(output) { output.address == fee_address }) + lovelace_of(fee_output.value) >= min_charge && ( + without_lovelace(fee_output.value) |> is_zero() + ) + } + } let fundraise_check = current_fundraised_amount >= fundraise_target let completion_script_withdrawal_credential: Credential = @@ -132,7 +145,7 @@ validator crowdfund(auth_token: PolicyId, proposer_key_hash: ByteArray) { let withdrawal_script_check = withdrawals |> has_key(completion_script_withdrawal_credential) - fundraise_check? && withdrawal_script_check? && input_lovelace_check? && policy_only_minted_token( + fee_output_check? && fundraise_check? && withdrawal_script_check? && input_lovelace_check? && policy_only_minted_token( mint, auth_token, completion_script, diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak index aae163a0c..ba6360ca6 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak @@ -5,18 +5,17 @@ use crowdfund.{ CompleteCrowdfund, ContributeFund, CrowdfundRedeemer as ACrowdfundRedeemer, } use mocktail.{ - add_redeemer, complete, mint, mock_policy_id, mock_script_hash, mock_tx_hash, - mock_utxo_ref, mocktail_tx, script_withdrawal, tx_in, tx_in_inline_datum, - tx_out, tx_out_inline_datum, + add_redeemer, complete, mint, mock_script_hash, mock_tx_hash, mock_utxo_ref, + mocktail_tx, script_withdrawal, tx_in, tx_in_inline_datum, tx_out, + tx_out_inline_datum, } use start use tests/utils.{ mock_auth_token, mock_completion_script, mock_crowdfund_address, mock_crowdfund_datum, mock_current_fundraised_amount, mock_deadline, - mock_extra_fundraised_amount, mock_fee_address, mock_fundraise_target, - mock_gov_action_period, mock_gov_address, mock_min_charge, - mock_proposer_key_hash, mock_share_token, mock_spend_script_hash, - mock_start_hash, + mock_fee_address, mock_fundraise_target, mock_gov_action_period, + mock_gov_address, mock_min_charge, mock_proposer_key_hash, mock_share_token, + mock_spend_script_hash, mock_start_hash, } use types.{Init, RMint} @@ -94,8 +93,7 @@ fn mock_complete_crowdfund_tx( |> tx_out( !is_output_to_fee_address_correct, mock_fee_address, - from_lovelace(mock_extra_fundraised_amount - 10) - |> add(mock_policy_id(999), mock_completion_script, 10), + from_lovelace(mock_min_charge - 1), ) |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) From 3f41946b1a5d1c45eeba3ac39d93878f69363e27 Mon Sep 17 00:00:00 2001 From: twwu123 Date: Thu, 13 Nov 2025 13:58:30 +0100 Subject: [PATCH 22/24] update scripts and folder names --- .../README.md | 0 .../aiken.lock | 0 .../aiken.toml | 0 .../lib/types.ak | 0 .../lib/utils.ak | 0 .../plutus.json | 0 .../specs/1_auth_token.md | 0 .../specs/2_shares.md | 0 .../specs/3_crowdfund.md | 0 .../specs/_scripts.md | 0 .../specs/application_setup_doc.md | 0 .../specs/user_action_doc.md | 0 .../validators/auth_token/mint.ak | 0 .../validators/crowdfund/spend.ak | 0 .../validators/share_token/mint.ak | 0 .../validators/tests/auth_token/mint.ak | 0 .../validators/tests/crowdfund/spend.ak | 0 .../tests/integration_test/contribute_fund.ak | 0 .../validators/tests/share_token/mint.ak | 0 .../validators/tests/utils.ak | 0 .../gov-crowdfund/plutus.json | 1076 ---------------- .../workflows/continuous-integration.yml | 0 .../.gitignore | 0 .../README.md | 0 .../aiken.lock | 0 .../aiken.toml | 0 .../lib/gov.ak | 0 .../lib/types.ak | 0 .../lib/utils.ak | 0 .../gov-extension/plutus.json | 1088 +++++++++++++++++ .../specs/1_spend.md | 0 .../specs/2_start.md | 0 .../specs/_scripts.md | 0 .../specs/user_action_doc.md | 0 .../validators/crowdfund.ak | 0 .../validators/spend.ak | 0 .../validators/start.ak | 0 .../intergration_test/complete_crowdfund.ak | 0 .../validators/tests/spend.ak | 0 .../validators/tests/start.ak | 0 .../validators/tests/utils.ak | 0 41 files changed, 1088 insertions(+), 1076 deletions(-) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/README.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/aiken.lock (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/aiken.toml (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/lib/types.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/lib/utils.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/plutus.json (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/specs/1_auth_token.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/specs/2_shares.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/specs/3_crowdfund.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/specs/_scripts.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/specs/application_setup_doc.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/specs/user_action_doc.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/auth_token/mint.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/crowdfund/spend.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/share_token/mint.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/tests/auth_token/mint.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/tests/crowdfund/spend.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/tests/integration_test/contribute_fund.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/tests/share_token/mint.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{aiken-crowdfund => base-crowdfund}/validators/tests/utils.ak (100%) delete mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/.github/workflows/continuous-integration.yml (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/.gitignore (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/README.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/aiken.lock (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/aiken.toml (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/lib/gov.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/lib/types.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/lib/utils.ak (100%) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/plutus.json rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/specs/1_spend.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/specs/2_start.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/specs/_scripts.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/specs/user_action_doc.md (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/crowdfund.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/spend.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/start.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/tests/intergration_test/complete_crowdfund.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/tests/spend.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/tests/start.ak (100%) rename packages/mesh-contract/src/crowdfund/aiken-workspace-v3/{gov-crowdfund => gov-extension}/validators/tests/utils.ak (100%) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/README.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/README.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/README.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/README.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.lock b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/aiken.lock similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.lock rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/aiken.lock diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.toml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/aiken.toml similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/aiken.toml rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/aiken.toml diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/lib/types.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/types.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/lib/types.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/lib/utils.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/lib/utils.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/lib/utils.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/plutus.json similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/plutus.json rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/plutus.json diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/1_auth_token.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/1_auth_token.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/1_auth_token.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/1_auth_token.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/2_shares.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/2_shares.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/2_shares.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/2_shares.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/3_crowdfund.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/_scripts.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/_scripts.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/_scripts.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/application_setup_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/application_setup_doc.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/application_setup_doc.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/application_setup_doc.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/user_action_doc.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/specs/user_action_doc.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/user_action_doc.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/auth_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/auth_token/mint.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/auth_token/mint.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/auth_token/mint.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/crowdfund/spend.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/crowdfund/spend.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/crowdfund/spend.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/share_token/mint.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/share_token/mint.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/share_token/mint.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/auth_token/mint.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/auth_token/mint.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/auth_token/mint.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/crowdfund/spend.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/crowdfund/spend.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/crowdfund/spend.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/integration_test/contribute_fund.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/integration_test/contribute_fund.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/integration_test/contribute_fund.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/share_token/mint.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/share_token/mint.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/share_token/mint.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/utils.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/aiken-crowdfund/validators/tests/utils.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/tests/utils.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json deleted file mode 100644 index 3c9d7328d..000000000 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/plutus.json +++ /dev/null @@ -1,1076 +0,0 @@ -{ - "preamble": { - "title": "sidan-lab/gov-crowdfund", - "description": "Aiken contracts for project 'sidan-lab/gov-crowdfund'", - "version": "0.0.0", - "plutusVersion": "v3", - "compiler": { - "name": "Aiken", - "version": "v1.1.7+e2fb28b" - }, - "license": "Apache-2.0" - }, - "validators": [ - { - "title": "crowdfund.crowdfund.spend", - "datum": { - "title": "datum_opt", - "schema": { - "$ref": "#/definitions/types~1CrowdfundDatum" - } - }, - "redeemer": { - "title": "redeemer", - "schema": { - "$ref": "#/definitions/crowdfund~1CrowdfundRedeemer" - } - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "proposer_key_hash", - "schema": { - "$ref": "#/definitions/ByteArray" - } - } - ], - "compiledCode": "59121c0101003232323232323223223225333006323232323253323300c3001300d3754004264664464646464a66602660060022a66602c602a6ea80280085854ccc04cc02000454ccc058c054dd50050010b0a99980998020008a99980b180a9baa00a00216153330133370e90030008a99980b180a9baa00a00216163013375401226464646464646464646464646464a66603e601e60406ea80044c94ccc080c040c084dd500909919191919299981418158010991919191919191919191919191919191919191919191929919981e9816803899192999821182280109919191980480089919191919192999824299982419b87006337026eb4c014c128dd500380c099b89482024bd0040185280a9998240020a9998240018a9998240010a9998240008991929998268008010a999826982800089919199911299982799b8f0030211533304f3371e004044266e1c0040345280a50375c60a20046eb8c144004dd69828982900098288009bac304f001002323300100103222533304e00114bd70099191919198008009bab3051004225333053001100313233055374e660aa6ea4014cc154c148004cc154c14c0052f5c06600600660ae00460aa0026600800860a60066eb8c134004c1400045280a5014a029405280a50303832533304b0011480004c8c034c94ccc134008520001300e33001001305000222533304e0011480004c03ccc008008c144004c138004c8cc004004dd5981398251baa00a22533304c00114bd70099191919198008009bab304f004225333051001100313233053374e660a66ea4014cc14cc140004cc14cc1440052f5c06600600660aa00460a60026600800860a20066eb8c12c004c138004cdd7802991919191816998271827802198271827801998271827801198271827800998271ba83370003401060a060a0002609e002609c002609a00260906ea8098c8c8c94ccc120c0f4c124dd50008a999824181e98249baa304d304e0021337106eb4c134c128dd500080b099b89375a609a60946ea8004058528182600099825182580099825199823181d98239baa304b304c0014c0103d87a80004c0103d87980004bd7018239baa304a304b3047375405664a66608a02829444cdc480080b1bad30013046375400646092609460946094609400266e0400800cc94ccc108c0ccc10cdd50008982398221baa0011630463047304730433754006600a6eacc07cc108dd500118021bab301e30413754603c60826ea806c58c10c004c8cc00400409c894ccc10800452f5c026644a666082a66608266ebcc118c10cdd500100f8991980080099198008009bab304830493045375400844a66608e002297ae0132323232330010013756609400844a66609800220062646609c6e9ccc138dd4802998271825800998271826000a5eb80cc00c00cc140008c138004cc010010c13000cdd7182300098248009129998230008a501332253330453371e6eb8c12800810c5288998020020009bac3048001304900114a026608a004660080080022660080080026088002608a0022a6466607c6066010264a666084608a646600200205244a666088002297ae013322533304353330433375e6044608a6ea8008dd3299982198198070a5eb7bdb1804c8c8cc0040052f5bded8c044a66609200226609466ec13001014000374c00697adef6c60132333222533304a3372091010000313304e337609801014000374c00e00a2a666094602000626609c66ec13001014000374c00e00226609c66ec0dd48019ba600233006006001375c60900026eacc124004c134008c12c004c8cc0040052f5bded8c044a66609000226609266ec13001014000375002097adef6c6013233322253330493372091010000313304d337609801014000375002800a2a666092601e00626609a66ec13001014000375002800226609a66ec0dd48019ba800233006006001375c608e0026eb4c120004c130008c1280044cdd7981398229baa00200f14a026608e00466008008002266008008002608c002608e002264a66608066e2404404054ccc10000454ccc1000084c8c94ccc11400400854ccc114c1200044c8cc894ccc114cdc780100c098040008a50375c60900026eb4c120c124004c120dd61823800801191980080099198008008159129998238008a5eb804c8c8c8c8cc004004dd598250021129998260008801899198271ba73304e375200a6609c60960026609c609800297ae0330030033050002304e00133004004304c003375c608c002609200244a66608c002297ae01332253330453371e6eb8c12800810c4cc124dd3801198020020008998020020009bac3048001304900114a029405280a5032323300100102822533304500114a026644a66608866ebc01400852889980200200098219823800982400099ba548008cc10cdd480925eb8058cdc499b8000900e30033756603a60806ea8c074c100dd500d0a99981f181780409919191929998229824001099191919806000899192999823a9998238048a51100815333047004153330470021533304700113232533304c0010021533304c304f00113232333222533304e3371e0060402a66609c66e3c0080844cdc38008060a5014a06eb8c140008dd718280009bad3050305100130500013758609c002004646600200206244a66609a002297ae013232323233001001375660a000844a6660a40022006264660a86e9ccc150dd48029982a18288009982a1829000a5eb80cc00c00cc158008c150004cc010010c14800cdd7182600098278008a5014a029405280a50303732533304a0011480004c8c030c94ccc130008520001300d33001001304f00222533304d0011480004c038cc008008c140004c134004c8cc004004dd5981318249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd7800991919191816198269827002198269827001998269827001198269827000998269ba83370003200e609e609e002609c002609a0026098002608e6ea8094c94ccc114c0d8c118dd50008982518239baa001163049304a304a3046375400666e20005200033702600e6eacc084c110dd500098039bab302130443754604260886ea807858c118004c8cc0040040a8894ccc11400452f5c026644a666088a66608866ebcc124c118dd50010110991980080099198008009bab304b304c3048375400844a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a501332253330483371e6eb8c1340081185288998020020009bac304b001304c00114a026609000466008008002266008008002608e002609000266e2403c040c8c8c8c94ccc108c0dcc10cdd50008a999821181b98219baa304730480021337100086eb4c11cc110dd5000899b89004375a608e60886ea8004528182300099822182280099822199820181a98209baa304530460014c103d87a80004c0103d87980004bd7018209baa30443041375404a66e0003002c4c8c94ccc100c8c8c94ccc10cc0e0c110dd50008a999821981c18221baa304830490021337100226eb4c120c114dd5000899b89011375a6090608a6ea8004528182380099822982300099822999820981b18211baa304630470014c0103d87a80004c0103d87980004bd7018211baa30453042375404c2a6660800042002294052819198008008129129998220008a501332253330433371e00407e29444cc010010004dd718230009823800a99981f19b884800003854ccc0f8c8c8c94ccc11000400854ccc110c11c0044c8cc894ccc110cdc780100b899b8700100614a06eb8c11c004dd69823982400098239bac30460010023233001001323300100102a22533304600114bd70099191919198008009bab304900422533304b00110031323304d374e6609a6ea4014cc134c128004cc134c12c0052f5c066006006609e004609a0026600800860960066eb8c114004c120004894ccc11400452f5c026644a66608866e3cdd7182480100b0998241ba7002330040040011330040040013758608e00260900022940cdc0a400001c26464a6660860020042a666086608c0022646644a66608666e3c0080584c0180045281bae3046001375a608c608e002608c6eb0c114004008c8cc004004c8cc0040040a4894ccc11400452f5c0264646464660020026eacc120010894ccc128004400c4c8cc130dd3998261ba90053304c30490013304c304a0014bd7019801801982700118260009980200218250019bae3044001304700122533304400114bd7009991299982199b8f375c609000408226608e6e9c008cc0100100044cc010010004dd6182300098238008a5014a026464a6660860020042a666086608c00226464666444a66608a66e3c00c10c54ccc114cdc780100c098040008a5014a06eb8c11c008dd718238009bad3047304800130470013758608a002004646600200205044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230008a50370e90009b80480088c94ccc0f4c0c8c0f8dd50008a400026eb4c108c0fcdd500099299981e9819181f1baa00114c0103d87a8000132330010013756608660806ea8008894ccc108004530103d87a8000132333222533304333722911000031533304330090031302633047375000497ae014c103d87a8000133006006001375c60820026eb4c108004c118008c110004c8cc004004008894ccc1040045300103d87a8000132333222533304233722911000031533304230080031302533046374c00497ae014c103d87a8000133006006001375c60800026eacc104004c114008c10c004dc7a450022533303b302b303c375400426464646464646464646464646464646464646464a6660a460aa00426602e01e26602e00602a2c6eb4c14c004c14c008c144004c144008dd6982780098278011bad304d001304d00232533304a30490011533304733712900218240008b0981e18240008b1baa304b001304b002375a609200260920046eb4c11c004c11c008c114004c114008dd7182180098218011bae3041001303d37540042c44a666074605460766ea80084c8c8c8c94ccc104c1100084cc01c00c4c94ccc0fcc0bc0044c8c94ccc110c11c0084c94ccc108c0c80044c8c94ccc11cc1280084cc03400402c58c120004c110dd50010a999821181b8008991919191919299982598270010078b1bad304c001304c002375a609400260940046eb4c120004c110dd50010b18211baa001163045001304137540042a66607e60680022a66608460826ea80080185858c0fcdd50008b182100098210011820000981e1baa002162232533303a302a00113232533303f304200200416375c608000260786ea800c54ccc0e8c0bc0044c8c94ccc0fcc10800801058dd71820000981e1baa00316303a3754004606e6ea80b4dd6981d181d804981c8041bad3038008375a606e010604c60646ea8c0d8020dd6981a8041bad3034008375c60660106eb8c0c8020c0c8004c0c4004c0c0004c0bc004c0b8004c0b4c0b4004c0b0004c09cdd50028b181480099198008008071129998140008a5eb804cc894ccc09d4ccc09ccdd7981618149baa302c302d3029375400400a2646600200264660020026eacc0b8c0bcc0acdd51817181798159baa00422533302d00114bd70099191919198008009bab3030004225333032001100313233034374e660686ea4014cc0d0c0c4004cc0d0c0c80052f5c066006006606c00460680026600800860640066eb8c0b0004c0bc004894ccc0b000452809991299981599b8f375c606000405229444cc010010004dd6181700098178008a5013302b00233004004001133004004001302a001302b001300630243754600260486ea800c8c09cc0a0004c094c088dd50090b181218109baa00116323300100100922533302300114c103d87a80001332253330223375e600c60486ea80080544c014cc0980092f5c0266008008002604a002604c0026e9520002302200137586040604200c603e00a6eacc078014dd5980e8029bac301c0053758603600a603600260346034002603260320026030603000260266ea8024dc3a40006e1d2004301200130123013001300e37540046e1d200216300f3010003300e002300d002300d0013008375400229309b2b1bae001375c002ae6955ceaab9e5573eae815d0aba201", - "hash": "c0f352bf5856e696038a0449a91382f35ba4a5741946736ca1480382" - }, - { - "title": "crowdfund.crowdfund.else", - "redeemer": { - "schema": {} - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "proposer_key_hash", - "schema": { - "$ref": "#/definitions/ByteArray" - } - } - ], - "compiledCode": "59121c0101003232323232323223223225333006323232323253323300c3001300d3754004264664464646464a66602660060022a66602c602a6ea80280085854ccc04cc02000454ccc058c054dd50050010b0a99980998020008a99980b180a9baa00a00216153330133370e90030008a99980b180a9baa00a00216163013375401226464646464646464646464646464a66603e601e60406ea80044c94ccc080c040c084dd500909919191919299981418158010991919191919191919191919191919191919191919191929919981e9816803899192999821182280109919191980480089919191919192999824299982419b87006337026eb4c014c128dd500380c099b89482024bd0040185280a9998240020a9998240018a9998240010a9998240008991929998268008010a999826982800089919199911299982799b8f0030211533304f3371e004044266e1c0040345280a50375c60a20046eb8c144004dd69828982900098288009bac304f001002323300100103222533304e00114bd70099191919198008009bab3051004225333053001100313233055374e660aa6ea4014cc154c148004cc154c14c0052f5c06600600660ae00460aa0026600800860a60066eb8c134004c1400045280a5014a029405280a50303832533304b0011480004c8c034c94ccc134008520001300e33001001305000222533304e0011480004c03ccc008008c144004c138004c8cc004004dd5981398251baa00a22533304c00114bd70099191919198008009bab304f004225333051001100313233053374e660a66ea4014cc14cc140004cc14cc1440052f5c06600600660aa00460a60026600800860a20066eb8c12c004c138004cdd7802991919191816998271827802198271827801998271827801198271827800998271ba83370003401060a060a0002609e002609c002609a00260906ea8098c8c8c94ccc120c0f4c124dd50008a999824181e98249baa304d304e0021337106eb4c134c128dd500080b099b89375a609a60946ea8004058528182600099825182580099825199823181d98239baa304b304c0014c0103d87a80004c0103d87980004bd7018239baa304a304b3047375405664a66608a02829444cdc480080b1bad30013046375400646092609460946094609400266e0400800cc94ccc108c0ccc10cdd50008982398221baa0011630463047304730433754006600a6eacc07cc108dd500118021bab301e30413754603c60826ea806c58c10c004c8cc00400409c894ccc10800452f5c026644a666082a66608266ebcc118c10cdd500100f8991980080099198008009bab304830493045375400844a66608e002297ae0132323232330010013756609400844a66609800220062646609c6e9ccc138dd4802998271825800998271826000a5eb80cc00c00cc140008c138004cc010010c13000cdd7182300098248009129998230008a501332253330453371e6eb8c12800810c5288998020020009bac3048001304900114a026608a004660080080022660080080026088002608a0022a6466607c6066010264a666084608a646600200205244a666088002297ae013322533304353330433375e6044608a6ea8008dd3299982198198070a5eb7bdb1804c8c8cc0040052f5bded8c044a66609200226609466ec13001014000374c00697adef6c60132333222533304a3372091010000313304e337609801014000374c00e00a2a666094602000626609c66ec13001014000374c00e00226609c66ec0dd48019ba600233006006001375c60900026eacc124004c134008c12c004c8cc0040052f5bded8c044a66609000226609266ec13001014000375002097adef6c6013233322253330493372091010000313304d337609801014000375002800a2a666092601e00626609a66ec13001014000375002800226609a66ec0dd48019ba800233006006001375c608e0026eb4c120004c130008c1280044cdd7981398229baa00200f14a026608e00466008008002266008008002608c002608e002264a66608066e2404404054ccc10000454ccc1000084c8c94ccc11400400854ccc114c1200044c8cc894ccc114cdc780100c098040008a50375c60900026eb4c120c124004c120dd61823800801191980080099198008008159129998238008a5eb804c8c8c8c8cc004004dd598250021129998260008801899198271ba73304e375200a6609c60960026609c609800297ae0330030033050002304e00133004004304c003375c608c002609200244a66608c002297ae01332253330453371e6eb8c12800810c4cc124dd3801198020020008998020020009bac3048001304900114a029405280a5032323300100102822533304500114a026644a66608866ebc01400852889980200200098219823800982400099ba548008cc10cdd480925eb8058cdc499b8000900e30033756603a60806ea8c074c100dd500d0a99981f181780409919191929998229824001099191919806000899192999823a9998238048a51100815333047004153330470021533304700113232533304c0010021533304c304f00113232333222533304e3371e0060402a66609c66e3c0080844cdc38008060a5014a06eb8c140008dd718280009bad3050305100130500013758609c002004646600200206244a66609a002297ae013232323233001001375660a000844a6660a40022006264660a86e9ccc150dd48029982a18288009982a1829000a5eb80cc00c00cc158008c150004cc010010c14800cdd7182600098278008a5014a029405280a50303732533304a0011480004c8c030c94ccc130008520001300d33001001304f00222533304d0011480004c038cc008008c140004c134004c8cc004004dd5981318249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd7800991919191816198269827002198269827001998269827001198269827000998269ba83370003200e609e609e002609c002609a0026098002608e6ea8094c94ccc114c0d8c118dd50008982518239baa001163049304a304a3046375400666e20005200033702600e6eacc084c110dd500098039bab302130443754604260886ea807858c118004c8cc0040040a8894ccc11400452f5c026644a666088a66608866ebcc124c118dd50010110991980080099198008009bab304b304c3048375400844a666094002297ae0132323232330010013756609a00844a66609e0022006264660a26e9ccc144dd4802998289827000998289827800a5eb80cc00c00cc14c008c144004cc010010c13c00cdd7182480098260009129998248008a501332253330483371e6eb8c1340081185288998020020009bac304b001304c00114a026609000466008008002266008008002608e002609000266e2403c040c8c8c8c94ccc108c0dcc10cdd50008a999821181b98219baa304730480021337100086eb4c11cc110dd5000899b89004375a608e60886ea8004528182300099822182280099822199820181a98209baa304530460014c103d87a80004c0103d87980004bd7018209baa30443041375404a66e0003002c4c8c94ccc100c8c8c94ccc10cc0e0c110dd50008a999821981c18221baa304830490021337100226eb4c120c114dd5000899b89011375a6090608a6ea8004528182380099822982300099822999820981b18211baa304630470014c0103d87a80004c0103d87980004bd7018211baa30453042375404c2a6660800042002294052819198008008129129998220008a501332253330433371e00407e29444cc010010004dd718230009823800a99981f19b884800003854ccc0f8c8c8c94ccc11000400854ccc110c11c0044c8cc894ccc110cdc780100b899b8700100614a06eb8c11c004dd69823982400098239bac30460010023233001001323300100102a22533304600114bd70099191919198008009bab304900422533304b00110031323304d374e6609a6ea4014cc134c128004cc134c12c0052f5c066006006609e004609a0026600800860960066eb8c114004c120004894ccc11400452f5c026644a66608866e3cdd7182480100b0998241ba7002330040040011330040040013758608e00260900022940cdc0a400001c26464a6660860020042a666086608c0022646644a66608666e3c0080584c0180045281bae3046001375a608c608e002608c6eb0c114004008c8cc004004c8cc0040040a4894ccc11400452f5c0264646464660020026eacc120010894ccc128004400c4c8cc130dd3998261ba90053304c30490013304c304a0014bd7019801801982700118260009980200218250019bae3044001304700122533304400114bd7009991299982199b8f375c609000408226608e6e9c008cc0100100044cc010010004dd6182300098238008a5014a026464a6660860020042a666086608c00226464666444a66608a66e3c00c10c54ccc114cdc780100c098040008a5014a06eb8c11c008dd718238009bad3047304800130470013758608a002004646600200205044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230008a50370e90009b80480088c94ccc0f4c0c8c0f8dd50008a400026eb4c108c0fcdd500099299981e9819181f1baa00114c0103d87a8000132330010013756608660806ea8008894ccc108004530103d87a8000132333222533304333722911000031533304330090031302633047375000497ae014c103d87a8000133006006001375c60820026eb4c108004c118008c110004c8cc004004008894ccc1040045300103d87a8000132333222533304233722911000031533304230080031302533046374c00497ae014c103d87a8000133006006001375c60800026eacc104004c114008c10c004dc7a450022533303b302b303c375400426464646464646464646464646464646464646464a6660a460aa00426602e01e26602e00602a2c6eb4c14c004c14c008c144004c144008dd6982780098278011bad304d001304d00232533304a30490011533304733712900218240008b0981e18240008b1baa304b001304b002375a609200260920046eb4c11c004c11c008c114004c114008dd7182180098218011bae3041001303d37540042c44a666074605460766ea80084c8c8c8c94ccc104c1100084cc01c00c4c94ccc0fcc0bc0044c8c94ccc110c11c0084c94ccc108c0c80044c8c94ccc11cc1280084cc03400402c58c120004c110dd50010a999821181b8008991919191919299982598270010078b1bad304c001304c002375a609400260940046eb4c120004c110dd50010b18211baa001163045001304137540042a66607e60680022a66608460826ea80080185858c0fcdd50008b182100098210011820000981e1baa002162232533303a302a00113232533303f304200200416375c608000260786ea800c54ccc0e8c0bc0044c8c94ccc0fcc10800801058dd71820000981e1baa00316303a3754004606e6ea80b4dd6981d181d804981c8041bad3038008375a606e010604c60646ea8c0d8020dd6981a8041bad3034008375c60660106eb8c0c8020c0c8004c0c4004c0c0004c0bc004c0b8004c0b4c0b4004c0b0004c09cdd50028b181480099198008008071129998140008a5eb804cc894ccc09d4ccc09ccdd7981618149baa302c302d3029375400400a2646600200264660020026eacc0b8c0bcc0acdd51817181798159baa00422533302d00114bd70099191919198008009bab3030004225333032001100313233034374e660686ea4014cc0d0c0c4004cc0d0c0c80052f5c066006006606c00460680026600800860640066eb8c0b0004c0bc004894ccc0b000452809991299981599b8f375c606000405229444cc010010004dd6181700098178008a5013302b00233004004001133004004001302a001302b001300630243754600260486ea800c8c09cc0a0004c094c088dd50090b181218109baa00116323300100100922533302300114c103d87a80001332253330223375e600c60486ea80080544c014cc0980092f5c0266008008002604a002604c0026e9520002302200137586040604200c603e00a6eacc078014dd5980e8029bac301c0053758603600a603600260346034002603260320026030603000260266ea8024dc3a40006e1d2004301200130123013001300e37540046e1d200216300f3010003300e002300d002300d0013008375400229309b2b1bae001375c002ae6955ceaab9e5573eae815d0aba201", - "hash": "c0f352bf5856e696038a0449a91382f35ba4a5741946736ca1480382" - }, - { - "title": "spend.spend.spend", - "datum": { - "title": "datum_opt", - "schema": { - "$ref": "#/definitions/types~1CrowdfundGovDatum" - } - }, - "redeemer": { - "title": "redeemer", - "schema": { - "$ref": "#/definitions/types~1CrowdfundRedeemer" - } - }, - "parameters": [ - { - "title": "delegate_pool_id", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action", - "schema": { - "$ref": "#/definitions/gov~1VGovernanceAction" - } - }, - { - "title": "proposer_key_hash", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "stake_register_deposit", - "schema": { - "$ref": "#/definitions/Lovelace" - } - }, - { - "title": "drep_register_deposit", - "schema": { - "$ref": "#/definitions/Lovelace" - } - } - ], - "compiledCode": "591a430101003232323232323223222322322322533300b323232323253323301130013012375400426466446464646464a66603260080022a66603860366ea802c0085854ccc064c02400454ccc070c06cdd50058010b0a99980c98028008a99980e180d9baa00b002161533301930030011533301c301b37540160042c2a66603266e1d20080011533301c301b37540160042c2c60326ea80284c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0a4c050c0a8dd50008992999815180a98159baa0171323232323232323232325323232333037302200a1533303730223038375401a2646464666644446464a666086608c004264a666082605860846ea80044c94ccc108c0b4c10cdd5000899191929998241825801099191980c800899191919191929998268040a9998268030a9998268028a9998268020a9998268018a99982680108008a5014a029405280a5014a064607a646600200205244a6660a400229000099912999828a99982899b87375a605660a66ea80092080a0b787e905153330513375e604c60a66ea80080144cdc79bb3305630573057305337540046ecc1385280a501301b001100130540013300200230550013026304e3754040a666096a66609666030054602e6609e0126609e602c6609e60486609e01297ae04bd7025eb804cc0600a8c05ccc13c024cc13cc090cc13cdd4824a5eb812f5c0294052889980c015180b9982780499827980b998279ba90493304f30243304f0094bd7025eb812f5c06602e05266e9520083304e0083304e375008297ae03301602830223304d0073304d4c103d87a80004bd70181a1929998260008a4000264602864a66609c004290000980a9980080098288011129998278008a40002602c6600400460a4002609e00264660020026eacc078c12cdd50029129998268008a5eb804c8c8c8c8cc004004dd5982800211299982900088018991982a1ba733054375200a660a860a2002660a860a400297ae03300300330560023054001330040043052003375c6098002609e00266ebc004c048cc12cdd4806998259ba900c3304b3750016660966ea00292f5c064a66608e606660906ea80044c130c124dd50008b18259826182618241baa00233301300600133702900019b803370007c0789040505bc3f4828b182480099198008008129129998240008a5eb804cc894ccc11d4ccc11ccdd7982618249baa00201b130373253330483038304937540022900009bad304d304a375400264a666090607060926ea80045300103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e301f0031533304e301e0031302733052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c098cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c1380045280998258011980200200089980200200098250009825800982398221baa001163046304337540022c602a60846ea805058c110004c8cc004004084894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd51823982418221baa002016130323253330433033304437540022900009bad30483045375400264a666086606660886ea80045300103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e604e0142a66606e604e60706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c8c94ccc114c1200084c8c8cc0580044c8c8c94ccc11c01454ccc11c00854ccc11c0044c8c94ccc124c0d0c128dd50008999119198008008019129998280008a5013322533304f3375e6e98cc14c0092f5bded8c06e98cc14c0152f5bded8c029444cc010010004c148004c14c004dd5982718259baa0013376000a980103d87a800016323300100102522533304d00114c0103d87a8000132333222533304e3375e00e0062604e660a46e980092f5c026600c00c00260980026eacc134004c144008c13c004c048cc12cc048cc12cdd4806a5eb812f5c029405280a50303232533304a0011480004c8c048c94ccc130008520001301333001001304f00222533304d0011480004c050cc008008c140004c134004c8cc004004dd5980e18249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd78011808998249ba900b330493752014660926ea0024cc124004cc124dd400425eb80c074cc120c078c118dd5180f18231baa01b330484c010100004bd70192999822181818229baa00113049304637540022c609060926092608a6ea8008cdd7980b98221baa301730443754006602e60886ea800458c118004c8cc004004088894ccc11400452f5c026644a666088a66608866ebcc124c118dd500100c0981a192999822981a98231baa0011480004dd6982518239baa0013253330453035304637540022980103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b301c0031533304b301b003130243304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00322533304900114c103d87a8000132333222533304a337220200062a66609466e3c04000c4c08ccc138dd300125eb80530103d87a8000133006006001375c60900026eacc124004c134008c12c00452809982400119802002000899802002000982380098240008b182200099198008008109129998218008a5eb804cc894ccc1094ccc108cdd7982398221baa304730483044375400402c2606464a666086606660886ea8004520001375a6090608a6ea8004c94ccc10cc0ccc110dd50008a6103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e60460142a66606e604660706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c94ccc104c0b0c108dd50008992999821181698219baa0011323232325333049304c002132323301a001132323232533304c0091533304c0061533304c0041533304c0031533304c002100114a029405280a5014a0606e64a66609e00229000099180b9929998288010a4000260306600200260a800444a6660a4002290000980c99801001182a800982900099198008009bab3021304e375400e44a6660a0002297ae013232323233001001375660a600844a6660aa0022006264660ae6e9ccc15cdd48029982b982a0009982b982a800a5eb80cc00c00cc164008c15c004cc010010c15400cdd7182780098290009980b81499ba548030cc138020cc138dd4020a5eb80cc0580a0c050cc13401ccc13530103d87a80004bd7019baf0013374a9003198261ba900e3304c375201a660986ea00312f5c064a666090606860926ea80044c134c128dd50008b18261826982698249baa0023330140070013370007e07a2c6094002646600200204c44a666092002297ae013322533304853330483375e609a60946ea80080704c0e0c94ccc124c0e4c128dd50008a400026eb4c138c12cdd5000992999824981c98251baa00114c0103d87a8000132330010013756609e60986ea8008894ccc138004530103d87a8000132333222533304f30200031533304f301f0031302833053375000497ae014c103d87a8000133006006001375c609a0026eb4c138004c148008c140004c8cc004004dd59827182798259baa00322533304d00114c103d87a8000132333222533304e337220280062a66609c66e3c05000c4c09ccc148dd300125eb80530103d87a8000133006006001375c60980026eacc134004c144008c13c00452809982600119802002000899802002000982580098260009919192999823181b18239baa0011533304630363047375460966098004266e20024dd6982598241baa0011337120126eb4c12cc120dd50008a50304a001330483049001330483330443034304537546092609400298103d87a80004c0103d87980004bd7018229baa304830453754042608e60886ea800458c118c10cdd50008b180a98211baa014163044001323300100102122533304300114bd70099912999821299982119baf304730443754608e609060886ea80080584c0c8c94ccc10cc0ccc110dd50008a400026eb4c120c114dd5000992999821981998221baa00114c0103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f98201820000981f800981f000981c9baa00d14a02a66606e60420142a66606e604260706ea80344c8c8ccc888c8c94ccc104c1100084c8c94ccc10cc1180084c8c8c8cc0540044c8c94ccc11401054ccc11400854ccc1140044c8c94ccc12800400854ccc128c1340044c8c8ccc8894ccc130cdc78018090a99982619b8f00201313370e00201829405281bae304e002375c609c0026eb4c138c13c004c138004dd6182600080119198008008139129998258008a5eb804c8c8c8c8cc004004dd598270021129998280008801899198291ba733052375200a660a4609e002660a460a000297ae03300300330540023052001330040043050003375c6094002609a00229405280a5014a0606064a6660900022900009918081929998250010a40002602266002002609a00444a6660960022900009809198010011827000982580099198008009bab301a3047375400c44a666092002297ae0132323232330010013756609800844a66609c0022006264660a06e9ccc140dd4802998281826800998281827000a5eb80cc00c00cc148008c140004cc010010c13800cdd71824000982580099baf0013374a9003198239ba900a3304737520126608e6ea0cdc0004001a5eb80c94ccc10cc0bcc110dd50008982418229baa001163047304830483044375400666e20005200033702601e6eacc054c108dd500098079bab301530423754602a60846ea800c58c110004c8cc004004080894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd500100b09819192999821981998221baa0011480004dd6982418229baa001325333043303330443754002298103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa00322533304700114c103d87a800013233322253330483372201e0062a66609066e3c03c00c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230008b1821000991980080080f9129998208008a5eb804cc894ccc1014ccc100cdd7982298211baa30453046304237540040282606064a666082606260846ea8004520001375a608c60866ea8004c94ccc104c0c4c108dd50008a6103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c00452809982200119802002000899802002000982180098220009bae303e002375c607c0026eb4c0f8c0fc004c0f8004c0e4dd50068a501533303730213038375401a26464666444a66607e6084646600200203e44a666082002297ae013322533304053330403375e608a60846ea8c114c118c108dd500100a09818192999820981898211baa0011480004dd6982318219baa001325333041303130423754002298103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c0045280998220011980200200089980200200098218009822000899299981ea99981e99b88480000084c8c8c94ccc10c00400854ccc10cc1180044c8cc894ccc10ccdc7801005099b8700100614a06eb8c118004dd69823182380098231bac30450010023233001001323300100102122533304500114bd70099191919198008009bab304800422533304a00110031323304c374e660986ea4014cc130c124004cc130c1280052f5c066006006609c00460980026600800860940066eb8c110004c11c004894ccc11000452f5c026644a66608666e3cdd718240010048998239ba7002330040040011330040040013758608c002608e0022940cdc0a4000004294454ccc0f40044c8c94ccc10800400854ccc108c1140044c8cc894ccc108c0480084cdc3800a40022940dd718228009bad304530460013045375860880020046466002002646600200204044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230009129998218008a5eb804cc894ccc108cdc79bae3047002009133046374e004660080080022660080080026eb0c114004c1180045280a5014a0646600200203444a66608200229404cc894ccc100cdc780101d8a51133004004001375c608600260880022c6eb8c0f8008dd7181f0009bad303e303f001303e0013039375401a2940dc0240046e952002374a900211191980080080191299981d0008a501332253330393375e00400a29444cc010010004c0f0004c0f4004888cdc399b81300437566014606e6ea8008c010dd59805181b9baa300a30373754006002464a666066604660686ea8004520001375a6070606a6ea8004c94ccc0ccc08cc0d0dd50008a60103d87a80001323300100137566072606c6ea8008894ccc0e0004530103d87a80001323332225333039300a003153330393009003130123303d375000497ae014c103d87a8000133006006001375c606e0026eb4c0e0004c0f0008c0e8004c8cc004004008894ccc0dc0045300103d87a800013233322253330383009003153330383008003130113303c374c00497ae014c103d87a8000133006006001375c606c0026eacc0dc004c0ec008c0e4004dc7a4500372291010022325333031301c00113232323232323232533303c303f00200a16375a607a002607a0046eb4c0ec004c0ec008dd7181c800981c8011bae3037001303337540062a666062604200226464646464646464a666078607e0040142c6eb4c0f4004c0f4008dd6981d800981d8011bae30390013039002375c606e00260666ea800c54ccc0c4c0740044c8c8c8c8c8c8c8c8c8c94ccc0f8c10400854ccc0ecc098c0f0dd5001899191919299982118228010080b1bad30430013043002375c6082002607a6ea800c5858dd6981f800981f801181e800981e8011bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018a999818980d8008991919191919299981d181e8010040b1bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018b18189baa002302e375403e600c605c6ea8c004c0b8dd5001918189819000981798161baa01716302e302b37540022c646600200201644a66605a002298103d87a800013322533302c3375e600c605c6ea80080684c014cc0c00092f5c0266008008002605e00260600026e9520002302c0013758605460560106eacc0a401cdd6181400398138039bac30260073756604a00e6eb0c09001cdd6181180398119811981198118009811000981098108009810000980f980f800980f180f000980c9baa00a370e90031b8748000dc3a4008602e002602e603000260266ea8008dc3a40042c6028602a006602600460240046024002601a6ea800452613656375a0026eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d11", - "hash": "b77e4f80ee4d5887de1f3954470f392f455198ff4372c4c7d0d6480c" - }, - { - "title": "spend.spend.else", - "redeemer": { - "schema": {} - }, - "parameters": [ - { - "title": "delegate_pool_id", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action", - "schema": { - "$ref": "#/definitions/gov~1VGovernanceAction" - } - }, - { - "title": "proposer_key_hash", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "stake_register_deposit", - "schema": { - "$ref": "#/definitions/Lovelace" - } - }, - { - "title": "drep_register_deposit", - "schema": { - "$ref": "#/definitions/Lovelace" - } - } - ], - "compiledCode": "591a430101003232323232323223222322322322533300b323232323253323301130013012375400426466446464646464a66603260080022a66603860366ea802c0085854ccc064c02400454ccc070c06cdd50058010b0a99980c98028008a99980e180d9baa00b002161533301930030011533301c301b37540160042c2a66603266e1d20080011533301c301b37540160042c2c60326ea80284c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0a4c050c0a8dd50008992999815180a98159baa0171323232323232323232325323232333037302200a1533303730223038375401a2646464666644446464a666086608c004264a666082605860846ea80044c94ccc108c0b4c10cdd5000899191929998241825801099191980c800899191919191929998268040a9998268030a9998268028a9998268020a9998268018a99982680108008a5014a029405280a5014a064607a646600200205244a6660a400229000099912999828a99982899b87375a605660a66ea80092080a0b787e905153330513375e604c60a66ea80080144cdc79bb3305630573057305337540046ecc1385280a501301b001100130540013300200230550013026304e3754040a666096a66609666030054602e6609e0126609e602c6609e60486609e01297ae04bd7025eb804cc0600a8c05ccc13c024cc13cc090cc13cdd4824a5eb812f5c0294052889980c015180b9982780499827980b998279ba90493304f30243304f0094bd7025eb812f5c06602e05266e9520083304e0083304e375008297ae03301602830223304d0073304d4c103d87a80004bd70181a1929998260008a4000264602864a66609c004290000980a9980080098288011129998278008a40002602c6600400460a4002609e00264660020026eacc078c12cdd50029129998268008a5eb804c8c8c8c8cc004004dd5982800211299982900088018991982a1ba733054375200a660a860a2002660a860a400297ae03300300330560023054001330040043052003375c6098002609e00266ebc004c048cc12cdd4806998259ba900c3304b3750016660966ea00292f5c064a66608e606660906ea80044c130c124dd50008b18259826182618241baa00233301300600133702900019b803370007c0789040505bc3f4828b182480099198008008129129998240008a5eb804cc894ccc11d4ccc11ccdd7982618249baa00201b130373253330483038304937540022900009bad304d304a375400264a666090607060926ea80045300103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e301f0031533304e301e0031302733052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c098cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c1380045280998258011980200200089980200200098250009825800982398221baa001163046304337540022c602a60846ea805058c110004c8cc004004084894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd51823982418221baa002016130323253330433033304437540022900009bad30483045375400264a666086606660886ea80045300103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e604e0142a66606e604e60706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c8c94ccc114c1200084c8c8cc0580044c8c8c94ccc11c01454ccc11c00854ccc11c0044c8c94ccc124c0d0c128dd50008999119198008008019129998280008a5013322533304f3375e6e98cc14c0092f5bded8c06e98cc14c0152f5bded8c029444cc010010004c148004c14c004dd5982718259baa0013376000a980103d87a800016323300100102522533304d00114c0103d87a8000132333222533304e3375e00e0062604e660a46e980092f5c026600c00c00260980026eacc134004c144008c13c004c048cc12cc048cc12cdd4806a5eb812f5c029405280a50303232533304a0011480004c8c048c94ccc130008520001301333001001304f00222533304d0011480004c050cc008008c140004c134004c8cc004004dd5980e18249baa00622533304b00114bd70099191919198008009bab304e004225333050001100313233052374e660a46ea4014cc148c13c004cc148c1400052f5c06600600660a800460a40026600800860a00066eb8c128004c134004cdd78011808998249ba900b330493752014660926ea0024cc124004cc124dd400425eb80c074cc120c078c118dd5180f18231baa01b330484c010100004bd70192999822181818229baa00113049304637540022c609060926092608a6ea8008cdd7980b98221baa301730443754006602e60886ea800458c118004c8cc004004088894ccc11400452f5c026644a666088a66608866ebcc124c118dd500100c0981a192999822981a98231baa0011480004dd6982518239baa0013253330453035304637540022980103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b301c0031533304b301b003130243304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00322533304900114c103d87a8000132333222533304a337220200062a66609466e3c04000c4c08ccc138dd300125eb80530103d87a8000133006006001375c60900026eacc124004c134008c12c00452809982400119802002000899802002000982380098240008b182200099198008008109129998218008a5eb804cc894ccc1094ccc108cdd7982398221baa304730483044375400402c2606464a666086606660886ea8004520001375a6090608a6ea8004c94ccc10cc0ccc110dd50008a6103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f9820000981f800981f000981c9baa00d14a02a66606e60460142a66606e604660706ea80344c8c8c8cccc8888c8c94ccc10cc1180084c94ccc104c0b0c108dd50008992999821181698219baa0011323232325333049304c002132323301a001132323232533304c0091533304c0061533304c0041533304c0031533304c002100114a029405280a5014a0606e64a66609e00229000099180b9929998288010a4000260306600200260a800444a6660a4002290000980c99801001182a800982900099198008009bab3021304e375400e44a6660a0002297ae013232323233001001375660a600844a6660aa0022006264660ae6e9ccc15cdd48029982b982a0009982b982a800a5eb80cc00c00cc164008c15c004cc010010c15400cdd7182780098290009980b81499ba548030cc138020cc138dd4020a5eb80cc0580a0c050cc13401ccc13530103d87a80004bd7019baf0013374a9003198261ba900e3304c375201a660986ea00312f5c064a666090606860926ea80044c134c128dd50008b18261826982698249baa0023330140070013370007e07a2c6094002646600200204c44a666092002297ae013322533304853330483375e609a60946ea80080704c0e0c94ccc124c0e4c128dd50008a400026eb4c138c12cdd5000992999824981c98251baa00114c0103d87a8000132330010013756609e60986ea8008894ccc138004530103d87a8000132333222533304f30200031533304f301f0031302833053375000497ae014c103d87a8000133006006001375c609a0026eb4c138004c148008c140004c8cc004004dd59827182798259baa00322533304d00114c103d87a8000132333222533304e337220280062a66609c66e3c05000c4c09ccc148dd300125eb80530103d87a8000133006006001375c60980026eacc134004c144008c13c00452809982600119802002000899802002000982580098260009919192999823181b18239baa0011533304630363047375460966098004266e20024dd6982598241baa0011337120126eb4c12cc120dd50008a50304a001330483049001330483330443034304537546092609400298103d87a80004c0103d87980004bd7018229baa304830453754042608e60886ea800458c118c10cdd50008b180a98211baa014163044001323300100102122533304300114bd70099912999821299982119baf304730443754608e609060886ea80080584c0c8c94ccc10cc0ccc110dd50008a400026eb4c120c114dd5000992999821981998221baa00114c0103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa304830493045375400644a66608e002298103d87a800013233322253330483372201c0062a66609066e3c03800c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230009bae303f003375c607e0046eb4c0fc004dd6981f98201820000981f800981f000981c9baa00d14a02a66606e60420142a66606e604260706ea80344c8c8ccc888c8c94ccc104c1100084c8c94ccc10cc1180084c8c8c8cc0540044c8c94ccc11401054ccc11400854ccc1140044c8c94ccc12800400854ccc128c1340044c8c8ccc8894ccc130cdc78018090a99982619b8f00201313370e00201829405281bae304e002375c609c0026eb4c138c13c004c138004dd6182600080119198008008139129998258008a5eb804c8c8c8c8cc004004dd598270021129998280008801899198291ba733052375200a660a4609e002660a460a000297ae03300300330540023052001330040043050003375c6094002609a00229405280a5014a0606064a6660900022900009918081929998250010a40002602266002002609a00444a6660960022900009809198010011827000982580099198008009bab301a3047375400c44a666092002297ae0132323232330010013756609800844a66609c0022006264660a06e9ccc140dd4802998281826800998281827000a5eb80cc00c00cc148008c140004cc010010c13800cdd71824000982580099baf0013374a9003198239ba900a3304737520126608e6ea0cdc0004001a5eb80c94ccc10cc0bcc110dd50008982418229baa001163047304830483044375400666e20005200033702601e6eacc054c108dd500098079bab301530423754602a60846ea800c58c110004c8cc004004080894ccc10c00452f5c026644a666084a66608466ebcc11cc110dd500100b09819192999821981998221baa0011480004dd6982418229baa001325333043303330443754002298103d87a80001323300100137566092608c6ea8008894ccc120004530103d87a80001323332225333049301a003153330493019003130223304d375000497ae014c103d87a8000133006006001375c608e0026eb4c120004c130008c128004c8cc004004dd59824182498229baa00322533304700114c103d87a800013233322253330483372201e0062a66609066e3c03c00c4c084cc130dd300125eb80530103d87a8000133006006001375c608c0026eacc11c004c12c008c12400452809982300119802002000899802002000982280098230008b1821000991980080080f9129998208008a5eb804cc894ccc1014ccc100cdd7982298211baa30453046304237540040282606064a666082606260846ea8004520001375a608c60866ea8004c94ccc104c0c4c108dd50008a6103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c00452809982200119802002000899802002000982180098220009bae303e002375c607c0026eb4c0f8c0fc004c0f8004c0e4dd50068a501533303730213038375401a26464666444a66607e6084646600200203e44a666082002297ae013322533304053330403375e608a60846ea8c114c118c108dd500100a09818192999820981898211baa0011480004dd6982318219baa001325333041303130423754002298103d87a8000132330010013756608e60886ea8008894ccc118004530103d87a800013233322253330473018003153330473017003130203304b375000497ae014c103d87a8000133006006001375c608a0026eb4c118004c128008c120004c8cc004004dd59823182398219baa304630473043375400644a66608a002298103d87a800013233322253330463372201a0062a66608c66e3c03400c4c07ccc128dd300125eb80530103d87a8000133006006001375c60880026eacc114004c124008c11c0045280998220011980200200089980200200098218009822000899299981ea99981e99b88480000084c8c8c94ccc10c00400854ccc10cc1180044c8cc894ccc10ccdc7801005099b8700100614a06eb8c118004dd69823182380098231bac30450010023233001001323300100102122533304500114bd70099191919198008009bab304800422533304a00110031323304c374e660986ea4014cc130c124004cc130c1280052f5c066006006609c00460980026600800860940066eb8c110004c11c004894ccc11000452f5c026644a66608666e3cdd718240010048998239ba7002330040040011330040040013758608c002608e0022940cdc0a4000004294454ccc0f40044c8c94ccc10800400854ccc108c1140044c8cc894ccc108c0480084cdc3800a40022940dd718228009bad304530460013045375860880020046466002002646600200204044a666088002297ae0132323232330010013756608e00844a6660920022006264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c004cc010010c12400cdd7182180098230009129998218008a5eb804cc894ccc108cdc79bae3047002009133046374e004660080080022660080080026eb0c114004c1180045280a5014a0646600200203444a66608200229404cc894ccc100cdc780101d8a51133004004001375c608600260880022c6eb8c0f8008dd7181f0009bad303e303f001303e0013039375401a2940dc0240046e952002374a900211191980080080191299981d0008a501332253330393375e00400a29444cc010010004c0f0004c0f4004888cdc399b81300437566014606e6ea8008c010dd59805181b9baa300a30373754006002464a666066604660686ea8004520001375a6070606a6ea8004c94ccc0ccc08cc0d0dd50008a60103d87a80001323300100137566072606c6ea8008894ccc0e0004530103d87a80001323332225333039300a003153330393009003130123303d375000497ae014c103d87a8000133006006001375c606e0026eb4c0e0004c0f0008c0e8004c8cc004004008894ccc0dc0045300103d87a800013233322253330383009003153330383008003130113303c374c00497ae014c103d87a8000133006006001375c606c0026eacc0dc004c0ec008c0e4004dc7a4500372291010022325333031301c00113232323232323232533303c303f00200a16375a607a002607a0046eb4c0ec004c0ec008dd7181c800981c8011bae3037001303337540062a666062604200226464646464646464a666078607e0040142c6eb4c0f4004c0f4008dd6981d800981d8011bae30390013039002375c606e00260666ea800c54ccc0c4c0740044c8c8c8c8c8c8c8c8c8c94ccc0f8c10400854ccc0ecc098c0f0dd5001899191919299982118228010080b1bad30430013043002375c6082002607a6ea800c5858dd6981f800981f801181e800981e8011bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018a999818980d8008991919191919299981d181e8010040b1bad303b001303b002375c607200260720046eb8c0dc004c0ccdd50018b18189baa002302e375403e600c605c6ea8c004c0b8dd5001918189819000981798161baa01716302e302b37540022c646600200201644a66605a002298103d87a800013322533302c3375e600c605c6ea80080684c014cc0c00092f5c0266008008002605e00260600026e9520002302c0013758605460560106eacc0a401cdd6181400398138039bac30260073756604a00e6eb0c09001cdd6181180398119811981198118009811000981098108009810000980f980f800980f180f000980c9baa00a370e90031b8748000dc3a4008602e002602e603000260266ea8008dc3a40042c6028602a006602600460240046024002601a6ea800452613656375a0026eb4004dd70009bae0015734aae7555cf2ab9f5740ae855d11", - "hash": "b77e4f80ee4d5887de1f3954470f392f455198ff4372c4c7d0d6480c" - }, - { - "title": "start.start.withdraw", - "redeemer": { - "title": "_r", - "schema": { - "$ref": "#/definitions/Data" - } - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "spend", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action_period", - "schema": { - "$ref": "#/definitions/Int" - } - } - ], - "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", - "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" - }, - { - "title": "start.start.mint", - "redeemer": { - "title": "redeemer", - "schema": { - "$ref": "#/definitions/types~1MintPolarity" - } - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "spend", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action_period", - "schema": { - "$ref": "#/definitions/Int" - } - } - ], - "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", - "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" - }, - { - "title": "start.start.publish", - "redeemer": { - "title": "redeemer", - "schema": { - "$ref": "#/definitions/types~1PublishRedeemer" - } - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "spend", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action_period", - "schema": { - "$ref": "#/definitions/Int" - } - } - ], - "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", - "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" - }, - { - "title": "start.start.propose", - "redeemer": { - "title": "_r", - "schema": { - "$ref": "#/definitions/Data" - } - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "spend", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action_period", - "schema": { - "$ref": "#/definitions/Int" - } - } - ], - "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", - "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" - }, - { - "title": "start.start.vote", - "redeemer": { - "title": "_r", - "schema": { - "$ref": "#/definitions/Data" - } - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "spend", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action_period", - "schema": { - "$ref": "#/definitions/Int" - } - } - ], - "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", - "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" - }, - { - "title": "start.start.else", - "redeemer": { - "schema": {} - }, - "parameters": [ - { - "title": "auth_token", - "schema": { - "$ref": "#/definitions/PolicyId" - } - }, - { - "title": "spend", - "schema": { - "$ref": "#/definitions/ByteArray" - } - }, - { - "title": "gov_action_period", - "schema": { - "$ref": "#/definitions/Int" - } - } - ], - "compiledCode": "590c2001010032323232323232232232232253330083232323232323232323232323232533301630060091323232323232323232533302230250021323232533302230143023375400626464646464646464646464646464646464646464a666072607800426602a01e26602a00626464646464646464646464646464a66608e6094004264646464a666090607400226464646464646464a6660a660ac0040142c6eb4c150004c150008dd6982900098290011bae30500013050002375c609c00260946ea800c54ccc120c0e40044c8c8c8c8c8c8c8c94ccc14cc15800802858dd6982a000982a0011bad30520013052002375c60a000260a00046eb8c138004c128dd50018a999824181c000899191919191919191919299982a982c0010a999829182218299baa0031323232325333059305c00201016375a60b400260b40046eb8c160004c150dd50018b0b1bad3056001305600230540013054002375a60a400260a40046eb8c140004c140008dd7182700098251baa00315333048303700113232323232325333051305400200816375a60a400260a40046eb8c140004c140008dd7182700098251baa003163048375400426464a666090607460926ea80044c8cc0dc0044c94ccc12802c54ccc12801854ccc12801054ccc128c8c94ccc13c00400854ccc13cc1480044c8cc894ccc13cc0380084c1000045281bae3052001375a60a460a600260a46eb0c144004008c8cc004004c8cc0040040c8894ccc14400452f5c0264646464660020026eacc150010894ccc158004400c4c8cc160dd39982c1ba90053305830550013305830560014bd7019801801982d001182c00099802002182b0019bae3050001305300122533305000114bd7009991299982799b8f375c60a800402a2660a66e9c008cc0100100044cc010010004dd6182900098298008a50100114a029405280a503375e002980103d87a8000304d304a37540022c6606405605266ebc004c0cccc128dd4806198251ba900b3304a3750012660946ea0cdc000402025eb80c94ccc118c0d8c11cdd50008982598241baa00116304a304b304b3047375400466e1cc94ccc114c0d8c118dd50008a400026eb4c128c11cdd5000992999822981b18231baa00114c0103d87a8000132330010013756609660906ea8008894ccc128004530103d87a8000132333222533304b300b0031533304b300a003130383304f375000497ae014c103d87a8000133006006001375c60920026eb4c128004c138008c130004c8cc004004dd59825182598239baa00222533304900114c103d87a8000132333222533304a300a0031533304a3009003130373304e374c00497ae014c103d87a8000133006006001375c60900026eacc124004c134008c12c00402058c120004c8c8cc0040040a8894ccc12000452f5c026644a66608ea66608e66ebcc130c124dd50010028981c192999824181c98249baa0011480004dd6982698251baa001325333048303930493754002298103d87a8000132330010013756609c60966ea8008894ccc134004530103d87a8000132333222533304e300e0031533304e300d0031303b33052375000497ae014c103d87a8000133006006001375c60980026eb4c134004c144008c13c004c8cc004004dd59826982718251baa00322533304c00114c103d87a8000132333222533304d337220260062a66609a66e3c04c00c4c0e8cc144dd300125eb80530103d87a8000133006006001375c60960026eacc130004c140008c13800452809982580119802002000899802002000982500098258009817998231817198231ba903e4bd70198231817998231817998231817198231ba90084bd7025eb812f5c097ae0371e9110037229101003375e6056660866ea40152f5c00526eb4c10cc110c110014dd698210021bad3041004375c60800086eb8c0fc010c0fc004c0f8c0f8004c0f4004c0e0dd500b8b1bad303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0d0008c94ccc0c4c0c000454ccc0b8cdc4a4008605e0022c2603e605e0022c6ea8c0c8004c0c8008dd6981800098180011bad302e001302e002302c001302c002375c605400260540046eb8c0a0004c090dd50018b112999811980a98121baa002132323232533302a302d0021330070031325333028301a00113232533302d3030002132533302b301d001132325333030303300213300d00100b163031001302d37540042a66605660380022646464646464a666068606e00401e2c6eb4c0d4004c0d4008dd6981980098198011bad3031001302d37540042c60566ea800458c0b8004c0a8dd50010a999814180c8008a99981598151baa0020061616302837540022c605600260560046052002604a6ea80085888c94ccc08cc0540044c8c94ccc0a0c0ac00801058dd7181480098129baa003153330233014001132325333028302b00200416375c6052002604a6ea800c58c08cdd5001192999810180818109baa00113025302237540022c6048604a604a60426ea8c090c094c084dd50008b181180099198008009bac302300722533302200114bd70099912999810991980080099198008009bab302830293025375460506052604a6ea8010894ccc09c00452f5c0264646464660020026eacc0a8010894ccc0b0004400c4c8cc0b8dd3998171ba90053302e302b0013302e302c0014bd7019801801981800118170009980200218160019bae3026001302900122533302600114a026644a66604a66e3cdd718150010118a5113300400400137586050002605200226604a004660080080022660080080026048002604a0026eacc084c088c088c088c088c08800cdd598100011bac301f002301f301f001301e301e0013019375401a603660306ea80284c8c94ccc060c02802c4c8c8c94ccc06cc03400454ccc078c074dd50080010b0a99980d98060008a99980f180e9baa0100021616301b375401e26464646464a66603c6020603e6ea804c4c8c8cc004004010894ccc09000452809991299981199baf00500214a22660080080026044604c002604e0026014660446ea40192f5c02666600e034006002980103d87d8000375660446046604660460066eacc084008dd61810001181018101810181018101810000980d9baa00f375c603a60346ea803054ccc060c01c02c4c8cc88c8c94ccc074c03c00454ccc080c07cdd50090010b0a99980e98070008a999810180f9baa0120021616301d3754022264646464a666044604a004264a666040602460426ea80044c8cc03c00454ccc084c04cc088dd500b099baf0014c0103d879800013375e00298103d87b80003025302237540022c660140060022c60460026644646600200200644a666048002297ae01332253330233375e6050604a6ea8c0a0c0a4c094dd500100289981380119802002000899802002000981300098138009bac3022002300701937566042604460446044604460446044604460446044002603a6ea8044dd6980f000980f180f800980d1baa00c153330183370e9005005899199119199980280c1bac30210013756604260446044604460446044604460446044604400298103d8798000301d37540226eb4c078004c078c07c004c068dd50060a99980c19b874802002c4c8c8cccc00c058dd6180f8009bab301f3020302030203020302030203020302030200014c0103d87a8000301b375401e603a60346ea8030588888c8c94ccc080c08c0084c94ccc078c040c07cdd500089919806800899baf0010053023302037540022c660100080022c604200264646600200200a44a666042002297ae01332253330203375e604a60446ea8c094c098c088dd500100289981200119802002000899802002000981180098120009802802118021980d98019980d9ba90014bd701980da60103d87a80004bd701119191980080080211299980e8008a6103d87a8000132333222533301e3375e00e006260166604400497ae0133006006001301c001301d0013021002301f00130033301b301c3019375400297ae0374a90011ba54800088c94ccc054c01c00454ccc060c05cdd50018010b0a99980a98030008a99980c180b9baa0030021615333015300500115333018301737540060042c2a66602a60080022a666030602e6ea800c0085854ccc054cdc3a40100022a666030602e6ea800c0085858c054dd50011b8748018dc3a40086e1d2002370e900018071baa001301130120033010002300f002300f001300a375400229309b2b1bad001375c0026eb80055cd2ab9d5573caae7d5d02ba15745", - "hash": "2cbea32ea6cd04837d0846fd7aa93b439238982029ddc09d09857f9d" - } - ], - "definitions": { - "Bool": { - "title": "Bool", - "anyOf": [ - { - "title": "False", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "True", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "ByteArray": { - "dataType": "bytes" - }, - "Data": { - "title": "Data", - "description": "Any Plutus data." - }, - "Index": { - "title": "Index", - "dataType": "integer" - }, - "Int": { - "dataType": "integer" - }, - "List$cardano/address/Credential": { - "dataType": "list", - "items": { - "$ref": "#/definitions/cardano~1address~1Credential" - } - }, - "Lovelace": { - "title": "Lovelace", - "dataType": "integer" - }, - "Mandate": { - "title": "Mandate", - "dataType": "integer" - }, - "Option$ScriptHash": { - "title": "Option", - "anyOf": [ - { - "title": "Some", - "description": "An optional value.", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/ScriptHash" - } - ] - }, - { - "title": "None", - "description": "Nothing.", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "Option$StakeCredential": { - "title": "Option", - "anyOf": [ - { - "title": "Some", - "description": "An optional value.", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/StakeCredential" - } - ] - }, - { - "title": "None", - "description": "Nothing.", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "Option$cardano/governance/GovernanceActionId": { - "title": "Option", - "anyOf": [ - { - "title": "Some", - "description": "An optional value.", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" - } - ] - }, - { - "title": "None", - "description": "Nothing.", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "Pairs$ProtocolParametersIndex_Data": { - "title": "Pairs", - "dataType": "map", - "keys": { - "$ref": "#/definitions/ProtocolParametersIndex" - }, - "values": { - "$ref": "#/definitions/Data" - } - }, - "Pairs$cardano/address/Credential_Lovelace": { - "title": "Pairs", - "dataType": "map", - "keys": { - "$ref": "#/definitions/cardano~1address~1Credential" - }, - "values": { - "$ref": "#/definitions/Lovelace" - } - }, - "Pairs$cardano/address/Credential_Mandate": { - "title": "Pairs", - "dataType": "map", - "keys": { - "$ref": "#/definitions/cardano~1address~1Credential" - }, - "values": { - "$ref": "#/definitions/Mandate" - } - }, - "PaymentCredential": { - "title": "PaymentCredential", - "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", - "anyOf": [ - { - "title": "VerificationKey", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/VerificationKeyHash" - } - ] - }, - { - "title": "Script", - "dataType": "constructor", - "index": 1, - "fields": [ - { - "$ref": "#/definitions/ScriptHash" - } - ] - } - ] - }, - "PolicyId": { - "title": "PolicyId", - "dataType": "bytes" - }, - "ProtocolParametersIndex": { - "title": "ProtocolParametersIndex", - "dataType": "integer" - }, - "ScriptHash": { - "title": "ScriptHash", - "dataType": "bytes" - }, - "StakeCredential": { - "title": "StakeCredential", - "description": "Represent a type of object that can be represented either inline (by hash)\n or via a reference (i.e. a pointer to an on-chain location).\n\n This is mainly use for capturing pointers to a stake credential\n registration certificate in the case of so-called pointer addresses.", - "anyOf": [ - { - "title": "Inline", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/cardano~1address~1Credential" - } - ] - }, - { - "title": "Pointer", - "dataType": "constructor", - "index": 1, - "fields": [ - { - "title": "slot_number", - "$ref": "#/definitions/Int" - }, - { - "title": "transaction_index", - "$ref": "#/definitions/Int" - }, - { - "title": "certificate_index", - "$ref": "#/definitions/Int" - } - ] - } - ] - }, - "TransactionId": { - "title": "TransactionId", - "dataType": "bytes" - }, - "VerificationKeyHash": { - "title": "VerificationKeyHash", - "dataType": "bytes" - }, - "cardano/address/Address": { - "title": "Address", - "description": "A Cardano `Address` typically holding one or two credential references.\n\n Note that legacy bootstrap addresses (a.k.a. 'Byron addresses') are\n completely excluded from Plutus contexts. Thus, from an on-chain\n perspective only exists addresses of type 00, 01, ..., 07 as detailed\n in [CIP-0019 :: Shelley Addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019/#shelley-addresses).", - "anyOf": [ - { - "title": "Address", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "payment_credential", - "$ref": "#/definitions/PaymentCredential" - }, - { - "title": "stake_credential", - "$ref": "#/definitions/Option$StakeCredential" - } - ] - } - ] - }, - "cardano/address/Credential": { - "title": "Credential", - "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", - "anyOf": [ - { - "title": "VerificationKey", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "$ref": "#/definitions/VerificationKeyHash" - } - ] - }, - { - "title": "Script", - "dataType": "constructor", - "index": 1, - "fields": [ - { - "$ref": "#/definitions/ScriptHash" - } - ] - } - ] - }, - "cardano/governance/Constitution": { - "title": "Constitution", - "anyOf": [ - { - "title": "Constitution", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "guardrails", - "$ref": "#/definitions/Option$ScriptHash" - } - ] - } - ] - }, - "cardano/governance/GovernanceActionId": { - "title": "GovernanceActionId", - "anyOf": [ - { - "title": "GovernanceActionId", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "transaction", - "$ref": "#/definitions/TransactionId" - }, - { - "title": "proposal_procedure", - "$ref": "#/definitions/Index" - } - ] - } - ] - }, - "cardano/governance/ProtocolVersion": { - "title": "ProtocolVersion", - "anyOf": [ - { - "title": "ProtocolVersion", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "major", - "$ref": "#/definitions/Int" - }, - { - "title": "minor", - "$ref": "#/definitions/Int" - } - ] - } - ] - }, - "crowdfund/CrowdfundRedeemer": { - "title": "CrowdfundRedeemer", - "anyOf": [ - { - "title": "ContributeFund", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "CompleteCrowdfund", - "dataType": "constructor", - "index": 1, - "fields": [] - }, - { - "title": "ContributorWithdrawal", - "dataType": "constructor", - "index": 2, - "fields": [] - }, - { - "title": "RemoveEmptyInstance", - "dataType": "constructor", - "index": 3, - "fields": [] - } - ] - }, - "gov/VGovernanceAction": { - "title": "VGovernanceAction", - "anyOf": [ - { - "title": "VProtocolParameters", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "ancestor", - "description": "The last governance action of type 'ProtocolParameters'. They must all\n form a chain.", - "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" - }, - { - "title": "new_parameters", - "description": "The new proposed protocol parameters. Only values set to `Some` are relevant.", - "$ref": "#/definitions/gov~1VProtocolParametersUpdate" - }, - { - "title": "guardrails", - "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the new protocol parameters to be deemed valid.", - "$ref": "#/definitions/Option$ScriptHash" - } - ] - }, - { - "title": "HardFork", - "dataType": "constructor", - "index": 1, - "fields": [ - { - "title": "ancestor", - "description": "The last governance action of type `HardFork`. They must all\n form a chain.", - "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" - }, - { - "title": "new_version", - "description": "The new proposed version. Few rules apply to proposing new versions:\n\n - The `major` component, if incremented, must be exactly one more than the current.\n - The `minor` component, if incremented, must be exactly one more than the current.\n - If the `major` component is incremented, `minor` must be set to `0`.\n - Neither `minor` nor `major` can be decremented.", - "$ref": "#/definitions/cardano~1governance~1ProtocolVersion" - } - ] - }, - { - "title": "TreasuryWithdrawal", - "dataType": "constructor", - "index": 2, - "fields": [ - { - "title": "beneficiaries", - "description": "A collection of beneficiaries, which can be plain verification key\n hashes or script hashes (e.g. DAO).", - "$ref": "#/definitions/Pairs$cardano~1address~1Credential_Lovelace" - }, - { - "title": "guardrails", - "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the withdrawals to be authorized.", - "$ref": "#/definitions/Option$ScriptHash" - } - ] - }, - { - "title": "NoConfidence", - "dataType": "constructor", - "index": 3, - "fields": [ - { - "title": "ancestor", - "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", - "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" - } - ] - }, - { - "title": "ConstitutionalCommittee", - "dataType": "constructor", - "index": 4, - "fields": [ - { - "title": "ancestor", - "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", - "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" - }, - { - "title": "evicted_members", - "description": "Constitutional members to be removed.", - "$ref": "#/definitions/List$cardano~1address~1Credential" - }, - { - "title": "added_members", - "description": "Constitutional members to be added.", - "$ref": "#/definitions/Pairs$cardano~1address~1Credential_Mandate" - }, - { - "title": "quorum", - "description": "The new quorum value, as a ratio of a numerator and a denominator. The\n quorum specifies the threshold of 'Yes' votes necessary for the\n constitutional committee to accept a proposal procedure.", - "$ref": "#/definitions/gov~1VRational" - } - ] - }, - { - "title": "NewConstitution", - "dataType": "constructor", - "index": 5, - "fields": [ - { - "title": "ancestor", - "description": "The last governance action of type `Constitution` or\n `ConstitutionalCommittee`. They must all / form a chain.", - "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" - }, - { - "title": "constitution", - "description": "The new proposed constitution.", - "$ref": "#/definitions/cardano~1governance~1Constitution" - } - ] - }, - { - "title": "NicePoll", - "dataType": "constructor", - "index": 6, - "fields": [] - } - ] - }, - "gov/VProtocolParametersUpdate": { - "title": "VProtocolParametersUpdate", - "anyOf": [ - { - "title": "VProtocolParametersUpdate", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "inner", - "$ref": "#/definitions/Pairs$ProtocolParametersIndex_Data" - } - ] - } - ] - }, - "gov/VRational": { - "title": "VRational", - "anyOf": [ - { - "title": "VRational", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "numerator", - "$ref": "#/definitions/Int" - }, - { - "title": "denominator", - "$ref": "#/definitions/Int" - } - ] - } - ] - }, - "types/CrowdfundDatum": { - "title": "CrowdfundDatum", - "anyOf": [ - { - "title": "CrowdfundDatum", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "completion_script", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "share_token", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "crowdfund_address", - "$ref": "#/definitions/cardano~1address~1Address" - }, - { - "title": "fundraise_target", - "$ref": "#/definitions/Int" - }, - { - "title": "current_fundraised_amount", - "$ref": "#/definitions/Int" - }, - { - "title": "allow_over_subscription", - "$ref": "#/definitions/Bool" - }, - { - "title": "deadline", - "$ref": "#/definitions/Int" - }, - { - "title": "expiry_buffer", - "$ref": "#/definitions/Int" - }, - { - "title": "fee_address", - "$ref": "#/definitions/cardano~1address~1Address" - }, - { - "title": "min_charge", - "$ref": "#/definitions/Int" - } - ] - } - ] - }, - "types/CrowdfundGovDatum": { - "title": "CrowdfundGovDatum", - "anyOf": [ - { - "title": "Init", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "start_hash", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "share_token", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "funds_controlled", - "$ref": "#/definitions/Int" - }, - { - "title": "deadline", - "$ref": "#/definitions/Int" - } - ] - }, - { - "title": "Proposed", - "dataType": "constructor", - "index": 1, - "fields": [ - { - "title": "start_hash", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "share_token", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "funds_controlled", - "$ref": "#/definitions/Int" - }, - { - "title": "deadline", - "$ref": "#/definitions/Int" - } - ] - }, - { - "title": "Voted", - "dataType": "constructor", - "index": 2, - "fields": [ - { - "title": "start_hash", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "share_token", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "funds_controlled", - "$ref": "#/definitions/Int" - }, - { - "title": "gov_tx_id", - "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" - }, - { - "title": "deadline", - "$ref": "#/definitions/Int" - } - ] - }, - { - "title": "Refundable", - "dataType": "constructor", - "index": 3, - "fields": [ - { - "title": "start_hash", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "share_token", - "$ref": "#/definitions/ByteArray" - }, - { - "title": "funds_controlled", - "$ref": "#/definitions/Int" - } - ] - } - ] - }, - "types/CrowdfundRedeemer": { - "title": "CrowdfundRedeemer", - "anyOf": [ - { - "title": "RegisterCerts", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "VoteOnGovAction", - "dataType": "constructor", - "index": 1, - "fields": [] - }, - { - "title": "DeregisterCerts", - "dataType": "constructor", - "index": 2, - "fields": [] - }, - { - "title": "ContributorWithdrawal", - "dataType": "constructor", - "index": 3, - "fields": [] - }, - { - "title": "RemoveEmptyInstance", - "dataType": "constructor", - "index": 4, - "fields": [] - } - ] - }, - "types/MintPolarity": { - "title": "MintPolarity", - "anyOf": [ - { - "title": "RMint", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "RBurn", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - }, - "types/PublishRedeemer": { - "title": "PublishRedeemer", - "anyOf": [ - { - "title": "Register", - "dataType": "constructor", - "index": 0, - "fields": [] - }, - { - "title": "Deregister", - "dataType": "constructor", - "index": 1, - "fields": [] - } - ] - } - } -} \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.github/workflows/continuous-integration.yml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/.github/workflows/continuous-integration.yml similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.github/workflows/continuous-integration.yml rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/.github/workflows/continuous-integration.yml diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.gitignore b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/.gitignore similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/.gitignore rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/.gitignore diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/README.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/README.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/README.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/README.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.lock b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/aiken.lock similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.lock rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/aiken.lock diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/aiken.toml similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/aiken.toml rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/aiken.toml diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/lib/gov.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/gov.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/lib/gov.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/lib/types.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/types.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/lib/types.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/lib/utils.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/lib/utils.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/lib/utils.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/plutus.json new file mode 100644 index 000000000..ea69aa018 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/plutus.json @@ -0,0 +1,1088 @@ +{ + "preamble": { + "title": "sidan-lab/gov-crowdfund", + "description": "Aiken contracts for project 'sidan-lab/gov-crowdfund'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.7+e2fb28b" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "crowdfund.crowdfund.spend", + "datum": { + "title": "datum_opt", + "schema": { + "$ref": "#/definitions/types~1CrowdfundDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/crowdfund~1CrowdfundRedeemer" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "5911d60101002229800aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae00248888888896600264653001300a00198051805800cdc3a4005300a0024888966002600460146ea800e33001300b3754007370e90024dc3a4001300a375400891111991192cc004c0140122b3001301237540170018b20268acc004c0240122b3001301237540170018b20268acc004c0180122b3001301237540170018b20268acc004cdc3a400c00915980098091baa00b800c590134590102020404080804ca6002602c602c0033758602a003374a900024446464653001301b0019919800800803112cc004006298103d87a80008992cc004cdd7980f180d9baa00100c898039980e800a5eb82266006006603e00480c8c07400501b4dd6180d8034dd5980d801a4444b3001300f301b37540071598009807980d9baa00c8991919912cc004c09000a33001302300298101baa001980f9baa01991192cc004c05800626464b300130290028024590261bae302700130233754007159800980d000c4c8c96600260520050048b204c375c604e00260466ea800e2c810902118109baa0029b91489009b8f4881009b80480092222222980098158034dd7181500348966002603860506ea800a2646464b3001303000289980498178018992cc004c080006264b30013032001899192cc004c08c006264b30013035001899807181a000804c5903218181baa0028acc004c09c00626464653001375a606c003375a606c007375a606c0049112cc004c0e801201d1640dc30360013035001303037540051640b88170c0b8dd50009818800c5902f18169baa0028acc004c0900062b3001302d37540050058b205c8b205640ac60566ea80062c8168c0b8004c0b8004c0a4dd500145902748c966002604060506ea80062900044dd6981618149baa001409c64b300130203028375400314c103d87a8000899198008009bab302d302a375400444b30010018a6103d87a8000899192cc004c0240062b300130080018980c99817981680125eb82298103d87a800040ad133004004303100340ac6eb8c0ac004c0b800502c204e32330010010022259800800c5300103d87a8000899192cc004c0200062b300130070018980c19817181600125eb82298103d87a800040a9133004004303000340a86eb8c0a8004c0b400502b24444646464646465300130340019bad30343035001912cc004c098c0c8dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c1000066eb8c10002a6eb8c1000266eb4c10001e6eb4c10001a64b3001303e0018acc004cdc4a4008607a003168981a981e800a0788b207e3754608000b375a6080009375a60800073040002488888888966002609401513301d304901113301d0010148b208e1820000981f800981f000981e800981e000981d800981d000981c800981c00098199baa0028b20629bae303400a9bad30340069bad3034005981418181baa30340049bad303400348888888966002605802f13259800981f000c4ca600260226eacc07cc0ecdd5000cc966002606060766ea80062607e60786ea80062c81d0c0f8c0fcc0fcc0ecdd5000cc044dd5980f981d9baa301f303b375403691119805801099912cc0056600266e1c008cdc09bad3001304037540080151337129040497a008014528207c8acc0056600201314a31337126eb4c004c100dd5002005a07c8acc004c8c8c966002607460846ea80062b3001303a30423754608c608e0051337106eb4c118c10cdd5000805c4cdc49bad304630433754002016820a2941041182280099821982200099821cc004c0e0c100dd518221822800d300103d87a8000a60103d879800040fc97ae0304037546086608860806ea80a22b30013375e0086464646460606608c608e0086608c608e0066608c608e0046608c608e0026608c6ea0cdc00070031824182400098238009823000982280098201baa0218acc004c0d0c966002003148002264603864b30010028a40011301d330010013047002411044b30010018a40011301e3300200230480014114608a0028210c8cc004004dd5981298209baa0072259800800c52f5c1132332232330010013756608c00844b30010018801c4c8cc128dd3998251ba90053304a30470013304a30480014bd701980180198260011825000a090375c608400266006006608e004608a002821a26644b30010018014566002608c003132325980099b8f375c608e00402115980099b8f375c608e00203913370e6eb4c11cc12000401a29410424528208430470013758608a003002410c82185281919800800813112cc004006297ae0899199119198008009bab30460042259800800c400e264660946e9ccc128dd4802998251823800998251824000a5eb80cc00c00cc130008c1280050481bae30420013300300330470023045001410d14a081f2294103e4528207c8a5040f914a081f0cdc08018009182118219821982198218008c0f40062c81d8c8cc004004080896600200314bd7044cc8966002b30013375e6080607a6ea80080822646600200264660020026eacc108c10cc0fcdd5002112cc004006297ae0899199119198008009bab30440042259800800c400e264660906e9ccc120dd4802998241822800998241823000a5eb80cc00c00cc128008c1200050461bae30400013300300330450023043001410444b30010018a508acc004cdc79bae30423758608400207914a3133002002304300140f48202294103b44cc0fc008cc01001000626600800800281d8c0f8004c0fc00503c44c9660026062031159800acc004c0b40222946264b3001303f0018992cc004cdc480518091bab3020303c375400313375e6e98c8cc004004dd59810981e9baa0022259800800c52f5bded8c113298009bae303e0019bab303f00198218012444b3001301e0038acc004c07400e200310054101133044337606ea400cdd300119803003000a0801820800a07e4c101a0008a5040e8607c0031640f0646600200204244b30010018a5eb8226644b30013375e6082607c6ea80080362660800046600800800313300400400140f0607e002608000281e9038456600266e240140122b30013232330010013756607e04c44b30010018a508acc004cdd7801981e1820000c528c4cc008008c10400503b207c3374a90011981e1ba90124bd70456600266e24cdc000400218081bab301e303a3754603c60746ea806a26644b3001001801456600260800031325980099b8f375c608000202b13004375a6080608200314a081d8c100dd6181f800c00903d207a14a06466002002646600200204244b30010018a5eb82264664464660020026eacc10401089660020031003899198229ba733045375200a6608a60840026608a608600297ae03300300330470023045001410c6eb8c0f4004cc00c00cc108008c10000503e112cc004006297ae0899912cc004cdc79bae304100203b8998201ba700233004004001899802002000a0783758607e002608000281ea2941038452820708a5040e114a081c22b3001302e0188cc004c8c8cc8966002606a607a6ea800a2b30013035303d3754608260840071337100026eb4c104c0f8dd500144cdc48009bad3041303e375400481e2294103c181f80099b80004375a607e01a6607a607c0026607b30013032303a3754607c607e0034c0103d87a8000a60103d879800040e497ae0303a3754607a60746ea808a66e24010016646600200204244b30010018a5eb8226644b30015980099baf3041303e375400404313233001001323300100137566086608860806ea8010896600200314bd7044c8cc88c8cc004004dd59822802112cc004006200713233049374e660926ea4014cc124c118004cc124c11c0052f5c066006006609600460920028238dd718208009980180198230011822000a0842259800800c528456600266e3cdd718219bac304300103d8a518998010011822000a07c410514a081e22660800046600800800313300400400140f0607e002608000281e9222598009820800c4c8c8cc88cc038004566002b30010078a518803207e8acc00400a2b30013375e0026464646460626608e60900086608e60900066608e60900046608e60900026608e6ea0cdc00078039824982480098240009823800982300098209baa0228acc004c0d4c966002003148002264603a64b30010028a40011301e330010013048002411444b30010018a40011301f3300200230490014118608c0028218c8cc004004dd5981318211baa0052259800800c52f5c1132332232330010013756608e00844b30010018801c4c8cc12cdd3998259ba90053304b30480013304b30490014bd701980180198268011825800a092375c6086002660060066090004608c002822226644b30010018014566002608e003132325980099b8f375c609000402315980099b8f375c609000203b13370e6eb4c120c12400401e29410434528208630480013758608c003002411082205281919800800813912cc004006297ae0899199119198008009bab30470042259800800c400e264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c0050491bae30430013300300330480023046001411114a081fa294103f4528207e8a5040fc66e2000520003259800981a181f9baa0018982198201baa0018b207c304230433043303f375400466e04c050dd59811181f1baa001301437566044607c6ea8c088c0f8dd500f1820000c5903e22b300132323259800981a181e1baa0018acc004c0d0c0f0dd51820182080144cdc40029bad3040303d375400313371200a6eb4c100c0f4dd5000a0768a5040ec607e0026607a607c0026607b30013032303a3754607c607e0034c0103d87a8000a60103d879800040e497ae0303a3754607a60746ea808a2b30015980099b88480000122b3001980099b814800001229426466002002646600200204244b30010018a5eb82264664464660020026eacc10401089660020031003899198229ba733045375200a6608a60840026608a608600297ae03300300330470023045001410c6eb8c0f4004cc00c00cc108008c10000503e112cc004006297ae0899912cc004cdc79bae304100200a8998201ba700233004004001899802002000a0783758607e002608000281e922259800800c00a2b300130410018992cc004cdc79bae3041001016899b87375a6082608400200914a081e0c104dd61820000c00903e207c44cc89660020030028acc004c100006264b30013371e6eb8c100004056260086eb4c100c104006294103b18201bac303f001801207a40f42940c8cc004004c8cc004004084896600200314bd7044c8cc88c8cc004004dd59820802112cc004006200713233045374e6608a6ea4014cc114c108004cc114c10c0052f5c066006006608e004608a0028218dd7181e8009980180198210011820000a07c2259800800c52f5c1133225980099b8f375c6082004077133040374e0046600800800313300400400140f06eb0c0fc004c10000503d45282070899912cc0040060051598009820000c4c8c96600266e3cdd7182080101dc56600266e3cdd7182080080b44c014dd698209821000c52820788a5040f060820026eb0c0fc00600481e903d0a5032330010010202259800800c52f5c1132332232330010013756608000844b30010018801c4c8cc110dd3998221ba90053304430410013304430420014bd701980180198230011822000a084375c6078002660060066082004607e00281e903844c8cc004004dd6181f181f812112cc00400629422b30013371e6eb8c0fc0040e22946266004004608000281d103d452820708a5040e081c10381b87480050370c0d0004c0cc004c0c8004c0c4004c0c0004c0bcc0bc0108b2042323300100100c2259800800c52f5c11332259800acc004cdd7981298111baa302530263022375400400b1323300100132330010013756604e605060486ea8c09cc0a0c090dd5002112cc004006297ae0899199119198008009bab30290042259800800c400e2646605a6e9ccc0b4dd4802998169815000998169815800a5eb80cc00c00cc0bc008c0b400502b1bae302500133003003302a0023028001409844b30010018a508acc004cdc79bae30273758604e00204314a313300200230280014088812a294102044cc090008cc0100100062660080080028100c08c004c0900050211810980f1baa00e3020301d37546002603a6ea8c080c074dd5002118101810800c5901a45901a0c06c004c068c068004c064c06400c60226ea801cc048010c048c04c011164024300a00130053754015149a26cac8019", + "hash": "329ae820b7bc0d7e59e16fca08631bb79dd7817fb5d1a50941e2cd6b" + }, + { + "title": "crowdfund.crowdfund.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "5911d60101002229800aba2aba1aba0aab9faab9eaab9dab9a9bae0039bae00248888888896600264653001300a00198051805800cdc3a4005300a0024888966002600460146ea800e33001300b3754007370e90024dc3a4001300a375400891111991192cc004c0140122b3001301237540170018b20268acc004c0240122b3001301237540170018b20268acc004c0180122b3001301237540170018b20268acc004cdc3a400c00915980098091baa00b800c590134590102020404080804ca6002602c602c0033758602a003374a900024446464653001301b0019919800800803112cc004006298103d87a80008992cc004cdd7980f180d9baa00100c898039980e800a5eb82266006006603e00480c8c07400501b4dd6180d8034dd5980d801a4444b3001300f301b37540071598009807980d9baa00c8991919912cc004c09000a33001302300298101baa001980f9baa01991192cc004c05800626464b300130290028024590261bae302700130233754007159800980d000c4c8c96600260520050048b204c375c604e00260466ea800e2c810902118109baa0029b91489009b8f4881009b80480092222222980098158034dd7181500348966002603860506ea800a2646464b3001303000289980498178018992cc004c080006264b30013032001899192cc004c08c006264b30013035001899807181a000804c5903218181baa0028acc004c09c00626464653001375a606c003375a606c007375a606c0049112cc004c0e801201d1640dc30360013035001303037540051640b88170c0b8dd50009818800c5902f18169baa0028acc004c0900062b3001302d37540050058b205c8b205640ac60566ea80062c8168c0b8004c0b8004c0a4dd500145902748c966002604060506ea80062900044dd6981618149baa001409c64b300130203028375400314c103d87a8000899198008009bab302d302a375400444b30010018a6103d87a8000899192cc004c0240062b300130080018980c99817981680125eb82298103d87a800040ad133004004303100340ac6eb8c0ac004c0b800502c204e32330010010022259800800c5300103d87a8000899192cc004c0200062b300130070018980c19817181600125eb82298103d87a800040a9133004004303000340a86eb8c0a8004c0b400502b24444646464646465300130340019bad30343035001912cc004c098c0c8dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c1000066eb8c10002a6eb8c1000266eb4c10001e6eb4c10001a64b3001303e0018acc004cdc4a4008607a003168981a981e800a0788b207e3754608000b375a6080009375a60800073040002488888888966002609401513301d304901113301d0010148b208e1820000981f800981f000981e800981e000981d800981d000981c800981c00098199baa0028b20629bae303400a9bad30340069bad3034005981418181baa30340049bad303400348888888966002605802f13259800981f000c4ca600260226eacc07cc0ecdd5000cc966002606060766ea80062607e60786ea80062c81d0c0f8c0fcc0fcc0ecdd5000cc044dd5980f981d9baa301f303b375403691119805801099912cc0056600266e1c008cdc09bad3001304037540080151337129040497a008014528207c8acc0056600201314a31337126eb4c004c100dd5002005a07c8acc004c8c8c966002607460846ea80062b3001303a30423754608c608e0051337106eb4c118c10cdd5000805c4cdc49bad304630433754002016820a2941041182280099821982200099821cc004c0e0c100dd518221822800d300103d87a8000a60103d879800040fc97ae0304037546086608860806ea80a22b30013375e0086464646460606608c608e0086608c608e0066608c608e0046608c608e0026608c6ea0cdc00070031824182400098238009823000982280098201baa0218acc004c0d0c966002003148002264603864b30010028a40011301d330010013047002411044b30010018a40011301e3300200230480014114608a0028210c8cc004004dd5981298209baa0072259800800c52f5c1132332232330010013756608c00844b30010018801c4c8cc128dd3998251ba90053304a30470013304a30480014bd701980180198260011825000a090375c608400266006006608e004608a002821a26644b30010018014566002608c003132325980099b8f375c608e00402115980099b8f375c608e00203913370e6eb4c11cc12000401a29410424528208430470013758608a003002410c82185281919800800813112cc004006297ae0899199119198008009bab30460042259800800c400e264660946e9ccc128dd4802998251823800998251824000a5eb80cc00c00cc130008c1280050481bae30420013300300330470023045001410d14a081f2294103e4528207c8a5040f914a081f0cdc08018009182118219821982198218008c0f40062c81d8c8cc004004080896600200314bd7044cc8966002b30013375e6080607a6ea80080822646600200264660020026eacc108c10cc0fcdd5002112cc004006297ae0899199119198008009bab30440042259800800c400e264660906e9ccc120dd4802998241822800998241823000a5eb80cc00c00cc128008c1200050461bae30400013300300330450023043001410444b30010018a508acc004cdc79bae30423758608400207914a3133002002304300140f48202294103b44cc0fc008cc01001000626600800800281d8c0f8004c0fc00503c44c9660026062031159800acc004c0b40222946264b3001303f0018992cc004cdc480518091bab3020303c375400313375e6e98c8cc004004dd59810981e9baa0022259800800c52f5bded8c113298009bae303e0019bab303f00198218012444b3001301e0038acc004c07400e200310054101133044337606ea400cdd300119803003000a0801820800a07e4c101a0008a5040e8607c0031640f0646600200204244b30010018a5eb8226644b30013375e6082607c6ea80080362660800046600800800313300400400140f0607e002608000281e9038456600266e240140122b30013232330010013756607e04c44b30010018a508acc004cdd7801981e1820000c528c4cc008008c10400503b207c3374a90011981e1ba90124bd70456600266e24cdc000400218081bab301e303a3754603c60746ea806a26644b3001001801456600260800031325980099b8f375c608000202b13004375a6080608200314a081d8c100dd6181f800c00903d207a14a06466002002646600200204244b30010018a5eb82264664464660020026eacc10401089660020031003899198229ba733045375200a6608a60840026608a608600297ae03300300330470023045001410c6eb8c0f4004cc00c00cc108008c10000503e112cc004006297ae0899912cc004cdc79bae304100203b8998201ba700233004004001899802002000a0783758607e002608000281ea2941038452820708a5040e114a081c22b3001302e0188cc004c8c8cc8966002606a607a6ea800a2b30013035303d3754608260840071337100026eb4c104c0f8dd500144cdc48009bad3041303e375400481e2294103c181f80099b80004375a607e01a6607a607c0026607b30013032303a3754607c607e0034c0103d87a8000a60103d879800040e497ae0303a3754607a60746ea808a66e24010016646600200204244b30010018a5eb8226644b30015980099baf3041303e375400404313233001001323300100137566086608860806ea8010896600200314bd7044c8cc88c8cc004004dd59822802112cc004006200713233049374e660926ea4014cc124c118004cc124c11c0052f5c066006006609600460920028238dd718208009980180198230011822000a0842259800800c528456600266e3cdd718219bac304300103d8a518998010011822000a07c410514a081e22660800046600800800313300400400140f0607e002608000281e9222598009820800c4c8c8cc88cc038004566002b30010078a518803207e8acc00400a2b30013375e0026464646460626608e60900086608e60900066608e60900046608e60900026608e6ea0cdc00078039824982480098240009823800982300098209baa0228acc004c0d4c966002003148002264603a64b30010028a40011301e330010013048002411444b30010018a40011301f3300200230490014118608c0028218c8cc004004dd5981318211baa0052259800800c52f5c1132332232330010013756608e00844b30010018801c4c8cc12cdd3998259ba90053304b30480013304b30490014bd701980180198268011825800a092375c6086002660060066090004608c002822226644b30010018014566002608e003132325980099b8f375c609000402315980099b8f375c609000203b13370e6eb4c120c12400401e29410434528208630480013758608c003002411082205281919800800813912cc004006297ae0899199119198008009bab30470042259800800c400e264660966e9ccc12cdd4802998259824000998259824800a5eb80cc00c00cc134008c12c0050491bae30430013300300330480023046001411114a081fa294103f4528207e8a5040fc66e2000520003259800981a181f9baa0018982198201baa0018b207c304230433043303f375400466e04c050dd59811181f1baa001301437566044607c6ea8c088c0f8dd500f1820000c5903e22b300132323259800981a181e1baa0018acc004c0d0c0f0dd51820182080144cdc40029bad3040303d375400313371200a6eb4c100c0f4dd5000a0768a5040ec607e0026607a607c0026607b30013032303a3754607c607e0034c0103d87a8000a60103d879800040e497ae0303a3754607a60746ea808a2b30015980099b88480000122b3001980099b814800001229426466002002646600200204244b30010018a5eb82264664464660020026eacc10401089660020031003899198229ba733045375200a6608a60840026608a608600297ae03300300330470023045001410c6eb8c0f4004cc00c00cc108008c10000503e112cc004006297ae0899912cc004cdc79bae304100200a8998201ba700233004004001899802002000a0783758607e002608000281e922259800800c00a2b300130410018992cc004cdc79bae3041001016899b87375a6082608400200914a081e0c104dd61820000c00903e207c44cc89660020030028acc004c100006264b30013371e6eb8c100004056260086eb4c100c104006294103b18201bac303f001801207a40f42940c8cc004004c8cc004004084896600200314bd7044c8cc88c8cc004004dd59820802112cc004006200713233045374e6608a6ea4014cc114c108004cc114c10c0052f5c066006006608e004608a0028218dd7181e8009980180198210011820000a07c2259800800c52f5c1133225980099b8f375c6082004077133040374e0046600800800313300400400140f06eb0c0fc004c10000503d45282070899912cc0040060051598009820000c4c8c96600266e3cdd7182080101dc56600266e3cdd7182080080b44c014dd698209821000c52820788a5040f060820026eb0c0fc00600481e903d0a5032330010010202259800800c52f5c1132332232330010013756608000844b30010018801c4c8cc110dd3998221ba90053304430410013304430420014bd701980180198230011822000a084375c6078002660060066082004607e00281e903844c8cc004004dd6181f181f812112cc00400629422b30013371e6eb8c0fc0040e22946266004004608000281d103d452820708a5040e081c10381b87480050370c0d0004c0cc004c0c8004c0c4004c0c0004c0bcc0bc0108b2042323300100100c2259800800c52f5c11332259800acc004cdd7981298111baa302530263022375400400b1323300100132330010013756604e605060486ea8c09cc0a0c090dd5002112cc004006297ae0899199119198008009bab30290042259800800c400e2646605a6e9ccc0b4dd4802998169815000998169815800a5eb80cc00c00cc0bc008c0b400502b1bae302500133003003302a0023028001409844b30010018a508acc004cdc79bae30273758604e00204314a313300200230280014088812a294102044cc090008cc0100100062660080080028100c08c004c0900050211810980f1baa00e3020301d37546002603a6ea8c080c074dd5002118101810800c5901a45901a0c06c004c068c068004c064c06400c60226ea801cc048010c048c04c011164024300a00130053754015149a26cac8019", + "hash": "329ae820b7bc0d7e59e16fca08631bb79dd7817fb5d1a50941e2cd6b" + }, + { + "title": "spend.spend.spend", + "datum": { + "title": "datum_opt", + "schema": { + "$ref": "#/definitions/types~1CrowdfundGovDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1CrowdfundRedeemer" + } + }, + "parameters": [ + { + "title": "delegate_pool_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action", + "schema": { + "$ref": "#/definitions/gov~1VGovernanceAction" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "stake_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "drep_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "gov_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + } + ], + "compiledCode": "591a6201010022222229800aba2aba1aba0aab9faab9eaab9dab9a9bae0079bae0059bad0049bad0039bad00248888888888896600264653001300d00198069807000cdc3a4005300d00248889660026004601a6ea800e33001300e3754007370e90024dc3a4001370e90034c034dd5002244444664464b300130060048acc004c058dd500640062c80ba2b3001300a0048acc004c058dd500640062c80ba2b300130070048acc004c058dd500640062c80ba2b300130050048acc004c058dd500640062c80ba2b30013370e90040024566002602c6ea803200316405d16405080a1014202840502653001301a301a0019bac30190019ba548001222323232323298009bab30210019bac302130220019919800800804112cc004006298103d87a80008992cc004cdd7981218109baa00100e8980499811800a5eb82266006006604a00480f8c08c0050214dd618108044dd59810802cdd618108022444444b300130143023375400913259800980a98121baa0118cc004c0a0c094dd5008c8c0a4c0a800660486ea806e4464b300130180018991919194c004dd69817800cdd718178024dd71817801cdd6981780124444b300130340058054590310c0bc004c0b8004c0b4004c0a0dd5001c566002603800313232323298009bad302f0019bae302f0049bae302f0039bad302f0024888966002606800b00a8b206218178009817000981680098141baa0038acc004c064006264646464653001375a6060003375c606000b375c6060009375a606000691112cc004c0d4016264b300130223031375400313232332259800981d001c0422c81b8dd6981b8009bae30370023037001303237540031640c0606800d1640c83030001302f001302e001302d00130283754007159800980b800c4c8c8ca60026eb4c0b80066eb8c0b800e6eb8c0b800922259800981900240222c8178605c002605a00260506ea800e2c8131026204c4098604c6ea800a6e452201009b8f488100911919800800801912cc00400629422b30013375e605800200714a3133002002302d001409c81526e9520049ba54800a6e01200248888888888c8cc89660026044017159800981118189baa00d8991991194c004dd6981c800cdd6981c981d000cc8cc004004080896600200314bd7044cc8966002b30013375e607a60746ea8c0f4c0f8c0e8dd5001004c4c0b8c966002605e60746ea80062900044dd6981f181d9baa00140e464b3001302f303a375400314c103d87a8000899198008009bab303f303c375400444b30010018a6103d87a8000899192cc004c0580062b300130150018981399820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e207232330010013756607c607e60766ea8c0f8c0fcc0ecdd5001912cc004006298103d87a8000899192cc004cdc8805000c56600266e3c0280062604c66080607c00497ae08a60103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d4528207089981e00119802002000c4cc010010005038181d800981e000a0729bae30390034888966002607c005132598009815981d1baa0018992cc004c0b0c0ecdd5000c4cc89660026084003132332233019001159800801456600266ebc004c050cc10cdd4806998219ba9008330433750016660866ea00292f5c11598009819192cc0040062900044c8c054c9660020051480022602c660020026090004822889660020031480022602e6600400460920028230c11800504319198008009bab301c3042375400844b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c11800504445660026602c03c60526608600a6608698103d87a80004bd7045660026602c03c66e9520083304300533043375007697ae08acc00566002b30013301601e301533043005330433014330433029330430054bd7025eb812f5c113301601e30153304300533043302933043375207c97ae04bd704528207e8a5189980b00f180a9982180299821980a998219ba903e330433029330430054bd7025eb812f5c081fa264606c646600200204844b30010018a40011332259800acc004cdc39bad30493046375400407f15980099baf30203046375400400b13371e6eccc124c128c128c118dd50011bb30508a50411114a082222603000310014110608e0026600400460900028228c050cc10cdd4806a5eb82294103f4528207e8a5040fd14a081fa294103f4528207e98009821003c00666e0520003370066e000e80e40e100f192cc004c0c4c0fcdd5000c4c10cc100dd5000c5903e182118219821981f9baa00130410018b207e303f303c3754002646600200203844b30010018a5eb8226644b30015980099baf30433040375400401f130343259800981a98201baa0018a40011375a608860826ea800503f192cc004c0d4c100dd5000c5300103d87a8000899198008009bab30453042375400444b30010018a6103d87a8000899192cc004c0700062b3001301b0018981699823982280125eb82298103d87a8000410d1330040043049003410c6eb8c10c004c118005044207e323300100137566088608a60826ea800c896600200314c103d87a8000899192cc004cdc8808000c56600266e3c040006260586608c608800497ae08a60103d87a80004109133004004304800341086eb8c108004c1140050434528207c89982100119802002000c4cc01001000503e18208009821000a07e8b2074303e303b37540031640e4602860746ea80262c81d86072004606e0026eb8c0d8004c0c8dd5006c52820608acc004c09802e2b300130263031375401b13233223298009bad30390019bad3039303a0019919800800810112cc004006297ae0899912cc0056600266ebcc0f4c0e8dd5181e981f181d1baa00200989817192cc004c0bcc0e8dd5000c5200089bad303e303b375400281c8c966002605e60746ea80062980103d87a8000899198008009bab303f303c375400444b30010018a6103d87a8000899192cc004c0580062b300130150018981399820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e207232330010013756607c607e60766ea8c0f8c0fcc0ecdd5001912cc004006298103d87a8000899192cc004cdc8805000c56600266e3c0280062604c66080607c00497ae08a60103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d4528207089981e00119802002000c4cc010010005038181d800981e000a0729bae30390034888966002607c00513259800981f800c4c8cc88cc0580044c96600200715980099baf0023013330413752016660826ea4018cc104dd400499820800998209ba80084bd704566002606064b30010018a4001132301332598008014520008980a19800800982300120862259800800c520008980a998010011823800a0883044001410464660020026eacc068c100dd5002912cc004006297ae0899199119198008009bab30450042259800800c400e264660926e9ccc124dd4802998249823000998249823800a5eb80cc00c00cc12c008c1240050471bae3041001330030033046002304400141091323259800981898201baa001899199119801001000912cc00400629422b30013375e6e98cc118c11c0052f5bded8c06e98cc11800d2f5bded8c114a3133002002304800141088228dd5982298211baa00233760006980103d87a80008b207e32330010010232259800800c530103d87a80008992cc004cdd78021821000c4c0accc114c10c0052f5c113300300330470024104608a0028218c048cc104c048cc104dd4805a5eb812f5c114a081ea294103d4528207a3026330403041303e37546082607c6ea8068cc10130010100004bd7019baf3016303c3754602c60786ea8c0fc010c058c0f0dd5000992cc004c0b8c0f0dd5000c4c100c0f4dd5000c5903b181f98201820181e1baa001303e0018b2078323300100101a2259800800c52f5c11332259800acc004cdd79820981f1baa00200d89819192cc004c0ccc0f8dd5000c5200089bad3042303f375400281e8c9660026066607c6ea8006298103d87a8000899198008009bab30433040375400444b30010018a6103d87a8000899192cc004c0680062b300130190018981599822982180125eb82298103d87a80004105133004004304700341046eb8c104004c110005042207a3233001001375660846086607e6ea800c896600200314c103d87a8000899192cc004cdc8807000c56600266e3c0380062605466088608400497ae08a60103d87a80004101133004004304600341006eb8c100004c10c0050414528207889982000119802002000c4cc01001000503c181f8009820000a07a8b2076181c801181b8009bae30360013032375401b14a081822b3001302300b8acc004c08cc0c4dd5006c4c8cc88ca60026eb4c0e40066eb4c0e4c0e8c0e8006646600200204044b30010018a5eb8226644b30015980099baf303d303a3754607a607c60746ea80080262605c64b3001302f303a375400314800226eb4c0f8c0ecdd5000a07232598009817981d1baa0018a60103d87a8000899198008009bab303f303c375400444b30010018a6103d87a8000899192cc004c0580062b300130150018981399820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e207232330010013756607c607e60766ea8c0f8c0fcc0ecdd5001912cc004006298103d87a8000899192cc004cdc8805000c56600266e3c0280062604c66080607c00497ae08a60103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d4528207089981e00119802002000c4cc010010005038181d800981e000a0729bae30390034888966002607c005132598009815981d1baa0018992cc004c0b0c0ecdd5000c66002607e60786ea8006646464b30013033303e37540031598009819981f1baa30423043002899b88008375a6084607e6ea8006266e24020dd69821181f9baa00140f514a081e8c104004cc0fcc100004cc0fe6002606260786ea8c100c10400698103d87a8000a60103d879800040ec97ae0303c3754607e60786ea8c0fc086646600200203844b30010018a5eb8226644b30015980099baf30433040375400401f130343259800981a98201baa0018a40011375a608860826ea800503f192cc004c0d4c100dd5000c5300103d87a8000899198008009bab30453042375400444b30010018a6103d87a8000899192cc004c0700062b3001301b0018981699823982280125eb82298103d87a8000410d1330040043049003410c6eb8c10c004c118005044207e323300100137566088608a60826ea800c896600200314c103d87a8000899192cc004cdc8808000c56600266e3c040006260586608c608800497ae08a60103d87a80004109133004004304800341086eb8c108004c1140050434528207c89982100119802002000c4cc01001000503e18208009821000a07e488966002608600313233223301a001159800802c56600200515980099baf0013374a9003198221ba900e330443752012660886ea00312f5c11598009980b80f980a9982200319822260103d87a80004bd7045660026602e03e66e95200c3304400633044375007897ae089819992cc0040062900044c8c058c9660020051480022602e66002002609200482308966002003148002260306600400460940028238c11c00504419198008009bab301d3043375400844b30010018a5eb82264664464660020026eacc12001089660020031003899198261ba73304c375200a66098609200266098609400297ae033003003304e002304c00141286eb8c110004cc00c00cc124008c11c005045452820808a50410114a0820229410404528208098009821804400666e00cdc001d81d01ca0203259800981918201baa0018982218209baa0018b207e3043304430443040375400260840031641008b2074303e303b37540031640e4602860746ea80262c81d86072004606e0026eb8c0d8004c0c8dd5006c52820608acc004c08402e2b300130213031375401b132332298009bae30380029bad30383039002991980080080f912cc004006297ae0899912cc0056600266ebcc0f0c0e4dd5181e181e981c9baa00200889816992cc004c0b8c0e4dd5000c5200089bad303d303a375400281c0c966002605c60726ea8006298103d87a8000899198008009bab303e303b375400444b30010018a6103d87a8000899192cc004c0540062b300130140018981319820181f00125eb82298103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d207032330010013756607a607c60746ea8c0f4c0f8c0e8dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062604a6607e607a00497ae08a60103d87a800040ed133004004304100340ec6eb8c0ec004c0f800503c4528206e89981d80119802002000c4cc010010005037181d000981d800a070488966002607800313259800981e800c4c8c8cc88cc05400456600200515980099baf0013374a90031981f9ba90093303f37520106607e6ea0cdc0003801a5eb822b3001302e3259800800c520008991808992cc00400a2900044c048cc004004c110009041112cc0040062900044c04ccc008008c1140050421821000a07e323300100137566030607c6ea8014896600200314bd7044c8cc88c8cc004004dd59821802112cc004006200713233047374e6608e6ea4014cc11cc110004cc11cc1140052f5c0660060066092004608e0028228dd7181f8009980180198220011821000a080899912cc0040060051598009821800c4c8c96600266e3cdd71822001006456600266e3cdd71822000806c4cdc39bad304430450010078a5040fd14a081f8c110004dd61821000c009040208014a0646600200203844b30010018a5eb82264664464660020026eacc10c01089660020031003899198239ba733047375200a6608e60880026608e608a00297ae0330030033049002304700141146eb8c0fc004cc00c00cc110008c108005040452820768a5040ed14a081d8cdc4000a400064b3001302d303b37540031303f303c37540031640e8607c607e607e60766ea8008cdc098059bab3014303a375400260166eacc050c0e8dd5180a181d1baa303d003303c0018b207432330010010182259800800c52f5c11332259800acc004cdd7981f981e1baa00200b89818192cc004c0c4c0f0dd5000c5200089bad3040303d375400281d8c966002606260786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0600062b300130170018981499821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806000c56600266e3c0300062605066084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a0768b2072181b8009bae30360013032375401b14a081822b300130213031375401b1323298009bae30370019bad303730380019bae30370024889660026076646600200204244b30010018a5eb8226644b30015980099baf303e303b3754607c607e60766ea800802a2605e64b30013030303b375400314800226eb4c0fcc0f0dd5000a07432598009818181d9baa0018a6103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c05c0062b300130160018981419821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8c0fcc100c0f0dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062604e66082607e00497ae08a60103d87a800040f5133004004304300340f46eb8c0f4004c10000503e4528207289981e80119802002000c4cc010010005039181e000981e800a0748acc0056600266e2120000028cc004cdc0a400000514a1323300100132330010010172259800800c52f5c1132332232330010013756607c00844b30010018801c4c8cc108dd3998211ba900533042303f0013304230400014bd701980180198220011821000a080375c607400266006006607e004607a00281d8896600200314bd7044cc896600266e3cdd7181f001003c4cc0f4dd380119802002000c4cc0100100050391bac303c001303d00140e89112cc004006005159800981f000c4c96600266e3cdd7181f000802c4cdc39bad303e303f0010048a5040e4607c6eb0c0f400600481d903b22945035456600264660020026eb0c0ec070896600200314a115980099b8f375c607800206b14a3133002002303d00140dc81d226644b30010018014566002607a0031325980098081bae303d001899b87375a607a607c0029000c5282070303d3758607800300240e881d05281919800800991980080080b912cc004006297ae0899199119198008009bab303e0042259800800c400e264660846e9ccc108dd480299821181f800998211820000a5eb80cc00c00cc110008c1080050401bae303a00133003003303f002303d00140ec44b30010018a5eb8226644b30013371e6eb8c0f800801626607a6e9c008cc01001000626600800800281c8dd6181e000981e800a0748a5040d514a081aa2c81c0606e00260646ea80362941030206040c0818103011119b873370260086eacc034c0ccdd500118021bab300d30333754601a60666ea800c004c0ccc0c0dd5180518181baa00c23259800981298181baa0018a40011375a606860626ea800502f192cc004c094c0c0dd5000c5300103d87a8000899198008009bab30353032375400444b30010018a6103d87a8000899192cc004c0300062b3001300b0018980e9981b981a80125eb82298103d87a800040cd133004004303900340cc6eb8c0cc004c0d8005034205e32330010010022259800800c5300103d87a8000899192cc004c02c0062b3001300a0018980e1981b181a00125eb82298103d87a800040c9133004004303800340c86eb8c0c8004c0d400503322c8118c09cc090dd50024590220c084c084c084c084004c080004c07cc07c004c078004c074c07400c602a6ea8020c058014c058c05c015164030300d0013008375401b149a26cac8031", + "hash": "f707e28ef1513c76e3ce6d34644bf721c1996de346546db71120831f" + }, + { + "title": "spend.spend.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "delegate_pool_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action", + "schema": { + "$ref": "#/definitions/gov~1VGovernanceAction" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "stake_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "drep_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "gov_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + } + ], + "compiledCode": "591a6201010022222229800aba2aba1aba0aab9faab9eaab9dab9a9bae0079bae0059bad0049bad0039bad00248888888888896600264653001300d00198069807000cdc3a4005300d00248889660026004601a6ea800e33001300e3754007370e90024dc3a4001370e90034c034dd5002244444664464b300130060048acc004c058dd500640062c80ba2b3001300a0048acc004c058dd500640062c80ba2b300130070048acc004c058dd500640062c80ba2b300130050048acc004c058dd500640062c80ba2b30013370e90040024566002602c6ea803200316405d16405080a1014202840502653001301a301a0019bac30190019ba548001222323232323298009bab30210019bac302130220019919800800804112cc004006298103d87a80008992cc004cdd7981218109baa00100e8980499811800a5eb82266006006604a00480f8c08c0050214dd618108044dd59810802cdd618108022444444b300130143023375400913259800980a98121baa0118cc004c0a0c094dd5008c8c0a4c0a800660486ea806e4464b300130180018991919194c004dd69817800cdd718178024dd71817801cdd6981780124444b300130340058054590310c0bc004c0b8004c0b4004c0a0dd5001c566002603800313232323298009bad302f0019bae302f0049bae302f0039bad302f0024888966002606800b00a8b206218178009817000981680098141baa0038acc004c064006264646464653001375a6060003375c606000b375c6060009375a606000691112cc004c0d4016264b300130223031375400313232332259800981d001c0422c81b8dd6981b8009bae30370023037001303237540031640c0606800d1640c83030001302f001302e001302d00130283754007159800980b800c4c8c8ca60026eb4c0b80066eb8c0b800e6eb8c0b800922259800981900240222c8178605c002605a00260506ea800e2c8131026204c4098604c6ea800a6e452201009b8f488100911919800800801912cc00400629422b30013375e605800200714a3133002002302d001409c81526e9520049ba54800a6e01200248888888888c8cc89660026044017159800981118189baa00d8991991194c004dd6981c800cdd6981c981d000cc8cc004004080896600200314bd7044cc8966002b30013375e607a60746ea8c0f4c0f8c0e8dd5001004c4c0b8c966002605e60746ea80062900044dd6981f181d9baa00140e464b3001302f303a375400314c103d87a8000899198008009bab303f303c375400444b30010018a6103d87a8000899192cc004c0580062b300130150018981399820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e207232330010013756607c607e60766ea8c0f8c0fcc0ecdd5001912cc004006298103d87a8000899192cc004cdc8805000c56600266e3c0280062604c66080607c00497ae08a60103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d4528207089981e00119802002000c4cc010010005038181d800981e000a0729bae30390034888966002607c005132598009815981d1baa0018992cc004c0b0c0ecdd5000c4cc89660026084003132332233019001159800801456600266ebc004c050cc10cdd4806998219ba9008330433750016660866ea00292f5c11598009819192cc0040062900044c8c054c9660020051480022602c660020026090004822889660020031480022602e6600400460920028230c11800504319198008009bab301c3042375400844b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c11800504445660026602c03c60526608600a6608698103d87a80004bd7045660026602c03c66e9520083304300533043375007697ae08acc00566002b30013301601e301533043005330433014330433029330430054bd7025eb812f5c113301601e30153304300533043302933043375207c97ae04bd704528207e8a5189980b00f180a9982180299821980a998219ba903e330433029330430054bd7025eb812f5c081fa264606c646600200204844b30010018a40011332259800acc004cdc39bad30493046375400407f15980099baf30203046375400400b13371e6eccc124c128c128c118dd50011bb30508a50411114a082222603000310014110608e0026600400460900028228c050cc10cdd4806a5eb82294103f4528207e8a5040fd14a081fa294103f4528207e98009821003c00666e0520003370066e000e80e40e100f192cc004c0c4c0fcdd5000c4c10cc100dd5000c5903e182118219821981f9baa00130410018b207e303f303c3754002646600200203844b30010018a5eb8226644b30015980099baf30433040375400401f130343259800981a98201baa0018a40011375a608860826ea800503f192cc004c0d4c100dd5000c5300103d87a8000899198008009bab30453042375400444b30010018a6103d87a8000899192cc004c0700062b3001301b0018981699823982280125eb82298103d87a8000410d1330040043049003410c6eb8c10c004c118005044207e323300100137566088608a60826ea800c896600200314c103d87a8000899192cc004cdc8808000c56600266e3c040006260586608c608800497ae08a60103d87a80004109133004004304800341086eb8c108004c1140050434528207c89982100119802002000c4cc01001000503e18208009821000a07e8b2074303e303b37540031640e4602860746ea80262c81d86072004606e0026eb8c0d8004c0c8dd5006c52820608acc004c09802e2b300130263031375401b13233223298009bad30390019bad3039303a0019919800800810112cc004006297ae0899912cc0056600266ebcc0f4c0e8dd5181e981f181d1baa00200989817192cc004c0bcc0e8dd5000c5200089bad303e303b375400281c8c966002605e60746ea80062980103d87a8000899198008009bab303f303c375400444b30010018a6103d87a8000899192cc004c0580062b300130150018981399820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e207232330010013756607c607e60766ea8c0f8c0fcc0ecdd5001912cc004006298103d87a8000899192cc004cdc8805000c56600266e3c0280062604c66080607c00497ae08a60103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d4528207089981e00119802002000c4cc010010005038181d800981e000a0729bae30390034888966002607c00513259800981f800c4c8cc88cc0580044c96600200715980099baf0023013330413752016660826ea4018cc104dd400499820800998209ba80084bd704566002606064b30010018a4001132301332598008014520008980a19800800982300120862259800800c520008980a998010011823800a0883044001410464660020026eacc068c100dd5002912cc004006297ae0899199119198008009bab30450042259800800c400e264660926e9ccc124dd4802998249823000998249823800a5eb80cc00c00cc12c008c1240050471bae3041001330030033046002304400141091323259800981898201baa001899199119801001000912cc00400629422b30013375e6e98cc118c11c0052f5bded8c06e98cc11800d2f5bded8c114a3133002002304800141088228dd5982298211baa00233760006980103d87a80008b207e32330010010232259800800c530103d87a80008992cc004cdd78021821000c4c0accc114c10c0052f5c113300300330470024104608a0028218c048cc104c048cc104dd4805a5eb812f5c114a081ea294103d4528207a3026330403041303e37546082607c6ea8068cc10130010100004bd7019baf3016303c3754602c60786ea8c0fc010c058c0f0dd5000992cc004c0b8c0f0dd5000c4c100c0f4dd5000c5903b181f98201820181e1baa001303e0018b2078323300100101a2259800800c52f5c11332259800acc004cdd79820981f1baa00200d89819192cc004c0ccc0f8dd5000c5200089bad3042303f375400281e8c9660026066607c6ea8006298103d87a8000899198008009bab30433040375400444b30010018a6103d87a8000899192cc004c0680062b300130190018981599822982180125eb82298103d87a80004105133004004304700341046eb8c104004c110005042207a3233001001375660846086607e6ea800c896600200314c103d87a8000899192cc004cdc8807000c56600266e3c0380062605466088608400497ae08a60103d87a80004101133004004304600341006eb8c100004c10c0050414528207889982000119802002000c4cc01001000503c181f8009820000a07a8b2076181c801181b8009bae30360013032375401b14a081822b3001302300b8acc004c08cc0c4dd5006c4c8cc88ca60026eb4c0e40066eb4c0e4c0e8c0e8006646600200204044b30010018a5eb8226644b30015980099baf303d303a3754607a607c60746ea80080262605c64b3001302f303a375400314800226eb4c0f8c0ecdd5000a07232598009817981d1baa0018a60103d87a8000899198008009bab303f303c375400444b30010018a6103d87a8000899192cc004c0580062b300130150018981399820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e207232330010013756607c607e60766ea8c0f8c0fcc0ecdd5001912cc004006298103d87a8000899192cc004cdc8805000c56600266e3c0280062604c66080607c00497ae08a60103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d4528207089981e00119802002000c4cc010010005038181d800981e000a0729bae30390034888966002607c005132598009815981d1baa0018992cc004c0b0c0ecdd5000c66002607e60786ea8006646464b30013033303e37540031598009819981f1baa30423043002899b88008375a6084607e6ea8006266e24020dd69821181f9baa00140f514a081e8c104004cc0fcc100004cc0fe6002606260786ea8c100c10400698103d87a8000a60103d879800040ec97ae0303c3754607e60786ea8c0fc086646600200203844b30010018a5eb8226644b30015980099baf30433040375400401f130343259800981a98201baa0018a40011375a608860826ea800503f192cc004c0d4c100dd5000c5300103d87a8000899198008009bab30453042375400444b30010018a6103d87a8000899192cc004c0700062b3001301b0018981699823982280125eb82298103d87a8000410d1330040043049003410c6eb8c10c004c118005044207e323300100137566088608a60826ea800c896600200314c103d87a8000899192cc004cdc8808000c56600266e3c040006260586608c608800497ae08a60103d87a80004109133004004304800341086eb8c108004c1140050434528207c89982100119802002000c4cc01001000503e18208009821000a07e488966002608600313233223301a001159800802c56600200515980099baf0013374a9003198221ba900e330443752012660886ea00312f5c11598009980b80f980a9982200319822260103d87a80004bd7045660026602e03e66e95200c3304400633044375007897ae089819992cc0040062900044c8c058c9660020051480022602e66002002609200482308966002003148002260306600400460940028238c11c00504419198008009bab301d3043375400844b30010018a5eb82264664464660020026eacc12001089660020031003899198261ba73304c375200a66098609200266098609400297ae033003003304e002304c00141286eb8c110004cc00c00cc124008c11c005045452820808a50410114a0820229410404528208098009821804400666e00cdc001d81d01ca0203259800981918201baa0018982218209baa0018b207e3043304430443040375400260840031641008b2074303e303b37540031640e4602860746ea80262c81d86072004606e0026eb8c0d8004c0c8dd5006c52820608acc004c08402e2b300130213031375401b132332298009bae30380029bad30383039002991980080080f912cc004006297ae0899912cc0056600266ebcc0f0c0e4dd5181e181e981c9baa00200889816992cc004c0b8c0e4dd5000c5200089bad303d303a375400281c0c966002605c60726ea8006298103d87a8000899198008009bab303e303b375400444b30010018a6103d87a8000899192cc004c0540062b300130140018981319820181f00125eb82298103d87a800040f1133004004304200340f06eb8c0f0004c0fc00503d207032330010013756607a607c60746ea8c0f4c0f8c0e8dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062604a6607e607a00497ae08a60103d87a800040ed133004004304100340ec6eb8c0ec004c0f800503c4528206e89981d80119802002000c4cc010010005037181d000981d800a070488966002607800313259800981e800c4c8c8cc88cc05400456600200515980099baf0013374a90031981f9ba90093303f37520106607e6ea0cdc0003801a5eb822b3001302e3259800800c520008991808992cc00400a2900044c048cc004004c110009041112cc0040062900044c04ccc008008c1140050421821000a07e323300100137566030607c6ea8014896600200314bd7044c8cc88c8cc004004dd59821802112cc004006200713233047374e6608e6ea4014cc11cc110004cc11cc1140052f5c0660060066092004608e0028228dd7181f8009980180198220011821000a080899912cc0040060051598009821800c4c8c96600266e3cdd71822001006456600266e3cdd71822000806c4cdc39bad304430450010078a5040fd14a081f8c110004dd61821000c009040208014a0646600200203844b30010018a5eb82264664464660020026eacc10c01089660020031003899198239ba733047375200a6608e60880026608e608a00297ae0330030033049002304700141146eb8c0fc004cc00c00cc110008c108005040452820768a5040ed14a081d8cdc4000a400064b3001302d303b37540031303f303c37540031640e8607c607e607e60766ea8008cdc098059bab3014303a375400260166eacc050c0e8dd5180a181d1baa303d003303c0018b207432330010010182259800800c52f5c11332259800acc004cdd7981f981e1baa00200b89818192cc004c0c4c0f0dd5000c5200089bad3040303d375400281d8c966002606260786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0600062b300130170018981499821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806000c56600266e3c0300062605066084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a0768b2072181b8009bae30360013032375401b14a081822b300130213031375401b1323298009bae30370019bad303730380019bae30370024889660026076646600200204244b30010018a5eb8226644b30015980099baf303e303b3754607c607e60766ea800802a2605e64b30013030303b375400314800226eb4c0fcc0f0dd5000a07432598009818181d9baa0018a6103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c05c0062b300130160018981419821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8c0fcc100c0f0dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062604e66082607e00497ae08a60103d87a800040f5133004004304300340f46eb8c0f4004c10000503e4528207289981e80119802002000c4cc010010005039181e000981e800a0748acc0056600266e2120000028cc004cdc0a400000514a1323300100132330010010172259800800c52f5c1132332232330010013756607c00844b30010018801c4c8cc108dd3998211ba900533042303f0013304230400014bd701980180198220011821000a080375c607400266006006607e004607a00281d8896600200314bd7044cc896600266e3cdd7181f001003c4cc0f4dd380119802002000c4cc0100100050391bac303c001303d00140e89112cc004006005159800981f000c4c96600266e3cdd7181f000802c4cdc39bad303e303f0010048a5040e4607c6eb0c0f400600481d903b22945035456600264660020026eb0c0ec070896600200314a115980099b8f375c607800206b14a3133002002303d00140dc81d226644b30010018014566002607a0031325980098081bae303d001899b87375a607a607c0029000c5282070303d3758607800300240e881d05281919800800991980080080b912cc004006297ae0899199119198008009bab303e0042259800800c400e264660846e9ccc108dd480299821181f800998211820000a5eb80cc00c00cc110008c1080050401bae303a00133003003303f002303d00140ec44b30010018a5eb8226644b30013371e6eb8c0f800801626607a6e9c008cc01001000626600800800281c8dd6181e000981e800a0748a5040d514a081aa2c81c0606e00260646ea80362941030206040c0818103011119b873370260086eacc034c0ccdd500118021bab300d30333754601a60666ea800c004c0ccc0c0dd5180518181baa00c23259800981298181baa0018a40011375a606860626ea800502f192cc004c094c0c0dd5000c5300103d87a8000899198008009bab30353032375400444b30010018a6103d87a8000899192cc004c0300062b3001300b0018980e9981b981a80125eb82298103d87a800040cd133004004303900340cc6eb8c0cc004c0d8005034205e32330010010022259800800c5300103d87a8000899192cc004c02c0062b3001300a0018980e1981b181a00125eb82298103d87a800040c9133004004303800340c86eb8c0c8004c0d400503322c8118c09cc090dd50024590220c084c084c084c084004c080004c07cc07c004c078004c074c07400c602a6ea8020c058014c058c05c015164030300d0013008375401b149a26cac8031", + "hash": "f707e28ef1513c76e3ce6d34644bf721c1996de346546db71120831f" + }, + { + "title": "start.start.withdraw", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590c4a01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e90004dc3a4005370e90024dc3a400d374a90004dd2a400491111114c004c04401e602000f2232598009804800c56600260206ea800e0051640451598009804000c56600260206ea800e0051640451598009803800c56600260206ea800e0051640451598009803000c56600260206ea800e00516404515980099b87480200062b3001301037540070028b20228b201c4038807100e201c300e3754005223232330010010042259800800c530103d87a80008992cc004cdd78021809000c4c020cc054c04c0052f5c113300300330170024044602a0028098c00ccc044c048c03cdd5000a5eb81222232332259800980580144c8c8ca60026eacc0680066034602e6ea801a64660020026eb0c06c010896600200314bd7044cc8966002646600200264660020026eacc080c084c074dd518101810980e9baa0042259800800c52f5c1132332232330010013756604400844b30010018801c4c8cc098dd3998131ba90053302630230013302630240014bd701980180198140011813000a048375c603c002660060066046004604200280f8896600200314a115980099b8f375c60406eb0c08000406a2946266004004604200280d901e44cc074008cc01001000626600800800280c8c070004c07400501a2444b3001301e0018999119912cc004c05cc074dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c0ac0066eb8c0ac02a6eb8c0ac0266eb4c0ac01e6eb4c0ac01a64b300130290018acc004cdc4a4008605000316898109814000a04e8b20543754605600b375a6056009375a6056007302b002488888888966002606a01513301430340111330140011329800981b000cdd7181a800cdc7a45009b9148810048888ca60026076003323322330020020012259800800c52f5c11332259800acc004cdd7981f981e1baa0020058981a192cc004c0d4c0f0dd5000c5200089bad3040303d375400281d8c966002606a60786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0300062b3001300d0018981b19821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806800c56600266e3c0340062606a66084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a076375860760466058660726056660726ea40cd2f5c0660726058660726058660726056660726ea40112f5c097ae04bd7025eb8266ebcc0accc0e4dd480225eb8007d22259800981f00144c8cc88cc8966002607000313232323298009bad30460019bae30460049bae30460039bad30460024888966002609600b00a8b2090182300098228009822000981f9baa0038acc004c0dc0062646464653001375a608c003375c608c009375c608c007375a608c00491112cc004c12c016015164120304600130450013044001303f3754007159800981b000c4c8c8c8c8ca60026eb4c11c0066eb8c11c0166eb8c11c0126eb4c11c00d2222598009826002c4c966002608460906ea8006264646644b3001305100380845904e1bad304e001375c609c004609c00260926ea80062c8238c12c01a2c8248608e002608c002608a0026088002607e6ea800e2b3001303500189919194c004dd69822800cdd71822801cdd718228012444b300130490048044590460c114004c110004c0fcdd5001c5903d207a40f481e84cc89660026070607c6ea8006264660620022b30010078acc0040162b30010038acc004cc89660020030028acc004c118006264b3001300f375c608c0031303b375a608c608e00314a08208c118dd61822800c009043208614a06466002002646600200205644b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc004006297ae0899912cc004cdc79bae30470020118998231ba700233004004001899802002000a0843758608a002608c002821a266ebc005300103d87a80008a5040f914a081f2294103e4528207c3042303f37540031640f466ebc004c0c8cc0fcdd48051981f98200059981f98200031981f9ba8337006eb4c100c104c1040180e12f5c06605a6eacc100c104c104c104c104c10409c08cc0f0dd500099b873259800981a181d9baa0018a40011375a607e60786ea800503a192cc004c0d0c0ecdd5000c530103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c02c0062b3001300c0018981a99821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8008896600200314c103d87a8000899192cc004c0280062b3001300b0018981a19820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e1bad303e00532598009819981d9baa0018981f981e1baa0018b2074303e303f303f303b3754002607a0051640ec303a303a00418189baa0158b2064181580098150009814800981400098138009813000981280098120009811800980f1baa0028b20383259800980a180e1baa00189810180e9baa0018b2036301f30203020301c3754603e604060386ea80088966002602e603a6ea800a2646464b3001302500289980318120018992cc004c06c006264b30013027001899192cc004c078006264b3001302a0018998059814800804c5902718129baa0028acc004c07400626464653001375a6056003375a6056007375a60560049112cc004c0bc01201d1640b0302b001302a0013025375400516408c8118c08cdd50009813000c5902418111baa0028acc004c0680062b3001302237540050058b20468b2040408060406ea80062c8110c08c004c08c004c078dd500145901c180e80091192cc004c05800626464b300130230028024590201bae3021001301d3754007159800980a800c4c8c96600260460050048b2040375c6042002603a6ea800e2c80d901b180d9baa0028b2036180d180d000980c980c800980a1baa006899192cc004c03c0122646644b300130120018acc004c064dd5003400a2c80d22b300130110018acc004c064dd5003400a2c80d22c80b9017099192cc004c048c060dd500344c8c8cc004004dd5980f001912cc00400629422b30013375e0066036603e00314a31330020023020001406880e8c034cc06cdd4801a5eb82330010159bac301c0029bab301c301d301d301d001a6103d87d8000401080b8c070c070c070c070c070c070004c05cdd5004980b1baa004375c6032602c6ea80162b3001300c0048994c004dd6980d000cc068c06c006602c6ea801226464b3001301d0018992cc004c04cc064dd5000c4c8cc030004566002602860346ea8022266ebc00530103d8798000899baf0014c103d87b80004064603a60346ea80062c80c0cc024dd5980e180e980e980e980e980e980e980e980e980e801180e000c5901a19199119801001000912cc004006297ae0899912cc004cdd79810180e9baa30203021301d375400400b13301f00233004004001899802002000a036301e001301f00140706eb0c070008c010050c05cdd5004a4444b300130140028acc004c06cdd500440062c80e22b300130130028acc004c06cdd500440062c80e22c80c90190c058dd5002c56600266e1d200a0048994c004dd6980d000cc068c06c006602e6ea8025222980080b4dd6180e800cdd5980e980f180f180f180f180f180f180f180f180f000d30103d879800040143016375400b15980099b87480200122664530010149bac301b0019bab301b301c301c301c301c301c301c301c301c301c001a60103d87a8000400c6032602c6ea8014c058dd50044590142028405080a08888c966002603c00313259800980a180d1baa00189919806800899baf001004301e301b375400316406466014006603a00316406c64646600200200a44b30010018a5eb8226644b30013375e6042603c6ea8c084c088c078dd5001002c4cc080008cc01001000626600800800280e0c07c004c08000501d1802802118051980b98049980b9ba90014bd701980ba60103d87a80004bd70202430113754002602a00a6028602a008452689b2b20081", + "hash": "55c2a7f6143ce2befd94139304436b30a0398f21cd2464c760455033" + }, + { + "title": "start.start.mint", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1MintPolarity" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590c4a01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e90004dc3a4005370e90024dc3a400d374a90004dd2a400491111114c004c04401e602000f2232598009804800c56600260206ea800e0051640451598009804000c56600260206ea800e0051640451598009803800c56600260206ea800e0051640451598009803000c56600260206ea800e00516404515980099b87480200062b3001301037540070028b20228b201c4038807100e201c300e3754005223232330010010042259800800c530103d87a80008992cc004cdd78021809000c4c020cc054c04c0052f5c113300300330170024044602a0028098c00ccc044c048c03cdd5000a5eb81222232332259800980580144c8c8ca60026eacc0680066034602e6ea801a64660020026eb0c06c010896600200314bd7044cc8966002646600200264660020026eacc080c084c074dd518101810980e9baa0042259800800c52f5c1132332232330010013756604400844b30010018801c4c8cc098dd3998131ba90053302630230013302630240014bd701980180198140011813000a048375c603c002660060066046004604200280f8896600200314a115980099b8f375c60406eb0c08000406a2946266004004604200280d901e44cc074008cc01001000626600800800280c8c070004c07400501a2444b3001301e0018999119912cc004c05cc074dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c0ac0066eb8c0ac02a6eb8c0ac0266eb4c0ac01e6eb4c0ac01a64b300130290018acc004cdc4a4008605000316898109814000a04e8b20543754605600b375a6056009375a6056007302b002488888888966002606a01513301430340111330140011329800981b000cdd7181a800cdc7a45009b9148810048888ca60026076003323322330020020012259800800c52f5c11332259800acc004cdd7981f981e1baa0020058981a192cc004c0d4c0f0dd5000c5200089bad3040303d375400281d8c966002606a60786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0300062b3001300d0018981b19821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806800c56600266e3c0340062606a66084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a076375860760466058660726056660726ea40cd2f5c0660726058660726058660726056660726ea40112f5c097ae04bd7025eb8266ebcc0accc0e4dd480225eb8007d22259800981f00144c8cc88cc8966002607000313232323298009bad30460019bae30460049bae30460039bad30460024888966002609600b00a8b2090182300098228009822000981f9baa0038acc004c0dc0062646464653001375a608c003375c608c009375c608c007375a608c00491112cc004c12c016015164120304600130450013044001303f3754007159800981b000c4c8c8c8c8ca60026eb4c11c0066eb8c11c0166eb8c11c0126eb4c11c00d2222598009826002c4c966002608460906ea8006264646644b3001305100380845904e1bad304e001375c609c004609c00260926ea80062c8238c12c01a2c8248608e002608c002608a0026088002607e6ea800e2b3001303500189919194c004dd69822800cdd71822801cdd718228012444b300130490048044590460c114004c110004c0fcdd5001c5903d207a40f481e84cc89660026070607c6ea8006264660620022b30010078acc0040162b30010038acc004cc89660020030028acc004c118006264b3001300f375c608c0031303b375a608c608e00314a08208c118dd61822800c009043208614a06466002002646600200205644b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc004006297ae0899912cc004cdc79bae30470020118998231ba700233004004001899802002000a0843758608a002608c002821a266ebc005300103d87a80008a5040f914a081f2294103e4528207c3042303f37540031640f466ebc004c0c8cc0fcdd48051981f98200059981f98200031981f9ba8337006eb4c100c104c1040180e12f5c06605a6eacc100c104c104c104c104c10409c08cc0f0dd500099b873259800981a181d9baa0018a40011375a607e60786ea800503a192cc004c0d0c0ecdd5000c530103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c02c0062b3001300c0018981a99821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8008896600200314c103d87a8000899192cc004c0280062b3001300b0018981a19820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e1bad303e00532598009819981d9baa0018981f981e1baa0018b2074303e303f303f303b3754002607a0051640ec303a303a00418189baa0158b2064181580098150009814800981400098138009813000981280098120009811800980f1baa0028b20383259800980a180e1baa00189810180e9baa0018b2036301f30203020301c3754603e604060386ea80088966002602e603a6ea800a2646464b3001302500289980318120018992cc004c06c006264b30013027001899192cc004c078006264b3001302a0018998059814800804c5902718129baa0028acc004c07400626464653001375a6056003375a6056007375a60560049112cc004c0bc01201d1640b0302b001302a0013025375400516408c8118c08cdd50009813000c5902418111baa0028acc004c0680062b3001302237540050058b20468b2040408060406ea80062c8110c08c004c08c004c078dd500145901c180e80091192cc004c05800626464b300130230028024590201bae3021001301d3754007159800980a800c4c8c96600260460050048b2040375c6042002603a6ea800e2c80d901b180d9baa0028b2036180d180d000980c980c800980a1baa006899192cc004c03c0122646644b300130120018acc004c064dd5003400a2c80d22b300130110018acc004c064dd5003400a2c80d22c80b9017099192cc004c048c060dd500344c8c8cc004004dd5980f001912cc00400629422b30013375e0066036603e00314a31330020023020001406880e8c034cc06cdd4801a5eb82330010159bac301c0029bab301c301d301d301d001a6103d87d8000401080b8c070c070c070c070c070c070004c05cdd5004980b1baa004375c6032602c6ea80162b3001300c0048994c004dd6980d000cc068c06c006602c6ea801226464b3001301d0018992cc004c04cc064dd5000c4c8cc030004566002602860346ea8022266ebc00530103d8798000899baf0014c103d87b80004064603a60346ea80062c80c0cc024dd5980e180e980e980e980e980e980e980e980e980e801180e000c5901a19199119801001000912cc004006297ae0899912cc004cdd79810180e9baa30203021301d375400400b13301f00233004004001899802002000a036301e001301f00140706eb0c070008c010050c05cdd5004a4444b300130140028acc004c06cdd500440062c80e22b300130130028acc004c06cdd500440062c80e22c80c90190c058dd5002c56600266e1d200a0048994c004dd6980d000cc068c06c006602e6ea8025222980080b4dd6180e800cdd5980e980f180f180f180f180f180f180f180f180f000d30103d879800040143016375400b15980099b87480200122664530010149bac301b0019bab301b301c301c301c301c301c301c301c301c301c001a60103d87a8000400c6032602c6ea8014c058dd50044590142028405080a08888c966002603c00313259800980a180d1baa00189919806800899baf001004301e301b375400316406466014006603a00316406c64646600200200a44b30010018a5eb8226644b30013375e6042603c6ea8c084c088c078dd5001002c4cc080008cc01001000626600800800280e0c07c004c08000501d1802802118051980b98049980b9ba90014bd701980ba60103d87a80004bd70202430113754002602a00a6028602a008452689b2b20081", + "hash": "55c2a7f6143ce2befd94139304436b30a0398f21cd2464c760455033" + }, + { + "title": "start.start.publish", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1PublishRedeemer" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590c4a01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e90004dc3a4005370e90024dc3a400d374a90004dd2a400491111114c004c04401e602000f2232598009804800c56600260206ea800e0051640451598009804000c56600260206ea800e0051640451598009803800c56600260206ea800e0051640451598009803000c56600260206ea800e00516404515980099b87480200062b3001301037540070028b20228b201c4038807100e201c300e3754005223232330010010042259800800c530103d87a80008992cc004cdd78021809000c4c020cc054c04c0052f5c113300300330170024044602a0028098c00ccc044c048c03cdd5000a5eb81222232332259800980580144c8c8ca60026eacc0680066034602e6ea801a64660020026eb0c06c010896600200314bd7044cc8966002646600200264660020026eacc080c084c074dd518101810980e9baa0042259800800c52f5c1132332232330010013756604400844b30010018801c4c8cc098dd3998131ba90053302630230013302630240014bd701980180198140011813000a048375c603c002660060066046004604200280f8896600200314a115980099b8f375c60406eb0c08000406a2946266004004604200280d901e44cc074008cc01001000626600800800280c8c070004c07400501a2444b3001301e0018999119912cc004c05cc074dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c0ac0066eb8c0ac02a6eb8c0ac0266eb4c0ac01e6eb4c0ac01a64b300130290018acc004cdc4a4008605000316898109814000a04e8b20543754605600b375a6056009375a6056007302b002488888888966002606a01513301430340111330140011329800981b000cdd7181a800cdc7a45009b9148810048888ca60026076003323322330020020012259800800c52f5c11332259800acc004cdd7981f981e1baa0020058981a192cc004c0d4c0f0dd5000c5200089bad3040303d375400281d8c966002606a60786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0300062b3001300d0018981b19821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806800c56600266e3c0340062606a66084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a076375860760466058660726056660726ea40cd2f5c0660726058660726058660726056660726ea40112f5c097ae04bd7025eb8266ebcc0accc0e4dd480225eb8007d22259800981f00144c8cc88cc8966002607000313232323298009bad30460019bae30460049bae30460039bad30460024888966002609600b00a8b2090182300098228009822000981f9baa0038acc004c0dc0062646464653001375a608c003375c608c009375c608c007375a608c00491112cc004c12c016015164120304600130450013044001303f3754007159800981b000c4c8c8c8c8ca60026eb4c11c0066eb8c11c0166eb8c11c0126eb4c11c00d2222598009826002c4c966002608460906ea8006264646644b3001305100380845904e1bad304e001375c609c004609c00260926ea80062c8238c12c01a2c8248608e002608c002608a0026088002607e6ea800e2b3001303500189919194c004dd69822800cdd71822801cdd718228012444b300130490048044590460c114004c110004c0fcdd5001c5903d207a40f481e84cc89660026070607c6ea8006264660620022b30010078acc0040162b30010038acc004cc89660020030028acc004c118006264b3001300f375c608c0031303b375a608c608e00314a08208c118dd61822800c009043208614a06466002002646600200205644b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc004006297ae0899912cc004cdc79bae30470020118998231ba700233004004001899802002000a0843758608a002608c002821a266ebc005300103d87a80008a5040f914a081f2294103e4528207c3042303f37540031640f466ebc004c0c8cc0fcdd48051981f98200059981f98200031981f9ba8337006eb4c100c104c1040180e12f5c06605a6eacc100c104c104c104c104c10409c08cc0f0dd500099b873259800981a181d9baa0018a40011375a607e60786ea800503a192cc004c0d0c0ecdd5000c530103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c02c0062b3001300c0018981a99821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8008896600200314c103d87a8000899192cc004c0280062b3001300b0018981a19820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e1bad303e00532598009819981d9baa0018981f981e1baa0018b2074303e303f303f303b3754002607a0051640ec303a303a00418189baa0158b2064181580098150009814800981400098138009813000981280098120009811800980f1baa0028b20383259800980a180e1baa00189810180e9baa0018b2036301f30203020301c3754603e604060386ea80088966002602e603a6ea800a2646464b3001302500289980318120018992cc004c06c006264b30013027001899192cc004c078006264b3001302a0018998059814800804c5902718129baa0028acc004c07400626464653001375a6056003375a6056007375a60560049112cc004c0bc01201d1640b0302b001302a0013025375400516408c8118c08cdd50009813000c5902418111baa0028acc004c0680062b3001302237540050058b20468b2040408060406ea80062c8110c08c004c08c004c078dd500145901c180e80091192cc004c05800626464b300130230028024590201bae3021001301d3754007159800980a800c4c8c96600260460050048b2040375c6042002603a6ea800e2c80d901b180d9baa0028b2036180d180d000980c980c800980a1baa006899192cc004c03c0122646644b300130120018acc004c064dd5003400a2c80d22b300130110018acc004c064dd5003400a2c80d22c80b9017099192cc004c048c060dd500344c8c8cc004004dd5980f001912cc00400629422b30013375e0066036603e00314a31330020023020001406880e8c034cc06cdd4801a5eb82330010159bac301c0029bab301c301d301d301d001a6103d87d8000401080b8c070c070c070c070c070c070004c05cdd5004980b1baa004375c6032602c6ea80162b3001300c0048994c004dd6980d000cc068c06c006602c6ea801226464b3001301d0018992cc004c04cc064dd5000c4c8cc030004566002602860346ea8022266ebc00530103d8798000899baf0014c103d87b80004064603a60346ea80062c80c0cc024dd5980e180e980e980e980e980e980e980e980e980e801180e000c5901a19199119801001000912cc004006297ae0899912cc004cdd79810180e9baa30203021301d375400400b13301f00233004004001899802002000a036301e001301f00140706eb0c070008c010050c05cdd5004a4444b300130140028acc004c06cdd500440062c80e22b300130130028acc004c06cdd500440062c80e22c80c90190c058dd5002c56600266e1d200a0048994c004dd6980d000cc068c06c006602e6ea8025222980080b4dd6180e800cdd5980e980f180f180f180f180f180f180f180f180f000d30103d879800040143016375400b15980099b87480200122664530010149bac301b0019bab301b301c301c301c301c301c301c301c301c301c001a60103d87a8000400c6032602c6ea8014c058dd50044590142028405080a08888c966002603c00313259800980a180d1baa00189919806800899baf001004301e301b375400316406466014006603a00316406c64646600200200a44b30010018a5eb8226644b30013375e6042603c6ea8c084c088c078dd5001002c4cc080008cc01001000626600800800280e0c07c004c08000501d1802802118051980b98049980b9ba90014bd701980ba60103d87a80004bd70202430113754002602a00a6028602a008452689b2b20081", + "hash": "55c2a7f6143ce2befd94139304436b30a0398f21cd2464c760455033" + }, + { + "title": "start.start.propose", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590c4a01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e90004dc3a4005370e90024dc3a400d374a90004dd2a400491111114c004c04401e602000f2232598009804800c56600260206ea800e0051640451598009804000c56600260206ea800e0051640451598009803800c56600260206ea800e0051640451598009803000c56600260206ea800e00516404515980099b87480200062b3001301037540070028b20228b201c4038807100e201c300e3754005223232330010010042259800800c530103d87a80008992cc004cdd78021809000c4c020cc054c04c0052f5c113300300330170024044602a0028098c00ccc044c048c03cdd5000a5eb81222232332259800980580144c8c8ca60026eacc0680066034602e6ea801a64660020026eb0c06c010896600200314bd7044cc8966002646600200264660020026eacc080c084c074dd518101810980e9baa0042259800800c52f5c1132332232330010013756604400844b30010018801c4c8cc098dd3998131ba90053302630230013302630240014bd701980180198140011813000a048375c603c002660060066046004604200280f8896600200314a115980099b8f375c60406eb0c08000406a2946266004004604200280d901e44cc074008cc01001000626600800800280c8c070004c07400501a2444b3001301e0018999119912cc004c05cc074dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c0ac0066eb8c0ac02a6eb8c0ac0266eb4c0ac01e6eb4c0ac01a64b300130290018acc004cdc4a4008605000316898109814000a04e8b20543754605600b375a6056009375a6056007302b002488888888966002606a01513301430340111330140011329800981b000cdd7181a800cdc7a45009b9148810048888ca60026076003323322330020020012259800800c52f5c11332259800acc004cdd7981f981e1baa0020058981a192cc004c0d4c0f0dd5000c5200089bad3040303d375400281d8c966002606a60786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0300062b3001300d0018981b19821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806800c56600266e3c0340062606a66084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a076375860760466058660726056660726ea40cd2f5c0660726058660726058660726056660726ea40112f5c097ae04bd7025eb8266ebcc0accc0e4dd480225eb8007d22259800981f00144c8cc88cc8966002607000313232323298009bad30460019bae30460049bae30460039bad30460024888966002609600b00a8b2090182300098228009822000981f9baa0038acc004c0dc0062646464653001375a608c003375c608c009375c608c007375a608c00491112cc004c12c016015164120304600130450013044001303f3754007159800981b000c4c8c8c8c8ca60026eb4c11c0066eb8c11c0166eb8c11c0126eb4c11c00d2222598009826002c4c966002608460906ea8006264646644b3001305100380845904e1bad304e001375c609c004609c00260926ea80062c8238c12c01a2c8248608e002608c002608a0026088002607e6ea800e2b3001303500189919194c004dd69822800cdd71822801cdd718228012444b300130490048044590460c114004c110004c0fcdd5001c5903d207a40f481e84cc89660026070607c6ea8006264660620022b30010078acc0040162b30010038acc004cc89660020030028acc004c118006264b3001300f375c608c0031303b375a608c608e00314a08208c118dd61822800c009043208614a06466002002646600200205644b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc004006297ae0899912cc004cdc79bae30470020118998231ba700233004004001899802002000a0843758608a002608c002821a266ebc005300103d87a80008a5040f914a081f2294103e4528207c3042303f37540031640f466ebc004c0c8cc0fcdd48051981f98200059981f98200031981f9ba8337006eb4c100c104c1040180e12f5c06605a6eacc100c104c104c104c104c10409c08cc0f0dd500099b873259800981a181d9baa0018a40011375a607e60786ea800503a192cc004c0d0c0ecdd5000c530103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c02c0062b3001300c0018981a99821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8008896600200314c103d87a8000899192cc004c0280062b3001300b0018981a19820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e1bad303e00532598009819981d9baa0018981f981e1baa0018b2074303e303f303f303b3754002607a0051640ec303a303a00418189baa0158b2064181580098150009814800981400098138009813000981280098120009811800980f1baa0028b20383259800980a180e1baa00189810180e9baa0018b2036301f30203020301c3754603e604060386ea80088966002602e603a6ea800a2646464b3001302500289980318120018992cc004c06c006264b30013027001899192cc004c078006264b3001302a0018998059814800804c5902718129baa0028acc004c07400626464653001375a6056003375a6056007375a60560049112cc004c0bc01201d1640b0302b001302a0013025375400516408c8118c08cdd50009813000c5902418111baa0028acc004c0680062b3001302237540050058b20468b2040408060406ea80062c8110c08c004c08c004c078dd500145901c180e80091192cc004c05800626464b300130230028024590201bae3021001301d3754007159800980a800c4c8c96600260460050048b2040375c6042002603a6ea800e2c80d901b180d9baa0028b2036180d180d000980c980c800980a1baa006899192cc004c03c0122646644b300130120018acc004c064dd5003400a2c80d22b300130110018acc004c064dd5003400a2c80d22c80b9017099192cc004c048c060dd500344c8c8cc004004dd5980f001912cc00400629422b30013375e0066036603e00314a31330020023020001406880e8c034cc06cdd4801a5eb82330010159bac301c0029bab301c301d301d301d001a6103d87d8000401080b8c070c070c070c070c070c070004c05cdd5004980b1baa004375c6032602c6ea80162b3001300c0048994c004dd6980d000cc068c06c006602c6ea801226464b3001301d0018992cc004c04cc064dd5000c4c8cc030004566002602860346ea8022266ebc00530103d8798000899baf0014c103d87b80004064603a60346ea80062c80c0cc024dd5980e180e980e980e980e980e980e980e980e980e801180e000c5901a19199119801001000912cc004006297ae0899912cc004cdd79810180e9baa30203021301d375400400b13301f00233004004001899802002000a036301e001301f00140706eb0c070008c010050c05cdd5004a4444b300130140028acc004c06cdd500440062c80e22b300130130028acc004c06cdd500440062c80e22c80c90190c058dd5002c56600266e1d200a0048994c004dd6980d000cc068c06c006602e6ea8025222980080b4dd6180e800cdd5980e980f180f180f180f180f180f180f180f180f000d30103d879800040143016375400b15980099b87480200122664530010149bac301b0019bab301b301c301c301c301c301c301c301c301c301c001a60103d87a8000400c6032602c6ea8014c058dd50044590142028405080a08888c966002603c00313259800980a180d1baa00189919806800899baf001004301e301b375400316406466014006603a00316406c64646600200200a44b30010018a5eb8226644b30013375e6042603c6ea8c084c088c078dd5001002c4cc080008cc01001000626600800800280e0c07c004c08000501d1802802118051980b98049980b9ba90014bd701980ba60103d87a80004bd70202430113754002602a00a6028602a008452689b2b20081", + "hash": "55c2a7f6143ce2befd94139304436b30a0398f21cd2464c760455033" + }, + { + "title": "start.start.vote", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590c4a01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e90004dc3a4005370e90024dc3a400d374a90004dd2a400491111114c004c04401e602000f2232598009804800c56600260206ea800e0051640451598009804000c56600260206ea800e0051640451598009803800c56600260206ea800e0051640451598009803000c56600260206ea800e00516404515980099b87480200062b3001301037540070028b20228b201c4038807100e201c300e3754005223232330010010042259800800c530103d87a80008992cc004cdd78021809000c4c020cc054c04c0052f5c113300300330170024044602a0028098c00ccc044c048c03cdd5000a5eb81222232332259800980580144c8c8ca60026eacc0680066034602e6ea801a64660020026eb0c06c010896600200314bd7044cc8966002646600200264660020026eacc080c084c074dd518101810980e9baa0042259800800c52f5c1132332232330010013756604400844b30010018801c4c8cc098dd3998131ba90053302630230013302630240014bd701980180198140011813000a048375c603c002660060066046004604200280f8896600200314a115980099b8f375c60406eb0c08000406a2946266004004604200280d901e44cc074008cc01001000626600800800280c8c070004c07400501a2444b3001301e0018999119912cc004c05cc074dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c0ac0066eb8c0ac02a6eb8c0ac0266eb4c0ac01e6eb4c0ac01a64b300130290018acc004cdc4a4008605000316898109814000a04e8b20543754605600b375a6056009375a6056007302b002488888888966002606a01513301430340111330140011329800981b000cdd7181a800cdc7a45009b9148810048888ca60026076003323322330020020012259800800c52f5c11332259800acc004cdd7981f981e1baa0020058981a192cc004c0d4c0f0dd5000c5200089bad3040303d375400281d8c966002606a60786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0300062b3001300d0018981b19821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806800c56600266e3c0340062606a66084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a076375860760466058660726056660726ea40cd2f5c0660726058660726058660726056660726ea40112f5c097ae04bd7025eb8266ebcc0accc0e4dd480225eb8007d22259800981f00144c8cc88cc8966002607000313232323298009bad30460019bae30460049bae30460039bad30460024888966002609600b00a8b2090182300098228009822000981f9baa0038acc004c0dc0062646464653001375a608c003375c608c009375c608c007375a608c00491112cc004c12c016015164120304600130450013044001303f3754007159800981b000c4c8c8c8c8ca60026eb4c11c0066eb8c11c0166eb8c11c0126eb4c11c00d2222598009826002c4c966002608460906ea8006264646644b3001305100380845904e1bad304e001375c609c004609c00260926ea80062c8238c12c01a2c8248608e002608c002608a0026088002607e6ea800e2b3001303500189919194c004dd69822800cdd71822801cdd718228012444b300130490048044590460c114004c110004c0fcdd5001c5903d207a40f481e84cc89660026070607c6ea8006264660620022b30010078acc0040162b30010038acc004cc89660020030028acc004c118006264b3001300f375c608c0031303b375a608c608e00314a08208c118dd61822800c009043208614a06466002002646600200205644b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc004006297ae0899912cc004cdc79bae30470020118998231ba700233004004001899802002000a0843758608a002608c002821a266ebc005300103d87a80008a5040f914a081f2294103e4528207c3042303f37540031640f466ebc004c0c8cc0fcdd48051981f98200059981f98200031981f9ba8337006eb4c100c104c1040180e12f5c06605a6eacc100c104c104c104c104c10409c08cc0f0dd500099b873259800981a181d9baa0018a40011375a607e60786ea800503a192cc004c0d0c0ecdd5000c530103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c02c0062b3001300c0018981a99821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8008896600200314c103d87a8000899192cc004c0280062b3001300b0018981a19820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e1bad303e00532598009819981d9baa0018981f981e1baa0018b2074303e303f303f303b3754002607a0051640ec303a303a00418189baa0158b2064181580098150009814800981400098138009813000981280098120009811800980f1baa0028b20383259800980a180e1baa00189810180e9baa0018b2036301f30203020301c3754603e604060386ea80088966002602e603a6ea800a2646464b3001302500289980318120018992cc004c06c006264b30013027001899192cc004c078006264b3001302a0018998059814800804c5902718129baa0028acc004c07400626464653001375a6056003375a6056007375a60560049112cc004c0bc01201d1640b0302b001302a0013025375400516408c8118c08cdd50009813000c5902418111baa0028acc004c0680062b3001302237540050058b20468b2040408060406ea80062c8110c08c004c08c004c078dd500145901c180e80091192cc004c05800626464b300130230028024590201bae3021001301d3754007159800980a800c4c8c96600260460050048b2040375c6042002603a6ea800e2c80d901b180d9baa0028b2036180d180d000980c980c800980a1baa006899192cc004c03c0122646644b300130120018acc004c064dd5003400a2c80d22b300130110018acc004c064dd5003400a2c80d22c80b9017099192cc004c048c060dd500344c8c8cc004004dd5980f001912cc00400629422b30013375e0066036603e00314a31330020023020001406880e8c034cc06cdd4801a5eb82330010159bac301c0029bab301c301d301d301d001a6103d87d8000401080b8c070c070c070c070c070c070004c05cdd5004980b1baa004375c6032602c6ea80162b3001300c0048994c004dd6980d000cc068c06c006602c6ea801226464b3001301d0018992cc004c04cc064dd5000c4c8cc030004566002602860346ea8022266ebc00530103d8798000899baf0014c103d87b80004064603a60346ea80062c80c0cc024dd5980e180e980e980e980e980e980e980e980e980e801180e000c5901a19199119801001000912cc004006297ae0899912cc004cdd79810180e9baa30203021301d375400400b13301f00233004004001899802002000a036301e001301f00140706eb0c070008c010050c05cdd5004a4444b300130140028acc004c06cdd500440062c80e22b300130130028acc004c06cdd500440062c80e22c80c90190c058dd5002c56600266e1d200a0048994c004dd6980d000cc068c06c006602e6ea8025222980080b4dd6180e800cdd5980e980f180f180f180f180f180f180f180f180f000d30103d879800040143016375400b15980099b87480200122664530010149bac301b0019bab301b301c301c301c301c301c301c301c301c301c001a60103d87a8000400c6032602c6ea8014c058dd50044590142028405080a08888c966002603c00313259800980a180d1baa00189919806800899baf001004301e301b375400316406466014006603a00316406c64646600200200a44b30010018a5eb8226644b30013375e6042603c6ea8c084c088c078dd5001002c4cc080008cc01001000626600800800280e0c07c004c08000501d1802802118051980b98049980b9ba90014bd701980ba60103d87a80004bd70202430113754002602a00a6028602a008452689b2b20081", + "hash": "55c2a7f6143ce2befd94139304436b30a0398f21cd2464c760455033" + }, + { + "title": "start.start.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "590c4a01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e90004dc3a4005370e90024dc3a400d374a90004dd2a400491111114c004c04401e602000f2232598009804800c56600260206ea800e0051640451598009804000c56600260206ea800e0051640451598009803800c56600260206ea800e0051640451598009803000c56600260206ea800e00516404515980099b87480200062b3001301037540070028b20228b201c4038807100e201c300e3754005223232330010010042259800800c530103d87a80008992cc004cdd78021809000c4c020cc054c04c0052f5c113300300330170024044602a0028098c00ccc044c048c03cdd5000a5eb81222232332259800980580144c8c8ca60026eacc0680066034602e6ea801a64660020026eb0c06c010896600200314bd7044cc8966002646600200264660020026eacc080c084c074dd518101810980e9baa0042259800800c52f5c1132332232330010013756604400844b30010018801c4c8cc098dd3998131ba90053302630230013302630240014bd701980180198140011813000a048375c603c002660060066046004604200280f8896600200314a115980099b8f375c60406eb0c08000406a2946266004004604200280d901e44cc074008cc01001000626600800800280c8c070004c07400501a2444b3001301e0018999119912cc004c05cc074dd500144c8c8c8c8c8c8c8c8c8ca60026eb4c0ac0066eb8c0ac02a6eb8c0ac0266eb4c0ac01e6eb4c0ac01a64b300130290018acc004cdc4a4008605000316898109814000a04e8b20543754605600b375a6056009375a6056007302b002488888888966002606a01513301430340111330140011329800981b000cdd7181a800cdc7a45009b9148810048888ca60026076003323322330020020012259800800c52f5c11332259800acc004cdd7981f981e1baa0020058981a192cc004c0d4c0f0dd5000c5200089bad3040303d375400281d8c966002606a60786ea80062980103d87a8000899198008009bab3041303e375400444b30010018a6103d87a8000899192cc004c0300062b3001300d0018981b19821982080125eb82298103d87a800040fd133004004304500340fc6eb8c0fc004c10800504020763233001001375660806082607a6ea800c896600200314c103d87a8000899192cc004cdc8806800c56600266e3c0340062606a66084608000497ae08a60103d87a800040f9133004004304400340f86eb8c0f8004c10400503f4528207489981f00119802002000c4cc01001000503a181e800981f000a076375860760466058660726056660726ea40cd2f5c0660726058660726058660726056660726ea40112f5c097ae04bd7025eb8266ebcc0accc0e4dd480225eb8007d22259800981f00144c8cc88cc8966002607000313232323298009bad30460019bae30460049bae30460039bad30460024888966002609600b00a8b2090182300098228009822000981f9baa0038acc004c0dc0062646464653001375a608c003375c608c009375c608c007375a608c00491112cc004c12c016015164120304600130450013044001303f3754007159800981b000c4c8c8c8c8ca60026eb4c11c0066eb8c11c0166eb8c11c0126eb4c11c00d2222598009826002c4c966002608460906ea8006264646644b3001305100380845904e1bad304e001375c609c004609c00260926ea80062c8238c12c01a2c8248608e002608c002608a0026088002607e6ea800e2b3001303500189919194c004dd69822800cdd71822801cdd718228012444b300130490048044590460c114004c110004c0fcdd5001c5903d207a40f481e84cc89660026070607c6ea8006264660620022b30010078acc0040162b30010038acc004cc89660020030028acc004c118006264b3001300f375c608c0031303b375a608c608e00314a08208c118dd61822800c009043208614a06466002002646600200205644b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc004006297ae0899912cc004cdc79bae30470020118998231ba700233004004001899802002000a0843758608a002608c002821a266ebc005300103d87a80008a5040f914a081f2294103e4528207c3042303f37540031640f466ebc004c0c8cc0fcdd48051981f98200059981f98200031981f9ba8337006eb4c100c104c1040180e12f5c06605a6eacc100c104c104c104c104c10409c08cc0f0dd500099b873259800981a181d9baa0018a40011375a607e60786ea800503a192cc004c0d0c0ecdd5000c530103d87a8000899198008009bab3040303d375400444b30010018a6103d87a8000899192cc004c02c0062b3001300c0018981a99821182000125eb82298103d87a800040f9133004004304400340f86eb8c0f8004c10400503f207432330010013756607e608060786ea8008896600200314c103d87a8000899192cc004c0280062b3001300b0018981a19820981f80125eb82298103d87a800040f5133004004304300340f46eb8c0f4004c10000503e1bad303e00532598009819981d9baa0018981f981e1baa0018b2074303e303f303f303b3754002607a0051640ec303a303a00418189baa0158b2064181580098150009814800981400098138009813000981280098120009811800980f1baa0028b20383259800980a180e1baa00189810180e9baa0018b2036301f30203020301c3754603e604060386ea80088966002602e603a6ea800a2646464b3001302500289980318120018992cc004c06c006264b30013027001899192cc004c078006264b3001302a0018998059814800804c5902718129baa0028acc004c07400626464653001375a6056003375a6056007375a60560049112cc004c0bc01201d1640b0302b001302a0013025375400516408c8118c08cdd50009813000c5902418111baa0028acc004c0680062b3001302237540050058b20468b2040408060406ea80062c8110c08c004c08c004c078dd500145901c180e80091192cc004c05800626464b300130230028024590201bae3021001301d3754007159800980a800c4c8c96600260460050048b2040375c6042002603a6ea800e2c80d901b180d9baa0028b2036180d180d000980c980c800980a1baa006899192cc004c03c0122646644b300130120018acc004c064dd5003400a2c80d22b300130110018acc004c064dd5003400a2c80d22c80b9017099192cc004c048c060dd500344c8c8cc004004dd5980f001912cc00400629422b30013375e0066036603e00314a31330020023020001406880e8c034cc06cdd4801a5eb82330010159bac301c0029bab301c301d301d301d001a6103d87d8000401080b8c070c070c070c070c070c070004c05cdd5004980b1baa004375c6032602c6ea80162b3001300c0048994c004dd6980d000cc068c06c006602c6ea801226464b3001301d0018992cc004c04cc064dd5000c4c8cc030004566002602860346ea8022266ebc00530103d8798000899baf0014c103d87b80004064603a60346ea80062c80c0cc024dd5980e180e980e980e980e980e980e980e980e980e801180e000c5901a19199119801001000912cc004006297ae0899912cc004cdd79810180e9baa30203021301d375400400b13301f00233004004001899802002000a036301e001301f00140706eb0c070008c010050c05cdd5004a4444b300130140028acc004c06cdd500440062c80e22b300130130028acc004c06cdd500440062c80e22c80c90190c058dd5002c56600266e1d200a0048994c004dd6980d000cc068c06c006602e6ea8025222980080b4dd6180e800cdd5980e980f180f180f180f180f180f180f180f180f000d30103d879800040143016375400b15980099b87480200122664530010149bac301b0019bab301b301c301c301c301c301c301c301c301c301c001a60103d87a8000400c6032602c6ea8014c058dd50044590142028405080a08888c966002603c00313259800980a180d1baa00189919806800899baf001004301e301b375400316406466014006603a00316406c64646600200200a44b30010018a5eb8226644b30013375e6042603c6ea8c084c088c078dd5001002c4cc080008cc01001000626600800800280e0c07c004c08000501d1802802118051980b98049980b9ba90014bd701980ba60103d87a80004bd70202430113754002602a00a6028602a008452689b2b20081", + "hash": "55c2a7f6143ce2befd94139304436b30a0398f21cd2464c760455033" + } + ], + "definitions": { + "Bool": { + "title": "Bool", + "anyOf": [ + { + "title": "False", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "True", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "ByteArray": { + "dataType": "bytes" + }, + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, + "Int": { + "dataType": "integer" + }, + "List$cardano/address/Credential": { + "dataType": "list", + "items": { + "$ref": "#/definitions/cardano~1address~1Credential" + } + }, + "Option$aiken/crypto/ScriptHash": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$cardano/address/StakeCredential": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1address~1StakeCredential" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$cardano/governance/GovernanceActionId": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Pairs$cardano/address/Credential_cardano/assets/Lovelace": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/cardano~1address~1Credential" + }, + "values": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + "Pairs$cardano/address/Credential_cardano/governance/Mandate": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/cardano~1address~1Credential" + }, + "values": { + "$ref": "#/definitions/cardano~1governance~1Mandate" + } + }, + "Pairs$gov/ProtocolParametersIndex_Data": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/gov~1ProtocolParametersIndex" + }, + "values": { + "$ref": "#/definitions/Data" + } + }, + "aiken/collection/Index": { + "title": "Index", + "dataType": "integer" + }, + "aiken/crypto/ScriptHash": { + "title": "ScriptHash", + "dataType": "bytes" + }, + "aiken/crypto/VerificationKeyHash": { + "title": "VerificationKeyHash", + "dataType": "bytes" + }, + "cardano/address/Address": { + "title": "Address", + "description": "A Cardano `Address` typically holding one or two credential references.\n\n Note that legacy bootstrap addresses (a.k.a. 'Byron addresses') are\n completely excluded from Plutus contexts. Thus, from an on-chain\n perspective only exists addresses of type 00, 01, ..., 07 as detailed\n in [CIP-0019 :: Shelley Addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019/#shelley-addresses).", + "anyOf": [ + { + "title": "Address", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "payment_credential", + "$ref": "#/definitions/cardano~1address~1PaymentCredential" + }, + { + "title": "stake_credential", + "$ref": "#/definitions/Option$cardano~1address~1StakeCredential" + } + ] + } + ] + }, + "cardano/address/Credential": { + "title": "Credential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + ] + } + ] + }, + "cardano/address/PaymentCredential": { + "title": "PaymentCredential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + ] + } + ] + }, + "cardano/address/StakeCredential": { + "title": "StakeCredential", + "description": "Represent a type of object that can be represented either inline (by hash)\n or via a reference (i.e. a pointer to an on-chain location).\n\n This is mainly use for capturing pointers to a stake credential\n registration certificate in the case of so-called pointer addresses.", + "anyOf": [ + { + "title": "Inline", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1address~1Credential" + } + ] + }, + { + "title": "Pointer", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "slot_number", + "$ref": "#/definitions/Int" + }, + { + "title": "transaction_index", + "$ref": "#/definitions/Int" + }, + { + "title": "certificate_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "cardano/assets/Lovelace": { + "title": "Lovelace", + "dataType": "integer" + }, + "cardano/assets/PolicyId": { + "title": "PolicyId", + "dataType": "bytes" + }, + "cardano/governance/Constitution": { + "title": "Constitution", + "anyOf": [ + { + "title": "Constitution", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "guardrails", + "$ref": "#/definitions/Option$aiken~1crypto~1ScriptHash" + } + ] + } + ] + }, + "cardano/governance/GovernanceActionId": { + "title": "GovernanceActionId", + "anyOf": [ + { + "title": "GovernanceActionId", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction", + "$ref": "#/definitions/cardano~1governance~1TransactionId" + }, + { + "title": "proposal_procedure", + "$ref": "#/definitions/aiken~1collection~1Index" + } + ] + } + ] + }, + "cardano/governance/Mandate": { + "title": "Mandate", + "dataType": "integer" + }, + "cardano/governance/ProtocolVersion": { + "title": "ProtocolVersion", + "anyOf": [ + { + "title": "ProtocolVersion", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "major", + "$ref": "#/definitions/Int" + }, + { + "title": "minor", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "cardano/governance/TransactionId": { + "title": "TransactionId", + "dataType": "bytes" + }, + "crowdfund/CrowdfundRedeemer": { + "title": "CrowdfundRedeemer", + "anyOf": [ + { + "title": "ContributeFund", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "CompleteCrowdfund", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "ContributorWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "RemoveEmptyInstance", + "dataType": "constructor", + "index": 3, + "fields": [] + } + ] + }, + "gov/ProtocolParametersIndex": { + "title": "ProtocolParametersIndex", + "dataType": "integer" + }, + "gov/VGovernanceAction": { + "title": "VGovernanceAction", + "anyOf": [ + { + "title": "VProtocolParameters", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type 'ProtocolParameters'. They must all\n form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "new_parameters", + "description": "The new proposed protocol parameters. Only values set to `Some` are relevant.", + "$ref": "#/definitions/gov~1VProtocolParametersUpdate" + }, + { + "title": "guardrails", + "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the new protocol parameters to be deemed valid.", + "$ref": "#/definitions/Option$aiken~1crypto~1ScriptHash" + } + ] + }, + { + "title": "HardFork", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `HardFork`. They must all\n form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "new_version", + "description": "The new proposed version. Few rules apply to proposing new versions:\n\n - The `major` component, if incremented, must be exactly one more than the current.\n - The `minor` component, if incremented, must be exactly one more than the current.\n - If the `major` component is incremented, `minor` must be set to `0`.\n - Neither `minor` nor `major` can be decremented.", + "$ref": "#/definitions/cardano~1governance~1ProtocolVersion" + } + ] + }, + { + "title": "TreasuryWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "title": "beneficiaries", + "description": "A collection of beneficiaries, which can be plain verification key\n hashes or script hashes (e.g. DAO).", + "$ref": "#/definitions/Pairs$cardano~1address~1Credential_cardano~1assets~1Lovelace" + }, + { + "title": "guardrails", + "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the withdrawals to be authorized.", + "$ref": "#/definitions/Option$aiken~1crypto~1ScriptHash" + } + ] + }, + { + "title": "NoConfidence", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + } + ] + }, + { + "title": "ConstitutionalCommittee", + "dataType": "constructor", + "index": 4, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "evicted_members", + "description": "Constitutional members to be removed.", + "$ref": "#/definitions/List$cardano~1address~1Credential" + }, + { + "title": "added_members", + "description": "Constitutional members to be added.", + "$ref": "#/definitions/Pairs$cardano~1address~1Credential_cardano~1governance~1Mandate" + }, + { + "title": "quorum", + "description": "The new quorum value, as a ratio of a numerator and a denominator. The\n quorum specifies the threshold of 'Yes' votes necessary for the\n constitutional committee to accept a proposal procedure.", + "$ref": "#/definitions/gov~1VRational" + } + ] + }, + { + "title": "NewConstitution", + "dataType": "constructor", + "index": 5, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `Constitution` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "constitution", + "description": "The new proposed constitution.", + "$ref": "#/definitions/cardano~1governance~1Constitution" + } + ] + }, + { + "title": "NicePoll", + "dataType": "constructor", + "index": 6, + "fields": [] + } + ] + }, + "gov/VProtocolParametersUpdate": { + "title": "VProtocolParametersUpdate", + "anyOf": [ + { + "title": "VProtocolParametersUpdate", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "inner", + "$ref": "#/definitions/Pairs$gov~1ProtocolParametersIndex_Data" + } + ] + } + ] + }, + "gov/VRational": { + "title": "VRational", + "anyOf": [ + { + "title": "VRational", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "numerator", + "$ref": "#/definitions/Int" + }, + { + "title": "denominator", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundDatum": { + "title": "CrowdfundDatum", + "anyOf": [ + { + "title": "CrowdfundDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "completion_script", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "crowdfund_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "fundraise_target", + "$ref": "#/definitions/Int" + }, + { + "title": "current_fundraised_amount", + "$ref": "#/definitions/Int" + }, + { + "title": "allow_over_subscription", + "$ref": "#/definitions/Bool" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + }, + { + "title": "expiry_buffer", + "$ref": "#/definitions/Int" + }, + { + "title": "fee_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "min_charge", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundGovDatum": { + "title": "CrowdfundGovDatum", + "anyOf": [ + { + "title": "Init", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Proposed", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Voted", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "gov_tx_id", + "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Refundable", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "title": "start_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundRedeemer": { + "title": "CrowdfundRedeemer", + "anyOf": [ + { + "title": "RegisterCerts", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "VoteOnGovAction", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "DeregisterCerts", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "ContributorWithdrawal", + "dataType": "constructor", + "index": 3, + "fields": [] + }, + { + "title": "RemoveEmptyInstance", + "dataType": "constructor", + "index": 4, + "fields": [] + } + ] + }, + "types/MintPolarity": { + "title": "MintPolarity", + "anyOf": [ + { + "title": "RMint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "RBurn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "types/PublishRedeemer": { + "title": "PublishRedeemer", + "anyOf": [ + { + "title": "Register", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Deregister", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + } + } +} \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/1_spend.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/1_spend.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/1_spend.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/2_start.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/2_start.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/2_start.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/_scripts.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/_scripts.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/_scripts.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/user_action_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/user_action_doc.md similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/specs/user_action_doc.md rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/specs/user_action_doc.md diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/crowdfund.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/crowdfund.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/crowdfund.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/spend.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/spend.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/spend.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/start.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/start.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/start.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/intergration_test/complete_crowdfund.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/intergration_test/complete_crowdfund.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/intergration_test/complete_crowdfund.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/spend.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/spend.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/spend.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/start.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/start.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/start.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/utils.ak similarity index 100% rename from packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfund/validators/tests/utils.ak rename to packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/tests/utils.ak From 883064e9d729d3f715fbad5f73265fe3bb32ec07 Mon Sep 17 00:00:00 2001 From: QSchlegel Date: Tue, 9 Sep 2025 10:25:44 +0200 Subject: [PATCH 23/24] fix: correct typos in documentation and validators --- .../aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md | 2 +- .../base-crowdfund/validators/share_token/mint.ak | 2 +- .../aiken-workspace-v3/gov-extension/validators/crowdfund.ak | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md index a99dbcc26..37c54e806 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/specs/3_crowdfund.md @@ -27,7 +27,7 @@ - The value increase in current respending utxo equal to the increase in `current_fundraised_amount`, comparing input output datum - If `allow_over_scription` is False, check whether `current_fundraised_amount` <= `fundraise_target` - `deadline` is not passed - - `Shares` - Minted exactly the amount of `share_token` that lovelave contributed, with token name of `completion_script` + - `Shares` - Minted exactly the amount of `share_token` that lovelace contributed, with token name of `completion_script` 2. CompleteCrowdfund diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/share_token/mint.ak index 01bad7385..2ff086575 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/share_token/mint.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/base-crowdfund/validators/share_token/mint.ak @@ -25,7 +25,7 @@ validator share_token(auth_token: PolicyId) { redeemer_check? } - RBurn -> quantity == -1 + RBurn -> quantity < 0 } } diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/crowdfund.ak index 7a0ad8d0b..15214850b 100644 --- a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/crowdfund.ak +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-extension/validators/crowdfund.ak @@ -67,7 +67,7 @@ validator crowdfund(auth_token: PolicyId, proposer_key_hash: ByteArray) { let current_address = own_input.output.address - // check only 1 auth toke input from current address + // check only 1 auth token input from current address expect [auth_input] = inputs_at_with_policy(inputs, current_address, auth_token) From cdf3a6fcb1514a011cf2d206ff29aecea4fec83c Mon Sep 17 00:00:00 2001 From: QSchlegel Date: Tue, 18 Nov 2025 17:56:35 +0100 Subject: [PATCH 24/24] gov-crowdfundV2 --- .../workflows/continuous-integration.yml | 18 + .../gov-crowdfundV2/.gitignore | 6 + .../gov-crowdfundV2/README.md | 1 + .../gov-crowdfundV2/aiken.lock | 26 + .../gov-crowdfundV2/aiken.toml | 23 + .../gov-crowdfundV2/lib/gov.ak | 81 ++ .../gov-crowdfundV2/lib/types.ak | 56 + .../gov-crowdfundV2/lib/utils.ak | 195 ++++ .../gov-crowdfundV2/plutus.json | 1039 +++++++++++++++++ .../gov-crowdfundV2/specs/1_gCf_spend.md | 277 +++++ .../gov-crowdfundV2/specs/2_gCf_stake.md | 89 ++ .../gov-crowdfundV2/specs/_scripts.md | 127 ++ .../gov-crowdfundV2/specs/user_action_doc.md | 116 ++ .../validators/auth_token/mint.ak | 27 + .../gov-crowdfundV2/validators/gcf_spend.ak | 463 ++++++++ .../gov-crowdfundV2/validators/gcf_stake.ak | 58 + .../validators/share_token/mint.ak | 35 + .../integration_test/complete_crowdfund.ak | 198 ++++ .../validators/tests/test_spend.ak | 650 +++++++++++ .../validators/tests/test_start.ak | 249 ++++ .../validators/tests/test_utils.ak | 123 ++ 21 files changed, 3857 insertions(+) create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.github/workflows/continuous-integration.yml create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.gitignore create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/README.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.lock create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.toml create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/gov.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/types.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/utils.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/plutus.json create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/1_gCf_spend.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/2_gCf_stake.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/_scripts.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/user_action_doc.md create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/auth_token/mint.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_spend.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_stake.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/share_token/mint.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/integration_test/complete_crowdfund.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_spend.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_start.ak create mode 100644 packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_utils.ak diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.github/workflows/continuous-integration.yml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.github/workflows/continuous-integration.yml new file mode 100644 index 000000000..ba419b4a2 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.github/workflows/continuous-integration.yml @@ -0,0 +1,18 @@ +name: Continuous Integration + +on: + push: + branches: ["main"] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: aiken-lang/setup-aiken@v1 + with: + version: v1.1.16 + - run: aiken fmt --check + - run: aiken check -D + - run: aiken build diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.gitignore b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.gitignore new file mode 100644 index 000000000..ff7811b15 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/.gitignore @@ -0,0 +1,6 @@ +# Aiken compilation artifacts +artifacts/ +# Aiken's project working directory +build/ +# Aiken's default documentation export +docs/ diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/README.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/README.md new file mode 100644 index 000000000..de5ef005b --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/README.md @@ -0,0 +1 @@ +Implement separately & publish SDK diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.lock b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.lock new file mode 100644 index 000000000..2e65bd164 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.lock @@ -0,0 +1,26 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +source = "github" + +[[requirements]] +name = "sidan-lab/vodka" +version = "0.1.13" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +requirements = [] +source = "github" + +[[packages]] +name = "sidan-lab/vodka" +version = "0.1.13" +requirements = [] +source = "github" + +[etags] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.toml b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.toml new file mode 100644 index 000000000..018228ce9 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/aiken.toml @@ -0,0 +1,23 @@ +name = "sidan-lab-&-MeshJS/gov-crowdfundV2" +version = "0.0.0" +compiler = "v1.1.16" +plutus = "v3" +license = "Apache-2.0" +description = "Aiken contracts for project 'gov-crowdfundV2'" + +[repository] +user = "sidan-lab-&-MeshJS" +project = "gov-crowdfundV2" +platform = "github" + +[[dependencies]] +name = "aiken-lang/stdlib" +version = "v2.2.0" +source = "github" + +[[dependencies]] +name = "sidan-lab/vodka" +version = "0.1.13" +source = "github" + +[config] diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/gov.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/gov.ak new file mode 100644 index 000000000..d29db7b58 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/gov.ak @@ -0,0 +1,81 @@ +use aiken/crypto.{ScriptHash} +use cardano/address.{Credential} +use cardano/assets.{Lovelace} +use cardano/governance.{ + Constitution, GovernanceActionId, Mandate, ProtocolVersion, +} + +type ProtocolParametersIndex = + Int + +pub type VProtocolParametersUpdate { + inner: Pairs, +} + +pub type VRational { + numerator: Int, + denominator: Int, +} + +pub type VGovernanceAction { + VProtocolParameters { + /// The last governance action of type 'ProtocolParameters'. They must all + /// form a chain. + ancestor: Option, + /// The new proposed protocol parameters. Only values set to `Some` are relevant. + new_parameters: VProtocolParametersUpdate, + /// The optional guardrails script defined in the constitution. The script + /// is executed by the ledger in addition to the hard-coded ledger rules. + /// + /// It must pass for the new protocol parameters to be deemed valid. + guardrails: Option, + } + HardFork { + /// The last governance action of type `HardFork`. They must all + /// form a chain. + ancestor: Option, + /// The new proposed version. Few rules apply to proposing new versions: + /// + /// - The `major` component, if incremented, must be exactly one more than the current. + /// - The `minor` component, if incremented, must be exactly one more than the current. + /// - If the `major` component is incremented, `minor` must be set to `0`. + /// - Neither `minor` nor `major` can be decremented. + new_version: ProtocolVersion, + } + TreasuryWithdrawal { + /// A collection of beneficiaries, which can be plain verification key + /// hashes or script hashes (e.g. DAO). + beneficiaries: Pairs, + /// The optional guardrails script defined in the constitution. The script + /// is executed by the ledger in addition to the hard-coded ledger rules. + /// + /// It must pass for the withdrawals to be authorized. + guardrails: Option, + } + NoConfidence { + /// The last governance action of type `NoConfidence` or + /// `ConstitutionalCommittee`. They must all / form a chain. + ancestor: Option, + } + ConstitutionalCommittee { + /// The last governance action of type `NoConfidence` or + /// `ConstitutionalCommittee`. They must all / form a chain. + ancestor: Option, + /// Constitutional members to be removed. + evicted_members: List, + /// Constitutional members to be added. + added_members: Pairs, + /// The new quorum value, as a ratio of a numerator and a denominator. The + /// quorum specifies the threshold of 'Yes' votes necessary for the + /// constitutional committee to accept a proposal procedure. + quorum: VRational, + } + NewConstitution { + /// The last governance action of type `Constitution` or + /// `ConstitutionalCommittee`. They must all / form a chain. + ancestor: Option, + /// The new proposed constitution. + constitution: Constitution, + } + NicePoll +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/types.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/types.ak new file mode 100644 index 000000000..db909cf85 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/types.ak @@ -0,0 +1,56 @@ +use cardano/address.{Address} +use cardano/governance.{GovernanceActionId} + +pub type CrowdfundGovRedeemer { + ContributeFund + CompleteCrowdfund + PreMatureContributorWithdrawal + PreMatureRemoveEmptyInstance + RegisterCerts + VoteOnGovAction + DeregisterCerts + AfterCompleteContributorWithdrawal + AfterCompleteRemoveEmptyInstance +} + +pub type CrowdfundGovDatum { + Crowdfund { + stake_hash: ByteArray, + share_token: ByteArray, + crowdfund_address: Address, + fundraise_target: Int, + current_fundraised_amount: Int, + allow_over_subscription: Bool, + deadline: Int, + expiry_buffer: Int, + min_charge: Int + } + Proposed { + stake_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } + Voted { + stake_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + gov_tx_id: GovernanceActionId, + deadline: Int, + } + Refundable { + stake_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + } +} + +pub type MintPolarity { + RMint + RBurn +} + +pub type PublishRedeemer { + Register + Deregister +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/utils.ak new file mode 100644 index 000000000..3c4b45970 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/lib/utils.ak @@ -0,0 +1,195 @@ +use aiken/cbor +use aiken/collection/list +use aiken/collection/pairs.{get_first} +use cardano/address.{Address, Credential, from_script} +use cardano/assets.{Lovelace, lovelace_of, from_lovelace} +use cardano/certificate.{ + Certificate, DelegateBlockProduction, DelegateBoth, DelegateCredential, + DelegateRepresentative, DelegateVote, RegisterCredential, + RegisterDelegateRepresentative, StakePoolId, UnregisterCredential, + UnregisterDelegateRepresentative, +} +use cardano/governance.{ + GovernanceAction, GovernanceActionId, ProposalProcedure, Vote, Voter, Yes, +} +use cardano/transaction.{Input, Output, Redeemer, ScriptPurpose, Spend} +use cocktail.{inputs_at} +use gov.{VGovernanceAction} +use types.{CrowdfundGovRedeemer} + + +pub fn check_fundraise_target( + allow_over_subscription: Bool, + fundraise_target: Int, + current_fundraised_amount: Int, +) -> Bool { + if allow_over_subscription { + True + } else { + current_fundraised_amount <= fundraise_target + } +} + +pub fn outputs_at_with_lovelace( + outputs: List, + address: Address, + lovelace: Lovelace, +) -> List { + list.filter( + outputs, + fn(output) { + let is_lovelace_match = output.value == from_lovelace(lovelace) + is_lovelace_match && output.address == address + }, + ) +} + +pub fn redeemer_with_input( + redeemers: Pairs, + input: Input, +) -> Option { + let output_reference = input.output_reference + redeemers |> pairs.get_first(Spend(output_reference)) +} + +pub fn register_stake_certificate( + certificates: List, + credential: Credential, +) { + list.has(certificates, RegisterCredential { credential, deposit: Never }) +} + +pub fn unregister_stake_certificate( + certificates: List, + credential: Credential, +) { + list.has(certificates, UnregisterCredential { credential, refund: Never }) +} + +pub fn register_drep_certificate( + certificates: List, + credential: Credential, + deposit: Lovelace, +) { + list.has( + certificates, + RegisterDelegateRepresentative { + delegate_representative: credential, + deposit, + }, + ) +} + +pub fn unregister_drep_certificate( + certificates: List, + credential: Credential, + refund: Lovelace, +) { + list.has( + certificates, + UnregisterDelegateRepresentative { + delegate_representative: credential, + refund, + }, + ) +} + +pub fn delegate_vote_certificate( + certificates: List, + credential: Credential, + delegate_representative: DelegateRepresentative, +) { + list.has( + certificates, + DelegateCredential { + credential, + delegate: DelegateVote { delegate_representative }, + }, + ) +} + +pub fn delegate_stake_certificate( + certificates: List, + credential: Credential, + stake_pool: StakePoolId, +) { + list.has( + certificates, + DelegateCredential { + credential, + delegate: DelegateBlockProduction { stake_pool }, + }, + ) +} + +pub fn delegate_stake_and_vote_certificate( + certificates: List, + credential: Credential, + stake_pool: StakePoolId, + delegate_representative: DelegateRepresentative, +) { + list.has( + certificates, + DelegateCredential { + credential, + delegate: DelegateBoth { stake_pool, delegate_representative }, + }, + ) +} + +pub fn check_lovelace_diff(input: Input, output: Output, diff: Lovelace) { + let lovelace_from_input_output = input.output.value |> lovelace_of() + let lovelace_from_output = output.value |> lovelace_of() + + lovelace_from_output - lovelace_from_input_output == diff +} + +pub fn check_spend_script_input_redeemer( + spend: ByteArray, + inputs: List, + redeemers: Pairs, + redeemer: CrowdfundGovRedeemer, +) { + let spend_address = from_script(spend) + expect [only_input] = inputs_at(inputs, spend_address) + expect Some(only_input_redeemer_data) = + redeemer_with_input(redeemers, only_input) + + expect only_input_redeemer: CrowdfundGovRedeemer = only_input_redeemer_data + + only_input_redeemer == redeemer +} + +pub fn compare_gov_action(agov: GovernanceAction, vgov: VGovernanceAction) { + let se_agov = cbor.serialise(agov) + let se_vgov = cbor.serialise(vgov) + se_agov == se_vgov +} + +pub fn check_proposal_procedure( + proposal_procedures: List, + deposit: Lovelace, + return_address: Credential, + vgovernance_action: VGovernanceAction, +) { + list.count( + proposal_procedures, + fn(proposal_procedure) { + proposal_procedure.deposit == deposit && proposal_procedure.return_address == return_address && compare_gov_action( + proposal_procedure.governance_action, + vgovernance_action, + ) + }, + ) == 1 +} + +pub fn check_vote( + votes: Pairs>, + drep: Voter, + gov_tx_id: GovernanceActionId, +) { + let value_list = get_first(votes, drep) + + expect Some(gov_pair) = value_list + list.has(gov_pair, Pair(gov_tx_id, Yes)) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/plutus.json b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/plutus.json new file mode 100644 index 000000000..7d9844021 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/plutus.json @@ -0,0 +1,1039 @@ +{ + "preamble": { + "title": "sidan-lab-&-MeshJS/gov-crowdfundV2", + "description": "Aiken contracts for project 'gov-crowdfundV2'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.17+c3a7fba" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "auth_token/mint.gcf_auth_mint.mint", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1MintPolarity" + } + }, + "parameters": [ + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "590178010100229800aba2aba1aba0aab9faab9eaab9dab9a488888896600264653001300800198041804800cdc3a400130080024888966002600460106ea800e266446644b300130060018acc004c034dd5004400a2c80722b300130030018acc004c034dd5004400a2c80722c805900b0992cc004c040006264b30013006300c375401115980099198008009bac3011300e375400c44b30010018a508acc004cdd7980918079baa30120010158a518998010011809800a01a4041130030018a50402d13370e0029000a016375a6018601e00316403464b30013002300b375400314bd6f7b63044dd5980798061baa001402864660020026eacc03cc040c040c040c040c030dd5002112cc0040062980103d87a8000899192cc004cdc8803000c56600266e3c018006266e95200033011300f0024bd7045300103d87a80004035133004004301300340346eb8c034004c04000500e18051baa006375c601860126ea800cdc3a400516401c300800130033754011149a26cac8009", + "hash": "476e529a91415c9d54d4a5293c81b21918d23f7695473cba3621b896" + }, + { + "title": "auth_token/mint.gcf_auth_mint.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "590178010100229800aba2aba1aba0aab9faab9eaab9dab9a488888896600264653001300800198041804800cdc3a400130080024888966002600460106ea800e266446644b300130060018acc004c034dd5004400a2c80722b300130030018acc004c034dd5004400a2c80722c805900b0992cc004c040006264b30013006300c375401115980099198008009bac3011300e375400c44b30010018a508acc004cdd7980918079baa30120010158a518998010011809800a01a4041130030018a50402d13370e0029000a016375a6018601e00316403464b30013002300b375400314bd6f7b63044dd5980798061baa001402864660020026eacc03cc040c040c040c040c030dd5002112cc0040062980103d87a8000899192cc004cdc8803000c56600266e3c018006266e95200033011300f0024bd7045300103d87a80004035133004004301300340346eb8c034004c04000500e18051baa006375c601860126ea800cdc3a400516401c300800130033754011149a26cac8009", + "hash": "476e529a91415c9d54d4a5293c81b21918d23f7695473cba3621b896" + }, + { + "title": "gcf_spend.gCf_spend.spend", + "datum": { + "title": "datum_opt", + "schema": { + "$ref": "#/definitions/types~1CrowdfundGovDatum" + } + }, + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1CrowdfundGovRedeemer" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action", + "schema": { + "$ref": "#/definitions/gov~1VGovernanceAction" + } + }, + { + "title": "delegate_pool_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "stake_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "drep_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "gov_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + } + ], + "compiledCode": "592890010100222222229800aba2aba1aba0aab9faab9eaab9dab9a9bae0089bae0079bae0059bad0049bad0039bad002488888888888896600264653001300e00198071807800cdc3a4005300e00248889660026004601c6ea800e33001300f3754007370e90024dc3a400d370e90004c038dd5002244444664464b300130050048acc004c05cdd500640062c80c22b3001300a0048acc004c05cdd500640062c80c22b300130070048acc004c05cdd500640062c80c22b300130060048acc004c05cdd500640062c80c22b30013370e90040024566002602e6ea803200316406115980099b87480280122b3001301737540190018b20308acc004cdc3a4018009159800980b9baa00c800c59018456600266e1d200e0048acc004c05cdd500640062c80c22b30013370e90080024566002602e6ea803200316406116405480a9015202a405480a9015202a40542653001301b301b0019bac301a0019ba548001222323232323298009bab30220019bac302230230019919800800804112cc0040062980103d87a80008992cc004cdd7981298111baa00100e8980499812000a5eb82266006006604c0048100c0900050224dd618110044dd59811002cdd618110024c08800e6eb0c0880092222222259800980a98131baa0068992cc004c058c09cdd5009c4c8c8cc896600260600051980098178014c0acdd5010c88c966002603a0031323259800981a80140122c8190dd7181980098179baa0038acc004c08800626464b300130350028024590321bae3033001302f37540071640b48168c0b4dd50014dc8a45009b8f4881009b80480092222223322598009811003c566002604460666ea8026264646464646464653001375a607e003375a607e6080003323300100101b2259800800c52f5c11332259800acc004cdd7982198201baa0020178991980080099198008009bab304530463042375400844b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc00400629422b30013371e6eb8c114dd6182280081fc528c4cc008008c11800504020868a5040f913304200233004004001899802002000a07c3041001304200140fd375c607e011375c607e00f303f0069bad303f0059bad303f0049817981d9baa303f0039bad303f002488888888896600260940111329800980a1bab301f304737540033259800981c18239baa0018982598241baa0018b208c304a304b304b3047375400330143756603e608e6ea8c07cc11cdd500da444660300042b30013038304937540051332259800acc004cdc380099b81002009899b89482024bd004006294104a4566002b30010088a51899b8900200a41291598009919192cc004c108c138dd5000c5660026084609c6ea8c148c14c00a266e20dd6982918279baa00100a899b89375a60a4609e6ea800402904d4528209a30510013304f30500013304f9800982018261baa30503051001a60103d87a8000a60103d8798000412c97ae0304c3754609e60a060986ea809e2b30013375e00860666609c6ea4034cc138dd480619827005998271ba800a3304e375066e00024004cc13a60020114c103d87a8000a60103d879800041286609c6ea001ccc138dd4008198271ba800f4bd704566002607864b30010018a4001132301d32598008014520008980f19800800982980120a02259800800c520008980f99801001182a000a0a23051001413864660020026eacc094c134dd5003912cc004006297ae0899199119198008009bab30520042259800800c400e264660ac6e9ccc158dd48029982b18298009982b182a000a5eb80cc00c00cc160008c1580050541bae304e0013300300330530023051001413d1332259800800c00a2b30013052001899192cc004cdc79bae30530020108acc004c080dd71829800c4cdc39bad305330540010058a50413914a08270c14c004dd61828800c00904f209e14a0646600200205444b30010018a5eb82264664464660020026eacc148010896600200310038991982b1ba733056375200a660ac60a6002660ac60a800297ae0330030033058002305600141506eb8c138004cc00c00cc14c008c14400504f452820948a50412914a08252294104a45282094375a609a609c609c609c609c60946ea8008cdc0801800c528209018248044590470c0fc004c0f8004c0f4004c0f0004c0ec004c0e8004c0e4004c0d0dd5004c52820648acc004c09001e2b3001302230333754013132323232329800981e800cdd6981e000cdd6981e00124446464664530013232332259800981b98219baa0028acc004c0dcc10cdd518239824001c4cdc40009bad3047304437540051337120026eb4c11cc110dd500120848a504108608a00266e0000c010cc10cc110004cc10e6002606860806ea8c110c11400698103d87a8000a60103d879800040fc97ae030403754608660806ea806e646600200203e44b30010018a5eb8226644b30015980099baf304730443754004037132330010013233001001375660926094608c6ea8010896600200314bd7044c8cc88c8cc004004dd59825802112cc00400620071323304f374e6609e6ea4014cc13cc130004cc13cc1340052f5c06600600660a2004609e0028268dd718238009980180198260011825000a0902259800800c528456600266e3cdd718249bac30490010438a518998010011825000a088411d14a0821226608c004660080080031330040040014108608a002608c002821a6eb8c10c0326eb8c10c02e60860153371200c00b3033303f3754608600f375a60866088006911111112cc004c13001e264646644660340022b3001303a304b3754003159800acc0040322946200e82522b30010028acc004cdd78009819998271ba900a3304e37520126609c0106609c6ea0044cc138dd419b800120033304e98008035300103d87a8000a60103d879800041286609c6ea0034cc138dd4007198271ba80054bd704566002607864b30010018a4001132301d32598008014520008980f19800800982980120a02259800800c520008980f99801001182a000a0a23051001413864660020026eacc094c134dd5002912cc004006297ae0899199119198008009bab30520042259800800c400e264660ac6e9ccc158dd48029982b18298009982b182a000a5eb80cc00c00cc160008c1580050541bae304e0013300300330530023051001413d1332259800800c00a2b30013052001899192cc004cdc79bae305300200d8acc004c080dd71829800c4cdc39bad305330540010078a50413914a08270c14c004dd61828800c00904f209e14a0646600200205444b30010018a5eb82264664464660020026eacc148010896600200310038991982b1ba733056375200a660ac60a6002660ac60a800297ae0330030033058002305600141506eb8c138004cc00c00cc14c008c14400504f452820948a50412914a08252294104a45282094337100029000192cc004c0ecc128dd5000c4c138c12cdd5000c5904918269827182718251baa00233702602c6eacc084c124dd5000980b1bab302130493754604260926ea8074c12c01e2c82486eb4c104004dd69820801182080098200018c0f0004c0ec004c0e8004c0e4004c0d0dd5004c5282064899912cc004c0940262b30013024303537540171323298009bad303b0019bad303b303c303c0019bae303b002488966002646464b30013031303d37540031598009818981e9baa30413042002899b88005375a6082607c6ea8006266e24014dd69820981f1baa00140f114a081e0c100004cc0f8c0fc004cc0fa6002605e60766ea8c0fcc10000698103d87a8000a60103d879800040e897ae0303b3754607c60766ea805a2b30015980099b884800000e2b300198009803801c5284c8cc004004c8cc004004068896600200314bd7044c8cc88c8cc004004dd59821002112cc004006200713233046374e6608c6ea4014cc118c10c004cc118c1100052f5c0660060066090004608c0028220dd7181f0009980180198218011820800a07e2259800800c52f5c1133225980099b8f375c608400400b133041374e0046600800800313300400400140f46eb0c100004c10400503e2444b3001001801456600260840031325980098079bae3042001899b87375a6084608600200914a081e8c108dd61820800c00903f207e44cc89660020030028acc004c104006264b3001300e375c608200313009375a6082608400314a081e0c104dd61820000c00903e207c14a06466002002646600200203444b30010018a5eb82264664464660020026eacc10801089660020031003899198231ba733046375200a6608c60860026608c608800297ae0330030033048002304600141106eb8c0f8004cc00c00cc10c008c10400503f112cc004006297ae0899912cc004cdc79bae304200203c8998209ba700233004004001899802002000a07a37586080002608200281f2294103944cc89660020030028acc004c10400626464b30013371e6eb8c1080080f22b3001300f375c60840031300a375a6084608600314a081ea294103d18210009bac3040001801207c40f82940c8cc004004064896600200314bd7044c8cc88c8cc004004dd59820802112cc004006200713233045374e6608a6ea4014cc114c108004cc114c10c0052f5c066006006608e004608a0028218dd7181e8009980180198210011820000a07c40e5132330010010162259800800c528456600266e3cdd7182000081cc528c4cc008008c10400503b207c8a5040e514a081c86076607660760026074606c6ea802e294103446600244466e1ccdc098031bab301130393754004600c6eacc044c0e4dd51808981c9baa003001911919800800801912cc00400629422b30013375e607a00200714a3133002002303e00140e081da6e9520049ba54800a6e440ce6e3c0cd2222225980099b874802003e2b3001302a303b3754023132323298009bad30420019bad3042304330430019919800800814112cc004006297ae0899912cc0056600266ebcc118c10cdd51823182398219baa00201a8981b192cc004c0dcc10cdd5000c5200089bad3047304437540028210c966002606e60866ea80062980103d87a8000899198008009bab30483045375400444b30010018a6103d87a8000899192cc004c0640062b300130180018981799825182400125eb82298103d87a80004119133004004304c00341186eb8c118004c124005047208432330010013756608e609060886ea8c11cc120c110dd5001912cc004006298103d87a8000899192cc004c0340062b3001300c0018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c1200050464528208289982280119802002000c4cc01001000504118220009822800a0849bae30420039bae304200248888966002609000713259800981998221baa0018992cc004c0d0c114dd5000c4cc89660026098003132332233019001159800801456600266ebc004c048cc134dd4804998269ba90083304d37500186609a6ea002d2f5c1159800981d992cc0040062900044c8c070c9660020051480022603a6600200260a4004827889660020031480022603c6600400460a60028280c14000504d19198008009bab3024304c375400844b30010018a5eb82264664464660020026eacc144010896600200310038991982a9ba733055375200a660aa60a4002660aa60a600297ae03300300330570023055001414c6eb8c134004cc00c00cc148008c14000504e45660026602804e60646609a00a6609a98103d87a80004bd7045660026602804e66e9520083304d0053304d375008897ae08acc00566002b30013301402730133304d0053304d30123304d30323304d0054bd7025eb812f5c113301402730133304d0053304d30323304d375208c97ae04bd70452820928a5189980a013980999826802998269809998269ba90463304d30323304d0054bd7025eb812f5c0824a264607e646600200205a44b30010018a40011332259800acc004cdc39bad30533050375400409115980099baf30283050375400400b13371e6eccc14cc150c150c140dd50011bb305a8a50413914a082722603e0031001413860a20026600400460a40028278c048cc134dd4804a5eb822941049452820928a50412514a0824a294104945282092980098260044006602a66e00cdc0021821020a0263259800981d18249baa0018982698251baa0018b2090304c304d304d3049375400260960031641246092608c6ea8004c8cc004004094896600200314bd7044cc8966002b30013375e609a60946ea80080862607a64b3001303e304a375400314800226eb4c138c12cdd5000a0923259800981f18251baa0018a60103d87a8000899198008009bab304f304c375400444b30010018a6103d87a8000899192cc004c0800062b3001301f0018981b19828982780125eb82298103d87a80004135133004004305300341346eb8c134004c14000504e209232330010013756609c609e60966ea800c896600200314c103d87a8000899192cc004c0500062b300130130018981a99828182700125eb82298103d87a80004131133004004305200341306eb8c130004c13c00504d4528209089982600119802002000c4cc01001000504818258009826000a0928b208830483045375400316410c603860886ea806e2c8228608460846084002608200260786ea8046294103a456600266e1d200a00f8acc004c0bcc0ecdd5008c4c8c8ca60026eb4c1080066eb4c108c10c006646600200205044b30010018a5eb8226644b30015980099baf304630433754608c608e60866ea800806a2606c64b300130373043375400314800226eb4c11cc110dd5000a0843259800981b98219baa0018a60103d87a8000899198008009bab30483045375400444b30010018a6103d87a8000899192cc004c0640062b300130180018981799825182400125eb82298103d87a80004119133004004304c00341186eb8c118004c124005047208432330010013756608e609060886ea8c11cc120c110dd5001912cc004006298103d87a8000899192cc004c0340062b3001300c0018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c1200050464528208289982280119802002000c4cc01001000504118220009822800a0849bae30420039bae3042002488889660026090007132598009824800c4c8cc88cc0580044c96600200715980099baf00230113304b375200e660966ea4018cc12cdd400519825800998259ba80094bd704566002607264b30010018a4001132301a32598008014520008980d998008009828001209a2259800800c520008980e198010011828800a09c304e001412c64660020026eacc088c128dd5002912cc004006297ae0899199119198008009bab304f0042259800800c400e264660a66e9ccc14cdd4802998299828000998299828800a5eb80cc00c00cc154008c14c0050511bae304b001330030033050002304e00141311323259800981c98251baa001899199119801001000912cc00400629422b30013375e6e98cc140c1440052f5bded8c06e98cc14000d2f5bded8c114a3133002002305200141308278dd5982798261baa00233760006980103d87a80008b2092323300100102c2259800800c530103d87a80008992cc004cdd78021826000c4c0d0cc13cc1340052f5c11330030033051002412c609e0028268c040cc12cc040cc12cdd4803a5eb812f5c114a0823a29410474528208e302f3304a304b30483754609660906ea8084cc12930010100004bd7019baf301e30463754603c608c6ea8c124014c078c118dd5000992cc004c0dcc118dd5000c4c128c11cdd5000c5904518249825182518231baa00130480018b208c32330010010232259800800c52f5c11332259800acc004cdd7982598241baa00201f8981d992cc004c0f0c120dd5000c5200089bad304c304937540028238c966002607860906ea8006298103d87a8000899198008009bab304d304a375400444b30010018a6103d87a8000899192cc004c0780062b3001301d0018981a19827982680125eb82298103d87a8000412d1330040043051003412c6eb8c12c004c13800504c208e323300100137566098609a60926ea800c896600200314c103d87a8000899192cc004c0480062b300130110018981999827182600125eb82298103d87a80004129133004004305000341286eb8c128004c13400504b4528208c89982500119802002000c4cc01001000504618248009825000a08e8b208a18210009820800981e1baa0118a5040e915980099b874803003e2b3001302c303b3754023132323298009bad30420019bad3042304330430019919800800814112cc004006297ae0899912cc0056600266ebcc118c10cdd51823182398219baa00201a8981b192cc004c0dcc10cdd5000c5200089bad3047304437540028210c966002606e60866ea8006298103d87a8000899198008009bab30483045375400444b30010018a6103d87a8000899192cc004c0640062b300130180018981799825182400125eb82298103d87a80004119133004004304c00341186eb8c118004c124005047208432330010013756608e609060886ea8c11cc120c110dd5001912cc004006298103d87a8000899192cc004c0340062b3001300c0018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c1200050464528208289982280119802002000c4cc01001000504118220009822800a0849bae30420039bae304200248888966002609000713259800981998221baa0018992cc004c0d0c114dd5000c660026092608c6ea8006646464b3001303c30483754003159800981e18241baa304c304d002899b88009375a609860926ea8006266e24024dd6982618249baa001411d14a08238c12c004cc124c128004cc12660026074608c6ea8c128c12c00698103d87a8000a60103d8798000411497ae0304637546092608c6ea8086646600200204a44b30010018a5eb8226644b30015980099baf304d304a37540040431303d3259800981f18251baa0018a40011375a609c60966ea8005049192cc004c0f8c128dd5000c5300103d87a8000899198008009bab304f304c375400444b30010018a6103d87a8000899192cc004c0800062b3001301f0018981b19828982780125eb82298103d87a80004135133004004305300341346eb8c134004c14000504e209232330010013756609c609e60966ea800c896600200314c103d87a8000899192cc004c0500062b300130130018981a99828182700125eb82298103d87a80004131133004004305200341306eb8c130004c13c00504d4528209089982600119802002000c4cc01001000504818258009826000a092488966002609a00313233223301a001159800802c56600200515980099baf0013374a9003198271ba900a3304e37520126609c6ea00352f5c11598009980a81418099982700319827260103d87a80004bd7045660026602a05066e95200c3304e0063304e375008a97ae08981e192cc0040062900044c8c074c9660020051480022603c6600200260a6004828089660020031480022603e6600400460a80028288c14400504e19198008009bab3025304d375400844b30010018a5eb82264664464660020026eacc148010896600200310038991982b1ba733056375200a660ac60a6002660ac60a800297ae0330030033058002305600141506eb8c138004cc00c00cc14c008c14400504f452820948a50412914a08252294104a4528209498009826804c00666e00cdc002202182120283259800981d98251baa0018982718259baa0018b2092304d304e304e304a375400260980031641288b208830483045375400316410c603860886ea806e2c82286084002608200260786ea8046294103a456600266e1d200e00f8acc004c0acc0ecdd5008c4c8ca60026eb8c1040066eb4c104c108006646600200204e44b30010018a5eb8226644b30015980099baf304530423754608a608c60846ea80080662606a64b300130363042375400314800226eb4c118c10cdd5000a0823259800981b18211baa0018a6103d87a8000899198008009bab30473044375400444b30010018a6103d87a8000899192cc004c0600062b300130170018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c120005046208232330010013756608c608e60866ea8c118c11cc10cdd5001912cc004006298103d87a8000899192cc004c0300062b3001300b0018981699824182300125eb82298103d87a80004111133004004304a00341106eb8c110004c11c0050454528208089982200119802002000c4cc01001000504018218009822000a0829bae30410024888966002608c005132598009823800c4c8c8cc88cc05400456600200515980099baf0013374a9003198249ba9006330493752012660926ea0cdc0004001a5eb822b300130373259800800c52000899180c192cc00400a2900044c064cc004004c13800904b112cc0040062900044c068cc008008c13c00504c1826000a09232330010013756604060906ea8014896600200314bd7044c8cc88c8cc004004dd59826802112cc004006200713233051374e660a26ea4014cc144c138004cc144c13c0052f5c06600600660a600460a20028278dd718248009980180198270011826000a094899912cc0040060051598009826800c4c8c96600266e3cdd71827001006c56600260366eb8c138006266e1cdd698271827800803c52820928a504124609c0026eb0c130006004825104a0a5032330010010252259800800c52f5c1132332232330010013756609a00844b30010018801c4c8cc144dd3998289ba900533051304e00133051304f0014bd701980180198298011828800a09e375c609200266006006609c0046098002825229410454528208a8a50411466e2000520003259800981b18229baa0018982498231baa0018b20883048304930493045375400466e04c044dd5980e18221baa00130113756603860886ea8c070c110dd518238021823000c590441919800800810912cc004006297ae0899912cc0056600266ebcc124c118dd500100ec4c0e4c9660026074608c6ea80062900044dd6982518239baa001411464b3001303a3046375400314c0103d87a8000899198008009bab304b3048375400444b30010018a6103d87a8000899192cc004c0700062b3001301b0018981919826982580125eb82298103d87a80004125133004004304f00341246eb8c124004c13000504a208a3233001001375660946096608e6ea800c896600200314c103d87a8000899192cc004c0400062b3001300f0018981899826182500125eb82298103d87a80004121133004004304e00341206eb8c120004c12c0050494528208889982400119802002000c4cc01001000504418238009824000a08a8b20861820800981e1baa0118a5040e91598009817807c5284566002605660766ea8046264653001375c6082003375a60826084003375c60820049112cc004c114c8cc0040040a8896600200314bd7044cc8966002b30013375e6090608a6ea8c120c124c114dd500100e44c0e0c9660026072608a6ea80062900044dd6982498231baa001411064b300130393045375400314c0103d87a8000899198008009bab304a3047375400444b30010018a6103d87a8000899192cc004c06c0062b3001301a0018981899826182500125eb82298103d87a80004121133004004304e00341206eb8c120004c12c00504920883233001001375660926094608c6ea8c124c128c118dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062606066096609200497ae08a60103d87a8000411d133004004304d003411c6eb8c11c004c1280050484528208689982380119802002000c4cc01001000504318230009823800a0888acc0056600266e2120000028cc004c03400a29426466002002646600200204044b30010018a5eb82264664464660020026eacc12001089660020031003899198261ba73304c375200a66098609200266098609400297ae033003003304e002304c00141286eb8c110004cc00c00cc124008c11c005045112cc004006297ae0899912cc004cdc79bae30480020078998239ba700233004004001899802002000a0863758608c002608e002822122259800800c00a2b300130480018992cc004c054dd71824000c4cdc39bad304830490010048a50410c60906eb0c11c00600482290452294503f4566002646600200203844b30010018a508acc004cdc79bae304600103f8a518998010011823800a08241111332259800800c00a2b300130470018992cc004c050dd71823800c4c03cdd698239824000c528208430473758608c0030024110822052819198008009919800800810112cc004006297ae0899199119198008009bab30480042259800800c400e264660986e9ccc130dd4802998261824800998261825000a5eb80cc00c00cc138008c13000504a1bae30440013300300330490023047001411444b30010018a5eb8226644b30013371e6eb8c12000810a26608e6e9c008cc0100100062660080080028218dd618230009823800a0888a5040fd14a081fa2c8210608200260786ea8046294103a207440e881d103a20742068370290001b874800503220642232598009811800c4c8c8c8c8c8c8c8c8ca60026eb4c1040066eb8c1040266eb8c1040226eb4c10401a6eb4c10401664b3001303f0018acc004cdc4a4008607c0031689819181f000a07a8b208037546082009375a6082007375a6082004911111112cc004c128026264b3001303530463754003132323259800982700144cc070c13400c4c9660026072003132598009828000c4c8c9660026078003132598009829800c4cc084c1480040722c8280c138dd500145660026082003132323298009bad30540019bad30540039bad305400248896600260b00090218b20aa182a000982980098271baa0028b2098413060986ea8004c13c0062c8268c12cdd50014566002607c00315980098259baa00280c45904c45904920923049375400316412c60980026098002608e6ea80062c8228c12403e2c823860820026080002607e002607c002607a002607800260760026074002606a6ea800e2b300130280018991919194c004dd6981e000cdd7181e0024dd7181e001cdd6981e00124444b3001304100580545903e0c0f0004c0ec004c0e8004c0d4dd5001c566002604a0031323232323298009bad303d0019bae303d0059bae303d0049bad303d0034888966002608400b132598009816981f1baa0018991919912cc004c11c00e0211641106eb4c110004dd718220011822000981f9baa0018b207a30410068b207e181e800981e000981d800981d000981a9baa0038acc004c09000626464653001375a6076003375c6076007375c60760049112cc004c0fc0120111640f0303b001303a001303537540071640cc8199033206630333754004464b300130273033375400314800226eb4c0dcc0d0dd5000a0643259800981398199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004c0240062b300130080018980f9981d181c00125eb82298103d87a800040d9133004004303c00340d86eb8c0d8004c0e4005037206432330010010022259800800c5300103d87a8000899192cc004c0200062b300130070018980f1981c981b80125eb82298103d87a800040d5133004004303b00340d46eb8c0d4004c0e000503622c8168c8cc00400404c896600200314bd7044cc8966002b30013375e6062605c6ea8c0c4c0c8c0b8dd5001002c4c8cc004004c8cc004004dd59819981a18181baa303330343030375400844b30010018a5eb82264664464660020026eacc0d4010896600200310038991981c9ba733039375200a66072606c00266072606e00297ae033003003303b002303900140dc6eb8c0c4004cc00c00cc0d8008c0d0005032112cc00400629422b30013371e6eb8c0ccdd61819800816c528c4cc008008c0d000502e20628a5040b113303000233004004001899802002000a058302f001303000140b4605a60546ea8054c0b0c0a4dd5180098149baa0022302c302d0018b204c302a3027375400d1640943022302230223022001302100130203020001301f001301e301e003180b1baa00830170053017301800545900d0c038004c024dd5007452689b2b200e1", + "hash": "8cfed220dadcf07254f4fbc3fd3e86f555cbf777f54ad0bdc7592bc8" + }, + { + "title": "gcf_spend.gCf_spend.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "proposer_key_hash", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "gov_action", + "schema": { + "$ref": "#/definitions/gov~1VGovernanceAction" + } + }, + { + "title": "delegate_pool_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "stake_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "drep_register_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + { + "title": "gov_deposit", + "schema": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + } + ], + "compiledCode": "592890010100222222229800aba2aba1aba0aab9faab9eaab9dab9a9bae0089bae0079bae0059bad0049bad0039bad002488888888888896600264653001300e00198071807800cdc3a4005300e00248889660026004601c6ea800e33001300f3754007370e90024dc3a400d370e90004c038dd5002244444664464b300130050048acc004c05cdd500640062c80c22b3001300a0048acc004c05cdd500640062c80c22b300130070048acc004c05cdd500640062c80c22b300130060048acc004c05cdd500640062c80c22b30013370e90040024566002602e6ea803200316406115980099b87480280122b3001301737540190018b20308acc004cdc3a4018009159800980b9baa00c800c59018456600266e1d200e0048acc004c05cdd500640062c80c22b30013370e90080024566002602e6ea803200316406116405480a9015202a405480a9015202a40542653001301b301b0019bac301a0019ba548001222323232323298009bab30220019bac302230230019919800800804112cc0040062980103d87a80008992cc004cdd7981298111baa00100e8980499812000a5eb82266006006604c0048100c0900050224dd618110044dd59811002cdd618110024c08800e6eb0c0880092222222259800980a98131baa0068992cc004c058c09cdd5009c4c8c8cc896600260600051980098178014c0acdd5010c88c966002603a0031323259800981a80140122c8190dd7181980098179baa0038acc004c08800626464b300130350028024590321bae3033001302f37540071640b48168c0b4dd50014dc8a45009b8f4881009b80480092222223322598009811003c566002604460666ea8026264646464646464653001375a607e003375a607e6080003323300100101b2259800800c52f5c11332259800acc004cdd7982198201baa0020178991980080099198008009bab304530463042375400844b30010018a5eb82264664464660020026eacc11c01089660020031003899198259ba73304b375200a66096609000266096609200297ae033003003304d002304b00141246eb8c10c004cc00c00cc120008c118005044112cc00400629422b30013371e6eb8c114dd6182280081fc528c4cc008008c11800504020868a5040f913304200233004004001899802002000a07c3041001304200140fd375c607e011375c607e00f303f0069bad303f0059bad303f0049817981d9baa303f0039bad303f002488888888896600260940111329800980a1bab301f304737540033259800981c18239baa0018982598241baa0018b208c304a304b304b3047375400330143756603e608e6ea8c07cc11cdd500da444660300042b30013038304937540051332259800acc004cdc380099b81002009899b89482024bd004006294104a4566002b30010088a51899b8900200a41291598009919192cc004c108c138dd5000c5660026084609c6ea8c148c14c00a266e20dd6982918279baa00100a899b89375a60a4609e6ea800402904d4528209a30510013304f30500013304f9800982018261baa30503051001a60103d87a8000a60103d8798000412c97ae0304c3754609e60a060986ea809e2b30013375e00860666609c6ea4034cc138dd480619827005998271ba800a3304e375066e00024004cc13a60020114c103d87a8000a60103d879800041286609c6ea001ccc138dd4008198271ba800f4bd704566002607864b30010018a4001132301d32598008014520008980f19800800982980120a02259800800c520008980f99801001182a000a0a23051001413864660020026eacc094c134dd5003912cc004006297ae0899199119198008009bab30520042259800800c400e264660ac6e9ccc158dd48029982b18298009982b182a000a5eb80cc00c00cc160008c1580050541bae304e0013300300330530023051001413d1332259800800c00a2b30013052001899192cc004cdc79bae30530020108acc004c080dd71829800c4cdc39bad305330540010058a50413914a08270c14c004dd61828800c00904f209e14a0646600200205444b30010018a5eb82264664464660020026eacc148010896600200310038991982b1ba733056375200a660ac60a6002660ac60a800297ae0330030033058002305600141506eb8c138004cc00c00cc14c008c14400504f452820948a50412914a08252294104a45282094375a609a609c609c609c609c60946ea8008cdc0801800c528209018248044590470c0fc004c0f8004c0f4004c0f0004c0ec004c0e8004c0e4004c0d0dd5004c52820648acc004c09001e2b3001302230333754013132323232329800981e800cdd6981e000cdd6981e00124446464664530013232332259800981b98219baa0028acc004c0dcc10cdd518239824001c4cdc40009bad3047304437540051337120026eb4c11cc110dd500120848a504108608a00266e0000c010cc10cc110004cc10e6002606860806ea8c110c11400698103d87a8000a60103d879800040fc97ae030403754608660806ea806e646600200203e44b30010018a5eb8226644b30015980099baf304730443754004037132330010013233001001375660926094608c6ea8010896600200314bd7044c8cc88c8cc004004dd59825802112cc00400620071323304f374e6609e6ea4014cc13cc130004cc13cc1340052f5c06600600660a2004609e0028268dd718238009980180198260011825000a0902259800800c528456600266e3cdd718249bac30490010438a518998010011825000a088411d14a0821226608c004660080080031330040040014108608a002608c002821a6eb8c10c0326eb8c10c02e60860153371200c00b3033303f3754608600f375a60866088006911111112cc004c13001e264646644660340022b3001303a304b3754003159800acc0040322946200e82522b30010028acc004cdd78009819998271ba900a3304e37520126609c0106609c6ea0044cc138dd419b800120033304e98008035300103d87a8000a60103d879800041286609c6ea0034cc138dd4007198271ba80054bd704566002607864b30010018a4001132301d32598008014520008980f19800800982980120a02259800800c520008980f99801001182a000a0a23051001413864660020026eacc094c134dd5002912cc004006297ae0899199119198008009bab30520042259800800c400e264660ac6e9ccc158dd48029982b18298009982b182a000a5eb80cc00c00cc160008c1580050541bae304e0013300300330530023051001413d1332259800800c00a2b30013052001899192cc004cdc79bae305300200d8acc004c080dd71829800c4cdc39bad305330540010078a50413914a08270c14c004dd61828800c00904f209e14a0646600200205444b30010018a5eb82264664464660020026eacc148010896600200310038991982b1ba733056375200a660ac60a6002660ac60a800297ae0330030033058002305600141506eb8c138004cc00c00cc14c008c14400504f452820948a50412914a08252294104a45282094337100029000192cc004c0ecc128dd5000c4c138c12cdd5000c5904918269827182718251baa00233702602c6eacc084c124dd5000980b1bab302130493754604260926ea8074c12c01e2c82486eb4c104004dd69820801182080098200018c0f0004c0ec004c0e8004c0e4004c0d0dd5004c5282064899912cc004c0940262b30013024303537540171323298009bad303b0019bad303b303c303c0019bae303b002488966002646464b30013031303d37540031598009818981e9baa30413042002899b88005375a6082607c6ea8006266e24014dd69820981f1baa00140f114a081e0c100004cc0f8c0fc004cc0fa6002605e60766ea8c0fcc10000698103d87a8000a60103d879800040e897ae0303b3754607c60766ea805a2b30015980099b884800000e2b300198009803801c5284c8cc004004c8cc004004068896600200314bd7044c8cc88c8cc004004dd59821002112cc004006200713233046374e6608c6ea4014cc118c10c004cc118c1100052f5c0660060066090004608c0028220dd7181f0009980180198218011820800a07e2259800800c52f5c1133225980099b8f375c608400400b133041374e0046600800800313300400400140f46eb0c100004c10400503e2444b3001001801456600260840031325980098079bae3042001899b87375a6084608600200914a081e8c108dd61820800c00903f207e44cc89660020030028acc004c104006264b3001300e375c608200313009375a6082608400314a081e0c104dd61820000c00903e207c14a06466002002646600200203444b30010018a5eb82264664464660020026eacc10801089660020031003899198231ba733046375200a6608c60860026608c608800297ae0330030033048002304600141106eb8c0f8004cc00c00cc10c008c10400503f112cc004006297ae0899912cc004cdc79bae304200203c8998209ba700233004004001899802002000a07a37586080002608200281f2294103944cc89660020030028acc004c10400626464b30013371e6eb8c1080080f22b3001300f375c60840031300a375a6084608600314a081ea294103d18210009bac3040001801207c40f82940c8cc004004064896600200314bd7044c8cc88c8cc004004dd59820802112cc004006200713233045374e6608a6ea4014cc114c108004cc114c10c0052f5c066006006608e004608a0028218dd7181e8009980180198210011820000a07c40e5132330010010162259800800c528456600266e3cdd7182000081cc528c4cc008008c10400503b207c8a5040e514a081c86076607660760026074606c6ea802e294103446600244466e1ccdc098031bab301130393754004600c6eacc044c0e4dd51808981c9baa003001911919800800801912cc00400629422b30013375e607a00200714a3133002002303e00140e081da6e9520049ba54800a6e440ce6e3c0cd2222225980099b874802003e2b3001302a303b3754023132323298009bad30420019bad3042304330430019919800800814112cc004006297ae0899912cc0056600266ebcc118c10cdd51823182398219baa00201a8981b192cc004c0dcc10cdd5000c5200089bad3047304437540028210c966002606e60866ea80062980103d87a8000899198008009bab30483045375400444b30010018a6103d87a8000899192cc004c0640062b300130180018981799825182400125eb82298103d87a80004119133004004304c00341186eb8c118004c124005047208432330010013756608e609060886ea8c11cc120c110dd5001912cc004006298103d87a8000899192cc004c0340062b3001300c0018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c1200050464528208289982280119802002000c4cc01001000504118220009822800a0849bae30420039bae304200248888966002609000713259800981998221baa0018992cc004c0d0c114dd5000c4cc89660026098003132332233019001159800801456600266ebc004c048cc134dd4804998269ba90083304d37500186609a6ea002d2f5c1159800981d992cc0040062900044c8c070c9660020051480022603a6600200260a4004827889660020031480022603c6600400460a60028280c14000504d19198008009bab3024304c375400844b30010018a5eb82264664464660020026eacc144010896600200310038991982a9ba733055375200a660aa60a4002660aa60a600297ae03300300330570023055001414c6eb8c134004cc00c00cc148008c14000504e45660026602804e60646609a00a6609a98103d87a80004bd7045660026602804e66e9520083304d0053304d375008897ae08acc00566002b30013301402730133304d0053304d30123304d30323304d0054bd7025eb812f5c113301402730133304d0053304d30323304d375208c97ae04bd70452820928a5189980a013980999826802998269809998269ba90463304d30323304d0054bd7025eb812f5c0824a264607e646600200205a44b30010018a40011332259800acc004cdc39bad30533050375400409115980099baf30283050375400400b13371e6eccc14cc150c150c140dd50011bb305a8a50413914a082722603e0031001413860a20026600400460a40028278c048cc134dd4804a5eb822941049452820928a50412514a0824a294104945282092980098260044006602a66e00cdc0021821020a0263259800981d18249baa0018982698251baa0018b2090304c304d304d3049375400260960031641246092608c6ea8004c8cc004004094896600200314bd7044cc8966002b30013375e609a60946ea80080862607a64b3001303e304a375400314800226eb4c138c12cdd5000a0923259800981f18251baa0018a60103d87a8000899198008009bab304f304c375400444b30010018a6103d87a8000899192cc004c0800062b3001301f0018981b19828982780125eb82298103d87a80004135133004004305300341346eb8c134004c14000504e209232330010013756609c609e60966ea800c896600200314c103d87a8000899192cc004c0500062b300130130018981a99828182700125eb82298103d87a80004131133004004305200341306eb8c130004c13c00504d4528209089982600119802002000c4cc01001000504818258009826000a0928b208830483045375400316410c603860886ea806e2c8228608460846084002608200260786ea8046294103a456600266e1d200a00f8acc004c0bcc0ecdd5008c4c8c8ca60026eb4c1080066eb4c108c10c006646600200205044b30010018a5eb8226644b30015980099baf304630433754608c608e60866ea800806a2606c64b300130373043375400314800226eb4c11cc110dd5000a0843259800981b98219baa0018a60103d87a8000899198008009bab30483045375400444b30010018a6103d87a8000899192cc004c0640062b300130180018981799825182400125eb82298103d87a80004119133004004304c00341186eb8c118004c124005047208432330010013756608e609060886ea8c11cc120c110dd5001912cc004006298103d87a8000899192cc004c0340062b3001300c0018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c1200050464528208289982280119802002000c4cc01001000504118220009822800a0849bae30420039bae3042002488889660026090007132598009824800c4c8cc88cc0580044c96600200715980099baf00230113304b375200e660966ea4018cc12cdd400519825800998259ba80094bd704566002607264b30010018a4001132301a32598008014520008980d998008009828001209a2259800800c520008980e198010011828800a09c304e001412c64660020026eacc088c128dd5002912cc004006297ae0899199119198008009bab304f0042259800800c400e264660a66e9ccc14cdd4802998299828000998299828800a5eb80cc00c00cc154008c14c0050511bae304b001330030033050002304e00141311323259800981c98251baa001899199119801001000912cc00400629422b30013375e6e98cc140c1440052f5bded8c06e98cc14000d2f5bded8c114a3133002002305200141308278dd5982798261baa00233760006980103d87a80008b2092323300100102c2259800800c530103d87a80008992cc004cdd78021826000c4c0d0cc13cc1340052f5c11330030033051002412c609e0028268c040cc12cc040cc12cdd4803a5eb812f5c114a0823a29410474528208e302f3304a304b30483754609660906ea8084cc12930010100004bd7019baf301e30463754603c608c6ea8c124014c078c118dd5000992cc004c0dcc118dd5000c4c128c11cdd5000c5904518249825182518231baa00130480018b208c32330010010232259800800c52f5c11332259800acc004cdd7982598241baa00201f8981d992cc004c0f0c120dd5000c5200089bad304c304937540028238c966002607860906ea8006298103d87a8000899198008009bab304d304a375400444b30010018a6103d87a8000899192cc004c0780062b3001301d0018981a19827982680125eb82298103d87a8000412d1330040043051003412c6eb8c12c004c13800504c208e323300100137566098609a60926ea800c896600200314c103d87a8000899192cc004c0480062b300130110018981999827182600125eb82298103d87a80004129133004004305000341286eb8c128004c13400504b4528208c89982500119802002000c4cc01001000504618248009825000a08e8b208a18210009820800981e1baa0118a5040e915980099b874803003e2b3001302c303b3754023132323298009bad30420019bad3042304330430019919800800814112cc004006297ae0899912cc0056600266ebcc118c10cdd51823182398219baa00201a8981b192cc004c0dcc10cdd5000c5200089bad3047304437540028210c966002606e60866ea8006298103d87a8000899198008009bab30483045375400444b30010018a6103d87a8000899192cc004c0640062b300130180018981799825182400125eb82298103d87a80004119133004004304c00341186eb8c118004c124005047208432330010013756608e609060886ea8c11cc120c110dd5001912cc004006298103d87a8000899192cc004c0340062b3001300c0018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c1200050464528208289982280119802002000c4cc01001000504118220009822800a0849bae30420039bae304200248888966002609000713259800981998221baa0018992cc004c0d0c114dd5000c660026092608c6ea8006646464b3001303c30483754003159800981e18241baa304c304d002899b88009375a609860926ea8006266e24024dd6982618249baa001411d14a08238c12c004cc124c128004cc12660026074608c6ea8c128c12c00698103d87a8000a60103d8798000411497ae0304637546092608c6ea8086646600200204a44b30010018a5eb8226644b30015980099baf304d304a37540040431303d3259800981f18251baa0018a40011375a609c60966ea8005049192cc004c0f8c128dd5000c5300103d87a8000899198008009bab304f304c375400444b30010018a6103d87a8000899192cc004c0800062b3001301f0018981b19828982780125eb82298103d87a80004135133004004305300341346eb8c134004c14000504e209232330010013756609c609e60966ea800c896600200314c103d87a8000899192cc004c0500062b300130130018981a99828182700125eb82298103d87a80004131133004004305200341306eb8c130004c13c00504d4528209089982600119802002000c4cc01001000504818258009826000a092488966002609a00313233223301a001159800802c56600200515980099baf0013374a9003198271ba900a3304e37520126609c6ea00352f5c11598009980a81418099982700319827260103d87a80004bd7045660026602a05066e95200c3304e0063304e375008a97ae08981e192cc0040062900044c8c074c9660020051480022603c6600200260a6004828089660020031480022603e6600400460a80028288c14400504e19198008009bab3025304d375400844b30010018a5eb82264664464660020026eacc148010896600200310038991982b1ba733056375200a660ac60a6002660ac60a800297ae0330030033058002305600141506eb8c138004cc00c00cc14c008c14400504f452820948a50412914a08252294104a4528209498009826804c00666e00cdc002202182120283259800981d98251baa0018982718259baa0018b2092304d304e304e304a375400260980031641288b208830483045375400316410c603860886ea806e2c82286084002608200260786ea8046294103a456600266e1d200e00f8acc004c0acc0ecdd5008c4c8ca60026eb8c1040066eb4c104c108006646600200204e44b30010018a5eb8226644b30015980099baf304530423754608a608c60846ea80080662606a64b300130363042375400314800226eb4c118c10cdd5000a0823259800981b18211baa0018a6103d87a8000899198008009bab30473044375400444b30010018a6103d87a8000899192cc004c0600062b300130170018981719824982380125eb82298103d87a80004115133004004304b00341146eb8c114004c120005046208232330010013756608c608e60866ea8c118c11cc10cdd5001912cc004006298103d87a8000899192cc004c0300062b3001300b0018981699824182300125eb82298103d87a80004111133004004304a00341106eb8c110004c11c0050454528208089982200119802002000c4cc01001000504018218009822000a0829bae30410024888966002608c005132598009823800c4c8c8cc88cc05400456600200515980099baf0013374a9003198249ba9006330493752012660926ea0cdc0004001a5eb822b300130373259800800c52000899180c192cc00400a2900044c064cc004004c13800904b112cc0040062900044c068cc008008c13c00504c1826000a09232330010013756604060906ea8014896600200314bd7044c8cc88c8cc004004dd59826802112cc004006200713233051374e660a26ea4014cc144c138004cc144c13c0052f5c06600600660a600460a20028278dd718248009980180198270011826000a094899912cc0040060051598009826800c4c8c96600266e3cdd71827001006c56600260366eb8c138006266e1cdd698271827800803c52820928a504124609c0026eb0c130006004825104a0a5032330010010252259800800c52f5c1132332232330010013756609a00844b30010018801c4c8cc144dd3998289ba900533051304e00133051304f0014bd701980180198298011828800a09e375c609200266006006609c0046098002825229410454528208a8a50411466e2000520003259800981b18229baa0018982498231baa0018b20883048304930493045375400466e04c044dd5980e18221baa00130113756603860886ea8c070c110dd518238021823000c590441919800800810912cc004006297ae0899912cc0056600266ebcc124c118dd500100ec4c0e4c9660026074608c6ea80062900044dd6982518239baa001411464b3001303a3046375400314c0103d87a8000899198008009bab304b3048375400444b30010018a6103d87a8000899192cc004c0700062b3001301b0018981919826982580125eb82298103d87a80004125133004004304f00341246eb8c124004c13000504a208a3233001001375660946096608e6ea800c896600200314c103d87a8000899192cc004c0400062b3001300f0018981899826182500125eb82298103d87a80004121133004004304e00341206eb8c120004c12c0050494528208889982400119802002000c4cc01001000504418238009824000a08a8b20861820800981e1baa0118a5040e91598009817807c5284566002605660766ea8046264653001375c6082003375a60826084003375c60820049112cc004c114c8cc0040040a8896600200314bd7044cc8966002b30013375e6090608a6ea8c120c124c114dd500100e44c0e0c9660026072608a6ea80062900044dd6982498231baa001411064b300130393045375400314c0103d87a8000899198008009bab304a3047375400444b30010018a6103d87a8000899192cc004c06c0062b3001301a0018981899826182500125eb82298103d87a80004121133004004304e00341206eb8c120004c12c00504920883233001001375660926094608c6ea8c124c128c118dd5001912cc004006298103d87a8000899192cc004cdc8804800c56600266e3c0240062606066096609200497ae08a60103d87a8000411d133004004304d003411c6eb8c11c004c1280050484528208689982380119802002000c4cc01001000504318230009823800a0888acc0056600266e2120000028cc004c03400a29426466002002646600200204044b30010018a5eb82264664464660020026eacc12001089660020031003899198261ba73304c375200a66098609200266098609400297ae033003003304e002304c00141286eb8c110004cc00c00cc124008c11c005045112cc004006297ae0899912cc004cdc79bae30480020078998239ba700233004004001899802002000a0863758608c002608e002822122259800800c00a2b300130480018992cc004c054dd71824000c4cdc39bad304830490010048a50410c60906eb0c11c00600482290452294503f4566002646600200203844b30010018a508acc004cdc79bae304600103f8a518998010011823800a08241111332259800800c00a2b300130470018992cc004c050dd71823800c4c03cdd698239824000c528208430473758608c0030024110822052819198008009919800800810112cc004006297ae0899199119198008009bab30480042259800800c400e264660986e9ccc130dd4802998261824800998261825000a5eb80cc00c00cc138008c13000504a1bae30440013300300330490023047001411444b30010018a5eb8226644b30013371e6eb8c12000810a26608e6e9c008cc0100100062660080080028218dd618230009823800a0888a5040fd14a081fa2c8210608200260786ea8046294103a207440e881d103a20742068370290001b874800503220642232598009811800c4c8c8c8c8c8c8c8c8ca60026eb4c1040066eb8c1040266eb8c1040226eb4c10401a6eb4c10401664b3001303f0018acc004cdc4a4008607c0031689819181f000a07a8b208037546082009375a6082007375a6082004911111112cc004c128026264b3001303530463754003132323259800982700144cc070c13400c4c9660026072003132598009828000c4c8c9660026078003132598009829800c4cc084c1480040722c8280c138dd500145660026082003132323298009bad30540019bad30540039bad305400248896600260b00090218b20aa182a000982980098271baa0028b2098413060986ea8004c13c0062c8268c12cdd50014566002607c00315980098259baa00280c45904c45904920923049375400316412c60980026098002608e6ea80062c8228c12403e2c823860820026080002607e002607c002607a002607800260760026074002606a6ea800e2b300130280018991919194c004dd6981e000cdd7181e0024dd7181e001cdd6981e00124444b3001304100580545903e0c0f0004c0ec004c0e8004c0d4dd5001c566002604a0031323232323298009bad303d0019bae303d0059bae303d0049bad303d0034888966002608400b132598009816981f1baa0018991919912cc004c11c00e0211641106eb4c110004dd718220011822000981f9baa0018b207a30410068b207e181e800981e000981d800981d000981a9baa0038acc004c09000626464653001375a6076003375c6076007375c60760049112cc004c0fc0120111640f0303b001303a001303537540071640cc8199033206630333754004464b300130273033375400314800226eb4c0dcc0d0dd5000a0643259800981398199baa0018a6103d87a8000899198008009bab30383035375400444b30010018a6103d87a8000899192cc004c0240062b300130080018980f9981d181c00125eb82298103d87a800040d9133004004303c00340d86eb8c0d8004c0e4005037206432330010010022259800800c5300103d87a8000899192cc004c0200062b300130070018980f1981c981b80125eb82298103d87a800040d5133004004303b00340d46eb8c0d4004c0e000503622c8168c8cc00400404c896600200314bd7044cc8966002b30013375e6062605c6ea8c0c4c0c8c0b8dd5001002c4c8cc004004c8cc004004dd59819981a18181baa303330343030375400844b30010018a5eb82264664464660020026eacc0d4010896600200310038991981c9ba733039375200a66072606c00266072606e00297ae033003003303b002303900140dc6eb8c0c4004cc00c00cc0d8008c0d0005032112cc00400629422b30013371e6eb8c0ccdd61819800816c528c4cc008008c0d000502e20628a5040b113303000233004004001899802002000a058302f001303000140b4605a60546ea8054c0b0c0a4dd5180098149baa0022302c302d0018b204c302a3027375400d1640943022302230223022001302100130203020001301f001301e301e003180b1baa00830170053017301800545900d0c038004c024dd5007452689b2b200e1", + "hash": "8cfed220dadcf07254f4fbc3fd3e86f555cbf777f54ad0bdc7592bc8" + }, + { + "title": "gcf_stake.gCf_stake.publish", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1PublishRedeemer" + } + }, + "parameters": [ + { + "title": "_auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "_gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "5903cf01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e9000488c8c8cc004004010896600200314c0103d87a80008992cc004cdd78021805800c4cdd2a40006601c601800297ae089980180198080012014300e001403066e9520023300a300b3008375400297ae0919ba548000cc024cdd2a4004660126ea40052f5c06601298103d87a80004bd702444464653001300b37540032232598009804000c566002601e6ea800e00516404115980099b87480080062b3001300f37540070028b20208acc004cdc3a400800315980098079baa003801459010456600266e1d20060018acc004c03cdd5001c00a2c80822b30013370e9004000c566002601e6ea800e00516404115980099b87480280062b3001300f37540070028b20208acc004cdc3a401800315980098079baa003801459010456600266e1d200e0018acc004c03cdd5001c00a2c80822b30013370e9008000c566002601e6ea800e005164041164034806900d201a4034806900d201a4034601a6ea800a601e00d300f002488896600266e1d20060048994c004dd6980a000cc050c05400660206ea800a26464b300130170018992cc004c034c04cdd5000c4c8cc020004566002601c60286ea801a266ebc005300103d87d8000899baf0014c103d87f8000404c602e60286ea80062c8090cc02cdd5980b180b980b980b980b980b980b980b980b980b801180b000c5901419199119801001000912cc004006297ae0899912cc004cdd7980d180b9baa301a301b3017375400400b13301900233004004001899802002000a02a3018001301900140586eb0c058008c024038c044dd5001a4444b3001300e0028acc004c054dd500340062c80b22b30013370e90010014566002602a6ea801a00316405916404c809860206ea8016264b30013370e9005002c4ca60026eb4c054006602a602c003301237540089114c0040466eb0c0600066eacc060c064c064c064c064c064c064c064c064c064006980103d87d800040143011375400d15980099b874802001626645300100f9bac30160019bab3016301730173017301730173017301730173017001a60103d87e8000400c602860226ea8018c044dd5001c5900f201e22223259800980c800c4c966002601e602a6ea800626466014002266ebc004010c064c058dd5000c5901419806801980c000c59016191919800800802912cc004006297ae0899912cc004cdd7980e180c9baa301c301d3019375400400b13301b00233004004001899802002000a02e301a001301b001406060160088070601c601e002601c0088a4d13656401001", + "hash": "fdf36c6bd97992a1a2c1059b5e2543b3d49b752520360d4f4ed4817d" + }, + { + "title": "gcf_stake.gCf_stake.propose", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "_auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "_gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "5903cf01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e9000488c8c8cc004004010896600200314c0103d87a80008992cc004cdd78021805800c4cdd2a40006601c601800297ae089980180198080012014300e001403066e9520023300a300b3008375400297ae0919ba548000cc024cdd2a4004660126ea40052f5c06601298103d87a80004bd702444464653001300b37540032232598009804000c566002601e6ea800e00516404115980099b87480080062b3001300f37540070028b20208acc004cdc3a400800315980098079baa003801459010456600266e1d20060018acc004c03cdd5001c00a2c80822b30013370e9004000c566002601e6ea800e00516404115980099b87480280062b3001300f37540070028b20208acc004cdc3a401800315980098079baa003801459010456600266e1d200e0018acc004c03cdd5001c00a2c80822b30013370e9008000c566002601e6ea800e005164041164034806900d201a4034806900d201a4034601a6ea800a601e00d300f002488896600266e1d20060048994c004dd6980a000cc050c05400660206ea800a26464b300130170018992cc004c034c04cdd5000c4c8cc020004566002601c60286ea801a266ebc005300103d87d8000899baf0014c103d87f8000404c602e60286ea80062c8090cc02cdd5980b180b980b980b980b980b980b980b980b980b801180b000c5901419199119801001000912cc004006297ae0899912cc004cdd7980d180b9baa301a301b3017375400400b13301900233004004001899802002000a02a3018001301900140586eb0c058008c024038c044dd5001a4444b3001300e0028acc004c054dd500340062c80b22b30013370e90010014566002602a6ea801a00316405916404c809860206ea8016264b30013370e9005002c4ca60026eb4c054006602a602c003301237540089114c0040466eb0c0600066eacc060c064c064c064c064c064c064c064c064c064006980103d87d800040143011375400d15980099b874802001626645300100f9bac30160019bab3016301730173017301730173017301730173017001a60103d87e8000400c602860226ea8018c044dd5001c5900f201e22223259800980c800c4c966002601e602a6ea800626466014002266ebc004010c064c058dd5000c5901419806801980c000c59016191919800800802912cc004006297ae0899912cc004cdd7980e180c9baa301c301d3019375400400b13301b00233004004001899802002000a02e301a001301b001406060160088070601c601e002601c0088a4d13656401001", + "hash": "fdf36c6bd97992a1a2c1059b5e2543b3d49b752520360d4f4ed4817d" + }, + { + "title": "gcf_stake.gCf_stake.vote", + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "_auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "_gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "5903cf01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e9000488c8c8cc004004010896600200314c0103d87a80008992cc004cdd78021805800c4cdd2a40006601c601800297ae089980180198080012014300e001403066e9520023300a300b3008375400297ae0919ba548000cc024cdd2a4004660126ea40052f5c06601298103d87a80004bd702444464653001300b37540032232598009804000c566002601e6ea800e00516404115980099b87480080062b3001300f37540070028b20208acc004cdc3a400800315980098079baa003801459010456600266e1d20060018acc004c03cdd5001c00a2c80822b30013370e9004000c566002601e6ea800e00516404115980099b87480280062b3001300f37540070028b20208acc004cdc3a401800315980098079baa003801459010456600266e1d200e0018acc004c03cdd5001c00a2c80822b30013370e9008000c566002601e6ea800e005164041164034806900d201a4034806900d201a4034601a6ea800a601e00d300f002488896600266e1d20060048994c004dd6980a000cc050c05400660206ea800a26464b300130170018992cc004c034c04cdd5000c4c8cc020004566002601c60286ea801a266ebc005300103d87d8000899baf0014c103d87f8000404c602e60286ea80062c8090cc02cdd5980b180b980b980b980b980b980b980b980b980b801180b000c5901419199119801001000912cc004006297ae0899912cc004cdd7980d180b9baa301a301b3017375400400b13301900233004004001899802002000a02a3018001301900140586eb0c058008c024038c044dd5001a4444b3001300e0028acc004c054dd500340062c80b22b30013370e90010014566002602a6ea801a00316405916404c809860206ea8016264b30013370e9005002c4ca60026eb4c054006602a602c003301237540089114c0040466eb0c0600066eacc060c064c064c064c064c064c064c064c064c064006980103d87d800040143011375400d15980099b874802001626645300100f9bac30160019bab3016301730173017301730173017301730173017001a60103d87e8000400c602860226ea8018c044dd5001c5900f201e22223259800980c800c4c966002601e602a6ea800626466014002266ebc004010c064c058dd5000c5901419806801980c000c59016191919800800802912cc004006297ae0899912cc004cdd7980e180c9baa301c301d3019375400400b13301b00233004004001899802002000a02e301a001301b001406060160088070601c601e002601c0088a4d13656401001", + "hash": "fdf36c6bd97992a1a2c1059b5e2543b3d49b752520360d4f4ed4817d" + }, + { + "title": "gcf_stake.gCf_stake.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "_auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + }, + { + "title": "spend", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "_gov_action_period", + "schema": { + "$ref": "#/definitions/Int" + } + } + ], + "compiledCode": "5903cf01010022229800aba2aba1aba0aab9faab9eaab9dab9a9bae0049bae0039bad0024888888888966003300130063754017370e9000488c8c8cc004004010896600200314c0103d87a80008992cc004cdd78021805800c4cdd2a40006601c601800297ae089980180198080012014300e001403066e9520023300a300b3008375400297ae0919ba548000cc024cdd2a4004660126ea40052f5c06601298103d87a80004bd702444464653001300b37540032232598009804000c566002601e6ea800e00516404115980099b87480080062b3001300f37540070028b20208acc004cdc3a400800315980098079baa003801459010456600266e1d20060018acc004c03cdd5001c00a2c80822b30013370e9004000c566002601e6ea800e00516404115980099b87480280062b3001300f37540070028b20208acc004cdc3a401800315980098079baa003801459010456600266e1d200e0018acc004c03cdd5001c00a2c80822b30013370e9008000c566002601e6ea800e005164041164034806900d201a4034806900d201a4034601a6ea800a601e00d300f002488896600266e1d20060048994c004dd6980a000cc050c05400660206ea800a26464b300130170018992cc004c034c04cdd5000c4c8cc020004566002601c60286ea801a266ebc005300103d87d8000899baf0014c103d87f8000404c602e60286ea80062c8090cc02cdd5980b180b980b980b980b980b980b980b980b980b801180b000c5901419199119801001000912cc004006297ae0899912cc004cdd7980d180b9baa301a301b3017375400400b13301900233004004001899802002000a02a3018001301900140586eb0c058008c024038c044dd5001a4444b3001300e0028acc004c054dd500340062c80b22b30013370e90010014566002602a6ea801a00316405916404c809860206ea8016264b30013370e9005002c4ca60026eb4c054006602a602c003301237540089114c0040466eb0c0600066eacc060c064c064c064c064c064c064c064c064c064006980103d87d800040143011375400d15980099b874802001626645300100f9bac30160019bab3016301730173017301730173017301730173017001a60103d87e8000400c602860226ea8018c044dd5001c5900f201e22223259800980c800c4c966002601e602a6ea800626466014002266ebc004010c064c058dd5000c5901419806801980c000c59016191919800800802912cc004006297ae0899912cc004cdd7980e180c9baa301c301d3019375400400b13301b00233004004001899802002000a02e301a001301b001406060160088070601c601e002601c0088a4d13656401001", + "hash": "fdf36c6bd97992a1a2c1059b5e2543b3d49b752520360d4f4ed4817d" + }, + { + "title": "share_token/mint.share_token.mint", + "redeemer": { + "title": "redeemer", + "schema": { + "$ref": "#/definitions/types~1MintPolarity" + } + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "590380010100229800aba2aba1aba0aab9faab9eaab9dab9a9bae0024888888896600264653001300900198049805000cdc3a400130090024888966002600460126ea800e266446644b300130060018acc004c038dd5004400a2c807a2b300130030018acc004c038dd5004400a2c807a2c806100c0992cc004c044006264b30013006300d3754011132598009809800c4c9660026010601e6ea80062646644b3001300b0018acc004c04cdd5001c00a2c80a22b300130080018acc004c04cdd5001c00a2c80a22b30013370e9002000c56600260266ea800e00516405115980099b87480180062b3001301337540070028b20288acc004cdc3a401000315980098099baa003801459014456600266e1d200a0018acc004c04cdd5001c00a2c80a22b30013370e9006000c56600260266ea800e00516405115980099b87480380062b3001301337540070028b20288acc004cdc3a402000315980098099baa003801459014459011202240448089011202240448089011099baf0014c103d879800030103754002602660206ea80062c8070c8c8cc004004dd5980a180a980a980a980a980a980a980a980a980a802112cc0040062980103d87a80008992cc004cdd78021809000c4cdd2a40006602a602600297ae0899801801980b80120223015001404c66e952002330113012300f3754602400297ae08b202032330010013758602400444b30010018a5eb8226644b3001323300100132330010013756602e603060286ea8c05cc060c050dd5002112cc004006297ae0899199119198008009bab30190042259800800c400e2646603a6e9ccc074dd48029980e980d0009980e980d800a5eb80cc00c00cc07c008c07400501b1bae301500133003003301a0023018001405844b30010018a508acc004cdc79bae30173758602e00202314a31330020023018001404880aa26602800466008008003133004004001404060260026028002808a266e20dd698071808801240008060c034dd500245900e192cc004c008c030dd5000c52f5bded8c1137566020601a6ea800500b19198008009bab30103011301130113011300d375400844b30010018a60103d87a8000899192cc004cdc8803000c56600266e3c018006266e9520003301230100024bd7045300103d87a80004039133004004301400340386eb8c038004c04400500f18059baa006375c601a60146ea800cdc3a4005164020300900130043754013149a26cac8011", + "hash": "04b3f2f84b2728dbcafcf64d06e182b812b826df6b3a246b3065dc66" + }, + { + "title": "share_token/mint.share_token.else", + "redeemer": { + "schema": {} + }, + "parameters": [ + { + "title": "auth_token", + "schema": { + "$ref": "#/definitions/cardano~1assets~1PolicyId" + } + } + ], + "compiledCode": "590380010100229800aba2aba1aba0aab9faab9eaab9dab9a9bae0024888888896600264653001300900198049805000cdc3a400130090024888966002600460126ea800e266446644b300130060018acc004c038dd5004400a2c807a2b300130030018acc004c038dd5004400a2c807a2c806100c0992cc004c044006264b30013006300d3754011132598009809800c4c9660026010601e6ea80062646644b3001300b0018acc004c04cdd5001c00a2c80a22b300130080018acc004c04cdd5001c00a2c80a22b30013370e9002000c56600260266ea800e00516405115980099b87480180062b3001301337540070028b20288acc004cdc3a401000315980098099baa003801459014456600266e1d200a0018acc004c04cdd5001c00a2c80a22b30013370e9006000c56600260266ea800e00516405115980099b87480380062b3001301337540070028b20288acc004cdc3a402000315980098099baa003801459014459011202240448089011202240448089011099baf0014c103d879800030103754002602660206ea80062c8070c8c8cc004004dd5980a180a980a980a980a980a980a980a980a980a802112cc0040062980103d87a80008992cc004cdd78021809000c4cdd2a40006602a602600297ae0899801801980b80120223015001404c66e952002330113012300f3754602400297ae08b202032330010013758602400444b30010018a5eb8226644b3001323300100132330010013756602e603060286ea8c05cc060c050dd5002112cc004006297ae0899199119198008009bab30190042259800800c400e2646603a6e9ccc074dd48029980e980d0009980e980d800a5eb80cc00c00cc07c008c07400501b1bae301500133003003301a0023018001405844b30010018a508acc004cdc79bae30173758602e00202314a31330020023018001404880aa26602800466008008003133004004001404060260026028002808a266e20dd698071808801240008060c034dd500245900e192cc004c008c030dd5000c52f5bded8c1137566020601a6ea800500b19198008009bab30103011301130113011300d375400844b30010018a60103d87a8000899192cc004cdc8803000c56600266e3c018006266e9520003301230100024bd7045300103d87a80004039133004004301400340386eb8c038004c04400500f18059baa006375c601a60146ea800cdc3a4005164020300900130043754013149a26cac8011", + "hash": "04b3f2f84b2728dbcafcf64d06e182b812b826df6b3a246b3065dc66" + } + ], + "definitions": { + "Bool": { + "title": "Bool", + "anyOf": [ + { + "title": "False", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "True", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "ByteArray": { + "dataType": "bytes" + }, + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, + "Int": { + "dataType": "integer" + }, + "List$cardano/address/Credential": { + "dataType": "list", + "items": { + "$ref": "#/definitions/cardano~1address~1Credential" + } + }, + "Option$aiken/crypto/ScriptHash": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$cardano/address/StakeCredential": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1address~1StakeCredential" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Option$cardano/governance/GovernanceActionId": { + "title": "Option", + "anyOf": [ + { + "title": "Some", + "description": "An optional value.", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" + } + ] + }, + { + "title": "None", + "description": "Nothing.", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "Pairs$cardano/address/Credential_cardano/assets/Lovelace": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/cardano~1address~1Credential" + }, + "values": { + "$ref": "#/definitions/cardano~1assets~1Lovelace" + } + }, + "Pairs$cardano/address/Credential_cardano/governance/Mandate": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/cardano~1address~1Credential" + }, + "values": { + "$ref": "#/definitions/cardano~1governance~1Mandate" + } + }, + "Pairs$gov/ProtocolParametersIndex_Data": { + "title": "Pairs", + "dataType": "map", + "keys": { + "$ref": "#/definitions/gov~1ProtocolParametersIndex" + }, + "values": { + "$ref": "#/definitions/Data" + } + }, + "aiken/collection/Index": { + "title": "Index", + "dataType": "integer" + }, + "aiken/crypto/ScriptHash": { + "title": "ScriptHash", + "dataType": "bytes" + }, + "aiken/crypto/VerificationKeyHash": { + "title": "VerificationKeyHash", + "dataType": "bytes" + }, + "cardano/address/Address": { + "title": "Address", + "description": "A Cardano `Address` typically holding one or two credential references.\n\n Note that legacy bootstrap addresses (a.k.a. 'Byron addresses') are\n completely excluded from Plutus contexts. Thus, from an on-chain\n perspective only exists addresses of type 00, 01, ..., 07 as detailed\n in [CIP-0019 :: Shelley Addresses](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0019/#shelley-addresses).", + "anyOf": [ + { + "title": "Address", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "payment_credential", + "$ref": "#/definitions/cardano~1address~1PaymentCredential" + }, + { + "title": "stake_credential", + "$ref": "#/definitions/Option$cardano~1address~1StakeCredential" + } + ] + } + ] + }, + "cardano/address/Credential": { + "title": "Credential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + ] + } + ] + }, + "cardano/address/PaymentCredential": { + "title": "PaymentCredential", + "description": "A general structure for representing an on-chain `Credential`.\n\n Credentials are always one of two kinds: a direct public/private key\n pair, or a script (native or Plutus).", + "anyOf": [ + { + "title": "VerificationKey", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1VerificationKeyHash" + } + ] + }, + { + "title": "Script", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "$ref": "#/definitions/aiken~1crypto~1ScriptHash" + } + ] + } + ] + }, + "cardano/address/StakeCredential": { + "title": "StakeCredential", + "description": "Represent a type of object that can be represented either inline (by hash)\n or via a reference (i.e. a pointer to an on-chain location).\n\n This is mainly use for capturing pointers to a stake credential\n registration certificate in the case of so-called pointer addresses.", + "anyOf": [ + { + "title": "Inline", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "$ref": "#/definitions/cardano~1address~1Credential" + } + ] + }, + { + "title": "Pointer", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "slot_number", + "$ref": "#/definitions/Int" + }, + { + "title": "transaction_index", + "$ref": "#/definitions/Int" + }, + { + "title": "certificate_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "cardano/assets/Lovelace": { + "title": "Lovelace", + "dataType": "integer" + }, + "cardano/assets/PolicyId": { + "title": "PolicyId", + "dataType": "bytes" + }, + "cardano/governance/Constitution": { + "title": "Constitution", + "anyOf": [ + { + "title": "Constitution", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "guardrails", + "$ref": "#/definitions/Option$aiken~1crypto~1ScriptHash" + } + ] + } + ] + }, + "cardano/governance/GovernanceActionId": { + "title": "GovernanceActionId", + "anyOf": [ + { + "title": "GovernanceActionId", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction", + "$ref": "#/definitions/cardano~1governance~1TransactionId" + }, + { + "title": "proposal_procedure", + "$ref": "#/definitions/aiken~1collection~1Index" + } + ] + } + ] + }, + "cardano/governance/Mandate": { + "title": "Mandate", + "dataType": "integer" + }, + "cardano/governance/ProtocolVersion": { + "title": "ProtocolVersion", + "anyOf": [ + { + "title": "ProtocolVersion", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "major", + "$ref": "#/definitions/Int" + }, + { + "title": "minor", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "cardano/governance/TransactionId": { + "title": "TransactionId", + "dataType": "bytes" + }, + "cardano/transaction/OutputReference": { + "title": "OutputReference", + "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", + "anyOf": [ + { + "title": "OutputReference", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction_id", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "output_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "gov/ProtocolParametersIndex": { + "title": "ProtocolParametersIndex", + "dataType": "integer" + }, + "gov/VGovernanceAction": { + "title": "VGovernanceAction", + "anyOf": [ + { + "title": "VProtocolParameters", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type 'ProtocolParameters'. They must all\n form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "new_parameters", + "description": "The new proposed protocol parameters. Only values set to `Some` are relevant.", + "$ref": "#/definitions/gov~1VProtocolParametersUpdate" + }, + { + "title": "guardrails", + "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the new protocol parameters to be deemed valid.", + "$ref": "#/definitions/Option$aiken~1crypto~1ScriptHash" + } + ] + }, + { + "title": "HardFork", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `HardFork`. They must all\n form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "new_version", + "description": "The new proposed version. Few rules apply to proposing new versions:\n\n - The `major` component, if incremented, must be exactly one more than the current.\n - The `minor` component, if incremented, must be exactly one more than the current.\n - If the `major` component is incremented, `minor` must be set to `0`.\n - Neither `minor` nor `major` can be decremented.", + "$ref": "#/definitions/cardano~1governance~1ProtocolVersion" + } + ] + }, + { + "title": "TreasuryWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "title": "beneficiaries", + "description": "A collection of beneficiaries, which can be plain verification key\n hashes or script hashes (e.g. DAO).", + "$ref": "#/definitions/Pairs$cardano~1address~1Credential_cardano~1assets~1Lovelace" + }, + { + "title": "guardrails", + "description": "The optional guardrails script defined in the constitution. The script\n is executed by the ledger in addition to the hard-coded ledger rules.\n\n It must pass for the withdrawals to be authorized.", + "$ref": "#/definitions/Option$aiken~1crypto~1ScriptHash" + } + ] + }, + { + "title": "NoConfidence", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + } + ] + }, + { + "title": "ConstitutionalCommittee", + "dataType": "constructor", + "index": 4, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `NoConfidence` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "evicted_members", + "description": "Constitutional members to be removed.", + "$ref": "#/definitions/List$cardano~1address~1Credential" + }, + { + "title": "added_members", + "description": "Constitutional members to be added.", + "$ref": "#/definitions/Pairs$cardano~1address~1Credential_cardano~1governance~1Mandate" + }, + { + "title": "quorum", + "description": "The new quorum value, as a ratio of a numerator and a denominator. The\n quorum specifies the threshold of 'Yes' votes necessary for the\n constitutional committee to accept a proposal procedure.", + "$ref": "#/definitions/gov~1VRational" + } + ] + }, + { + "title": "NewConstitution", + "dataType": "constructor", + "index": 5, + "fields": [ + { + "title": "ancestor", + "description": "The last governance action of type `Constitution` or\n `ConstitutionalCommittee`. They must all / form a chain.", + "$ref": "#/definitions/Option$cardano~1governance~1GovernanceActionId" + }, + { + "title": "constitution", + "description": "The new proposed constitution.", + "$ref": "#/definitions/cardano~1governance~1Constitution" + } + ] + }, + { + "title": "NicePoll", + "dataType": "constructor", + "index": 6, + "fields": [] + } + ] + }, + "gov/VProtocolParametersUpdate": { + "title": "VProtocolParametersUpdate", + "anyOf": [ + { + "title": "VProtocolParametersUpdate", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "inner", + "$ref": "#/definitions/Pairs$gov~1ProtocolParametersIndex_Data" + } + ] + } + ] + }, + "gov/VRational": { + "title": "VRational", + "anyOf": [ + { + "title": "VRational", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "numerator", + "$ref": "#/definitions/Int" + }, + { + "title": "denominator", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundGovDatum": { + "title": "CrowdfundGovDatum", + "anyOf": [ + { + "title": "Crowdfund", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "stake_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "crowdfund_address", + "$ref": "#/definitions/cardano~1address~1Address" + }, + { + "title": "fundraise_target", + "$ref": "#/definitions/Int" + }, + { + "title": "current_fundraised_amount", + "$ref": "#/definitions/Int" + }, + { + "title": "allow_over_subscription", + "$ref": "#/definitions/Bool" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + }, + { + "title": "expiry_buffer", + "$ref": "#/definitions/Int" + }, + { + "title": "min_charge", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Proposed", + "dataType": "constructor", + "index": 1, + "fields": [ + { + "title": "stake_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Voted", + "dataType": "constructor", + "index": 2, + "fields": [ + { + "title": "stake_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + }, + { + "title": "gov_tx_id", + "$ref": "#/definitions/cardano~1governance~1GovernanceActionId" + }, + { + "title": "deadline", + "$ref": "#/definitions/Int" + } + ] + }, + { + "title": "Refundable", + "dataType": "constructor", + "index": 3, + "fields": [ + { + "title": "stake_hash", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "share_token", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "funds_controlled", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "types/CrowdfundGovRedeemer": { + "title": "CrowdfundGovRedeemer", + "anyOf": [ + { + "title": "ContributeFund", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "CompleteCrowdfund", + "dataType": "constructor", + "index": 1, + "fields": [] + }, + { + "title": "PreMatureContributorWithdrawal", + "dataType": "constructor", + "index": 2, + "fields": [] + }, + { + "title": "PreMatureRemoveEmptyInstance", + "dataType": "constructor", + "index": 3, + "fields": [] + }, + { + "title": "RegisterCerts", + "dataType": "constructor", + "index": 4, + "fields": [] + }, + { + "title": "VoteOnGovAction", + "dataType": "constructor", + "index": 5, + "fields": [] + }, + { + "title": "DeregisterCerts", + "dataType": "constructor", + "index": 6, + "fields": [] + }, + { + "title": "AfterCompleteContributorWithdrawal", + "dataType": "constructor", + "index": 7, + "fields": [] + }, + { + "title": "AfterCompleteRemoveEmptyInstance", + "dataType": "constructor", + "index": 8, + "fields": [] + } + ] + }, + "types/MintPolarity": { + "title": "MintPolarity", + "anyOf": [ + { + "title": "RMint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "RBurn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + }, + "types/PublishRedeemer": { + "title": "PublishRedeemer", + "anyOf": [ + { + "title": "Register", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Deregister", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + } + } +} \ No newline at end of file diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/1_gCf_spend.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/1_gCf_spend.md new file mode 100644 index 000000000..aedc267a5 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/1_gCf_spend.md @@ -0,0 +1,277 @@ +# Specification - gCf_spend + +## Overview + +The `gCf_spend` validator is a unified spending validator that handles both crowdfunding operations and governance operations. It merges functionality from `aiken-crowdfund` and `gov-crowdfund` into a single contract. + +## Parameters + +- `auth_token`: PolicyId - The policy ID of the crowdfunding authentication token +- `proposer_key_hash`: ByteArray - The hash of the proposer's public key for authorization +- `gov_action`: VGovernanceAction - The governance action to be proposed +- `delegate_pool_id`: ByteArray - The stake pool ID to delegate to during governance +- `stake_register_deposit`: Lovelace - Dynamic stake registration deposit amount +- `drep_register_deposit`: Lovelace - Dynamic DRep registration deposit amount +- `gov_deposit`: Lovelace - Dynamic governance proposal deposit amount + +## Datum + +The validator accepts `CrowdfundGovDatum` which can be in one of four states. The main user-facing states are `Crowdfund`, `Proposed`, and `Voted`. The `Refundable` state is an intermediate state used for post-governance fund withdrawals: + +```rs +pub type CrowdfundGovDatum { + // Crowdfunding phase - active crowdfunding campaign + Crowdfund { + stake_hash: ByteArray, + share_token: ByteArray, + crowdfund_address: Address, + fundraise_target: Int, + current_fundraised_amount: Int, + allow_over_subscription: Bool, + deadline: Int, + expiry_buffer: Int, + min_charge: Int + } + // Governance phase - proposal submitted + Proposed { + stake_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + deadline: Int, + } + // Governance phase - proposal voted on + Voted { + stake_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + gov_tx_id: GovernanceActionId, + deadline: Int, + } + // Governance phase - ready for refunds + Refundable { + stake_hash: ByteArray, + share_token: ByteArray, + funds_controlled: Int, + } +} +``` + +## User Actions + +### 1. ContributeFund + +**Phase**: Crowdfunding +**Datum State**: `Crowdfund` → `Crowdfund` + +Allows contributors to add funds to an active crowdfunding campaign. + +**Requirements**: +- Exactly one input with `auth_token` (empty token name) from current address +- Exactly one output with `auth_token` (empty token name) to current address +- Minimum contribution: 2 ADA (2,000,000 lovelace) +- The increase in output lovelace equals the increase in `current_fundraised_amount` +- If `allow_over_subscription` is `False`, `current_fundraised_amount` must not exceed `fundraise_target` +- Transaction must occur before `deadline` +- Output value must contain exactly 2 assets (`auth_token` + lovelace) +- Share tokens minted: exactly `fundraise_added` amount of `share_token` with empty token name (`""`) + +**Validation**: +- Lovelace difference matches datum update +- Fundraise target constraint respected +- Deadline not passed +- Output datum correctly updated +- Share tokens minted proportionally + +### 2. PreMatureContributorWithdrawal + +**Phase**: Crowdfunding +**Datum State**: `Crowdfund` → `Crowdfund` + +Allows contributors to withdraw funds before crowdfunding completion if campaign failed or deadline expired. + +**Requirements**: +- Exactly one input with `auth_token` (empty token name) from current address +- Exactly one output with `auth_token` (empty token name) to current address +- Either: + - `deadline + expiry_buffer` has passed, OR + - `current_fundraised_amount <= fundraise_target` (campaign failed) +- Lovelace withdrawn (negative difference) equals share tokens burned +- Output value must contain exactly 2 assets +- Share tokens burned: exactly `|lovelace_withdrawn|` amount of `share_token` with empty token name (`""`) + +**Validation**: +- Validity period check OR fundraise failure check +- Lovelace withdrawn matches share tokens burned +- Output datum correctly updated with reduced `current_fundraised_amount` + +### 3. PreMatureRemoveEmptyInstance + +**Phase**: Crowdfunding +**Datum State**: `Crowdfund` → (consumed) + +Allows proposer to remove an empty crowdfunding instance after deadline. + +**Requirements**: +- `deadline` has passed +- Exactly one input with `auth_token` (empty token name) from current address +- If `current_fundraised_amount > 0`: + - Burn all `share_token` tokens (amount: `-current_fundraised_amount`, empty token name `""`) + - Burn `auth_token` (amount: -1, empty token name `""`) +- If `current_fundraised_amount == 0`: + - Burn only `auth_token` (amount: -1, empty token name `""`) +- Must be signed by `proposer_key_hash` + +**Validation**: +- Deadline passed +- Appropriate tokens burned +- Proposer authorization + +### 4. RegisterCerts + +**Phase**: Governance +**Datum State**: `Crowdfund` → `Proposed` + +Registers stake and DRep certificates, delegates, and submits governance proposal. Can be called directly from the crowdfunding phase. + +**Requirements**: +- Exactly one input with `auth_token` (empty token name) from current address +- Exactly one output with `auth_token` (empty token name) to current address +- Input datum must be `Crowdfund` state +- Output datum must be `Proposed` state with: + - `stake_hash` from input datum + - `share_token` from input datum + - `funds_controlled` set to `current_fundraised_amount` from input datum + - `deadline` from input datum +- Output value deducted by exactly `stake_register_deposit + drep_register_deposit + gov_deposit` +- Output value must contain exactly 2 assets (`auth_token` + lovelace) +- Current address must have inline stake credential + +**Certificates Required**: +- Register stake certificate (no deposit required) +- Register DRep certificate with `drep_register_deposit` +- Delegate vote to own DRep (Registered credential) +- Delegate stake to `delegate_pool_id` + - OR delegate both vote and stake in single certificate +- Submit governance proposal with: + - Deposit: `gov_deposit` + - Return address: Script(`stake_hash` from datum) + - Governance action: `gov_action` + +**Validation**: +- Lovelace deduction matches deposits +- Datum state transition correct +- All required certificates present +- Proposal procedure valid + +### 5. VoteOnGovAction + +**Phase**: Governance +**Datum State**: `Proposed` → `Voted` + +Records that the governance action has been voted on. + +**Requirements**: +- Exactly one input with `auth_token` (empty token name) from current address +- Exactly one output with `auth_token` (empty token name) to current address +- Input datum must be `Proposed` state +- Output datum must be `Voted` state with: + - Same fields as input except `gov_tx_id` added + - `gov_tx_id` constructed from own input's `transaction_id` + `proposal_procedure: 0` +- Input and output values must be identical +- Output value must contain exactly 2 assets + +**Vote Required**: +- DRep (Script(`stake_hash` from datum)) must vote `Yes` on the governance action identified by `gov_tx_id` + +**Validation**: +- Value preservation +- Datum state transition correct +- Vote recorded correctly + +### 6. DeregisterCerts + +**Phase**: Governance +**Datum State**: `Voted` → `Refundable` + +Deregisters certificates and transitions to refundable state after governance period. + +**Requirements**: +- `deadline` has passed +- Exactly one input with `auth_token` (empty token name) from current address +- Exactly one output with `auth_token` (empty token name) to current address +- Input datum must be `Voted` state +- Output datum must be `Refundable` state with same fields (excluding `gov_tx_id` and `deadline`) +- Output value increased by exactly `stake_register_deposit + drep_register_deposit + gov_deposit` (refunds) +- Output value must contain exactly 2 assets +- Current address must have inline stake credential + +**Certificates Required**: +- Unregister stake certificate (refund received) +- Unregister DRep certificate with `drep_register_deposit` refund + +**Validation**: +- Deadline passed +- Lovelace increase matches refunds +- Datum state transition correct +- Certificates deregistered + +### 7. AfterCompleteContributorWithdrawal + +**Phase**: Post-Governance +**Datum State**: `Refundable` → `Refundable` + +Allows contributors to withdraw funds after governance completion by burning share tokens. + +**Requirements**: +- Exactly one input with `auth_token` (empty token name) from current address +- Exactly one output with `auth_token` (empty token name) to current address +- Input datum must be `Refundable` state +- Output datum must be `Refundable` state with `funds_controlled` increased by `lovelace_withdrawn` +- Lovelace withdrawn (negative difference) equals share tokens burned +- Output value must contain exactly 2 assets +- Share tokens burned: exactly `|lovelace_withdrawn|` amount of `share_token` with empty token name (`""`) + +**Validation**: +- Lovelace withdrawn matches share tokens burned +- Output datum correctly updated + +### 8. AfterCompleteRemoveEmptyInstance + +**Phase**: Post-Governance +**Datum State**: `Refundable` → (consumed) + +Allows proposer to remove empty instance after all funds withdrawn. + +**Requirements**: +- Exactly one input with token of policy `stake_hash` (from datum, empty token name) from current address +- If `funds_controlled > 0`: + - Burn all remaining `share_token` tokens (amount: `-funds_controlled`, empty token name `""`) +- Burn `auth_token` (amount: -1, empty token name `""`) +- Must be signed by `proposer_key_hash` + +**Validation**: +- Appropriate tokens burned +- Proposer authorization + +## State Transition Flow + +**Main Flow:** +``` +Crowdfund → RegisterCerts → Proposed +Proposed → VoteOnGovAction → Voted +Voted → DeregisterCerts → Refundable +``` + +**Post-Governance:** +``` +Refundable → AfterCompleteContributorWithdrawal → Refundable (loop until empty) +Refundable → AfterCompleteRemoveEmptyInstance → (consumed) +``` + +The `Refundable` state is an intermediate state that allows contributors to withdraw funds after governance completion. From a user perspective, withdrawals happen after the governance proposal is voted on (Voted state), but internally the contract transitions through `Refundable` for fund management. + +## Token Usage + +- **`auth_token`**: Used throughout all phases (Phases 1-4) to identify UTxOs. Token name is empty string (`""`) in all phases +- **`share_token`**: Minted/burned proportionally to contributions/withdrawals. Token name is empty string (`""`) in all phases +- **`stake_hash`**: Stored in all datum states (`Crowdfund`, `Proposed`, `Voted`, `Refundable`). This is the stake validator script hash, used as the return address for governance proposals and as the DRep credential for voting diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/2_gCf_stake.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/2_gCf_stake.md new file mode 100644 index 000000000..9e990d26e --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/2_gCf_stake.md @@ -0,0 +1,89 @@ +# Specification - gCf_stake + +## Overview + +The `gCf_stake` validator is a stake script validator that coordinates publishing operations (certificate registration/deregistration) and governance proposal/vote validation. It works in conjunction with `gCf_spend` to provide governance capabilities. The validator no longer handles token minting/burning - `auth_token` is used throughout all phases. + +## Parameters + +- `auth_token`: PolicyId - The policy ID of the crowdfunding authentication token (used for reference) +- `spend`: ByteArray - The script hash of the `gCf_spend` validator +- `gov_action_period`: Int - The buffer period added to crowdfund deadline for governance operations (currently unused but reserved for future use) + +## User Actions + +### 1. Publish - Register + +**Purpose**: Validate that stake/DRep registration is happening via the spend validator. + +**Requirements**: +- Redeemer: `Register` +- Exactly one input from the `spend` script address +- The spend validator input must have redeemer `RegisterCerts` + +**Validation**: +- Spend script input redeemer check: Ensures `RegisterCerts` is being used in spend validator + +**Usage**: Called when registering certificates and submitting governance proposal. + +### 2. Publish - Deregister + +**Purpose**: Validate that stake/DRep deregistration is happening via the spend validator. + +**Requirements**: +- Redeemer: `Deregister` +- Exactly one input from the `spend` script address +- The spend validator input must have redeemer `DeregisterCerts` + +**Validation**: +- Spend script input redeemer check: Ensures `DeregisterCerts` is being used in spend validator + +**Usage**: Called when deregistering certificates after governance period. + +### 3. Propose + +**Purpose**: Validate that a governance proposal is being submitted via the spend validator. + +**Requirements**: +- Exactly one input from the `spend` script address +- The spend validator input must have redeemer `RegisterCerts` + +**Validation**: +- Spend script input redeemer check: Ensures `RegisterCerts` is being used in spend validator + +**Usage**: Called when submitting a governance proposal. The proposal itself is validated in the spend validator's `RegisterCerts` case. + +### 4. Vote + +**Purpose**: Validate that a governance vote is being cast via the spend validator. + +**Requirements**: +- Exactly one input from the `spend` script address +- The spend validator input must have redeemer `VoteOnGovAction` + +**Validation**: +- Spend script input redeemer check: Ensures `VoteOnGovAction` is being used in spend validator + +**Usage**: Called when voting on a governance action. The vote itself is validated in the spend validator's `VoteOnGovAction` case. + +## Relationship with gCf_spend + +The `gCf_stake` validator acts as a coordination layer that: + +1. **Publishing**: Validates that certificate registration/deregistration operations are properly coordinated through the spend validator + +2. **Governance**: Ensures that proposal submission and voting operations are properly coordinated through the spend validator + +The actual business logic and state transitions are handled by `gCf_spend`, while `gCf_stake` ensures these operations are authorized and coordinated correctly. + +## Token Usage + +- **`auth_token`**: Used throughout all phases to identify UTxOs. The same `auth_token` policy is used consistently across crowdfunding and governance phases, with empty token name (`""`) +- **`stake_hash`**: The stake validator's script hash is stored in all datum states (`Crowdfund`, `Proposed`, `Voted`, and `Refundable` for post-governance withdrawals) and used as: + - The return address for governance proposals + - The DRep credential for voting + +## Integration Points + +- **Spend Validator Coordination**: All governance operations must be coordinated through the spend validator with appropriate redeemers +- **No Token Minting/Burning**: The stake validator no longer handles token lifecycle - `auth_token` is used throughout all phases diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/_scripts.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/_scripts.md new file mode 100644 index 000000000..59e754d5f --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/_scripts.md @@ -0,0 +1,127 @@ +# Gov Crowdfund V2 - Scripts Overview + +## Overview + +The `gov-crowdfundV2` contract is a unified system that merges crowdfunding and governance functionality into a single integrated contract. This design addresses usability challenges present in the modular contract architecture. + +## Scripts + +### 1. gCf_spend + +The spending validator that guards both crowdfunded funds and governance operations. + +**Responsibilities**: +- Manages crowdfunding contributions and withdrawals +- Handles governance certificate registration/deregistration +- Validates governance proposal submission and voting +- Manages state transitions through the complete lifecycle + +**Key Features**: +- Unified datum type (`CrowdfundGovDatum`) supporting both crowdfunding and governance states +- Eight distinct redeemer types covering all operations: + 1. `ContributeFund`: Add funds during crowdfunding + 2. `PreMatureContributorWithdrawal`: Withdraw funds if campaign fails/expires + 3. `PreMatureRemoveEmptyInstance`: Remove empty instance after deadline + 4. `RegisterCerts`: Register certificates and submit governance proposal + 5. `VoteOnGovAction`: Vote on governance proposal + 6. `DeregisterCerts`: Deregister certificates after governance period + 7. `AfterCompleteContributorWithdrawal`: Withdraw funds after governance completion + 8. `AfterCompleteRemoveEmptyInstance`: Remove empty instance after all funds withdrawn +- Dynamic deposit parameters (`stake_register_deposit`, `drep_register_deposit`, `gov_deposit`) to avoid hardcoding values +- Integrated validation for both crowdfunding and governance phases + +**States Managed**: +- `Crowdfunding`: Active crowdfunding campaign (can transition directly to governance) +- `Proposed`: Governance proposal submitted and voted on +- `Refundable`: Post-governance state ready for contributor withdrawals + +### 2. gCf_stake + +The stake script validator that coordinates governance operations. + +**Responsibilities**: +- Validates publishing operations (certificate registration/deregistration) +- Coordinates governance proposal submission +- Coordinates governance voting + +**Key Features**: +- Publishing operations coordinated with spend validator +- Governance operations coordinated with spend validator +- No token minting/burning - `auth_token` used throughout all phases + +**Integration**: +- Works in conjunction with `gCf_spend` to provide complete governance functionality +- Validates that spend validator operations are properly coordinated +- Stake validator script hash (`stake_hash`) stored in all datum states (`Crowdfund`, `Proposed`, `Voted`, `Refundable`) and used for proposal return address and DRep credential + +## Contract Lifecycle + +The contract follows a simplified lifecycle flow: + +### Crowdfunding Phase +- **Start**: Propose Governance Action to Crowdfund (campaign initialization) +- **Crowdfunding**: Active crowdfunding state +- **Contribute**: Contributors can add funds repeatedly, looping back to crowdfunding state +- **Contributor Withdrawal**: Contributors can withdraw funds if campaign fails or expires, looping back to crowdfunding state +- **Remove Empty**: Proposer can remove empty instance (from crowdfunding or refundable state), transitioning to End +- **If Funded**: When funding target is reached, transition to governance proposal and vote (Proposed state) + +### Governance Phase +- **Propose Governance Action & Vote**: When funding target is reached, register certificates, submit governance proposal, and vote on it, transitioning to Proposed state +- **Proposed**: Governance proposal has been submitted and voted on +- **After 6 Epochs**: Governance voting period completes, transitioning from Proposed to Deregister +- **Deregister**: Deregister certificates after governance period, transitioning to Refundable state + +### Completion Phase +- **Refundable**: Post-governance state ready for contributor withdrawals +- **Contributor Withdrawal**: Contributors can withdraw funds by burning share tokens, looping back to Refundable state +- **Remove Empty**: Proposer can remove empty instance from Refundable state, transitioning to End state +- **End**: Final state when instance is removed + +## State Transition Diagram + +```mermaid +--- +config: + theme: default + look: classic +--- +flowchart LR + A(["Propose
Governance Action
to Crowdfund"]) --> B(("Crowdfunding")) + B --> C(["Contribute"]) & D(["Contributer
Withdrawal"]) & n3(["Remove Empty"]) + B -- if Funded --> F(["Propose
Governance Action
& Vote"]) + C --> B + G(("Refundable")) --> I(["Contributer
Withdrawal"]) & n3 + F --> n1(("Proposed")) + I --> G + n2(["Deregister"]) --> G + n1 -- after
6 epochs --> n2 + D --> B + n3 --> H["End"] + H@{ shape: dbl-circ} +``` + +The diagram illustrates the simplified user-facing flow: +- **Propose Governance Action to Crowdfund**: Initial step to create and initialize the crowdfunding campaign +- **Crowdfunding**: The active phase where contributors can repeatedly contribute or withdraw funds, looping back to the crowdfunding state +- **Remove Empty**: Proposer can remove empty instances from either Crowdfunding or Refundable states, transitioning to End +- **Propose Governance Action & Vote**: When funding target is reached, governance proposal is submitted and voted on in a single transaction, transitioning to Proposed state +- **Proposed**: The governance proposal has been submitted and voted on, awaiting the governance period completion +- **Deregister**: After 6 epochs (governance voting period), certificates are deregistered, transitioning to Refundable state +- **Refundable**: Post-governance state where contributors can withdraw funds +- **Contributor Withdrawal**: Contributors can withdraw funds by burning share tokens, looping back to Refundable state until empty +- **End**: Final state when instance is removed (reached via Remove Empty action) + +### gCf_spend Parameters +- `auth_token`: PolicyId for crowdfunding authentication +- `proposer_key_hash`: Authorization for instance removal +- `gov_action`: The governance action to propose +- `delegate_pool_id`: Stake pool for delegation +- `stake_register_deposit`: Dynamic stake registration deposit +- `drep_register_deposit`: Dynamic DRep registration deposit +- `gov_deposit`: Dynamic governance proposal deposit + +### gCf_stake Parameters +- `auth_token`: Reference to crowdfunding token (for coordination) +- `spend`: Script hash of `gCf_spend` validator +- `gov_action_period`: Buffer period for governance operations diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/user_action_doc.md b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/user_action_doc.md new file mode 100644 index 000000000..64dabc4da --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/specs/user_action_doc.md @@ -0,0 +1,116 @@ +# User Actions Documentation + +## Contributors (Normal Users) + +### Phase 1: Crowdfunding + +1. **ContributeFund** - Add funds to active crowdfunding campaign + - **Redeemer**: `ContributeFund` + - **Datum State**: `Crowdfund` → `Crowdfund` + - **Requirements**: + - Minimum contribution: 2 ADA (2,000,000 lovelace) + - Transaction must occur before `deadline` + - Share tokens minted proportionally to contribution amount + - **Validation**: Lovelace difference matches datum update, fundraise target respected, deadline not passed + +2. **PreMatureContributorWithdrawal** - Withdraw funds if campaign failed or expired + - **Redeemer**: `PreMatureContributorWithdrawal` + - **Datum State**: `Crowdfund` → `Crowdfund` + - **Requirements**: + - Either `deadline + expiry_buffer` has passed, OR campaign failed (`current_fundraised_amount <= fundraise_target`) + - Share tokens burned equal to lovelace withdrawn + - **Validation**: Validity period check OR fundraise failure check, share tokens burned match withdrawal + +### Phase 3: Post-Governance Refunds + +3. **AfterCompleteContributorWithdrawal** - Withdraw funds after governance completion + - **Redeemer**: `AfterCompleteContributorWithdrawal` + - **Datum State**: `Refundable` → `Refundable` + - **Requirements**: + - Burn `share_token` tokens (empty token name `""`) + - Lovelace withdrawn equals share tokens burned + - **Validation**: Lovelace withdrawn matches share tokens burned, datum correctly updated + +## Proposer + +### Phase 1: Crowdfunding + +1. **PreMatureRemoveEmptyInstance** - Remove empty crowdfunding instance after deadline + - **Redeemer**: `PreMatureRemoveEmptyInstance` + - **Datum State**: `Crowdfund` → (consumed) + - **Requirements**: + - `deadline` has passed + - If `current_fundraised_amount > 0`: Burn all `share_token` tokens and `auth_token` + - If `current_fundraised_amount == 0`: Burn only `auth_token` + - Must be signed by `proposer_key_hash` + - **Validation**: Deadline passed, appropriate tokens burned, proposer authorization + +### Phase 2: Governance + +2. **RegisterCerts & VoteOnGovAction** - Register certificates, delegate, submit governance proposal, and vote on it + - **Redeemers**: `RegisterCerts` followed by `VoteOnGovAction` (typically happen together or immediately sequentially) + - **Datum State**: `Crowdfund` → `Proposed` (via RegisterCerts), then `Proposed` → `Voted` (via VoteOnGovAction) + - **Requirements for RegisterCerts**: + - Exactly one input/output with `auth_token` (empty token name) from current address + - Register stake certificate (no deposit) + - Register DRep certificate (deposit: `drep_register_deposit`) + - Delegate vote to own DRep (Registered credential) + - Delegate stake to `delegate_pool_id` + - Submit governance proposal: + - Deposit: `gov_deposit` + - Return address: Script(`stake_hash` from datum) + - Governance action: `gov_action` + - Output value deducted by `stake_register_deposit + drep_register_deposit + gov_deposit` + - **Requirements for VoteOnGovAction**: + - Exactly one input/output with `auth_token` (empty token name) from current address + - DRep (Script(`stake_hash` from datum)) votes `Yes` on the governance action + - `gov_tx_id` recorded in output datum + - Input and output values identical + - **Validation**: Lovelace deduction matches deposits, all certificates present, proposal procedure valid, vote recorded correctly + - **Note**: From a user perspective, these actions happen together, transitioning from `Crowdfund` through `Proposed` to `Voted` state + +3. **DeregisterCerts** - Deregister certificates after governance period + - **Redeemer**: `DeregisterCerts` + - **Datum State**: `Voted` → `Refundable` + - **Requirements**: + - `deadline` has passed + - Exactly one input/output with `auth_token` (empty token name) from current address + - Unregister stake certificate (refund received) + - Unregister DRep certificate (refund: `drep_register_deposit`) + - Output value increased by `stake_register_deposit + drep_register_deposit + gov_deposit` + - **Validation**: Deadline passed, lovelace increase matches refunds, certificates deregistered + +### Phase 3: Post-Governance Cleanup + +4. **AfterCompleteRemoveEmptyInstance** - Remove empty instance after all funds withdrawn + - **Redeemer**: `AfterCompleteRemoveEmptyInstance` + - **Datum State**: `Refundable` → (consumed) + - **Requirements**: + - Exactly one input with token of policy `stake_hash` (from datum, empty token name) from current address + - If `funds_controlled > 0`: Burn all remaining `share_token` tokens (empty token name `""`) + - Burn `auth_token` (empty token name `""`) + - Must be signed by `proposer_key_hash` + - **Validation**: Appropriate tokens burned, proposer authorization + +## State Transitions Summary + +**Main Flow:** +``` +Crowdfund → RegisterCerts → Proposed +Proposed → VoteOnGovAction → Voted +Voted → DeregisterCerts → Refundable (after 6 epochs) +``` + +**Post-Governance:** +``` +Refundable → AfterCompleteContributorWithdrawal → Refundable (loop until empty) +Refundable → AfterCompleteRemoveEmptyInstance → (consumed) +``` + +**Note**: From a user perspective, `RegisterCerts` and `VoteOnGovAction` typically happen together (or immediately sequentially), quickly transitioning from `Crowdfund` through `Proposed` to `Voted` state. The `Voted` state then transitions to `Refundable` via `DeregisterCerts` after the governance period (6 epochs). The simplified diagram may show `Proposed` as representing the post-vote state for clarity. + +## Token Usage + +- **auth_token**: Identifies UTxOs throughout all phases (Phases 1-4). Token name is empty string (`""`) in all phases. Used consistently across crowdfunding and governance phases +- **share_token**: Proportional tokens minted/burned with contributions/withdrawals. Token name is empty string (`""`) in all phases +- **stake_hash**: Stored in all datum states (`Crowdfund`, `Proposed`, `Voted`, `Refundable`). This is the stake validator script hash, used as the return address for governance proposals and as the DRep credential for voting diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/auth_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/auth_token/mint.ak new file mode 100644 index 000000000..b9389c8b5 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/auth_token/mint.ak @@ -0,0 +1,27 @@ +use aiken/collection/dict +use aiken/collection/list +use cardano/assets.{PolicyId} +use cardano/transaction.{OutputReference, Transaction} +use types.{MintPolarity, RBurn, RMint} + +validator gcf_auth_mint(utxo_ref: OutputReference) { + mint(redeemer: MintPolarity, policy_id: PolicyId, self: Transaction) { + expect [Pair(_asset_name, quantity)] = + self.mint + |> assets.tokens(policy_id) + |> dict.to_pairs() + let Transaction { inputs, .. } = self + when redeemer is { + RMint -> { + let is_output_consumed = + list.any(inputs, fn(input) { input.output_reference == utxo_ref }) + is_output_consumed? && quantity == 1 + } + RBurn -> quantity == -1 + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_spend.ak new file mode 100644 index 000000000..e9000604e --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_spend.ak @@ -0,0 +1,463 @@ +use cardano/address.{Address, Inline, Script} +use cardano/assets.{Lovelace, PolicyId, lovelace_of} +use cardano/certificate.{Registered} +use cardano/governance.{DelegateRepresentative, GovernanceActionId} +use cardano/transaction.{Output, OutputReference, Transaction, find_input} +use cocktail.{ + inputs_at_with, inputs_at_with_policy, key_signed, only_minted_token, + output_inline_datum, outputs_at_with, outputs_at_with_policy, + policy_only_minted_token, valid_after, valid_before, value_length, +} +use gov.{VGovernanceAction} +use types.{ + AfterCompleteContributorWithdrawal, AfterCompleteRemoveEmptyInstance, + CompleteCrowdfund, ContributeFund, Crowdfund, CrowdfundGovDatum, + CrowdfundGovRedeemer, DeregisterCerts, PreMatureContributorWithdrawal, + PreMatureRemoveEmptyInstance, Proposed, Refundable, RegisterCerts, + VoteOnGovAction, Voted, +} +use utils.{ + check_fundraise_target, check_lovelace_diff, check_proposal_procedure, + check_vote, delegate_stake_and_vote_certificate, delegate_stake_certificate, + delegate_vote_certificate, register_drep_certificate, + register_stake_certificate, unregister_drep_certificate, + unregister_stake_certificate, +} + +// Unified spending validator handling both crowdfunding and governance operations +validator gCf_spend( + auth_token: PolicyId, + proposer_key_hash: ByteArray, + gov_action: VGovernanceAction, + delegate_pool_id: ByteArray, + // dynamic deposit parameters to avoid hardcoding values + stake_register_deposit: Lovelace, + drep_register_deposit: Lovelace, + gov_deposit: Lovelace, +) { + spend( + datum_opt: Option, + redeemer: CrowdfundGovRedeemer, + input: OutputReference, + self: Transaction, + ) { + let Transaction { + inputs, + validity_range, + mint, + outputs, + extra_signatories, + certificates, + proposal_procedures, + votes, + .. + } = self + + expect Some(own_input) = find_input(inputs, input) + expect Some(auth_input_datum) = datum_opt + + let current_address = own_input.output.address + + // check only 1 auth token input from current address + expect [auth_input] = + inputs_at_with_policy(inputs, current_address, auth_token) + + when redeemer is { + // Crowdfunding: Add funds to active campaign, mint proportional share tokens + ContributeFund -> + when auth_input_datum is { + Crowdfund { + stake_hash, + share_token, + crowdfund_address, + fundraise_target, + current_fundraised_amount: input_current_fundraised_amount, + allow_over_subscription, + deadline, + expiry_buffer, + min_charge, + } -> { + expect [auth_output] = + outputs_at_with_policy(outputs, current_address, auth_token) + + let lovelace_from_auth_input = + auth_input.output.value |> lovelace_of() + let lovelace_from_auth_output = auth_output.value |> lovelace_of() + expect auth_output_datum_raw: CrowdfundGovDatum = + output_inline_datum(auth_output) + + when auth_output_datum_raw is { + Crowdfund { + current_fundraised_amount: output_current_fundraised_amount, + .. + } -> { + let fundraise_added = + lovelace_from_auth_output - lovelace_from_auth_input + let fundraise_check = + (fundraise_added == output_current_fundraised_amount - input_current_fundraised_amount)? && (fundraise_added >= 2000000)? + + let fundraise_target_check = + check_fundraise_target( + allow_over_subscription, + fundraise_target, + output_current_fundraised_amount, + ) + + let validity_check = valid_before(validity_range, deadline) + + let output_datum_check = + auth_output_datum_raw == Crowdfund { + stake_hash, + share_token, + crowdfund_address, + fundraise_target, + current_fundraised_amount: input_current_fundraised_amount + fundraise_added, + allow_over_subscription, + deadline, + expiry_buffer, + min_charge, + } + + let is_auth_output_value_clean = + value_length(auth_output.value) == 2 + fundraise_check? && fundraise_target_check? && validity_check? && output_datum_check? && is_auth_output_value_clean? && only_minted_token( + mint, + share_token, + "", + fundraise_added, + )? + } + _ -> False + } + } + _ -> False + } + + // Crowdfunding: Withdraw funds before completion (failed campaign or expired) + PreMatureContributorWithdrawal -> + when auth_input_datum is { + Crowdfund { + stake_hash, + share_token, + crowdfund_address, + fundraise_target, + current_fundraised_amount: input_current_fundraised_amount, + allow_over_subscription, + deadline, + expiry_buffer, + min_charge, + } -> { + let validity_check = + valid_after(validity_range, deadline + expiry_buffer) + let fund_check = input_current_fundraised_amount <= fundraise_target + + expect [auth_output] = + outputs_at_with_policy(outputs, current_address, auth_token) + + let lovelace_from_auth_input = + auth_input.output.value |> lovelace_of() + let lovelace_from_auth_output = auth_output.value |> lovelace_of() + + let lovelace_withdrawn = + lovelace_from_auth_output - lovelace_from_auth_input + + let lovelace_withdrawn_check = lovelace_withdrawn < 0 + + expect auth_output_datum_raw: CrowdfundGovDatum = + output_inline_datum(auth_output) + when auth_output_datum_raw is { + Crowdfund { current_fundraised_amount: _, .. } -> { + let output_datum_check = + auth_output_datum_raw == Crowdfund { + stake_hash, + share_token, + crowdfund_address, + fundraise_target, + current_fundraised_amount: input_current_fundraised_amount + lovelace_withdrawn, + allow_over_subscription, + deadline, + expiry_buffer, + min_charge, + } + + let is_auth_output_value_clean = + value_length(auth_output.value) == 2 + (validity_check || fund_check)? && lovelace_withdrawn_check? && output_datum_check? && is_auth_output_value_clean? && only_minted_token( + mint, + share_token, + "", + lovelace_withdrawn, + )? + } + _ -> False + } + } + _ -> False + } + // Crowdfunding: Remove empty instance after deadline, burn tokens + PreMatureRemoveEmptyInstance -> + when auth_input_datum is { + Crowdfund { share_token, current_fundraised_amount, deadline, .. } -> { + let validity_check = valid_after(validity_range, deadline) + + let token_burnt_check = + if current_fundraised_amount > 0 { + policy_only_minted_token( + mint, + share_token, + "", + -current_fundraised_amount, + )? && policy_only_minted_token(mint, auth_token, "", -1)? + } else { + only_minted_token(mint, auth_token, "", -1)? + } + let proposer_key_signed_check = + key_signed(extra_signatories, proposer_key_hash) + validity_check? && token_burnt_check? && proposer_key_signed_check? + } + _ -> False + } + + // Governance: Register certificates, delegate, submit proposal (Crowdfund → Proposed) + RegisterCerts -> + when auth_input_datum is { + Crowdfund { + stake_hash, + share_token, + current_fundraised_amount, + deadline, + .. + } -> { + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, auth_token, "") + expect Some(current_stake_credential) = + current_address.stake_credential + + expect Inline(current_credential) = current_stake_credential + + expect [only_output] = + outputs_at_with(outputs, current_address, auth_token, "") + + let lovelace_check = + check_lovelace_diff( + only_input, + only_output, + -(stake_register_deposit + drep_register_deposit + gov_deposit), + ) + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Proposed { + stake_hash, + share_token, + funds_controlled: current_fundraised_amount, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + + let reg_stake_cert_check = + register_stake_certificate(certificates, current_credential) + + let reg_drep_cert_check = + register_drep_certificate( + certificates, + current_credential, + drep_register_deposit, + ) + + let delegate_check = + delegate_vote_certificate( + certificates, + current_credential, + Registered(current_credential), + ) && delegate_stake_certificate( + certificates, + current_credential, + delegate_pool_id, + ) || delegate_stake_and_vote_certificate( + certificates, + current_credential, + delegate_pool_id, + Registered(current_credential), + ) + + let proposal_check = + check_proposal_procedure( + proposal_procedures, + gov_deposit, + Script(stake_hash), + gov_action, + ) + lovelace_check? && output_datum_check? && is_only_output_value_clean? && reg_stake_cert_check? && reg_drep_cert_check? && delegate_check? && proposal_check? + } + _ -> False + } + // Governance: Record vote on proposal (Proposed → Voted) + VoteOnGovAction -> + when auth_input_datum is { + Proposed { stake_hash, share_token, funds_controlled, deadline } -> { + // check only 1 input with authtoken residing at current address + expect [only_input] = + inputs_at_with(inputs, current_address, auth_token, "") + expect [only_output] = + outputs_at_with(outputs, current_address, auth_token, "") + + let value_check = only_input.output.value == only_output.value + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let gov_tx_id = + GovernanceActionId { + transaction: own_input.output_reference.transaction_id, + proposal_procedure: 0, + } + let output_datum_check = + only_output_datum == Voted { + stake_hash, + share_token, + funds_controlled, + gov_tx_id, + deadline, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + + value_check? && output_datum_check? && is_only_output_value_clean? && check_vote( + votes, + DelegateRepresentative(Script(stake_hash)), + gov_tx_id, + ) + } + _ -> False + } + // Governance: Deregister certificates after governance period (Voted → Refundable) + DeregisterCerts -> + when auth_input_datum is { + Voted { stake_hash, share_token, funds_controlled, deadline, .. } -> { + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, auth_token, "") + expect Some(current_stake_credential) = + current_address.stake_credential + + expect Inline(current_credential) = current_stake_credential + let validity_check = valid_after(validity_range, deadline) + expect [only_output] = + outputs_at_with(outputs, current_address, auth_token, "") + let lovelace_check = + check_lovelace_diff( + only_input, + only_output, + stake_register_deposit + drep_register_deposit + gov_deposit, + ) + + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Refundable { + stake_hash, + share_token, + funds_controlled, + } + + let unreg_stake_cert_check = + unregister_stake_certificate(certificates, current_credential) + + let unreg_drep_cert_check = + unregister_drep_certificate( + certificates, + current_credential, + drep_register_deposit, + ) + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + validity_check? && lovelace_check? && output_datum_check? && unreg_stake_cert_check? && unreg_drep_cert_check? && is_only_output_value_clean? + } + + _ -> False + } + + // Post-governance: Withdraw funds by burning share tokens + AfterCompleteContributorWithdrawal -> + when auth_input_datum is { + Refundable { stake_hash, share_token, funds_controlled } -> { + // check only 1 input with token from current address + expect [only_input] = + inputs_at_with(inputs, current_address, auth_token, "") + expect [only_output] = + outputs_at_with(outputs, current_address, auth_token, "") + + let lovelace_from_only_input = + only_input.output.value |> lovelace_of() + let lovelace_from_only_output = only_output.value |> lovelace_of() + + let lovelace_withdrawn = + lovelace_from_only_output - lovelace_from_only_input + + let lovelace_withdrawn_check = lovelace_withdrawn < 0 + + expect only_output_datum: CrowdfundGovDatum = + output_inline_datum(only_output) + let output_datum_check = + only_output_datum == Refundable { + stake_hash, + share_token, + funds_controlled: funds_controlled + lovelace_withdrawn, + } + + let is_only_output_value_clean = + value_length(only_output.value) == 2 + + lovelace_withdrawn_check? && output_datum_check? && is_only_output_value_clean? && only_minted_token( + mint, + share_token, + "", + lovelace_withdrawn, + )? + } + _ -> False + } + + // CompleteCrowdfund - Not implemented in gov-crowdfundV2 (uses governance flow instead) + CompleteCrowdfund -> False + + // Post-governance: Remove empty instance after all funds withdrawn + AfterCompleteRemoveEmptyInstance -> + when auth_input_datum is { + Refundable { stake_hash, share_token, funds_controlled } -> { + // check only 1 input with token from current address + expect [_] = inputs_at_with(inputs, current_address, stake_hash, "") + let token_burnt_check = + if funds_controlled > 0 { + policy_only_minted_token( + mint, + share_token, + "", + -funds_controlled, + ) + } else { + True + } + + let proposer_key_signed_check = + key_signed(extra_signatories, proposer_key_hash) + token_burnt_check? && proposer_key_signed_check? && policy_only_minted_token( + mint, + auth_token, + "", + -1, + )? + } + _ -> False + } + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_stake.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_stake.ak new file mode 100644 index 000000000..53bc2174e --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/gcf_stake.ak @@ -0,0 +1,58 @@ +use cardano/address.{from_script} +use cardano/assets.{PolicyId} +use cardano/transaction.{Transaction} +use cocktail.{inputs_at} +use types.{ + CrowdfundGovRedeemer, Deregister, DeregisterCerts, PublishRedeemer, Register, + RegisterCerts, VoteOnGovAction, +} +use utils.{check_spend_script_input_redeemer, redeemer_with_input} + +// Stake validator coordinating governance operations and token lifecycle +validator gCf_stake( + _auth_token: PolicyId, + spend: ByteArray, + _gov_action_period: Int, +) { + // Publish: Validate certificate registration/deregistration coordination + publish(redeemer: PublishRedeemer, _c, self: Transaction) { + let Transaction { inputs, redeemers, .. } = self + let spend_address = from_script(spend) + expect [only_input] = inputs_at(inputs, spend_address) + expect Some(only_inpuy_redeemer_data) = + redeemer_with_input(redeemers, only_input) + + expect only_input_redeemer: CrowdfundGovRedeemer = only_inpuy_redeemer_data + + when redeemer is { + // Register: Validate spend validator is registering certificates + Register -> { + let redeemer_check = only_input_redeemer == RegisterCerts + + redeemer_check? + } + // Deregister: Validate spend validator is deregistering certificates + Deregister -> { + let redeemer_check = only_input_redeemer == DeregisterCerts + + redeemer_check? + } + } + } + + // Propose: Validate governance proposal submission coordination + propose(_r, _p, self: Transaction) { + let Transaction { inputs, redeemers, .. } = self + check_spend_script_input_redeemer(spend, inputs, redeemers, RegisterCerts)? + } + + // Vote: Validate governance vote coordination + vote(_r, _v, self: Transaction) { + let Transaction { inputs, redeemers, .. } = self + check_spend_script_input_redeemer(spend, inputs, redeemers, VoteOnGovAction)? + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/share_token/mint.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/share_token/mint.ak new file mode 100644 index 000000000..01df88ab6 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/share_token/mint.ak @@ -0,0 +1,35 @@ +use aiken/collection/dict +use cardano/assets.{PolicyId} +use cardano/transaction.{Transaction} +use cocktail.{inputs_with_policy} +use types.{ContributeFund, CrowdfundGovRedeemer, MintPolarity, RBurn, RMint} +use utils.{redeemer_with_input} + +validator share_token(auth_token: PolicyId) { + mint(redeemer: MintPolarity, policy_id: PolicyId, self: Transaction) { + expect [Pair(_asset_name, quantity)] = + self.mint + |> assets.tokens(policy_id) + |> dict.to_pairs() + let Transaction { inputs, redeemers, .. } = self + when redeemer is { + RMint -> { + expect [auth_token_input] = inputs_with_policy(inputs, auth_token) + + expect Some(auth_token_redeemer_data) = + redeemer_with_input(redeemers, auth_token_input) + + expect auth_token_redeemer: CrowdfundGovRedeemer = auth_token_redeemer_data + + let redeemer_check = auth_token_redeemer == ContributeFund + + redeemer_check? + } + RBurn -> quantity < 0 + } + } + + else(_) { + fail + } +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/integration_test/complete_crowdfund.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/integration_test/complete_crowdfund.ak new file mode 100644 index 000000000..dfdb3dbfc --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/integration_test/complete_crowdfund.ak @@ -0,0 +1,198 @@ +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{OutputReference, Spend, Transaction} +use gcf_spend as gcf_spend_validator +use mocktail.{ + add_redeemer, complete, mint, mock_policy_id, mock_tx_hash, + mock_utxo_ref, mocktail_tx, script_withdrawal, tx_in, tx_in_inline_datum, + tx_out, tx_out_inline_datum, +} +use share_token/mint as share_token_mint +use tests/test_utils.{ + mock_auth_token, mock_completion_script, mock_crowdfund_address, + mock_crowdfund_datum, mock_current_fundraised_amount, + mock_delegate_pool_id, mock_drep_register_deposit, mock_fee_address, + mock_fundraise_target, mock_gov_action, mock_gov_deposit, + mock_gov_address, mock_min_charge, mock_proposer_key_hash, mock_share_token, + mock_stake_hash, mock_stake_register_deposit, +} +use types.{CompleteCrowdfund, CrowdfundGovRedeemer, RegisterCerts, RMint} + +// Note: CompleteCrowdfund is not implemented in V2 (returns False) +// This test file is kept for reference but tests will fail as expected +// The actual completion flow uses RegisterCerts instead + +type CompleteCrowdfundTestCase { + is_only_one_auth_inputed: Bool, + is_output_to_fee_address_correct: Bool, + is_auth_burnt: Bool, + is_completion_script_executed: Bool, + is_fundraise_target_sent: Bool, + is_fundraise_target_amount_correct: Bool, + is_fundraise_output_datum_correct: Bool, + is_token_minted: Bool, +} + +fn mock_complete_crowdfund_tx( + test_case: CompleteCrowdfundTestCase, + current_fundraised_amount: Int, + auth_token_redeemer: CrowdfundGovRedeemer, +) -> Transaction { + let CompleteCrowdfundTestCase { + is_only_one_auth_inputed, + is_output_to_fee_address_correct, + is_auth_burnt, + is_completion_script_executed, + is_fundraise_target_sent, + is_fundraise_target_amount_correct, + is_fundraise_output_datum_correct, + is_token_minted, + } = test_case + let auth_token_redeemer_data: Data = auth_token_redeemer + let fundraise_output = + if is_fundraise_target_amount_correct { + from_lovelace(mock_fundraise_target) + |> add(mock_stake_hash, "", 1) + } else { + from_lovelace(mock_fundraise_target - 1000000) + |> add(mock_stake_hash, "", 1) + } + let fundraise_output_datum = + if is_fundraise_output_datum_correct { + mock_crowdfund_datum(current_fundraised_amount, False) + } else { + mock_crowdfund_datum(current_fundraised_amount + 1000000, False) + } + let input_value = + from_lovelace(current_fundraised_amount + mock_min_charge) + |> add(mock_auth_token, "", 1) + + let output_value = from_lovelace(mock_min_charge) + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_crowdfund_address) + |> tx_in_inline_datum( + True, + mock_crowdfund_datum(current_fundraised_amount, False), + ) + |> tx_in( + !is_only_one_auth_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_crowdfund_address, + ) + |> tx_out(is_output_to_fee_address_correct, mock_fee_address, output_value) + |> tx_out( + !is_output_to_fee_address_correct, + mock_fee_address, + from_lovelace(mock_current_fundraised_amount - 10) + |> add(mock_policy_id(999), mock_completion_script, 10), + ) + |> tx_out(is_fundraise_target_sent, mock_gov_address, fundraise_output) + |> tx_out_inline_datum(is_fundraise_target_sent, fundraise_output_datum) + |> script_withdrawal( + is_completion_script_executed, + mock_completion_script, + 2_000_000, + ) + |> mint(is_auth_burnt, -1, mock_auth_token, "") + |> mint(is_token_minted, 1, mock_stake_hash, "") + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + auth_token_redeemer_data, + ), + ) +} + +fn check_all_scripts( + test_case: CompleteCrowdfundTestCase, + current_fundraised_amount: Int, + auth_token_redeemer: CrowdfundGovRedeemer, + _stake_hash: ByteArray, +) { + let tx = + mock_complete_crowdfund_tx( + test_case, + current_fundraised_amount, + auth_token_redeemer, + ) + + let check_auth_spend = + gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(mock_crowdfund_datum(mock_current_fundraised_amount, False)), + auth_token_redeemer, + mock_utxo_ref(0, 0), + tx, + ) + let check_token_mint = + share_token_mint.share_token.mint( + mock_auth_token, + RMint, + mock_share_token, + tx, + ) + + // Note: V2 doesn't have withdraw/mint for stake validator like V1 + // The stake validator only handles publish/propose/vote + check_auth_spend? && check_token_mint? +} + +// These tests will fail as CompleteCrowdfund returns False in V2 +// They are kept for reference/documentation purposes + +test complete_crowdfund_fail_not_implemented() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + // CompleteCrowdfund is not implemented in V2 + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + CompleteCrowdfund, + mock_stake_hash, + ) +} + +test complete_crowdfund_fail_with_input_wrong_redeemer() { + let test_case = + CompleteCrowdfundTestCase { + is_only_one_auth_inputed: True, + is_output_to_fee_address_correct: True, + is_auth_burnt: True, + is_completion_script_executed: True, + is_fundraise_target_sent: True, + is_fundraise_target_amount_correct: True, + is_fundraise_output_datum_correct: True, + is_token_minted: True, + } + + // Using RegisterCerts instead - this should also fail for CompleteCrowdfund flow + !check_all_scripts( + test_case, + mock_current_fundraised_amount, + RegisterCerts, + mock_stake_hash, + ) +} + diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_spend.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_spend.ak new file mode 100644 index 000000000..04ac3d5cd --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_spend.ak @@ -0,0 +1,650 @@ +use cardano/address.{Script} +use cardano/assets.{add, from_lovelace} +use cardano/certificate.{ + DelegateBlockProduction, DelegateCredential, DelegateVote, RegisterCredential, + RegisterDelegateRepresentative, Registered, +} +use cardano/governance.{NoConfidence, ProposalProcedure} +use cardano/transaction.{Transaction} +use gcf_spend as gcf_spend_validator +use mocktail.{ + add_certificate, complete, mock_policy_id, mock_tx_hash, mock_utxo_ref, + mocktail_tx, tx_in, tx_in_inline_datum, tx_out, tx_out_inline_datum, +} +use tests/test_utils.{ + add_proposal_procedure, mock_auth_token, mock_crowdfund_address, mock_deadline, + mock_delegate_pool_id, mock_drep_register_deposit, mock_fundraise_target, + mock_funds_controlled, mock_gov_action, mock_gov_action_period, + mock_gov_address, mock_gov_deposit, mock_proposer_key_hash, mock_share_token, + mock_stake_hash, mock_stake_register_deposit, +} +use types.{Crowdfund, CrowdfundGovDatum, Proposed, RegisterCerts} + +type RegisterCertsTestCase { + is_only_one_inputed: Bool, + is_only_one_outputed: Bool, + is_output_datum_correct: Bool, + is_output_value_clean: Bool, + is_output_value_correct: Bool, + is_stake_cert_register: Bool, + is_drep_cert_register: Bool, + is_drep_deposit_correct: Bool, + is_stake_delegated: Bool, + is_vote_delegated: Bool, + is_gov_proposed: Bool, +} + +fn mock_register_cert_tx(test_case: RegisterCertsTestCase) -> Transaction { + let RegisterCertsTestCase { + is_only_one_inputed, + is_only_one_outputed, + is_output_datum_correct, + is_output_value_clean, + is_output_value_correct, + is_stake_cert_register, + is_drep_cert_register, + is_drep_deposit_correct, + is_stake_delegated, + is_vote_delegated, + is_gov_proposed, + } = test_case + + let input_value = + from_lovelace(mock_funds_controlled) + |> add(mock_stake_hash, "", 1) + |> add(mock_auth_token, "", 1) + + let input_datum: CrowdfundGovDatum = + Crowdfund { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount: mock_funds_controlled, + allow_over_subscription: False, + deadline: mock_deadline + mock_gov_action_period, + expiry_buffer: 3600 * 24, + min_charge: 10, + } + let output_value = + if is_output_value_correct { + from_lovelace( + mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit - mock_gov_deposit, + ) + |> add(mock_stake_hash, "", 1) + |> add(mock_auth_token, "", 1) + } else { + from_lovelace( + mock_funds_controlled - mock_stake_register_deposit - mock_drep_register_deposit - mock_gov_deposit + 10, + ) + |> add(mock_stake_hash, "", 1) + |> add(mock_auth_token, "", 1) + } + + let output_datum: CrowdfundGovDatum = + if is_output_datum_correct { + Proposed { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + } + } else { + Proposed { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled + 10, + deadline: mock_deadline + mock_gov_action_period, + } + } + + let drep_deposit = + if is_drep_deposit_correct { + mock_drep_register_deposit + } else { + mock_drep_register_deposit - 1000000 + } + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, input_value, mock_gov_address) + |> tx_in_inline_datum(True, input_datum) + |> tx_in( + !is_only_one_inputed, + mock_tx_hash(0), + 1, + input_value, + mock_gov_address, + ) + |> tx_out(is_output_value_clean, mock_gov_address, output_value) + |> tx_out( + !is_output_value_clean, + mock_gov_address, + output_value |> add(mock_policy_id(999), mock_stake_hash, 1), + ) + |> tx_out_inline_datum(True, output_datum) + |> tx_out(!is_only_one_outputed, mock_gov_address, output_value) + |> complete() + |> add_certificate( + is_stake_cert_register, + RegisterCredential { + credential: Script(mock_stake_hash), + deposit: Never, + }, + ) + |> add_certificate( + is_drep_cert_register, + RegisterDelegateRepresentative { + delegate_representative: Script(mock_stake_hash), + deposit: drep_deposit, + }, + ) + |> add_certificate( + is_stake_delegated, + DelegateCredential { + credential: Script(mock_stake_hash), + delegate: DelegateBlockProduction { + stake_pool: mock_delegate_pool_id, + }, + }, + ) + |> add_certificate( + is_vote_delegated, + DelegateCredential { + credential: Script(mock_stake_hash), + delegate: DelegateVote { + delegate_representative: Registered(Script(mock_stake_hash)), + }, + }, + ) + |> add_proposal_procedure( + is_gov_proposed, + ProposalProcedure { + deposit: mock_gov_deposit, + return_address: Script(mock_stake_hash), + governance_action: NoConfidence { ancestor: None }, + }, + ) +} + +test s1_spend_success_reg_cert() { + let input_datum: CrowdfundGovDatum = + Crowdfund { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount: mock_funds_controlled, + allow_over_subscription: False, + deadline: mock_deadline + mock_gov_action_period, + expiry_buffer: 3600 * 24, + min_charge: 10, + } + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_not_crowdfund_state() { + let input_datum: CrowdfundGovDatum = + Proposed { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + funds_controlled: mock_funds_controlled, + deadline: mock_deadline + mock_gov_action_period, + } + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_more_than_one_input() fail { + let input_datum: CrowdfundGovDatum = + Crowdfund { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount: mock_funds_controlled, + allow_over_subscription: False, + deadline: mock_deadline + mock_gov_action_period, + expiry_buffer: 3600 * 24, + min_charge: 10, + } + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: False, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +fn mock_crowdfund_datum_for_tests() -> CrowdfundGovDatum { + Crowdfund { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount: mock_funds_controlled, + allow_over_subscription: False, + deadline: mock_deadline + mock_gov_action_period, + expiry_buffer: 3600 * 24, + min_charge: 10, + } +} + +test s1_spend_fail_reg_cert_with_more_than_one_output() fail { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: False, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_incorrect_output_datum() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: False, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_output_value_not_clean() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: False, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_incorrect_output_value() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: False, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_stake_cert_not_reg() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: False, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_drep_cert_not_reg() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: False, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_drep_deposit_incorrect() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: False, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_stake_not_delegated() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: False, + is_vote_delegated: True, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_vote_not_delegated() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: False, + is_gov_proposed: True, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} + +test s1_spend_fail_reg_cert_with_gov_not_proposed() { + let input_datum = mock_crowdfund_datum_for_tests() + let tx = + mock_register_cert_tx( + RegisterCertsTestCase { + is_only_one_inputed: True, + is_only_one_outputed: True, + is_output_datum_correct: True, + is_output_value_clean: True, + is_output_value_correct: True, + is_stake_cert_register: True, + is_drep_cert_register: True, + is_drep_deposit_correct: True, + is_stake_delegated: True, + is_vote_delegated: True, + is_gov_proposed: False, + }, + ) + + !gcf_spend_validator.gCf_spend.spend( + mock_auth_token, + mock_proposer_key_hash, + mock_gov_action, + mock_delegate_pool_id, + mock_stake_register_deposit, + mock_drep_register_deposit, + mock_gov_deposit, + Some(input_datum), + RegisterCerts, + mock_utxo_ref(0, 0), + tx, + ) +} diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_start.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_start.ak new file mode 100644 index 000000000..20998ff46 --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_start.ak @@ -0,0 +1,249 @@ +use cardano/assets.{add, from_lovelace} +use cardano/transaction.{OutputReference, Spend, Transaction} +use gcf_stake as gcf_stake_validator +use mocktail.{ + add_redeemer, complete, mock_tx_hash, mocktail_tx, + tx_in, +} +use tests/test_utils.{ + mock_auth_token, mock_crowdfund_gov_address, + mock_fundraise_target, mock_gov_action_period, + mock_spend_script_hash, mock_stake_hash, +} +use types.{ + Deregister, DeregisterCerts, Register, RegisterCerts, + VoteOnGovAction, +} + +type StartTestCase { + is_only_one_spend_inputed: Bool, +} + +fn mock_start_tx( + test_case: StartTestCase, + only_input_redeemer: Data, +) -> Transaction { + let StartTestCase { is_only_one_spend_inputed } = test_case + let only_input = + from_lovelace(mock_fundraise_target) + |> add(mock_stake_hash, "", 1) + |> add(mock_auth_token, "", 1) + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, only_input, mock_crowdfund_gov_address) + |> tx_in( + !is_only_one_spend_inputed, + mock_tx_hash(0), + 1, + only_input, + mock_crowdfund_gov_address, + ) + |> complete() + |> add_redeemer( + True, + Pair( + Spend( + OutputReference { transaction_id: mock_tx_hash(0), output_index: 0 }, + ), + only_input_redeemer, + ), + ) +} + +test s2_success_publish_with_reg() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Register, + None, + tx, + ) +} + +test s2_success_publish_with_dereg() { + let only_input_redeemer: Data = DeregisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Deregister, + None, + tx, + ) +} + +test s2_fail_publish_with_reg_but_deregister_cert() { + let only_input_redeemer: Data = DeregisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !gcf_stake_validator.gCf_stake.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Register, + None, + tx, + ) +} + +test s2_fail_publish_with_dereg_but_register_cert() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !gcf_stake_validator.gCf_stake.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Deregister, + None, + tx, + ) +} + +test s2_fail_publish_with_more_than_one_input_from_hash() fail { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.publish( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + Register, + None, + tx, + ) +} + +test s2_success_propose() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.propose( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_propose_with_wrong_redeemer() { + let only_input_redeemer: Data = VoteOnGovAction + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !gcf_stake_validator.gCf_stake.propose( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_propose_with_more_than_one_inputed() fail { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.propose( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_success_vote() { + let only_input_redeemer: Data = VoteOnGovAction + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.vote( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_vote_with_wrong_redeemer() { + let only_input_redeemer: Data = RegisterCerts + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: True }, + only_input_redeemer, + ) + !gcf_stake_validator.gCf_stake.vote( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + +test s2_fail_vote_with_more_than_one_inputed() fail { + let only_input_redeemer: Data = VoteOnGovAction + + let tx = + mock_start_tx( + StartTestCase { is_only_one_spend_inputed: False }, + only_input_redeemer, + ) + gcf_stake_validator.gCf_stake.vote( + mock_auth_token, + mock_spend_script_hash, + mock_gov_action_period, + None, + None, + tx, + ) +} + diff --git a/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_utils.ak b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_utils.ak new file mode 100644 index 000000000..595f16dbe --- /dev/null +++ b/packages/mesh-contract/src/crowdfund/aiken-workspace-v3/gov-crowdfundV2/validators/tests/test_utils.ak @@ -0,0 +1,123 @@ +use aiken/collection/list +use cardano/address.{Address, Inline, Script, from_script} +use cardano/governance.{GovernanceActionId, ProposalProcedure, Vote, Voter} +use cardano/transaction.{Transaction} +use gov.{NoConfidence} +use mocktail.{ + mock_policy_id, mock_pub_key_hash, mock_script_hash, + mock_script_stake_key_hash, mock_tx_hash, +} +use types.{Crowdfund, CrowdfundGovDatum} + +pub const mock_auth_token = mock_policy_id(0) + +pub const mock_share_token = mock_policy_id(1) + +pub const mock_completion_script = mock_script_hash(0) + +pub const mock_crowdfund_spend_script_hash = mock_script_hash(1) + +pub const mock_crowdfund_stake_script_hash = mock_script_stake_key_hash(0) + +pub const mock_crowdfund_address = from_script(mock_crowdfund_spend_script_hash) + +pub const mock_fee_address = from_script("fee_address") + +pub const mock_fundraise_target = 100000000000 + +pub const mock_extra_fundraised_amount = 4000000 + +pub const mock_min_charge = 10 + +pub const mock_current_fundraised_amount = + mock_fundraise_target + mock_extra_fundraised_amount + mock_min_charge + +pub const mock_contribute_min_fundraised_amount = 2000000 + +pub const mock_contribute_over_fundraised_amount = + mock_fundraise_target + mock_contribute_min_fundraised_amount + +pub const mock_deadline = 1750735607 + +pub const mock_expiry_buffer = 3600 * 24 + +pub fn mock_crowdfund_datum( + current_fundraised_amount: Int, + allow_over_subscription: Bool, +) -> CrowdfundGovDatum { + Crowdfund { + stake_hash: mock_stake_hash, + share_token: mock_share_token, + crowdfund_address: mock_crowdfund_address, + fundraise_target: mock_fundraise_target, + current_fundraised_amount, + allow_over_subscription, + deadline: mock_deadline, + expiry_buffer: mock_expiry_buffer, + min_charge: mock_min_charge, + } +} + +pub const mock_stake_hash = mock_script_hash(0) + +pub const mock_spend_script_hash = mock_script_hash(1) + +pub const mock_crowdfund_gov_address = from_script(mock_spend_script_hash) + +pub const mock_gov_address = + Address { + payment_credential: Script(mock_spend_script_hash), + stake_credential: Some(Inline(Script(mock_stake_hash))), + } + +pub const mock_gov_action_period = 3600 + +pub const mock_delegate_pool_id = mock_script_hash(3) + +pub const mock_gov_action = NoConfidence { ancestor: None } + +pub const mock_proposer_key_hash = mock_pub_key_hash(0) + +pub const mock_stake_register_deposit = 2000000 + +pub const mock_drep_register_deposit = 500000000 + +pub const mock_gov_deposit = 50000000 + +pub const mock_funds_controlled = + mock_fundraise_target + mock_stake_register_deposit + mock_drep_register_deposit + 1000000 + +pub const mock_gov_action_id = + GovernanceActionId { transaction: mock_tx_hash(0), proposal_procedure: 0 } + +pub fn add_proposal_procedure( + tx: Transaction, + condition: Bool, + proposal_procedure: ProposalProcedure, +) -> Transaction { + if !condition { + tx + } else { + Transaction { + ..tx, + proposal_procedures: tx.proposal_procedures + |> list.concat([proposal_procedure]), + } + } +} + +pub fn add_vote( + tx: Transaction, + condition: Bool, + vote: Pair>, +) -> Transaction { + if !condition { + tx + } else { + Transaction { + ..tx, + votes: tx.votes + |> list.concat([vote]), + } + } +}