From 645e696de1628ca1619240e32f0e4077ddc2d46b Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Thu, 30 Jul 2026 17:15:45 +0300 Subject: [PATCH 1/6] feat: add dependencies and rewrite asset_auth_vault.simf with std --- Cargo.lock | 68 ++++++------ Cargo.toml | 2 +- crates/contracts/.gitignore | 3 +- crates/contracts/Simplex.toml | 14 ++- crates/contracts/simf/asset_auth_vault.simf | 113 ++++++++++++-------- crates/contracts/simf/script_auth.simf | 2 +- 6 files changed, 123 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 578450cc..6b27da4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1742,7 +1742,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" dependencies = [ "base64 0.13.1", - "minreq", + "minreq 2.14.1", "serde", "serde_json", ] @@ -1772,7 +1772,7 @@ dependencies = [ "dotenvy", "hex", "lending-contracts", - "minreq", + "minreq 2.14.1", "serde", "sled", "smplx-std", @@ -2004,6 +2004,19 @@ dependencies = [ "webpki-roots 0.25.4", ] +[[package]] +name = "minreq" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "659579df697b372ef9e36f02fcbb41f6d6f157dcec7db9c9618fa0f23cf0fc20" +dependencies = [ + "rustls 0.23.40", + "rustls-webpki 0.103.13", + "serde", + "serde_json", + "webpki-roots 1.0.7", +] + [[package]] name = "mio" version = "1.2.1" @@ -2754,6 +2767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", + "log", "once_cell", "ring", "rustls-pki-types", @@ -2854,15 +2868,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "santiago" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de36022292bc2086eb8f55bffa460fef3475e4459b478820711f4c421feb87ec" -dependencies = [ - "regex", -] - [[package]] name = "schannel" version = "0.1.29" @@ -3144,9 +3149,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "simplicity-lang" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e57bd4d84853974a212eab24ed89da54f49fbccf5e33e93bcd29f0a6591cd5" +checksum = "13ed081e3046d66c146d7201bcbf3b655ca3436cb83f6efc26d7895bd2b79d06" dependencies = [ "bitcoin", "bitcoin_hashes", @@ -3156,15 +3161,14 @@ dependencies = [ "ghost-cell", "hex-conservative", "miniscript", - "santiago", "simplicity-sys", ] [[package]] name = "simplicity-sys" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3401ee7331f183a5458c0f5a4b3d5d00bde0fd12e2e03728c537df34efae289" +checksum = "96d1ec5477c7650b8ef511aa56dccb28f2e8cdb6e87f260ecffdaf0ebfef2d3b" dependencies = [ "bitcoin_hashes", "cc", @@ -3172,9 +3176,9 @@ dependencies = [ [[package]] name = "simplicityhl" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25de8990174fe3e1a843df138cacc4265d05839ebd2550c18b9196f567d55e81" +checksum = "361316795ec753230c421d964ab60940d20d5252c2d39272452528832c9e0ec5" dependencies = [ "base64 0.21.7", "chumsky", @@ -3221,9 +3225,9 @@ dependencies = [ [[package]] name = "smplx-build" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3170d79eafea8c119d0b491014aaf2054679ba8c285c453c2acb879b52896b5e" +checksum = "0f090cc306bc000e1f926d0fbbf92080626530095a3b4541caf8f6b8bedb0a62" dependencies = [ "glob", "globwalk", @@ -3240,9 +3244,9 @@ dependencies = [ [[package]] name = "smplx-macros" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e591d0bb8c971f38ea525b5e1bc18a39b369bc1fdecc07632120142afb7e34" +checksum = "6758957dde925b558d5453fbf39ca551ee3e0ae04b032686aa5444e695455595" dependencies = [ "smplx-build", "smplx-test", @@ -3251,9 +3255,9 @@ dependencies = [ [[package]] name = "smplx-regtest" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b42c1ad54f123195eb90543e88a2e3b1519a11479862ac29a5cd7a0e24f13d7" +checksum = "d9e96c8226c35603c08f37dda2fa319f4d822790c2f0d922d690a952399a4c92" dependencies = [ "electrsd", "hex", @@ -3267,17 +3271,17 @@ dependencies = [ [[package]] name = "smplx-sdk" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe05e7d0f9cef029968453f087f323df01f92e13fc240796a732cffac734074a" +checksum = "68d02d154ff3b7459f86e60dd60edd693a7f60b91ba1ccb29c34be171796fce6" dependencies = [ "bip39", "bitcoin_hashes", + "bitcoincore-rpc", "dyn-clone", - "electrsd", "elements-miniscript", "hex", - "minreq", + "minreq 3.0.0", "serde", "serde_json", "sha2", @@ -3287,9 +3291,9 @@ dependencies = [ [[package]] name = "smplx-std" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8465bd3dae0d1bf37c88f2ba4144e5b5157d390a3c5e56016ff04b64ee9fc199" +checksum = "41d7cde217178eddb3f50572d2d728560388cc74899e38ca9aee0378f3d261db" dependencies = [ "either", "serde", @@ -3301,9 +3305,9 @@ dependencies = [ [[package]] name = "smplx-test" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1025e34b6101ab8e92b6baa4807227894ca324e0405d22a703c2ddd6c5af979" +checksum = "200a3f0cf072ffb8df5f841e478d7c46d5649d6d2f0487b5c72a0731d7c882a1" dependencies = [ "electrsd", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 9976e7e9..6ecb5e41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ multiple_crate_versions = "allow" [workspace.dependencies] ring = "0.17.14" hex = "0.4.3" -smplx-std = "0.0.5" +smplx-std = "0.0.7" sha2 = { version = "0.10.9", features = ["compress"] } serde = { version = "1.0.228", features = ["derive"]} thiserror = { version = "2.0.18" } diff --git a/crates/contracts/.gitignore b/crates/contracts/.gitignore index cbd40b05..74d515f3 100644 --- a/crates/contracts/.gitignore +++ b/crates/contracts/.gitignore @@ -1 +1,2 @@ -src/artifacts \ No newline at end of file +src/artifacts +deps/ \ No newline at end of file diff --git a/crates/contracts/Simplex.toml b/crates/contracts/Simplex.toml index 31ec9fb1..c0dd0456 100644 --- a/crates/contracts/Simplex.toml +++ b/crates/contracts/Simplex.toml @@ -5,17 +5,27 @@ # simf_files = ["*.simf"] # out_dir = "./src/artifacts" +[dependencies] +std = { git = "https://github.com/BlockstreamResearch/simplicityhl-std.git" } + # [regtest] # mnemonic = "exist carry drive collect lend cereal occur much tiger just involve mean" +# bitcoins = 10_000_000 +# rpc_port = 18443 +# esplora_port = 3000 +# rpc_user = "user" +# rpc_password = "password" # [test] # mnemonic = "exist carry drive collect lend cereal occur much tiger just involve mean" +# bitcoins = 10_000_000 +# verbosity = 0 # 0 - none, 1 - debug, 2 - trace # [test.esplora] # url = "" # network = "" - +# # [test.rpc] # url = "" # username = "" -# password = "" \ No newline at end of file +# password = "" diff --git a/crates/contracts/simf/asset_auth_vault.simf b/crates/contracts/simf/asset_auth_vault.simf index 8191f348..c7b83f50 100644 --- a/crates/contracts/simf/asset_auth_vault.simf +++ b/crates/contracts/simf/asset_auth_vault.simf @@ -1,9 +1,20 @@ +use std::lib::binary::not; +use std::lib::asserts::assert_eq_64; +use std::lib::op_return::is_output_op_return as is_op_return; + // Helper getters -fn get_script_hash(index: u32, is_input_index: bool) -> u256 { +fn get_script_hash( + index: u32, + is_input_index: bool +) -> u256 { let script_hash: u256 = match is_input_index { - true => unwrap(jet::input_script_hash(index)), - false => unwrap(jet::output_script_hash(index)), + false => { + unwrap(jet::output_script_hash(index)) + }, + true => { + unwrap(jet::input_script_hash(index)) + } }; script_hash @@ -11,8 +22,12 @@ fn get_script_hash(index: u32, is_input_index: bool) -> u256 { fn get_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { let pair: (Asset1, Amount1) = match is_input_index { - true => unwrap(jet::input_amount(index)), - false => unwrap(jet::output_amount(index)), + false => { + unwrap(jet::output_amount(index)) + }, + true => { + unwrap(jet::input_amount(index)) + } }; let (asset, amount): (Asset1, Amount1) = pair; let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); @@ -20,13 +35,6 @@ fn get_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { (asset_bits, amount) } -fn is_op_return(output_index: u32) -> bool { - match jet::output_null_datum(output_index, 0) { - Some(entry: Option>>) => true, - None => false, - } -} - // Math helpers fn safe_add_64(first: u64, second: u64) -> u64 { @@ -38,7 +46,7 @@ fn safe_add_64(first: u64, second: u64) -> u64 { // Check helpers fn check_asset_amounts_eq(asset_amount_1: u64, asset_amount_2: u64) { - assert!(jet::eq_64(asset_amount_1, asset_amount_2)); + assert_eq_64(asset_amount_1, asset_amount_2); } fn check_assets_eq(asset_bits_1: u256, asset_bits_2: u256) { @@ -49,25 +57,21 @@ fn check_script_hashes_eq(script_1: u256, script_2: u256) { assert!(jet::eq_256(script_1, script_2)); } -fn check_flags_eq(flag_1: bool, flag_2: bool) { - assert!(jet::eq_1(::into(flag_1), ::into(flag_2))); -} - -fn ensure_output_is_op_return(index: u32) { - check_flags_eq(is_op_return(index), true); -} - -fn ensure_output_is_not_an_op_return(index: u32) { - check_flags_eq(is_op_return(index), false); -} - -fn ensure_asset_and_amount_ge(index: u32, is_input_index: bool, expected_asset_bits: u256, expected_amount: u64) { +fn ensure_asset_and_amount_ge( + index: u32, + is_input_index: bool, + expected_asset_bits: u256, + expected_amount: u64 +) { let (asset_bits, amount): (u256, u64) = get_asset_and_amount(index, is_input_index); assert!(jet::eq_256(asset_bits, expected_asset_bits)); assert!(jet::le_64(expected_amount, amount)); } -fn ensure_active_status(expected_status: bool) { +// TODO: Consider to add `assert_eq_bool` function to std. +fn ensure_active_status( + expected_status: bool +) { assert!(jet::eq_1(::into(expected_status), ::into(param::IS_ACTIVE))); } @@ -101,16 +105,26 @@ fn auth_with_burn_check( expected_minimal_asset_amount: u64, with_asset_burn: bool ) { - ensure_asset_and_amount_ge(input_asset_index, true, expected_asset_id, expected_minimal_asset_amount); - ensure_asset_and_amount_ge(output_asset_index, false, expected_asset_id, expected_minimal_asset_amount); + ensure_asset_and_amount_ge( + input_asset_index, + true, + expected_asset_id, + expected_minimal_asset_amount + ); + ensure_asset_and_amount_ge( + output_asset_index, + false, + expected_asset_id, + expected_minimal_asset_amount + ); match with_asset_burn { - true => { - ensure_output_is_op_return(output_asset_index); - }, false => { - ensure_output_is_not_an_op_return(output_asset_index) + assert!(not(is_op_return(output_asset_index))); }, + true => { + assert!(is_op_return(output_asset_index)); + } } } @@ -130,7 +144,12 @@ fn withdraw_all(input_keeper_index: u32, output_keeper_index: u32) { let vault_amount: u64 = ensure_vault_asset(jet::current_index(), true); } -fn withdraw_part(input_keeper_index: u32, output_keeper_index: u32, vault_output_index: u32, amount_to_withdraw: u64) { +fn withdraw_part( + input_keeper_index: u32, + output_keeper_index: u32, + vault_output_index: u32, + amount_to_withdraw: u64 +) { ensure_active_status(true); auth_with_burn_check( @@ -205,11 +224,16 @@ fn main() { input_keeper_index, output_keeper_index, vault_output_index, - amount_to_withdraw, + amount_to_withdraw ): (u32, u32, u32, u64) = withdraw_part_params; - withdraw_part(input_keeper_index, output_keeper_index, vault_output_index, amount_to_withdraw); - }, + withdraw_part( + input_keeper_index, + output_keeper_index, + vault_output_index, + amount_to_withdraw + ); + } } }, Right(supply_params: Either<(u32, u32, u32, u64), (u32, u32, u32, u64)>) => { @@ -219,17 +243,22 @@ fn main() { input_supplier_index, output_supplier_index, vault_output_index, - amount_to_supply, + amount_to_supply ): (u32, u32, u32, u64) = supply_params; - supply(input_supplier_index, output_supplier_index, vault_output_index, amount_to_supply); + supply( + input_supplier_index, + output_supplier_index, + vault_output_index, + amount_to_supply + ); }, Right(final_supply_params: (u32, u32, u32, u64)) => { let ( input_supplier_index, output_supplier_index, finalized_vault_output_index, - amount_to_supply, + amount_to_supply ): (u32, u32, u32, u64) = final_supply_params; final_supply( @@ -240,6 +269,6 @@ fn main() { ); } } - }, + } } -} \ No newline at end of file +} diff --git a/crates/contracts/simf/script_auth.simf b/crates/contracts/simf/script_auth.simf index 35566f99..8524a6be 100644 --- a/crates/contracts/simf/script_auth.simf +++ b/crates/contracts/simf/script_auth.simf @@ -10,4 +10,4 @@ fn script_auth_check(input_script_index: u32) { fn main() { script_auth_check(witness::INPUT_SCRIPT_INDEX); -} \ No newline at end of file +} From c95f7a47a089450d73940e9e00e22b5ca5aa01ad Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Thu, 30 Jul 2026 17:45:54 +0300 Subject: [PATCH 2/6] feat: add helper and rewrite asset_auth.simf file --- crates/contracts/simf/asset_auth.simf | 33 ++++++++------------- crates/contracts/simf/asset_auth_vault.simf | 32 ++++---------------- crates/contracts/simf/helper.simf | 15 ++++++++++ 3 files changed, 33 insertions(+), 47 deletions(-) create mode 100644 crates/contracts/simf/helper.simf diff --git a/crates/contracts/simf/asset_auth.simf b/crates/contracts/simf/asset_auth.simf index 6abb6f5a..f3382483 100644 --- a/crates/contracts/simf/asset_auth.simf +++ b/crates/contracts/simf/asset_auth.simf @@ -1,22 +1,13 @@ -fn get_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { - let pair: (Asset1, Amount1) = match is_input_index { - true => unwrap(jet::input_amount(index)), - false => unwrap(jet::output_amount(index)), - }; - let (asset, amount): (Asset1, Amount1) = pair; - let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); - let amount: u64 = unwrap_right::<(u1, u256)>(amount); - (asset_bits, amount) -} +use std::lib::op_return::assert_output_is_op_return; -fn ensure_output_is_op_return(index: u32) { - match jet::output_null_datum(index, 0) { - Some(entry: Option>>) => (), - None => panic!(), - } -} +use crate::helper::get_asset_and_amount; -fn ensure_asset_and_amount_eq(index: u32, is_input_index: bool, expected_asset_bits: u256, expected_amount: u64) { +fn ensure_asset_and_amount_eq( + index: u32, + is_input_index: bool, + expected_asset_bits: u256, + expected_amount: u64 +) { let (asset_bits, amount): (u256, u64) = get_asset_and_amount(index, is_input_index); assert!(jet::eq_256(asset_bits, expected_asset_bits)); assert!(jet::eq_64(amount, expected_amount)); @@ -27,13 +18,13 @@ fn auth_with_burn_check(input_asset_index: u32, output_asset_index: u32) { ensure_asset_and_amount_eq(output_asset_index, false, param::ASSET_ID, param::ASSET_AMOUNT); match param::WITH_ASSET_BURN { - true => { - ensure_output_is_op_return(output_asset_index); - }, false => {}, + true => { + assert_output_is_op_return(output_asset_index); + } } } fn main() { auth_with_burn_check(witness::INPUT_ASSET_INDEX, witness::OUTPUT_ASSET_INDEX); -} \ No newline at end of file +} diff --git a/crates/contracts/simf/asset_auth_vault.simf b/crates/contracts/simf/asset_auth_vault.simf index c7b83f50..fdabf5b7 100644 --- a/crates/contracts/simf/asset_auth_vault.simf +++ b/crates/contracts/simf/asset_auth_vault.simf @@ -1,6 +1,9 @@ use std::lib::binary::not; use std::lib::asserts::assert_eq_64; -use std::lib::op_return::is_output_op_return as is_op_return; +use std::lib::op_return::is_output_op_return; +use std::lib::u64::safe_add_64; + +use crate::helper::get_asset_and_amount; // Helper getters @@ -20,29 +23,6 @@ fn get_script_hash( script_hash } -fn get_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { - let pair: (Asset1, Amount1) = match is_input_index { - false => { - unwrap(jet::output_amount(index)) - }, - true => { - unwrap(jet::input_amount(index)) - } - }; - let (asset, amount): (Asset1, Amount1) = pair; - let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); - let amount: u64 = unwrap_right::<(u1, u256)>(amount); - (asset_bits, amount) -} - -// Math helpers - -fn safe_add_64(first: u64, second: u64) -> u64 { - let (carry, result): (bool, u64) = jet::add_64(first, second); - - result -} - // Check helpers fn check_asset_amounts_eq(asset_amount_1: u64, asset_amount_2: u64) { @@ -120,10 +100,10 @@ fn auth_with_burn_check( match with_asset_burn { false => { - assert!(not(is_op_return(output_asset_index))); + assert!(not(is_output_op_return(output_asset_index))); }, true => { - assert!(is_op_return(output_asset_index)); + assert!(is_output_op_return(output_asset_index)); } } } diff --git a/crates/contracts/simf/helper.simf b/crates/contracts/simf/helper.simf new file mode 100644 index 00000000..b9135c2e --- /dev/null +++ b/crates/contracts/simf/helper.simf @@ -0,0 +1,15 @@ +pub fn get_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { + let pair: (Asset1, Amount1) = match is_input_index { + false => { + unwrap(jet::output_amount(index)) + }, + true => { + unwrap(jet::input_amount(index)) + } + }; + + let (asset, amount): (Asset1, Amount1) = pair; + let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); + let amount: u64 = unwrap_right::<(u1, u256)>(amount); + (asset_bits, amount) +} From 3fe975de479d3a8e08356640bb5e9c40bdf218e5 Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Thu, 30 Jul 2026 17:47:29 +0300 Subject: [PATCH 3/6] feat: add simplex install to github lint workflow --- .github/workflows/lint.yml | 5 +++-- .github/workflows/tests.yml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 581eb8ad..cafeab95 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest env: SQLX_OFFLINE: true - SIMPLEX_COMMIT: 1945d11b47fff8838c3e99c210133519a9522324 + SIMPLEX_VERSION: 0.0.7 steps: - name: Checkout @@ -45,7 +45,7 @@ jobs: BASE_DIR="${XDG_CONFIG_HOME:-$HOME}" SIMPLEX_DIR="${SIMPLEX_DIR:-$BASE_DIR/.simplex}" SIMPLEX_BIN_DIR="$SIMPLEX_DIR/bin" - "$SIMPLEX_BIN_DIR/simplexup" --commit "$SIMPLEX_COMMIT" + "$SIMPLEX_BIN_DIR/simplexup" --install "$SIMPLEX_VERSION" echo "$SIMPLEX_BIN_DIR" >> "$GITHUB_PATH" "$SIMPLEX_BIN_DIR/simplex" --version @@ -53,6 +53,7 @@ jobs: shell: bash run: | cd crates/contracts + simplex install simplex build test -f src/artifacts/mod.rs diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f7c6db15..0241b6fc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ env: SQLX_VERSION: 0.8.0 SQLX_FEATURES: "rustls,postgres" SQLX_FEATURES_KEY: "rustls-postgres" - SIMPLEX_COMMIT: 1945d11b47fff8838c3e99c210133519a9522324 + SIMPLEX_VERSION: 0.0.7 APP_USER: app APP_USER_PWD: secret APP_DB_NAME: lending-indexer @@ -84,7 +84,7 @@ jobs: BASE_DIR="${XDG_CONFIG_HOME:-$HOME}" SIMPLEX_DIR="${SIMPLEX_DIR:-$BASE_DIR/.simplex}" SIMPLEX_BIN_DIR="$SIMPLEX_DIR/bin" - "$SIMPLEX_BIN_DIR/simplexup" --commit "$SIMPLEX_COMMIT" + "$SIMPLEX_BIN_DIR/simplexup" --install "$SIMPLEX_VERSION" echo "$SIMPLEX_BIN_DIR" >> "$GITHUB_PATH" "$SIMPLEX_BIN_DIR/simplex" --version @@ -92,6 +92,7 @@ jobs: shell: bash run: | cd crates/contracts + simplex install simplex build test -f src/artifacts/mod.rs From cec15f541739f439ba7c2d0a90724a7069705ab1 Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 31 Jul 2026 13:29:21 +0300 Subject: [PATCH 4/6] feat: migrate get_explicit_asset_and_amount to helper function and apply simfmt --- crates/contracts/simf/asset_auth.simf | 4 +- crates/contracts/simf/asset_auth_vault.simf | 9 +- crates/contracts/simf/helper.simf | 7 +- crates/contracts/simf/issuance_factory.simf | 128 ++++++--- crates/contracts/simf/lending.simf | 298 ++++++++++++++------ 5 files changed, 325 insertions(+), 121 deletions(-) diff --git a/crates/contracts/simf/asset_auth.simf b/crates/contracts/simf/asset_auth.simf index f3382483..96ccdee1 100644 --- a/crates/contracts/simf/asset_auth.simf +++ b/crates/contracts/simf/asset_auth.simf @@ -1,6 +1,6 @@ use std::lib::op_return::assert_output_is_op_return; -use crate::helper::get_asset_and_amount; +use crate::helper::get_explicit_asset_and_amount; fn ensure_asset_and_amount_eq( index: u32, @@ -8,7 +8,7 @@ fn ensure_asset_and_amount_eq( expected_asset_bits: u256, expected_amount: u64 ) { - let (asset_bits, amount): (u256, u64) = get_asset_and_amount(index, is_input_index); + let (asset_bits, amount): (u256, u64) = get_explicit_asset_and_amount(index, is_input_index); assert!(jet::eq_256(asset_bits, expected_asset_bits)); assert!(jet::eq_64(amount, expected_amount)); } diff --git a/crates/contracts/simf/asset_auth_vault.simf b/crates/contracts/simf/asset_auth_vault.simf index fdabf5b7..ccdd9783 100644 --- a/crates/contracts/simf/asset_auth_vault.simf +++ b/crates/contracts/simf/asset_auth_vault.simf @@ -3,7 +3,7 @@ use std::lib::asserts::assert_eq_64; use std::lib::op_return::is_output_op_return; use std::lib::u64::safe_add_64; -use crate::helper::get_asset_and_amount; +use crate::helper::get_explicit_asset_and_amount; // Helper getters @@ -43,7 +43,7 @@ fn ensure_asset_and_amount_ge( expected_asset_bits: u256, expected_amount: u64 ) { - let (asset_bits, amount): (u256, u64) = get_asset_and_amount(index, is_input_index); + let (asset_bits, amount): (u256, u64) = get_explicit_asset_and_amount(index, is_input_index); assert!(jet::eq_256(asset_bits, expected_asset_bits)); assert!(jet::le_64(expected_amount, amount)); } @@ -60,7 +60,10 @@ fn ensure_output_script_hash(index: u32, expected_script_hash: u256) { } fn ensure_vault_asset(index: u32, is_input_index: bool) -> u64 { - let (vault_asset_id, vault_amount): (u256, u64) = get_asset_and_amount(index, is_input_index); + let ( + vault_asset_id, + vault_amount + ): (u256, u64) = get_explicit_asset_and_amount(index, is_input_index); check_assets_eq(vault_asset_id, param::VAULT_ASSET_ID); diff --git a/crates/contracts/simf/helper.simf b/crates/contracts/simf/helper.simf index b9135c2e..a74c7b44 100644 --- a/crates/contracts/simf/helper.simf +++ b/crates/contracts/simf/helper.simf @@ -1,4 +1,9 @@ -pub fn get_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { +// Helper getters + +pub fn get_explicit_asset_and_amount( + index: u32, + is_input_index: bool +) -> (u256, u64) { let pair: (Asset1, Amount1) = match is_input_index { false => { unwrap(jet::output_amount(index)) diff --git a/crates/contracts/simf/issuance_factory.simf b/crates/contracts/simf/issuance_factory.simf index 8a2fc922..e7aa4fb5 100644 --- a/crates/contracts/simf/issuance_factory.simf +++ b/crates/contracts/simf/issuance_factory.simf @@ -1,25 +1,23 @@ +use crate::helper::get_explicit_asset_and_amount; + // Helper getters -fn get_script_hash(index: u32, is_input_index: bool) -> u256 { +fn get_script_hash( + index: u32, + is_input_index: bool +) -> u256 { let script_hash: u256 = match is_input_index { - true => unwrap(jet::input_script_hash(index)), - false => unwrap(jet::output_script_hash(index)), + false => { + unwrap(jet::output_script_hash(index)) + }, + true => { + unwrap(jet::input_script_hash(index)) + } }; script_hash } -fn get_explicit_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { - let pair: (Asset1, Amount1) = match is_input_index { - true => unwrap(jet::input_amount(index)), - false => unwrap(jet::output_amount(index)), - }; - let (asset, amount): (Asset1, Amount1) = pair; - let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); - let amount: u64 = unwrap_right::<(u1, u256)>(amount); - (asset_bits, amount) -} - fn get_current_explicit_asset() -> u256 { let asset: Asset1 = jet::current_asset(); let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); @@ -29,8 +27,12 @@ fn get_current_explicit_asset() -> u256 { fn is_op_return(output_index: u32) -> bool { match jet::output_null_datum(output_index, 0) { - Some(entry: Option>>) => true, - None => false, + None => { + false + }, + Some(entry: Option>>) => { + true + } } } @@ -69,16 +71,30 @@ fn ensure_non_zero_amount(amount: u64) { assert!(jet::some_64(amount)); } -fn ensure_output_asset_and_amount(output_index: u32, expected_asset_bits: u256, expected_amount: u64) { +fn ensure_output_asset_and_amount( + output_index: u32, + expected_asset_bits: u256, + expected_amount: u64 +) { let (asset_bits, amount): (u256, u64) = get_explicit_asset_and_amount(output_index, false); check_assets_eq(asset_bits, expected_asset_bits); check_asset_amounts_eq(amount, expected_amount); } -fn ensure_io_asset_eq(input_index: u32, output_index: u32, expected_asset_bits: u256) -> (u64, u64) { - let (input_asset_bits, input_amount): (u256, u64) = get_explicit_asset_and_amount(input_index, true); - let (output_asset_bits, output_amount): (u256, u64) = get_explicit_asset_and_amount(output_index, false); +fn ensure_io_asset_eq( + input_index: u32, + output_index: u32, + expected_asset_bits: u256 +) -> (u64, u64) { + let ( + input_asset_bits, + input_amount + ): (u256, u64) = get_explicit_asset_and_amount(input_index, true); + let ( + output_asset_bits, + output_amount + ): (u256, u64) = get_explicit_asset_and_amount(output_index, false); check_assets_eq(input_asset_bits, expected_asset_bits); check_assets_eq(input_asset_bits, output_asset_bits); @@ -92,7 +108,10 @@ fn ensure_io_asset_and_amount_eq( expected_asset_bits: u256, expected_amount: u64 ) { - let (input_amount, output_amount): (u64, u64) = ensure_io_asset_eq(input_index, output_index, expected_asset_bits); + let ( + input_amount, + output_amount + ): (u64, u64) = ensure_io_asset_eq(input_index, output_index, expected_asset_bits); check_asset_amounts_eq(input_amount, expected_amount); check_asset_amounts_eq(input_amount, output_amount); @@ -104,12 +123,19 @@ fn ensure_input_asset_and_amount_burn( expected_asset_bits: u256, expected_asset_amount: u64 ) { - ensure_io_asset_and_amount_eq(input_index, output_index, expected_asset_bits, expected_asset_amount); + ensure_io_asset_and_amount_eq( + input_index, + output_index, + expected_asset_bits, + expected_asset_amount + ); ensure_output_is_op_return(output_index); } -fn ensure_zero_bit(bit: bool) { assert!(jet::eq_1(::into(bit), 0)); } +fn ensure_zero_bit(bit: bool) { + assert!(jet::eq_1(::into(bit), 0)); +} // Math helpers @@ -159,7 +185,6 @@ fn verify_issuance(input_index: u32, output_index: u32, reissuance_flag: bool) { fn verify_issuance_step(acc: (), start_output_index: u32, i: u8) -> Either<(), ()> { match jet::le_8(param::ISSUING_UTXOS_COUNT, i) { - true => Left(()), false => { let step_index: u32 = <(u16, u16)>::into((0, <(u8, u8)>::into((0, i)))); @@ -169,13 +194,19 @@ fn verify_issuance_step(acc: (), start_output_index: u32, i: u8) -> Either<(), ( verify_issuance(input_index, output_index, get_reissuance_flag(i)); Right(()) + }, + true => { + Left(()) } } } // Assets issuance flow -fn get_asset_issuance_issuance_factory_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_asset_issuance_issuance_factory_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 1), safe_add_32(start_output_index, 1)) } @@ -188,34 +219,58 @@ fn issue_new_assets(output_index: u32) { let ( issuance_factory_input_index, issuance_factory_output_index - ): (u32, u32) = get_asset_issuance_issuance_factory_indexes(auth_nft_input_index, auth_nft_output_index); + ): (u32, u32) = get_asset_issuance_issuance_factory_indexes( + auth_nft_input_index, + auth_nft_output_index + ); assert!(jet::eq_32(issuance_factory_input_index, jet::current_index())); let current_asset_bits: u256 = get_current_explicit_asset(); - ensure_io_asset_and_amount_eq(auth_nft_input_index, auth_nft_output_index, current_asset_bits, 1); - ensure_io_asset_and_amount_eq(issuance_factory_input_index, issuance_factory_output_index, current_asset_bits, 1); + ensure_io_asset_and_amount_eq( + auth_nft_input_index, + auth_nft_output_index, + current_asset_bits, + 1 + ); + ensure_io_asset_and_amount_eq( + issuance_factory_input_index, + issuance_factory_output_index, + current_asset_bits, + 1 + ); ensure_io_script_hashes_eq(issuance_factory_input_index, issuance_factory_output_index); - let issued_outputs_start_index: u32 = get_asset_issuance_start_issued_output_index(auth_nft_output_index); + let issued_outputs_start_index: u32 = get_asset_issuance_start_issued_output_index( + auth_nft_output_index + ); unwrap_left::<()>(for_while::((), issued_outputs_start_index)); } // Factory removing flow -fn get_removing_auth_nft_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_removing_auth_nft_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 1), safe_add_32(start_output_index, 1)) } fn remove_factory(output_index: u32) { - let (issuance_factory_input_index, issuance_factory_output_index): (u32, u32) = (0, output_index); + let ( + issuance_factory_input_index, + issuance_factory_output_index + ): (u32, u32) = (0, output_index); let ( auth_nft_input_index, auth_nft_output_index - ): (u32, u32) = get_removing_auth_nft_indexes(issuance_factory_input_index, issuance_factory_output_index); + ): (u32, u32) = get_removing_auth_nft_indexes( + issuance_factory_input_index, + issuance_factory_output_index + ); assert!(jet::eq_32(issuance_factory_input_index, jet::current_index())); @@ -227,7 +282,12 @@ fn remove_factory(output_index: u32) { current_asset_bits, 1 ); - ensure_input_asset_and_amount_burn(auth_nft_input_index, auth_nft_output_index, current_asset_bits, 1); + ensure_input_asset_and_amount_burn( + auth_nft_input_index, + auth_nft_output_index, + current_asset_bits, + 1 + ); } fn main() { @@ -239,4 +299,4 @@ fn main() { remove_factory(output_index); } } -} \ No newline at end of file +} diff --git a/crates/contracts/simf/lending.simf b/crates/contracts/simf/lending.simf index ea649371..4951fc8b 100644 --- a/crates/contracts/simf/lending.simf +++ b/crates/contracts/simf/lending.simf @@ -1,29 +1,31 @@ +use crate::helper::get_explicit_asset_and_amount; + // Helper getters -fn get_script_hash(index: u32, is_input_index: bool) -> u256 { +fn get_script_hash( + index: u32, + is_input_index: bool +) -> u256 { let script_hash: u256 = match is_input_index { - true => unwrap(jet::input_script_hash(index)), - false => unwrap(jet::output_script_hash(index)), + false => { + unwrap(jet::output_script_hash(index)) + }, + true => { + unwrap(jet::input_script_hash(index)) + } }; script_hash } -fn get_explicit_asset_and_amount(index: u32, is_input_index: bool) -> (u256, u64) { - let pair: (Asset1, Amount1) = match is_input_index { - true => unwrap(jet::input_amount(index)), - false => unwrap(jet::output_amount(index)), - }; - let (asset, amount): (Asset1, Amount1) = pair; - let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); - let amount: u64 = unwrap_right::<(u1, u256)>(amount); - (asset_bits, amount) -} - fn is_op_return(output_index: u32) -> bool { match jet::output_null_datum(output_index, 0) { - Some(entry: Option>>) => true, - None => false, + None => { + false + }, + Some(entry: Option>>) => { + true + } } } @@ -73,8 +75,12 @@ fn safe_sub_64(first: u64, second: u64) -> u64 { fn min_64(first: u64, second: u64) -> u64 { match jet::lt_64(first, second) { - true => first, - false => second, + false => { + second + }, + true => { + first + } } } @@ -106,23 +112,41 @@ fn ensure_script_hash_transition( ensure_output_script_hash(output_index, expected_output_script_hash); } -fn ensure_input_asset_and_amount(input_index: u32, expected_asset_bits: u256, expected_amount: u64) { +fn ensure_input_asset_and_amount( + input_index: u32, + expected_asset_bits: u256, + expected_amount: u64 +) { let (asset_bits, amount): (u256, u64) = get_explicit_asset_and_amount(input_index, true); check_assets_eq(asset_bits, expected_asset_bits); check_asset_amounts_eq(amount, expected_amount); } -fn ensure_output_asset_and_amount(output_index: u32, expected_asset_bits: u256, expected_amount: u64) { +fn ensure_output_asset_and_amount( + output_index: u32, + expected_asset_bits: u256, + expected_amount: u64 +) { let (asset_bits, amount): (u256, u64) = get_explicit_asset_and_amount(output_index, false); check_assets_eq(asset_bits, expected_asset_bits); check_asset_amounts_eq(amount, expected_amount); } -fn ensure_io_asset_eq(input_index: u32, output_index: u32, expected_asset_bits: u256) -> (u64, u64) { - let (input_asset_bits, input_amount): (u256, u64) = get_explicit_asset_and_amount(input_index, true); - let (output_asset_bits, output_amount): (u256, u64) = get_explicit_asset_and_amount(output_index, false); +fn ensure_io_asset_eq( + input_index: u32, + output_index: u32, + expected_asset_bits: u256 +) -> (u64, u64) { + let ( + input_asset_bits, + input_amount + ): (u256, u64) = get_explicit_asset_and_amount(input_index, true); + let ( + output_asset_bits, + output_amount + ): (u256, u64) = get_explicit_asset_and_amount(output_index, false); check_assets_eq(input_asset_bits, expected_asset_bits); check_assets_eq(input_asset_bits, output_asset_bits); @@ -136,7 +160,10 @@ fn ensure_io_asset_and_amount_eq( expected_asset_bits: u256, expected_amount: u64 ) { - let (input_amount, output_amount): (u64, u64) = ensure_io_asset_eq(input_index, output_index, expected_asset_bits); + let ( + input_amount, + output_amount + ): (u64, u64) = ensure_io_asset_eq(input_index, output_index, expected_asset_bits); check_asset_amounts_eq(input_amount, expected_amount); check_asset_amounts_eq(input_amount, output_amount); @@ -148,7 +175,12 @@ fn ensure_input_asset_and_amount_burn( expected_asset_bits: u256, expected_asset_amount: u64 ) { - ensure_io_asset_and_amount_eq(input_index, output_index, expected_asset_bits, expected_asset_amount); + ensure_io_asset_and_amount_eq( + input_index, + output_index, + expected_asset_bits, + expected_asset_amount + ); ensure_output_is_op_return(output_index); } @@ -159,7 +191,10 @@ fn ensure_asset_transition_with_additional_amount( expected_asset_bits: u256, additional_amount: u64 ) { - let (input_amount, output_amount): (u64, u64) = ensure_io_asset_eq(input_index, output_index, expected_asset_bits); + let ( + input_amount, + output_amount + ): (u64, u64) = ensure_io_asset_eq(input_index, output_index, expected_asset_bits); let new_asset_amount: u64 = safe_add_64(input_amount, additional_amount); @@ -183,7 +218,7 @@ fn mul_div(x: u64, y: u64, denominator: u64) -> u64 { // Basis points math fn get_max_basis_points() -> u64 { - 10_000 + 10000 } fn apply_basis_points(amount: u64, bps: u64) -> u64 { @@ -260,11 +295,17 @@ fn split_repayment_by_fees(fee_left: u64, amount_to_repay: u64) -> (u64, u64) { } fn validate_collateral_input(input_index: u32, current_debt: u64) -> u64 { - let (asset_bits, current_collateral_amount): (u256, u64) = get_explicit_asset_and_amount(input_index, true); + let ( + asset_bits, + current_collateral_amount + ): (u256, u64) = get_explicit_asset_and_amount(input_index, true); let already_paid_debt: u64 = safe_sub_64(get_total_amount_to_repay(), current_debt); let already_unlocked_collateral: u64 = get_collateral_for_principal(already_paid_debt); - let total_collateral_amount: u64 = safe_add_64(current_collateral_amount, already_unlocked_collateral); + let total_collateral_amount: u64 = safe_add_64( + current_collateral_amount, + already_unlocked_collateral + ); check_assets_eq(asset_bits, param::COLLATERAL_ASSET_ID); check_asset_amounts_eq(total_collateral_amount, param::COLLATERAL_AMOUNT); @@ -280,7 +321,10 @@ fn validate_vaults( ) { let total_fee_amount: u64 = get_total_fee_amount(); - let already_repaid_amount: u64 = safe_sub_64(get_total_amount_to_repay(), current_borrower_debt); + let already_repaid_amount: u64 = safe_sub_64( + get_total_amount_to_repay(), + current_borrower_debt + ); let ( already_repaid_fee, @@ -289,26 +333,64 @@ fn validate_vaults( let fee_left: u64 = safe_sub_64(total_fee_amount, already_repaid_fee); - let (fee_repaid, protocol_fee_repaid): (u64, u64) = split_repayment_by_fees(fee_left, amount_to_repay); + let ( + fee_repaid, + protocol_fee_repaid + ): (u64, u64) = split_repayment_by_fees(fee_left, amount_to_repay); - let total_repaid_protocol_fee: u64 = safe_add_64(already_repaid_protocol_fee, protocol_fee_repaid); + let total_repaid_protocol_fee: u64 = safe_add_64( + already_repaid_protocol_fee, + protocol_fee_repaid + ); let additional_lender_vault_amount: u64 = safe_sub_64(amount_to_repay, protocol_fee_repaid); let total_protocol_fee: u64 = get_protocol_fee_amount(total_fee_amount); let lender_vault_output_hash: u256 = match jet::eq_64(current_borrower_debt, amount_to_repay) { - true => param::FINALIZED_LENDER_VAULT_COV_HASH, - false => param::LENDER_VAULT_COV_HASH, + false => { + param::LENDER_VAULT_COV_HASH + }, + true => { + param::FINALIZED_LENDER_VAULT_COV_HASH + } }; - let protocol_fee_vault_output_hash: u256 = match jet::eq_64(total_repaid_protocol_fee, total_protocol_fee) { - true => param::FINALIZED_PROTOCOL_FEE_VAULT_COV_HASH, - false => param::PROTOCOL_FEE_VAULT_COV_HASH, + let protocol_fee_vault_output_hash: u256 = match jet::eq_64( + total_repaid_protocol_fee, + total_protocol_fee + ) { + false => { + param::PROTOCOL_FEE_VAULT_COV_HASH + }, + true => { + param::FINALIZED_PROTOCOL_FEE_VAULT_COV_HASH + } }; let (lender_vault_input_index, lender_vault_output_index): (u32, u32) = lender_vault_indexes; - let (protocol_fee_vault_input_index, protocol_fee_vault_output_index): (u32, u32) = protocol_fee_vault_indexes; + let ( + protocol_fee_vault_input_index, + protocol_fee_vault_output_index + ): (u32, u32) = protocol_fee_vault_indexes; match jet::some_64(already_repaid_amount) { + false => { + ensure_output_asset_and_amount( + lender_vault_output_index, + param::PRINCIPAL_ASSET_ID, + additional_lender_vault_amount + ); + ensure_output_script_hash(lender_vault_output_index, lender_vault_output_hash); + + ensure_output_asset_and_amount( + protocol_fee_vault_output_index, + param::PRINCIPAL_ASSET_ID, + protocol_fee_repaid + ); + ensure_output_script_hash( + protocol_fee_vault_output_index, + protocol_fee_vault_output_hash + ); + }, true => { ensure_asset_transition_with_additional_amount( lender_vault_input_index, @@ -324,6 +406,7 @@ fn validate_vaults( ); match jet::lt_64(already_repaid_protocol_fee, total_protocol_fee) { + false => {}, true => { ensure_asset_transition_with_additional_amount( protocol_fee_vault_input_index, @@ -337,39 +420,32 @@ fn validate_vaults( param::PROTOCOL_FEE_VAULT_COV_HASH, protocol_fee_vault_output_hash ); - }, - false => {}, + } }; - }, - false => { - ensure_output_asset_and_amount( - lender_vault_output_index, - param::PRINCIPAL_ASSET_ID, - additional_lender_vault_amount - ); - ensure_output_script_hash(lender_vault_output_index, lender_vault_output_hash); - - ensure_output_asset_and_amount( - protocol_fee_vault_output_index, - param::PRINCIPAL_ASSET_ID, - protocol_fee_repaid - ); - ensure_output_script_hash(protocol_fee_vault_output_index, protocol_fee_vault_output_hash); - }, + } }; } // Partial repayment flow -fn get_partial_repayment_offer_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_partial_repayment_offer_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 1), safe_add_32(start_output_index, 1)) } -fn get_partial_repayment_lender_vault_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_partial_repayment_lender_vault_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 2), safe_add_32(start_output_index, 2)) } -fn get_partial_repayment_protocol_fee_vault_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_partial_repayment_protocol_fee_vault_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 3), safe_add_32(start_output_index, 3)) } @@ -378,7 +454,10 @@ fn partial_repay_offer(current_debt: u64, amount_to_repay: u64) { let ( offer_input_index, offer_output_index - ): (u32, u32) = get_partial_repayment_offer_indexes(borrower_nft_input_index, borrower_nft_output_index); + ): (u32, u32) = get_partial_repayment_offer_indexes( + borrower_nft_input_index, + borrower_nft_output_index + ); assert!(jet::eq_32(jet::current_index(), offer_input_index)); @@ -392,7 +471,11 @@ fn partial_repay_offer(current_debt: u64, amount_to_repay: u64) { let collateral_to_unlock: u64 = get_collateral_for_principal(amount_to_repay); let new_collateral_amount: u64 = safe_sub_64(current_collateral_amount, collateral_to_unlock); - ensure_output_asset_and_amount(offer_output_index, param::COLLATERAL_ASSET_ID, new_collateral_amount); + ensure_output_asset_and_amount( + offer_output_index, + param::COLLATERAL_ASSET_ID, + new_collateral_amount + ); let new_debt: u64 = safe_sub_64(current_debt, amount_to_repay); let new_offer_script_hash: u256 = get_script_hash_for_storage(true, new_debt); @@ -407,8 +490,14 @@ fn partial_repay_offer(current_debt: u64, amount_to_repay: u64) { ); validate_vaults( - get_partial_repayment_lender_vault_indexes(borrower_nft_input_index, borrower_nft_output_index), - get_partial_repayment_protocol_fee_vault_indexes(borrower_nft_input_index, borrower_nft_output_index), + get_partial_repayment_lender_vault_indexes( + borrower_nft_input_index, + borrower_nft_output_index + ), + get_partial_repayment_protocol_fee_vault_indexes( + borrower_nft_input_index, + borrower_nft_output_index + ), current_debt, amount_to_repay ); @@ -420,11 +509,17 @@ fn get_full_repayment_offer_input_index(start_input_index: u32) -> u32 { safe_add_32(start_input_index, 1) } -fn get_full_repayment_lender_vault_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_full_repayment_lender_vault_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 2), safe_add_32(start_output_index, 1)) } -fn get_full_repayment_protocol_fee_vault_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_full_repayment_protocol_fee_vault_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 3), safe_add_32(start_output_index, 2)) } @@ -447,8 +542,14 @@ fn full_repay_offer(current_debt: u64) { ); validate_vaults( - get_full_repayment_lender_vault_indexes(borrower_nft_input_index, borrower_nft_output_index), - get_full_repayment_protocol_fee_vault_indexes(borrower_nft_input_index, borrower_nft_output_index), + get_full_repayment_lender_vault_indexes( + borrower_nft_input_index, + borrower_nft_output_index + ), + get_full_repayment_protocol_fee_vault_indexes( + borrower_nft_input_index, + borrower_nft_output_index + ), current_debt, current_debt ); @@ -456,7 +557,10 @@ fn full_repay_offer(current_debt: u64) { // Liquidation flow -fn get_liquidation_lender_nft_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_liquidation_lender_nft_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 1), start_output_index) } @@ -476,16 +580,26 @@ fn liquidate_offer(current_debt: u64) { let _: u64 = validate_collateral_input(lending_input_index, current_debt); - ensure_input_asset_and_amount_burn(lender_nft_input_index, lender_nft_output_index, param::LENDER_NFT_ASSET_ID, 1); + ensure_input_asset_and_amount_burn( + lender_nft_input_index, + lender_nft_output_index, + param::LENDER_NFT_ASSET_ID, + 1 + ); } // Offer acceptance flow -fn get_acceptance_principal_output_index(start_output_index: u32) -> u32 { +fn get_acceptance_principal_output_index( + start_output_index: u32 +) -> u32 { safe_add_32(start_output_index, 1) } -fn get_acceptance_lender_nft_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_acceptance_lender_nft_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 1), safe_add_32(start_output_index, 2)) } @@ -516,19 +630,34 @@ fn accept_offer() { active_offer_script_hash ); - ensure_io_asset_and_amount_eq(lender_nft_input_index, lender_nft_output_index, param::LENDER_NFT_ASSET_ID, 1); + ensure_io_asset_and_amount_eq( + lender_nft_input_index, + lender_nft_output_index, + param::LENDER_NFT_ASSET_ID, + 1 + ); - ensure_output_asset_and_amount(principal_output_index, param::PRINCIPAL_ASSET_ID, param::PRINCIPAL_AMOUNT); + ensure_output_asset_and_amount( + principal_output_index, + param::PRINCIPAL_ASSET_ID, + param::PRINCIPAL_AMOUNT + ); ensure_output_script_hash(principal_output_index, param::PRINCIPAL_OUTPUT_SCRIPT_HASH); } // Offer cancellation flow -fn get_cancellation_lender_nft_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_cancellation_lender_nft_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 1), start_output_index) } -fn get_cancellation_borrower_nft_indexes(start_input_index: u32, start_output_index: u32) -> (u32, u32) { +fn get_cancellation_borrower_nft_indexes( + start_input_index: u32, + start_output_index: u32 +) -> (u32, u32) { (safe_add_32(start_input_index, 2), safe_add_32(start_output_index, 1)) } @@ -548,7 +677,11 @@ fn cancel_offer() { let current_script_hash: u256 = get_script_hash_for_storage(false, get_total_amount_to_repay()); ensure_input_script_hash(lending_input_index, current_script_hash); - ensure_input_asset_and_amount(lending_input_index, param::COLLATERAL_ASSET_ID, param::COLLATERAL_AMOUNT); + ensure_input_asset_and_amount( + lending_input_index, + param::COLLATERAL_ASSET_ID, + param::COLLATERAL_AMOUNT + ); ensure_input_asset_and_amount_burn( borrower_nft_input_index, @@ -573,7 +706,7 @@ fn main() { }, Right(params: ()) => { cancel_offer(); - }, + } } }, Right(active_offer_params: Either, u64>) => { @@ -581,19 +714,22 @@ fn main() { Left(repayment_params: Either<(u64, u64), u64>) => { match repayment_params { Left(partial_repayment_params: (u64, u64)) => { - let (current_debt, amount_to_repay): (u64, u64) = partial_repayment_params; + let ( + current_debt, + amount_to_repay + ): (u64, u64) = partial_repayment_params; partial_repay_offer(current_debt, amount_to_repay); }, Right(current_debt: u64) => { full_repay_offer(current_debt); - }, + } } }, Right(current_debt: u64) => { liquidate_offer(current_debt); } } - }, + } } -} \ No newline at end of file +} From 9193f47a36af910648c155ed1707f435976dc29a Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 31 Jul 2026 14:03:33 +0300 Subject: [PATCH 5/6] feat: migrate get_script_hash to helper.simf --- crates/contracts/simf/asset_auth_vault.simf | 23 +++---------- crates/contracts/simf/helper.simf | 11 +++++++ crates/contracts/simf/issuance_factory.simf | 21 +++--------- crates/contracts/simf/lending.simf | 36 ++++----------------- 4 files changed, 25 insertions(+), 66 deletions(-) diff --git a/crates/contracts/simf/asset_auth_vault.simf b/crates/contracts/simf/asset_auth_vault.simf index ccdd9783..79cbdc08 100644 --- a/crates/contracts/simf/asset_auth_vault.simf +++ b/crates/contracts/simf/asset_auth_vault.simf @@ -3,25 +3,10 @@ use std::lib::asserts::assert_eq_64; use std::lib::op_return::is_output_op_return; use std::lib::u64::safe_add_64; -use crate::helper::get_explicit_asset_and_amount; - -// Helper getters - -fn get_script_hash( - index: u32, - is_input_index: bool -) -> u256 { - let script_hash: u256 = match is_input_index { - false => { - unwrap(jet::output_script_hash(index)) - }, - true => { - unwrap(jet::input_script_hash(index)) - } - }; - - script_hash -} +use crate::helper::{ + get_explicit_asset_and_amount, + get_script_hash +}; // Check helpers diff --git a/crates/contracts/simf/helper.simf b/crates/contracts/simf/helper.simf index a74c7b44..8588cc17 100644 --- a/crates/contracts/simf/helper.simf +++ b/crates/contracts/simf/helper.simf @@ -18,3 +18,14 @@ pub fn get_explicit_asset_and_amount( let amount: u64 = unwrap_right::<(u1, u256)>(amount); (asset_bits, amount) } + +pub fn get_script_hash(index: u32, is_input_index: bool) -> u256 { + match is_input_index { + false => { + unwrap(jet::output_script_hash(index)) + }, + true => { + unwrap(jet::input_script_hash(index)) + } + } +} diff --git a/crates/contracts/simf/issuance_factory.simf b/crates/contracts/simf/issuance_factory.simf index e7aa4fb5..79b1bd63 100644 --- a/crates/contracts/simf/issuance_factory.simf +++ b/crates/contracts/simf/issuance_factory.simf @@ -1,23 +1,10 @@ -use crate::helper::get_explicit_asset_and_amount; +use crate::helper::{ + get_explicit_asset_and_amount, + get_script_hash +}; // Helper getters -fn get_script_hash( - index: u32, - is_input_index: bool -) -> u256 { - let script_hash: u256 = match is_input_index { - false => { - unwrap(jet::output_script_hash(index)) - }, - true => { - unwrap(jet::input_script_hash(index)) - } - }; - - script_hash -} - fn get_current_explicit_asset() -> u256 { let asset: Asset1 = jet::current_asset(); let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset); diff --git a/crates/contracts/simf/lending.simf b/crates/contracts/simf/lending.simf index 4951fc8b..8dce2dd4 100644 --- a/crates/contracts/simf/lending.simf +++ b/crates/contracts/simf/lending.simf @@ -1,33 +1,9 @@ -use crate::helper::get_explicit_asset_and_amount; +use std::lib::op_return::is_output_op_return; -// Helper getters - -fn get_script_hash( - index: u32, - is_input_index: bool -) -> u256 { - let script_hash: u256 = match is_input_index { - false => { - unwrap(jet::output_script_hash(index)) - }, - true => { - unwrap(jet::input_script_hash(index)) - } - }; - - script_hash -} - -fn is_op_return(output_index: u32) -> bool { - match jet::output_null_datum(output_index, 0) { - None => { - false - }, - Some(entry: Option>>) => { - true - } - } -} +use crate::helper::{ + get_explicit_asset_and_amount, + get_script_hash +}; // Check helpers @@ -87,7 +63,7 @@ fn min_64(first: u64, second: u64) -> u64 { // Ensure functions fn ensure_output_is_op_return(index: u32) { - check_flags_eq(is_op_return(index), true); + check_flags_eq(is_output_op_return(index), true); } fn ensure_input_script_hash(input_index: u32, expected_script_hash: u256) { From 6283c7363ce52acb75be9f1c3cfa44b01b3a294a Mon Sep 17 00:00:00 2001 From: LesterEvSe Date: Fri, 31 Jul 2026 15:08:26 +0300 Subject: [PATCH 6/6] feat: add fmt.sh script and add minor fixes to other files --- crates/contracts/fmt.sh | 28 +++++++++++++++++++++ crates/contracts/simf/issuance_factory.simf | 15 +++-------- crates/contracts/simf/lending.simf | 26 ++----------------- 3 files changed, 33 insertions(+), 36 deletions(-) create mode 100644 crates/contracts/fmt.sh diff --git a/crates/contracts/fmt.sh b/crates/contracts/fmt.sh new file mode 100644 index 00000000..b18d2e1d --- /dev/null +++ b/crates/contracts/fmt.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# WIP: early development, not intended for external use. + +set -euo pipefail + +SIMF_DIR="./simf" + +usage() { + echo "usage: $(basename "$0") | all" >&2 + exit 2 +} + +[[ $# -eq 1 ]] || usage + +case "$1" in + all) + [[ -d "$SIMF_DIR" ]] || { echo "no such dir: $SIMF_DIR" >&2; exit 1; } + # NUL-delimited so filenames with spaces survive + find "$SIMF_DIR" -type f -name '*.simf' -print0 \ + | xargs -0 -r -n1 simfmt + ;; + *) + [[ -f "$1" ]] || { echo "no such file: $1" >&2; exit 1; } + [[ "$1" == *.simf ]] || echo "warning: $1 is not a .simf file" >&2 + simfmt "$1" + ;; +esac diff --git a/crates/contracts/simf/issuance_factory.simf b/crates/contracts/simf/issuance_factory.simf index 79b1bd63..0f616979 100644 --- a/crates/contracts/simf/issuance_factory.simf +++ b/crates/contracts/simf/issuance_factory.simf @@ -1,3 +1,5 @@ +use std::lib::op_return::is_output_op_return; + use crate::helper::{ get_explicit_asset_and_amount, get_script_hash @@ -12,17 +14,6 @@ fn get_current_explicit_asset() -> u256 { asset_bits } -fn is_op_return(output_index: u32) -> bool { - match jet::output_null_datum(output_index, 0) { - None => { - false - }, - Some(entry: Option>>) => { - true - } - } -} - // Check helpers fn check_asset_amounts_eq(asset_amount_1: u64, asset_amount_2: u64) { @@ -44,7 +35,7 @@ fn check_flags_eq(flag_1: bool, flag_2: bool) { // Ensure functions fn ensure_output_is_op_return(index: u32) { - check_flags_eq(is_op_return(index), true); + check_flags_eq(is_output_op_return(index), true); } fn ensure_io_script_hashes_eq(input_index: u32, output_index: u32) { diff --git a/crates/contracts/simf/lending.simf b/crates/contracts/simf/lending.simf index 8dce2dd4..37cde03a 100644 --- a/crates/contracts/simf/lending.simf +++ b/crates/contracts/simf/lending.simf @@ -1,4 +1,6 @@ use std::lib::op_return::is_output_op_return; +use std::lib::u64::{safe_add_64, safe_sub_64}; +use std::lib::u32::safe_add_32; use crate::helper::{ get_explicit_asset_and_amount, @@ -25,30 +27,6 @@ fn check_flags_eq(flag_1: bool, flag_2: bool) { // Math helpers -fn safe_add_64(first: u64, second: u64) -> u64 { - let (carry, result): (bool, u64) = jet::add_64(first, second); - - check_flags_eq(carry, false); - - result -} - -fn safe_add_32(first: u32, second: u32) -> u32 { - let (carry, result): (bool, u32) = jet::add_32(first, second); - - check_flags_eq(carry, false); - - result -} - -fn safe_sub_64(first: u64, second: u64) -> u64 { - let (carry, result): (bool, u64) = jet::subtract_64(first, second); - - check_flags_eq(carry, false); - - result -} - fn min_64(first: u64, second: u64) -> u64 { match jet::lt_64(first, second) { false => {