Skip to content

Conversation

@artur-abliazimov
Copy link
Contributor

@artur-abliazimov artur-abliazimov commented Sep 26, 2025

Summary by CodeRabbit

  • New Features

    • Added protocolFee helper exported to integration tests.
  • Refactor

    • Switched to typed contract events across contracts, updated registration/initialization patterns, and bumped contract versions.
  • Chores

    • Upgraded SDKs/dependencies, changed WASM build target/artifact paths, marked multiple crates non-publishable, and updated deploy/upgrade scripts.
  • Tests

    • Updated unit/integration tests for Map-based event payloads, new registration APIs, cost-estimate budget model, WASM paths, and simplified liquidate signatures.
  • Documentation

    • README updated to recommend Stellar CLI.

@coderabbitai
Copy link

coderabbitai bot commented Sep 26, 2025

Walkthrough

Refactors ad-hoc event emissions to typed #[contractevent] structs, upgrades Soroban workspace dependencies, switches Rust WASM target/artifact paths to wasm32v1-none, updates deploy/register APIs and budget cost-estimate usage, and updates Makefile, CI, deploy scripts, tests, and integration-test tooling.

Changes

Cohort / File(s) Summary
Build & CI target switch
​.github/workflows/tests.yml, Makefile, deploy/scripts/deploy.sh, deploy/scripts/upgrade.sh, integration-tests/tests/pool.sut.ts, deploy/artifacts/*/.contracts
Change Rust WASM target and artifact paths from wasm32-unknown-unknownwasm32v1-none; update CI/test commands, Stellar CLI calls (install/upload), and deploy artifact entries.
Workspace dependencies
Cargo.toml
Bump soroban-sdk & soroban-token-sdk to 23.0.2; replace soroban-fixed-point-math version with a git dependency at tag soroban-sdk-23.0.2.
Package manifests (disable publish)
contracts/common-token/Cargo.toml, contracts/common/Cargo.toml, contracts/debt-token/Cargo.toml, contracts/pool/Cargo.toml, contracts/s-token/Cargo.toml
Add publish = false to package manifests.
Deployer & registration API
contracts/deployer/src/lib.rs, contracts/deployer/src/test.rs, contracts/*/src/tests/*, contracts/*/src/tests/sut.rs
Replace deploy/register calls with new forms (deploy_v2(..., ()), env.register(..., ())), use register_stellar_asset_contract_v2(...).address(), and switch budget resets to env.cost_estimate().budget() APIs.
Event model: pool, s-token, debt-token
contracts/pool/src/event.rs, contracts/s-token/src/event.rs, contracts/debt-token/src/event.rs
Remove ad-hoc event helper functions and add typed #[contractevent] structs (InitializedEvent, DepositEvent, BorrowEvent, etc.) with topic and data_format annotations.
Emit typed events in code paths
contracts/pool/src/methods/*.rs, contracts/pool/src/types/user_configurator.rs, contracts/s-token/src/lib.rs, contracts/debt-token/src/lib.rs, related tests
Replace event::foo(...) calls with EventStruct { ... }.publish(env); update imports, clone/ownership adjustments, and some argument borrow/value changes.
Pool tests: payload & API updates
contracts/pool/src/tests/*.rs
Update test expectations to Map-based event payloads, migrate to env.register(...), use register_stellar_asset_contract_v2(...).address(), cost_estimate budget APIs, wasm v1 imports, and apply small lifetime/index fixes.
SToken tests & wiring
contracts/s-token/src/tests/test.rs, contracts/s-token/src/lib.rs
Update client lifetimes and registration/asset wiring to address-based register(..., ()), change budget resets to cost_estimate, and replace event emissions with typed publish calls.
Integration tests & TS tooling
integration-tests/**/*, integration-tests/package.json, integration-tests/tests/*.ts
Switch TypeScript Stellar imports to @stellar/stellar-sdk; add exported protocolFee; coerce numeric fields; read simulation cost via simulation["cost"]; adjust resources reads; bump devDependencies; update liquidate signatures and wasm paths.
Misc: small logic & mocks
contracts/pool/src/types/price_provider.rs, mocks/flash-loan-receiver-mock/src/lib.rs, README.md
Minor refactors: use is_multiple_of(2), pass Address by value for transfers, and update README CLI install line.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller as Tests / CLI
  participant Deployer as Deployer lib
  participant Env as Env
  participant Contract as Deployed Contract

  Note over Deployer,Env: deployment now uses deploy_v2(..., ())
  Caller->>Deployer: deploy_*(salt, wasm_hash, init_args)
  Deployer->>Env: deploy_v2(wasm_hash, ())
  Env-->>Deployer: contract_id
  Deployer->>Contract: initialize(init_args)
  Contract-->>Deployer: Ok
  Deployer-->>Caller: (contract_id, Ok)
Loading
sequenceDiagram
  autonumber
  participant Logic as Contract logic
  participant Event as #[contractevent] Type
  participant Env as Env

  Note over Logic,Event: typed event emission
  Logic->>Event: construct Event{ fields... }
  Event->>Env: .publish(&env)
  Env-->>Logic: event recorded
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • release/v1 #150 — Overlapping workspace dependency/version upgrades for soroban-sdk/soroban-token-sdk and the soroban-fixed-point-math change.
  • prices and balances calls fixes #149 — Changes to integration-tests pool sut and price-feed wiring overlap with the TS/integration test edits here.

Suggested reviewers

  • mn13

Poem

I nibble carrots, code in paw,
Events now typed — neat lines I saw.
Wasm target hopped, deploy scripts hum,
Tests adjusted, bindings strum.
Hooray — the rabbit stitches change with a drum! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly conveys the primary objective of upgrading the codebase to Protocol 23, matching the widespread dependency and API changes introduced in this pull request. It is concise and specific, avoiding extraneous detail while clearly indicating the main purpose. A reviewer scanning the history will immediately understand that this PR adapts the code to the new protocol version.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/protocol-23

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (12)
.github/workflows/tests.yml (1)

17-27: Please upgrade actions/checkout to v4.

actionlint flags Line 17 because actions/checkout@v3 is now on deprecated Node 16 and will stop receiving updates. Bumping to actions/checkout@v4 keeps the workflow on supported infrastructure and future-proofs the job.

deploy/scripts/upgrade.sh (1)

33-33: Update path LGTM; quote args for safety.

Path switch to wasm32v1-none is correct. Quote args to avoid word-splitting and strange secrets expansion.

Apply:

-POOL_HASH=$(install "../target/wasm32v1-none/release/pool.wasm" $ADMIN_SECRET)
+POOL_HASH=$(install "../target/wasm32v1-none/release/pool.wasm" "$ADMIN_SECRET")
contracts/pool/src/tests/budget.rs (2)

705-705: Ensure cost-estimate budget actually captures callback costs.

Using cost_estimate() without holding/using the same handle can be confusing. Capture it once and read from the same handle.

-    env.cost_estimate().budget().reset_unlimited();
+    let ce = env.cost_estimate();
+    ce.budget().reset_unlimited();

Please verify the snapshot records non‑zero cpu/memory after these tests run (to confirm costs are measured, not zeros).


709-710: Read costs from the same cost-estimate handle.

Prevents accidental drift if cost_estimate() semantics change.

-    let cpu = env.cost_estimate().budget().cpu_instruction_cost();
-    let memory = env.cost_estimate().budget().memory_bytes_cost();
+    let cpu = ce.budget().cpu_instruction_cost();
+    let memory = ce.budget().memory_bytes_cost();
Cargo.toml (1)

41-42: Pin git dep by tag LGTM; consider adding rev for reproducibility.

Tag is fine; adding a commit rev would make builds fully reproducible.

contracts/pool/src/tests/configure_as_collateral.rs (1)

160-183: Event assertion moved to Map payload—verify key names and avoid order brittleness.

  • Confirm the keys "liq_cap", "pen_order", "util_cap", "discount" exactly match those emitted by the contract event (typos will silently fail the equality).
  • Map equality can be order-sensitive depending on construction; if the emitter changes insertion order later, this test may become flaky. Consider asserting by decoding/inspecting keys rather than full Map equality, or use typed event parsing if available.
contracts/pool/src/methods/enable_borrowing_on_reserve.rs (1)

22-31: Emit events only on actual state change (optional).

Currently an event is published even if the flag value stays the same. To reduce noise and preserve idempotency semantics, early-return when no change is needed.

Apply this diff:

-    reserve.configuration.borrowing_enabled = enabled;
-    write_reserve(env, asset, &reserve);
+    if reserve.configuration.borrowing_enabled == enabled {
+        return Ok(());
+    }
+    reserve.configuration.borrowing_enabled = enabled;
+    write_reserve(env, asset, &reserve);
contracts/pool/src/methods/initialize.rs (1)

18-35: InitializedEvent fields sourced from input—consider sourcing from persisted config.

If set_pool_configuration mutates or normalizes values, emitting the event from the stored config guarantees alignment with on-chain state.

contracts/pool/src/tests/withdraw.rs (2)

363-375: Map-based event assertion looks correct; optional nits.

  • You can use symbol_short! for constant keys to avoid repeated allocations: "to", "asset", "amount".
  • Minor: token_address is borrowed in into_val, so no need to wrap with extra parentheses.

379-379: Avoid relying on hard-coded event index.

Using events.get(0) is brittle; prefer locating the event by topic symbol (e.g., "reserve_used_as_coll_disabled") to make the test order-independent.

Additionally, please verify that the new event ordering is stable across runs.

contracts/s-token/src/lib.rs (1)

407-413: Avoid overloading TransferEvent for underlying transfers

Using the same TransferEvent for s-token transfers and underlying token transfers can confuse indexers/consumers. Prefer a distinct UnderlyingTransferEvent.

Apply this diff here:

-        TransferEvent {
-            from: current_address,
-            to: to.clone(),
-            amount,
-        }
-        .publish(&e);
+        UnderlyingTransferEvent {
+            from: current_address,
+            to: to.clone(),
+            amount,
+        }
+        .publish(&e);

Add this struct in contracts/s-token/src/event.rs:

#[contractevent(topics=["underlying_transfer"], data_format = "single-value")]
pub(crate) struct UnderlyingTransferEvent {
    #[topic]
    pub from: Address,
    #[topic]
    pub to: Address,
    pub amount: i128,
}
contracts/pool/src/event.rs (1)

93-99: ReserveStatusChangedEvent: naming consistency nit

Consider aligning topic string with others ("reserve_status_changed") is fine, but ensure downstream consumers expect this exact topic. No change required if tests cover it.

Confirm event topic names remain stable across analytics/indexers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd0b0a7 and d72031c.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • contracts/pool/src/tests/snapshots/budget_utilization.snap is excluded by !**/*.snap
📒 Files selected for processing (44)
  • .github/workflows/tests.yml (1 hunks)
  • Cargo.toml (1 hunks)
  • Makefile (2 hunks)
  • contracts/common-token/Cargo.toml (1 hunks)
  • contracts/common/Cargo.toml (1 hunks)
  • contracts/debt-token/Cargo.toml (1 hunks)
  • contracts/debt-token/src/event.rs (1 hunks)
  • contracts/debt-token/src/lib.rs (6 hunks)
  • contracts/debt-token/src/test.rs (2 hunks)
  • contracts/deployer/src/lib.rs (3 hunks)
  • contracts/deployer/src/test.rs (3 hunks)
  • contracts/pool/Cargo.toml (1 hunks)
  • contracts/pool/src/event.rs (1 hunks)
  • contracts/pool/src/methods/borrow.rs (2 hunks)
  • contracts/pool/src/methods/configure_as_collateral.rs (2 hunks)
  • contracts/pool/src/methods/deposit.rs (2 hunks)
  • contracts/pool/src/methods/enable_borrowing_on_reserve.rs (2 hunks)
  • contracts/pool/src/methods/flash_loan.rs (2 hunks)
  • contracts/pool/src/methods/initialize.rs (2 hunks)
  • contracts/pool/src/methods/liquidate.rs (3 hunks)
  • contracts/pool/src/methods/repay.rs (2 hunks)
  • contracts/pool/src/methods/set_reserve_status.rs (2 hunks)
  • contracts/pool/src/methods/withdraw.rs (2 hunks)
  • contracts/pool/src/tests/borrow.rs (2 hunks)
  • contracts/pool/src/tests/budget.rs (1 hunks)
  • contracts/pool/src/tests/configure_as_collateral.rs (2 hunks)
  • contracts/pool/src/tests/deposit.rs (2 hunks)
  • contracts/pool/src/tests/flash_loan.rs (2 hunks)
  • contracts/pool/src/tests/init_reserve.rs (1 hunks)
  • contracts/pool/src/tests/liquidate.rs (2 hunks)
  • contracts/pool/src/tests/repay.rs (2 hunks)
  • contracts/pool/src/tests/rounding.rs (2 hunks)
  • contracts/pool/src/tests/set_as_collateral.rs (2 hunks)
  • contracts/pool/src/tests/set_reserve_status.rs (2 hunks)
  • contracts/pool/src/tests/sut.rs (6 hunks)
  • contracts/pool/src/tests/withdraw.rs (2 hunks)
  • contracts/pool/src/types/user_configurator.rs (3 hunks)
  • contracts/s-token/Cargo.toml (1 hunks)
  • contracts/s-token/src/event.rs (1 hunks)
  • contracts/s-token/src/lib.rs (9 hunks)
  • contracts/s-token/src/tests/test.rs (4 hunks)
  • deploy/scripts/deploy.sh (1 hunks)
  • deploy/scripts/upgrade.sh (1 hunks)
  • integration-tests/tests/pool.sut.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (15)
contracts/pool/src/tests/borrow.rs (1)
contracts/pool/src/types/price_provider.rs (1)
  • new (22-30)
contracts/pool/src/tests/repay.rs (2)
contracts/pool/src/types/price_provider.rs (1)
  • new (22-30)
contracts/pool/src/tests/sut.rs (2)
  • debt_token (590-592)
  • debt_token (614-616)
contracts/pool/src/tests/liquidate.rs (1)
contracts/pool/src/types/price_provider.rs (1)
  • new (22-30)
contracts/pool/src/tests/deposit.rs (1)
contracts/pool/src/types/price_provider.rs (1)
  • new (22-30)
contracts/pool/src/methods/flash_loan.rs (2)
contracts/pool/src/methods/utils/validation.rs (1)
  • require_not_in_grace_period (160-167)
contracts/pool/src/storage.rs (6)
  • read_reserve (54-61)
  • read_token_balance (197-210)
  • read_token_total_supply (175-180)
  • add_protocol_fee_vault (248-257)
  • read_pause_info (139-150)
  • read_pool_config (267-274)
contracts/debt-token/src/lib.rs (1)
contracts/common-token/src/storage.rs (1)
  • write_metadata (135-138)
contracts/s-token/src/tests/test.rs (1)
contracts/debt-token/src/test.rs (1)
  • create_token (11-30)
deploy/scripts/upgrade.sh (1)
deploy/scripts/deploy.sh (1)
  • install (18-26)
contracts/pool/src/tests/flash_loan.rs (1)
contracts/pool/src/types/price_provider.rs (1)
  • new (22-30)
contracts/pool/src/methods/repay.rs (1)
contracts/pool/src/storage.rs (8)
  • read_token_balance (197-210)
  • read_token_total_supply (175-180)
  • write_token_balance (212-229)
  • write_token_total_supply (182-195)
  • add_protocol_fee_vault (248-257)
  • add_token_balance (158-173)
  • read_pause_info (139-150)
  • read_pool_config (267-274)
contracts/pool/src/methods/liquidate.rs (1)
contracts/pool/src/storage.rs (4)
  • add_protocol_fee_vault (248-257)
  • add_token_balance (158-173)
  • read_pause_info (139-150)
  • read_pool_config (267-274)
contracts/pool/src/tests/configure_as_collateral.rs (1)
contracts/pool/src/types/price_provider.rs (1)
  • new (22-30)
contracts/pool/src/methods/set_reserve_status.rs (1)
contracts/pool/src/storage.rs (2)
  • read_reserve (54-61)
  • write_reserve (63-68)
contracts/pool/src/methods/withdraw.rs (3)
contracts/pool/src/methods/utils/get_collat_coeff.rs (3)
  • get_collat_coeff (9-34)
  • get_compounded_amount (36-63)
  • get_lp_amount (66-109)
contracts/pool/src/methods/utils/validation.rs (1)
  • require_gte_initial_health (122-150)
contracts/pool/src/storage.rs (1)
  • read_pause_info (139-150)
contracts/pool/src/tests/sut.rs (1)
contracts/pool/src/tests/budget.rs (1)
  • price_feed (302-311)
🪛 GitHub Actions: Linter and tests
Makefile

[error] 1-1: Command failed: make clippy. The clippy check failed during the CI run.

🪛 actionlint (1.7.7)
.github/workflows/tests.yml

17-17: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (89)
contracts/pool/src/tests/set_as_collateral.rs (2)

219-231: Lifetimes aligned with the new Sut contract

Passing &Env through and returning Sut<'_> keeps the helper consistent with the updated pool scaffolding while preserving the existing test flow. No issues spotted.


234-255: Borrowed Env plumbing looks solid

Chaining through to init(env) and propagating the Sut<'_> lifetime ensures the debt-setup helper stays compatible with the refactored clients without altering behavior. Looks good.

contracts/deployer/src/lib.rs (3)

25-28: Protocol 23 deploy_v2 migration looks correct

Switching to deploy_v2 with the empty metadata payload keeps the deployment semantics aligned with the old deploy call for Protocol 23. No further changes needed here.


48-51: Consistent deploy_v2 usage for s-token

This mirrors the pool deployment update and keeps behavior consistent while adopting the new API. All good.


77-80: Debt-token deploy_v2 update LGTM

The debt-token deployment now matches the new Protocol 23 expectations; no issues spotted.

contracts/pool/src/tests/repay.rs (1)

187-194: Event payload assertion matches the new typed event contract.

The map keys and value conversions line up with the RepayEvent structure, so this test now accurately validates the emitted data.

contracts/s-token/Cargo.toml (1)

6-6: Non-publishable flag aligns with workspace convention.

Marking this contract crate as non-publishable matches the rest of the workspace and avoids accidental publishes. Looks good.

contracts/pool/Cargo.toml (1)

6-6: Non-publishable flag looks good.

Consistent with the other contract crates—no issues spotted.

contracts/common/Cargo.toml (1)

6-10: Workspace dependency + publish flag are correct.

Disabling publishing and drawing soroban-fixed-point-math from the workspace are both in line with the migration plan.

deploy/scripts/deploy.sh (1)

4-4: Artifact path update matches the new target triple.

The deploy script now points at the wasm32v1-none output directory, so deployments will pick up the freshly built artifacts. Looks correct.

contracts/common-token/Cargo.toml (1)

6-6: Non-publishable flag is consistent.

Mirrors the other contract crates—no concerns here.

Makefile (2)

19-21: Build step matches the wasm32v1-none rollout.

Switching both the build target and artifact listing to the new triple keeps the tooling consistent. All good.


39-40: Check target update looks good.

cargo check now runs against wasm32v1-none, aligning with the rest of the build. No issues spotted.

contracts/debt-token/Cargo.toml (1)

6-6: Non-publishable flag confirmed.

Matches the broader policy for contract crates—looks good.

Cargo.toml (1)

35-39: SDK upgrade to 23.0.2 looks good.

Matches Protocol 23 migration; no issues spotted.

contracts/deployer/src/test.rs (5)

11-20: WASM imports updated to wasm32v1-none are correct.

Imports align with the new target; good.


25-25: New registration API usage LGTM.

env.register(Deployer, ()) is the correct Protocol 23 pattern.


64-64: Budget reset path migrated correctly.

env.cost_estimate().budget().reset_default() aligns with the new API.


70-72: Asset registration v2 usage LGTM.

register_stellar_asset_contract_v2(...).address() is the right flow.


95-95: Consistent budget reset after deployments.

No issues.

contracts/debt-token/src/event.rs (5)

1-12: Typed events for initialize look correct.

Topics and map data are appropriate for Protocol 23.


14-19: SetAuthorizedEvent definition LGTM.

Single-value payload with topic id is correct.


21-29: MintEvent definition LGTM.

Admin and to as topics; amount as data matches single-value format.


30-36: BurnEvent definition LGTM.


37-43: ClawbackEvent definition LGTM.

contracts/debt-token/src/lib.rs (7)

11-12: Event imports are correct.

Matches the new typed events module.


53-59: Decimals propagation LGTM.

Reads decimals from underlying and stores in metadata correctly.


64-72: InitializedEvent publish LGTM.

Fields align with event definition.


155-156: BurnEvent publish LGTM.


178-179: SetAuthorizedEvent publish LGTM.


199-205: MintEvent publish LGTM.

Includes admin topic from verified pool.


226-227: ClawbackEvent publish LGTM.

contracts/pool/src/tests/flash_loan.rs (2)

5-5: Added Map/Val imports for structured event payloads LGTM.


220-227: Event assertion migrated to Map payload correctly.

Keys and values match the new event format.

Please confirm the event struct in pool emits these keys ("amount", "premium", "borrow") to keep tests stable.

contracts/pool/src/tests/deposit.rs (2)

5-5: Added Map/Val imports LGTM.


240-251: Deposit event assertion migrated to Map payload correctly.

Matches the new typed event structure.

contracts/pool/src/methods/repay.rs (2)

8-8: Import correctly updated for typed event system.

The import change from generic event module to RepayEvent struct aligns with Protocol 23's migration to typed contract events.


172-177: Event emission properly migrated to structured format.

The transition from direct event function calls to structured event publication using .publish(env) is consistent with Protocol 23's typed contract event system. The RepayEvent struct maintains the same event parameters (who, asset, amount) while providing type safety and better tooling support.

contracts/pool/src/types/user_configurator.rs (2)

5-5: Event imports aligned with typed event system.

The import of ReserveUsedAsCollDisabledEvent and ReserveUsedAsCollEnabledEvent follows the consistent pattern of migrating to structured event types across the codebase.


50-54: Structured event emission implemented correctly.

Both withdraw and deposit methods properly emit typed events with appropriate parameters. The structured approach improves type safety and maintains consistent event schemas.

Also applies to: 78-82

contracts/pool/src/tests/borrow.rs (2)

5-5: Test imports updated for structured event data.

The addition of Map and Val imports supports the new Map-based event payload format that accompanies the structured event system.


372-379: Test payload structure updated for typed events.

The test now expects a Map-based payload structure instead of a flat tuple, reflecting the structured event format introduced in Protocol 23. This change ensures tests remain compatible with the new event emission system while maintaining the same validation logic.

contracts/pool/src/tests/init_reserve.rs (1)

86-86: Contract registration updated to new SDK API.

The change from register_contract(None, LendingPool) to register(LendingPool {}, ()) aligns with Protocol 23's updated contract registration API. This reflects broader test infrastructure changes to support the new environment setup.

contracts/pool/src/tests/rounding.rs (1)

25-25: Budget access API updated correctly.

The migration from env.budget().reset_unlimited() to env.cost_estimate().budget().reset_unlimited() follows the updated Soroban SDK budget access pattern. This change maintains the same functionality while using the new API structure.

Also applies to: 91-91

integration-tests/tests/pool.sut.ts (1)

543-543: WASM target path updated for Protocol 23.

The path change from wasm32-unknown-unknown to wasm32v1-none target aligns with Protocol 23's updated WASM target requirements. This ensures compatibility with the new runtime environment.

contracts/pool/src/methods/borrow.rs (2)

10-10: Event import migrated to typed system.

The import change to BorrowEvent from the generic event module is consistent with the Protocol 23 structured event pattern.


162-167: Borrow event emission properly structured.

The event emission follows the same pattern as other pool methods, using structured BorrowEvent with .publish(env). This maintains event data integrity while improving type safety.

contracts/pool/src/methods/withdraw.rs (2)

2-2: Imports correctly updated for Protocol 23.

The addition of WithdrawEvent import and read_pause_info aligns with the structured event system and provides necessary functionality for the withdraw operation.

Also applies to: 6-6


205-211: Withdraw event properly structured.

The WithdrawEvent emission includes all relevant parameters (who, asset, to, amount) and follows the consistent structured pattern across pool methods. The event maintains full traceability of withdrawal operations.

contracts/pool/src/tests/liquidate.rs (2)

7-7: Event test payload migration correctly updated

The import addition of Map and Val from soroban_sdk is appropriate for the new contract event structure. Protocol 23 introduces unified event streams between Classic operations and Soroban contracts, with events now supporting map-based data fields.


794-807: Event payload structure correctly adapted to Protocol 23 format

The test properly constructs the event payload using Map::<Symbol, Val>::from_array() with structured keys "covered_debt" and "liquidated_collateral". This aligns with the new typed contract event system where events are emitted as structured data rather than simple tuples. The change correctly reflects the migration from function-based event emission to structured contract events.

contracts/pool/src/methods/configure_as_collateral.rs (2)

5-5: Correct import for typed contract events

The import change from generic event module to CollatConfigChangeEvent struct is appropriate for the Protocol 23 migration to typed contract events.


26-33: Proper migration to typed contract event publishing

The refactoring correctly replaces direct event function calls with structured event construction and publishing. The CollatConfigChangeEvent struct properly captures all relevant parameters (asset, liq_cap, pen_order, util_cap, discount) and uses the new .publish(env) pattern consistent with Protocol 23 event system changes.

contracts/pool/src/methods/set_reserve_status.rs (2)

4-7: Correctly updated imports for typed events

The import restructuring properly imports ReserveStatusChangedEvent for the new contract event system while maintaining necessary storage functions.


19-23: Proper event publishing migration

The code correctly constructs ReserveStatusChangedEvent with asset and activated fields and publishes it using .publish(env). This follows the Protocol 23 pattern of typed contract events rather than direct function-based event emissions.

contracts/debt-token/src/test.rs (2)

14-14: Contract registration updated to new API

The migration from register_contract(None, DebtToken {}) to register(DebtToken {}, ()) follows the new deployment API pattern introduced in Protocol 23. This is a correct adaptation to the updated Soroban SDK registration methods.

Also applies to: 38-38


18-20: Stellar asset registration properly migrated to v2 API

The change from older registration patterns to register_stellar_asset_contract_v2() with .address() extraction correctly adapts to the new Protocol 23 asset contract registration API. Protocol 23 introduces support for the new wasm32v1-none target and updated contract deployment APIs.

Also applies to: 42-44

contracts/pool/src/methods/liquidate.rs (2)

9-9: Import correctly updated for typed events

The addition of LiquidationEvent import is appropriate for the Protocol 23 event system migration.


60-65: Event emission properly migrated to structured format

The liquidation event is correctly constructed using LiquidationEvent struct with who, covered_debt, and liquidated_collateral fields, then published via .publish(env). This properly replaces the previous function-based event emission with the new typed contract event system required by Protocol 23.

contracts/pool/src/methods/deposit.rs (2)

9-9: Correct event import for Protocol 23

The import of DepositEvent replaces the previous generic event module usage, properly adapting to the typed contract event system.


73-78: Deposit event migration correctly implemented

The code properly constructs DepositEvent with who, asset, and amount fields and publishes it using .publish(env). This correctly replaces the previous direct event function call pattern with the new structured event approach required by Protocol 23.

contracts/pool/src/tests/set_reserve_status.rs (1)

84-84: Event payload format correctly updated for Protocol 23

The test expectations are properly updated to include the event topic as a tuple (Symbol::new(&env, "reserve_status_changed"), asset) rather than just the asset. This aligns with the new structured contract event format where topics are explicitly defined in the event payload. The change is consistent across both test assertions.

Also applies to: 100-100

contracts/pool/src/methods/flash_loan.rs (2)

8-8: Flash loan event import correctly added

The import of FlashLoanEvent follows the Protocol 23 pattern for typed contract events.


123-131: Flash loan event properly migrated to structured format

The FlashLoanEvent is correctly constructed with all necessary fields (who, receiver, asset, amount, premium, borrow) and published using .publish(env). The event captures all the relevant flash loan parameters and follows the new Protocol 23 typed event pattern.

contracts/pool/src/tests/configure_as_collateral.rs (1)

7-7: Import additions look correct.

Including Map and Val aligns with the new Map-based event payloads in tests.

contracts/pool/src/methods/enable_borrowing_on_reserve.rs (1)

4-4: Typed event imports LGTM.

Matches the migration to struct-based events with .publish(env).

contracts/pool/src/methods/initialize.rs (1)

5-5: Import switch to InitializedEvent LGTM.

contracts/pool/src/tests/withdraw.rs (1)

5-5: Import additions LGTM.

Map and Val are consistent with the new event payload format.

contracts/pool/src/tests/sut.rs (3)

21-40: Target switch to wasm32v1-none paths LGTM; verify CI artifact paths.

The new contractimport! file paths look consistent. Ensure your build produces artifacts under target/wasm32v1-none/release in CI.


48-53: Migration to register/register_stellar_asset_contract_v2 LGTM.

  • Using address() for TokenClient/TokenAdminClient is correct.
  • e.register(...) usage for pool/s-token/debt-token/price-feed/flash-loan-receiver aligns with the new APIs.

Also applies to: 63-66, 100-101, 117-117, 130-130, 134-134


138-138: Budget API change—confirm intended semantics.

env.cost_estimate().budget().reset_unlimited() differs from the old env.budget().reset_unlimited(). Confirm this is the desired mechanism for unbounded execution in tests under Protocol 23.

contracts/s-token/src/lib.rs (7)

75-83: Event migration looks correct for initialize()

InitializedEvent fields and publish site match storage writes and underlying token decimals.


130-139: ApproveEvent emission aligns with new storage write

Topics and payload are coherent; no behavior change.


249-254: ClawbackEvent emission matches state mutation

Event mirrors spend_balance and total_supply decrement.


272-273: SetAuthorizedEvent publish looks good

Event carries id and authorize; consistent with write_authorization.


292-298: MintEvent uses pool as admin — good

Correctly captures caller pool and minted amount.


319-324: BurnEvent mirrors burn amount

Event corresponds to SToken burn path; OK.


458-464: TransferEvent emission in do_transfer() is correct

Published after state updates and optional finalize_transfer; good placement.

contracts/s-token/src/event.rs (3)

13-20: Single-value format for TransferEvent is appropriate

Two topics (from, to) with a single data field (amount) keeps events compact.


52-61: InitializedEvent payload looks consistent

Topics (underlying_asset, pool) and map fields (decimals, name, symbol) are aligned with initialize().


1-11: No changes needed for contractevent data_format
The data_format = "map" option is valid (and the default) in the pinned Soroban SDK.

contracts/s-token/src/tests/test.rs (3)

18-27: WASM imports updated to wasm32v1-none — good

Paths and targets match Protocol 23 expectations for tests.


40-46: Switch to register/register_stellar_asset_contract_v2 is correct

Constructing clients from returned addresses is the new pattern; looks good.

If CI builds only the s-token crate, ensure workspace-level build includes pool, debt_token, and oracle so their WASM artifacts exist at ../../target/wasm32v1-none/release.


71-73: Budget reset via cost_estimate() is correct

Matches updated API.

contracts/pool/src/event.rs (5)

3-22: Pool InitializedEvent fields cover prior config fully

Topics and data fields mirror initialize() inputs; good migration.


24-36: reserve_used_as_coll_ events are compact and clear*

Single-value format with who as topic is sensible.


38-69: Deposit/Borrow/Repay events use map — consistent

Fields and types align with expected semantics.


71-80: CollatConfigChangeEvent covers all parameters

Naming and types match config fields.


108-119: FlashLoanEvent includes who, receiver, asset as topics — good for filtering

Payload captures amount, premium, borrow flag. Looks correct.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96538ce and bcd8ebf.

⛔ Files ignored due to path filters (2)
  • contracts/pool/src/tests/snapshots/budget_utilization.snap is excluded by !**/*.snap
  • integration-tests/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • README.md (1 hunks)
  • integration-tests/package.json (1 hunks)
  • integration-tests/tests/pool.sut.ts (8 hunks)
  • integration-tests/tests/pool/7.liquidate.budget.spec.ts (1 hunks)
  • integration-tests/tests/soroban.client.ts (4 hunks)
  • integration-tests/tests/soroban.config.ts (1 hunks)
  • integration-tests/tests/soroban.converter.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • integration-tests/tests/soroban.config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • integration-tests/tests/pool.sut.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (3)
integration-tests/tests/pool/7.liquidate.budget.spec.ts (1)

1-1: Scoped SDK import looks good

The switch to the scoped @stellar/stellar-sdk import keeps the test suite aligned with the new dependency layout. Nicely done.

integration-tests/tests/soroban.converter.ts (1)

1-1: Converter now points at the scoped SDK

Importing Address and xdr from @stellar/stellar-sdk matches the package update. All good here.

integration-tests/tests/soroban.client.ts (1)

1-132: RPC migration looks consistent

The client now relies on the rpc namespace throughout, and the simulation/assemble flow matches the Protocol 23 SDK. Looks solid.

Comment on lines 16 to 29
"@types/chai": "^5.2.2",
"@types/chai-as-promised": "^8.0.2",
"@types/mocha": "^10.0.10",
"@types/node": "^24.5.2",
"@stellar/stellar-sdk": "14.2.0",
"bigint-conversion": "^2.4.3",
"bignumber.js": "^9.3.1",
"chai": "^6.0.1",
"chai-as-promised": "^8.0.2",
"cross-env": "^10.0.0",
"dotenv": "^17.2.2",
"mocha": "^11.7.2",
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix SDK version to a published release

@stellar/[email protected] hasn’t been published, so installs will fail and the integration tests can’t run. Please pin to the latest available release (14.1.1 today) or whichever version is actually published before merging.

-    "@stellar/stellar-sdk": "14.2.0",
+    "@stellar/stellar-sdk": "14.1.1",

Based on learnings.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@types/chai": "^5.2.2",
"@types/chai-as-promised": "^8.0.2",
"@types/mocha": "^10.0.10",
"@types/node": "^24.5.2",
"@stellar/stellar-sdk": "14.2.0",
"bigint-conversion": "^2.4.3",
"bignumber.js": "^9.3.1",
"chai": "^6.0.1",
"chai-as-promised": "^8.0.2",
"cross-env": "^10.0.0",
"dotenv": "^17.2.2",
"mocha": "^11.7.2",
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
"@types/chai": "^5.2.2",
"@types/chai-as-promised": "^8.0.2",
"@types/mocha": "^10.0.10",
"@types/node": "^24.5.2",
"@stellar/stellar-sdk": "14.1.1",
"bigint-conversion": "^2.4.3",
"bignumber.js": "^9.3.1",
"chai": "^6.0.1",
"chai-as-promised": "^8.0.2",
"cross-env": "^10.0.0",
"dotenv": "^17.2.2",
"mocha": "^11.7.2",
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
🤖 Prompt for AI Agents
In integration-tests/package.json around lines 16 to 29, the dependency
@stellar/stellar-sdk is set to 14.2.0 which is not published and breaks
installs; update the package.json to pin @stellar/stellar-sdk to a published
release (e.g., "14.1.1") or any currently published version, run npm install (or
yarn) to verify resolution, and update package-lock.json/yarn.lock accordingly
before committing.

Comment on lines 29 to 33
To run the tests you need to install **soroban-cli** version 20.0.2

```shell
cargo install --locked --version 20.1.1 soroban-cli --features opt
cargo install --locked stellar-cli@23.1.3 --features opt
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix CLI name/version inconsistency

Line 29 still tells readers to install soroban-cli 20.0.2, but the command below now installs [email protected]. This contradicts itself and will confuse anyone following the setup steps. Please align the prose with the actual command.

-To run the tests you need to install **soroban-cli** version 20.0.2
+To run the tests you need to install **stellar-cli** version 23.1.3
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
To run the tests you need to install **soroban-cli** version 20.0.2
```shell
cargo install --locked --version 20.1.1 soroban-cli --features opt
cargo install --locked [email protected] --features opt
```
To run the tests you need to install **stellar-cli** version 23.1.3
🤖 Prompt for AI Agents
In README.md around lines 29 to 33, the text says to install soroban-cli version
20.0.2 but the command installs [email protected]; update the prose to match
the actual install command (or alternatively change the command to install
[email protected] if that was intended). Ensure the line clearly states the
correct CLI name and version that the subsequent shell command will install and
keep the version number consistent between the sentence and the command.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
integration-tests/tests/soroban.converter.ts (2)

70-75: Guard TransactionMeta version; unguarded meta.v4() can throw on non‑v4 transactions.

On networks/artifacts not yet at the targeted protocol, meta.v4() will raise. Recommend handling v4 with a safe fallback to v3 (and a clear error otherwise).

Apply:

-export function parseMetaXdrToJs<T>(meta: xdr.TransactionMeta): T {
-    const value = meta.v4()
-        .sorobanMeta()
-        .returnValue();
-
-    return parseScvToJs(value);
-}
+export function parseMetaXdrToJs<T>(meta: xdr.TransactionMeta): T {
+    // Be resilient to v3/v4 TransactionMeta during protocol transitions.
+    let value: xdr.ScVal;
+    try {
+        value = (meta as any).v4().sorobanMeta().returnValue();
+    } catch {
+        try {
+            value = (meta as any).v3().sorobanMeta().returnValue();
+        } catch {
+            throw new Error(`Unsupported TransactionMeta arm: ${(meta.switch() as any)?.name}`);
+        }
+    }
+    return parseScvToJs(value);
+}

If you prefer strict typing, switch on meta.switch() against the sdk’s TransactionMetaType enum for v4/v3 instead of try/catch (names vary slightly across sdk gens—verify in your installed version).


46-49: Bug: convertToScvU128 uses Int64 for the high part (should be Uint64).

xdr.UInt128Parts.hi expects an unsigned 64‑bit integer. Using xdr.Int64 can corrupt values ≥ 2^63.

Apply:

 export function convertToScvU128(value: bigint): xdr.ScVal {
     return xdr.ScVal.scvU128(new xdr.UInt128Parts({
         lo: xdr.Uint64.fromString((value & BigInt(0xFFFFFFFFFFFFFFFFn)).toString()),
-        hi: xdr.Int64.fromString(((value >> BigInt(64)) & BigInt(0xFFFFFFFFFFFFFFFFn)).toString()),
+        hi: xdr.Uint64.fromString(((value >> BigInt(64)) & BigInt(0xFFFFFFFFFFFFFFFFn)).toString()),
     }))
 }
integration-tests/tests/pool.sut.ts (1)

211-257: Default asset_decimals for XRP/USDC should be 9 (not 7).

Fallbacks of 7 will misconfigure price feed decimals if env vars are absent, diverging from token initialization (XRP/USDC are set to 9 elsewhere). Use 9 as defaults.

Apply:

         {
             asset: "XRP",
-            asset_decimals: +(process.env['XRP_DECIMALS'] ?? 7),
+            asset_decimals: +(process.env['XRP_DECIMALS'] ?? 9),
             ...
         },
         {
             asset: "USDC",
-            asset_decimals: +(process.env['USDC_DECIMALS'] ?? 7),
+            asset_decimals: +(process.env['USDC_DECIMALS'] ?? 9),
             ...
         },
🧹 Nitpick comments (5)
Makefile (1)

39-39: Align check target with configurable triple; consider dropping --release for speed.

Use the same $(WASM_TARGET). Release opts don’t affect cargo check and slow CI.

-check:
-	cargo check --target wasm32v1-none --release
+check:
+	cargo check --target $(WASM_TARGET)

CI tip: update any cache keys/paths from target/wasm32-unknown-unknown to target/$(WASM_TARGET) to avoid cache misses.

integration-tests/tests/soroban.converter.ts (1)

56-58: Avoid 53‑bit loss constructing U64 from a JS number.

new xdr.Uint64(value) risks precision loss for values > 2^53‑1. Prefer string‑based ctor.

Apply:

 export function convertToScvU64(value: number): xdr.ScVal {
-    return xdr.ScVal.scvU64(new xdr.Uint64(value));
+    return xdr.ScVal.scvU64(xdr.Uint64.fromString(String(value)));
 }
integration-tests/tests/pool/1.borrower.spec.ts (3)

250-263: Assert the intended invariant explicitly (pool accounting vs ledger).

To make the intent unambiguous, assert that the token ledger at the sToken contract address equals pool sToken balance + protocol fee.

Apply in-place:

         assert.equal(sXlmBalance + protocolFeeXlmBalance, 10_000_000n);
         assert.equal(sXlmTokenBalance, 10_000_000n);
+        assert.equal(sXlmTokenBalance, sXlmBalance + protocolFeeXlmBalance);

271-283: Mirror the invariant check from Case 7 for full repay.

Optional: also fetch sXLM token ledger and assert equality with pool accounting + protocol fee, like in Case 7.

Example:

         const borrower1DXlmBalance = await debtTokenBalanceOf(client, "XLM", borrower1Address);
         const sXlmBalance = await sTokenUnderlyingBalanceOf(client, "XLM");
+        const sXlmTokenBalance = await tokenBalanceOf(client, "XLM", process.env.SLENDER_S_TOKEN_XLM);
         const dXlmSupply = await debtTokenTotalSupply(client, "XLM");

         assert(borrower1XlmBalance < 10_000_000n
             && borrower1XlmBalance > 9_990_000n);
         assert(protocolFeeXlmBalance > 0 && protocolFeeXlmBalance < 1_000n);
         assert.equal(borrower1DXlmBalance, 0n);
         assert(sXlmBalance + protocolFeeXlmBalance > 90_000_000n
             && sXlmBalance + protocolFeeXlmBalance < 90_010_000n);
+        assert.equal(sXlmTokenBalance, sXlmBalance + protocolFeeXlmBalance);

291-304: Do the same invariant check for XRP for completeness.

Optional: verify ledger vs pool+protocolFee equality for XRP as well.

Example:

         const borrower2DXrpBalance = await debtTokenBalanceOf(client, "XRP", borrower2Address);
         const sXrpBalance = await sTokenUnderlyingBalanceOf(client, "XRP");
+        const sXrpTokenBalance = await tokenBalanceOf(client, "XRP", process.env.SLENDER_S_TOKEN_XRP);
         const dXrpSupply = await debtTokenTotalSupply(client, "XRP");

         assert(borrower2XrpBalance < 1_000_000_000n
             && borrower2XrpBalance > 999_000_000n);
         assert(protocolFeeXrpBalance > 0 && protocolFeeXrpBalance < 100_000n);
         assert.equal(borrower2DXrpBalance, 0n);
         assert(sXrpBalance + protocolFeeXrpBalance > 9_000_000_000n
             && sXrpBalance + protocolFeeXrpBalance < 9_001_000_000n);
+        assert.equal(sXrpTokenBalance, sXrpBalance + protocolFeeXrpBalance);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcd8ebf and b437486.

⛔ Files ignored due to path filters (9)
  • deploy/artifacts/testnet/contract-bindings.zip is excluded by !**/*.zip
  • deploy/artifacts/testnet/debt_token.wasm is excluded by !**/*.wasm
  • deploy/artifacts/testnet/deployer.wasm is excluded by !**/*.wasm
  • deploy/artifacts/testnet/flash_loan_receiver_mock.wasm is excluded by !**/*.wasm
  • deploy/artifacts/testnet/pool.wasm is excluded by !**/*.wasm
  • deploy/artifacts/testnet/price_feed_mock.wasm is excluded by !**/*.wasm
  • deploy/artifacts/testnet/s_token.wasm is excluded by !**/*.wasm
  • deploy/artifacts/testnet/token.wasm is excluded by !**/*.wasm
  • integration-tests/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • Makefile (2 hunks)
  • deploy/artifacts/testnet/.contracts (1 hunks)
  • deploy/scripts/deploy.sh (2 hunks)
  • integration-tests/package.json (1 hunks)
  • integration-tests/tests/pool.sut.ts (10 hunks)
  • integration-tests/tests/pool/1.borrower.spec.ts (5 hunks)
  • integration-tests/tests/soroban.converter.ts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • integration-tests/package.json
🧰 Additional context used
🧬 Code graph analysis (2)
integration-tests/tests/pool/1.borrower.spec.ts (1)
integration-tests/tests/pool.sut.ts (5)
  • tokenBalanceOf (308-320)
  • debtTokenBalanceOf (294-306)
  • sTokenUnderlyingBalanceOf (352-364)
  • protocolFee (366-377)
  • debtTokenTotalSupply (391-401)
integration-tests/tests/pool.sut.ts (2)
integration-tests/tests/soroban.client.ts (1)
  • SorobanClient (19-132)
integration-tests/tests/soroban.converter.ts (5)
  • convertToScvAddress (9-12)
  • parseScvToJs (77-156)
  • convertToScvU32 (52-54)
  • convertToScvU64 (56-58)
  • convertToScvI128 (38-43)
🪛 Gitleaks (8.28.0)
deploy/scripts/deploy.sh

[high] 4-4: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 20-20: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

deploy/artifacts/testnet/.contracts

[high] 1-1: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 2-2: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 4-4: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 5-5: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 6-6: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 16-16: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 17-17: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 18-18: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 19-19: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 20-20: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 21-21: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (9)
deploy/scripts/deploy.sh (2)

4-4: Align build path with wasm32v1-none artifacts

Pointing BUILD at target/wasm32v1-none/release matches the output location produced by the Protocol 23 stellar contract build, so the later copy/optimize steps still pick up the compiled WASM.(developers.stellar.org)


20-24: Adopt the non-deprecated WASM upload command

Switching to stellar contract upload keeps the script current with the CLI (the old install subcommand is now deprecated) and ensures the function continues to return the WASM hash expected by downstream steps.(developers.stellar.org)

deploy/artifacts/testnet/.contracts (1)

1-21: Contract/account IDs flagged as secrets are expected. The values beginning with C and G are Soroban contract IDs and Stellar public account IDs respectively; they are intended to be public and don't expose secret material, so the Gitleaks alerts here are false positives.(stellar.github.io)

Makefile (1)

19-20: Make Wasm target configurable and artifact listing robust

  • Introduce WASM_TARGET ?= wasm32v1-none at the top for easy overrides.
  • Replace brittle ls on a glob with a find … -exec to avoid failures when no artifacts exist.

Apply:

WASM_TARGET ?= wasm32v1-none

build:
-	cargo build --target wasm32v1-none --release
-	@ls -l target/wasm32v1-none/release/*.wasm
+	cargo build --target $(WASM_TARGET) --release
+	@find target/$(WASM_TARGET)/release -maxdepth 1 -name '*.wasm' -exec ls -l {} + 2>/dev/null || true

Manually verify that the $(WASM_TARGET) Rust target is installed (e.g., via rustup target list) since rustup/rustc weren’t available during automated verification.

integration-tests/tests/soroban.converter.ts (1)

1-1: Verify imports, dependency versions, and Node.js engine requirements

  • Confirm no remaining stellar-sdk imports in the repo.
  • Ensure @stellar/stellar-sdk and @stellar/stellar-base are both declared at v14.x in package.json.
  • Verify CI and runtime are configured to use Node.js ≥ 20 (required by SDK v14.x).
integration-tests/tests/pool/1.borrower.spec.ts (1)

460-463: LGTM: full RWA withdraw assertions are precise.

The after/before deltas and zeroed in‑pool checks are clear and correct.

integration-tests/tests/pool.sut.ts (3)

366-377: New protocolFee() helper looks good; ensure method name matches contract spec.

Interface aligns with other simulate helpers; just confirm pool method is exactly "protocol_fee".


552-559: WASM target path updated — verify build artifact exists.

Ensure CI/build produces ../target/wasm32v1-none/release/flash_loan_receiver_mock.wasm before deploy step.


704-714: Budget snapshot fields: confirm cost/readBytes under Protocol 23 SDK.

  • simulation["cost"]: confirm property path (might be simulation.cost).
  • resources.diskReadBytes(): verify renamed method exists; otherwise fall back to resources.readBytes().

Example defensive tweak if needed:

-                        cost: transactionResult.simulation["cost"],
+                        cost: (transactionResult.simulation as any).cost ?? transactionResult.simulation["cost"],
-                        readBytes: resources.diskReadBytes(),
+                        readBytes: (resources as any).diskReadBytes ? resources.diskReadBytes() : resources.readBytes(),

@@ -1,4 +1,4 @@
import { Keypair, xdr } from "stellar-sdk";
import { Keypair, xdr } from "@stellar/stellar-sdk";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

SDK bump requires Node 20 and base XDR alignment — verify CI/runtime.

Upgrading to @stellar/stellar-sdk v14.x implies Node >= 20 and matching @stellar/stellar-base to avoid XDR mismatches. Please confirm CI and package versions are aligned.

Based on learnings

Run:


🏁 Script executed:

#!/bin/bash
set -e

echo "== Node versions in workflows =="
fd -a .github/workflows 2>/dev/null | xargs -I {} rg -n "setup-node|node-version" {} || true

echo "== Declared SDK/base versions =="
fd -a package.json 2>/dev/null | while read f; do
  echo ":: $f"
  jq -r '{
    sdk: (.dependencies["@stellar/stellar-sdk"] // .devDependencies["@stellar/stellar-sdk"]),
    base: (.dependencies["@stellar/stellar-base"] // .devDependencies["@stellar/stellar-base"]),
    engines: .engines?
  }' "$f"
done

Length of output: 175


Require Node ≥20 in CI and pin matching stellar-base version
integration-tests/package.json uses @stellar/[email protected] without specifying @stellar/stellar-base or a Node engine, and CI workflows don’t pin node-version. To prevent runtime and XDR mismatches, add "engines": { "node": ">=20" } to package.json, pin Node 20.x in your CI workflows, and include @stellar/[email protected] in dependencies.

🤖 Prompt for AI Agents
In integration-tests/tests/pool.sut.ts around lines 1 to 1: CI and package setup
can cause runtime/XDR mismatches because package.json doesn’t declare a Node
engine or pin stellar-base; update integration-tests/package.json to include
"engines": { "node": ">=20" } and add "@stellar/stellar-base": "14.2.0" to
dependencies, and update CI workflow files to pin Node to a 20.x version (e.g.,
node-version: '20') so the test environment and
@stellar/stellar-sdk/@stellar/stellar-base versions are consistent.


deploy-contracts:
(cd deploy/artifacts && shopt -s dotglob; rm -rf *)
(cd deploy/artifacts/$(env) && shopt -s dotglob; rm -rf *)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Bash-only shopt under /bin/sh breaks cleanup; also mkdir is missing.

make defaults to /bin/sh; shopt will fail and dotfiles won’t be removed. Ensure the dir exists and use a POSIX-safe deletion.

Apply:

-deploy-contracts:
-	(cd deploy/artifacts/$(env) && shopt -s dotglob; rm -rf *)
+deploy-contracts:
+	@mkdir -p deploy/artifacts/$(env)
+	@(cd deploy/artifacts/$(env) && find . -mindepth 1 -exec rm -rf {} +)
 	./deploy/scripts/deploy.sh $(env)

Optional (outside this hunk): set the shell and validate env.

SHELL := /usr/bin/env bash

ifndef env
  $(error env is not set. Usage: make <target> env=local|testnet|mainnet)
endif
🤖 Prompt for AI Agents
Makefile lines 23: the recipe uses the bash-only "shopt -s dotglob" which will
fail under /bin/sh and also doesn't ensure the target directory exists or create
it before deletion; replace the bash-specific construct with POSIX-safe
commands: ensure the target directory exists with mkdir -p
deploy/artifacts/$(env) and then remove its contents with a POSIX-safe rm -rf
deploy/artifacts/$(env)/* deploy/artifacts/$(env)/.[!.]*
deploy/artifacts/$(env)/..?* (or simply rm -rf deploy/artifacts/$(env)/*
deploy/artifacts/$(env)/.[!.]* deploy/artifacts/$(env)/..?* to avoid deleting
the directory itself), and avoid shopt entirely; optionally, outside this hunk
add a SHELL := /usr/bin/env bash and an env existence check as suggested if you
intentionally require bash.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
deploy/scripts/upgrade.sh (1)

25-30: Command change to "upload" looks correct, but improve error handling.

The change from stellar contract install to stellar contract upload correctly aligns with Protocol 23 and matches the implementation in deploy.sh.

However, combining local declaration with command substitution masks the command's exit code. If stellar contract upload fails, the function will still appear to succeed because local always returns 0.

Apply this diff to separate declaration from assignment for proper error propagation:

-    local hash=$(stellar contract upload \
+    local hash
+    hash=$(stellar contract upload \
         --wasm $1 \
         --source $2 \
         --rpc-url "$SOROBAN_RPC_URL" \
         --network-passphrase "$PASSPHRASE")
     echo $hash
contracts/s-token/src/lib.rs (3)

249-253: LGTM! ClawbackEvent properly captures the clawback operation.

The event correctly includes the from address and amount. Minor note: from.clone() at line 250 is redundant since from was already cloned at line 246, but this doesn't affect correctness.

If desired, you can remove the redundant clone:

        ClawbackEvent {
-            from: from.clone(),
+            from,
            amount,
        }
        .publish(&e);

407-412: LGTM! TransferEvent properly logged after underlying asset transfer.

The event correctly captures the transfer of underlying assets from the contract to the recipient. The ordering (transfer action followed by event emission) is correct. Minor note: to.clone() at line 409 is redundant since to was already borrowed at line 405.

If desired, you can remove the redundant clone:

        TransferEvent {
            from: current_address,
-            to: to.clone(),
+            to,
            amount,
        }
        .publish(&e);

458-463: LGTM! TransferEvent properly logged in core transfer logic.

The event correctly captures the transfer details after balance updates and validation are complete. Minor note: both from.clone() and to.clone() are redundant since these addresses were already cloned earlier in the function (lines 437-438, 440-441).

If desired, you can remove the redundant clones:

    TransferEvent {
-        from: from.clone(),
-        to: to.clone(),
+        from,
+        to,
        amount,
    }
    .publish(e);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b437486 and cf2f257.

⛔ Files ignored due to path filters (8)
  • deploy/artifacts/mainnet/debt_token.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/debt_token_optimized.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/deployer.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/flash_loan_receiver_mock.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/pool.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/pool_optimized.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/price_feed_mock.wasm is excluded by !**/*.wasm
  • deploy/artifacts/mainnet/s_token_optimized.wasm is excluded by !**/*.wasm
📒 Files selected for processing (6)
  • contracts/debt-token/src/lib.rs (7 hunks)
  • contracts/pool/src/lib.rs (1 hunks)
  • contracts/s-token/src/lib.rs (10 hunks)
  • deploy/artifacts/mainnet/.contracts (1 hunks)
  • deploy/scripts/upgrade.sh (1 hunks)
  • integration-tests/tests/pool/1.borrower.spec.ts (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • contracts/debt-token/src/lib.rs
🧰 Additional context used
🧬 Code graph analysis (3)
deploy/scripts/upgrade.sh (1)
deploy/scripts/deploy.sh (1)
  • install (18-26)
integration-tests/tests/pool/1.borrower.spec.ts (1)
integration-tests/tests/pool.sut.ts (5)
  • tokenBalanceOf (308-320)
  • debtTokenBalanceOf (294-306)
  • sTokenUnderlyingBalanceOf (352-364)
  • protocolFee (366-377)
  • debtTokenTotalSupply (391-401)
contracts/s-token/src/lib.rs (1)
contracts/s-token/src/storage.rs (1)
  • e (47-47)
🪛 Shellcheck (0.11.0)
deploy/scripts/upgrade.sh

[warning] 25-25: Declare and assign separately to avoid masking return values.

(SC2155)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (15)
deploy/artifacts/mainnet/.contracts (1)

4-8: Approve updated contract hashes
SLENDER_S_TOKEN_HASH, SLENDER_DEBT_TOKEN_HASH, and SLENDER_POOL_HASH have been updated to correctly formatted 256-bit hex values consistent with Protocol 23 redeployment. No residual references to previous hashes remain in the codebase. Please confirm these values match the actual deployed mainnet contracts.

contracts/pool/src/lib.rs (1)

55-57: LGTM! Version bump to 2 aligns with Protocol 23 and all version checks and tests now reference the updated version.

deploy/scripts/upgrade.sh (1)

33-33: WASM target path update verified

Makefile, CI workflows, and deploy scripts all reference the new wasm32v1-none target path; no further changes required.

integration-tests/tests/pool/1.borrower.spec.ts (5)

14-14: LGTM! Import changes align with Protocol 23 migration.

The addition of protocolFee import and removal of treasury-related imports correctly reflect the transition from treasury-based to protocol-fee-based accounting.

Also applies to: 26-26


249-262: LGTM! Protocol fee accounting is correctly implemented.

The test properly verifies that:

  • The s-token contract holds the expected total tokens (line 261)
  • The available balance plus protocol fee equals the total repayment (line 260)
  • Protocol fees are being accrued as expected (line 257)

271-282: LGTM! Full repayment verification is correct.

The assertions properly validate that after full repayment:

  • Protocol fees continue to accrue (line 278)
  • Total balance (available + protocol fee) matches the expected repayment amount within the interest accrual range (lines 280-281)
  • Borrower's debt is cleared (line 279)

291-302: LGTM! XRP repayment validation mirrors XLM logic correctly.

The test properly verifies XRP protocol fee accounting with appropriately scaled assertion ranges that match the debt magnitude.


459-462: LGTM! Withdrawal assertions are logically sound.

The updated assertions clearly verify full withdrawal behavior:

  • Balance increases by the withdrawal amount (line 459)
  • In-pool balance is fully depleted (lines 460-461)

Note: There's a typo borrwer1RWABalanceBefore (missing 'o') that exists throughout the file, but it's used consistently.

contracts/s-token/src/lib.rs (7)

4-10: LGTM! Event imports properly structured.

The refactored imports correctly bring in the typed event structs from crate::event alongside the existing storage module, aligning with the Protocol 23 migration pattern.


75-82: LGTM! InitializedEvent properly captures initialization state.

The typed event correctly includes all relevant initialization parameters (underlying_asset, pool, decimals, name, symbol) and uses .publish(&e) to emit the event.


92-92: LGTM! Version bumped for Protocol 23.

The version increment to 2 appropriately reflects the breaking changes introduced by the Protocol 23 event refactor.


132-138: LGTM! ApproveEvent correctly models the approval.

The event properly captures the approval details with to representing the spender, consistent with token standard conventions.


272-272: LGTM! SetAuthorizedEvent properly records authorization changes.

The event correctly captures the id and authorize status in a concise manner.


292-297: LGTM! MintEvent properly captures mint authorization.

The event correctly records the admin (pool), to recipient, and amount, providing a complete audit trail for mint operations.


319-323: LGTM! BurnEvent correctly captures the burn amount.

The event records the from address and the amount_to_burn. Note that amount_to_withdraw is not included in the event, which appears intentional since the event focuses on the burn operation itself rather than the subsequent withdrawal.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
contracts/pool/src/tests/upgrade.rs (2)

28-30: Rename variable to reflect v100 artifact.

The variable pool_v2_wasm references a v100 artifact but retains the old v2 naming, which is misleading.

Apply this diff to improve clarity:

-    let pool_v2_wasm = env.deployer().upload_contract_wasm(pool_v100::WASM);
+    let pool_v100_wasm = env.deployer().upload_contract_wasm(pool_v100::WASM);

-    sut.pool.upgrade(&pool_v2_wasm);
+    sut.pool.upgrade(&pool_v100_wasm);

And update the assertion references:

                    vec![&env, pool_v2_wasm.into_val(&env)]
+                    vec![&env, pool_v100_wasm.into_val(&env)]

56-58: Rename variables to reflect v100 artifacts.

The variables pool_v2_wasm, s_token_v2_wasm, and debt_token_v2_wasm reference v100 artifacts but retain the old v2 naming.

Apply this diff to improve clarity:

-    let pool_v2_wasm = env.deployer().upload_contract_wasm(pool_v100::WASM);
-    let s_token_v2_wasm = env.deployer().upload_contract_wasm(s_token_v100::WASM);
-    let debt_token_v2_wasm = env.deployer().upload_contract_wasm(debt_token_v100::WASM);
+    let pool_v100_wasm = env.deployer().upload_contract_wasm(pool_v100::WASM);
+    let s_token_v100_wasm = env.deployer().upload_contract_wasm(s_token_v100::WASM);
+    let debt_token_v100_wasm = env.deployer().upload_contract_wasm(debt_token_v100::WASM);

And update all usage sites at lines 64-66:

-    sut.pool.upgrade_token(&asset, &true, &s_token_v2_wasm);
-    sut.pool.upgrade_token(&asset, &false, &debt_token_v2_wasm);
-    sut.pool.upgrade(&pool_v2_wasm);
+    sut.pool.upgrade_token(&asset, &true, &s_token_v100_wasm);
+    sut.pool.upgrade_token(&asset, &false, &debt_token_v100_wasm);
+    sut.pool.upgrade(&pool_v100_wasm);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf2f257 and 9353da7.

⛔ Files ignored due to path filters (6)
  • mocks/debt_token_v100_mock.wasm is excluded by !**/*.wasm
  • mocks/debt_token_v2_mock.wasm is excluded by !**/*.wasm
  • mocks/pool_v100_mock.wasm is excluded by !**/*.wasm
  • mocks/pool_v2_mock.wasm is excluded by !**/*.wasm
  • mocks/s_token_v100_mock.wasm is excluded by !**/*.wasm
  • mocks/s_token_v2_mock.wasm is excluded by !**/*.wasm
📒 Files selected for processing (2)
  • contracts/pool/src/tests/budget.rs (5 hunks)
  • contracts/pool/src/tests/upgrade.rs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
contracts/pool/src/tests/budget.rs (4)
contracts/debt-token/src/lib.rs (1)
  • upgrade (84-88)
contracts/pool/src/lib.rs (1)
  • upgrade (42-44)
contracts/s-token/src/lib.rs (1)
  • upgrade (85-89)
interfaces/pool-interface/src/lib.rs (1)
  • upgrade (27-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (7)
contracts/pool/src/tests/upgrade.rs (2)

10-20: LGTM! Mock imports updated to v100.

The module imports have been correctly updated from v2 to v100, with proper paths to the v100 mock WASM files.


72-77: LGTM! Version assertions updated correctly.

The version checks have been properly updated from the old v1/v2 versions (1, 2) to the new Protocol 23 versions (2, 100), consistent with the mock artifact changes.

contracts/pool/src/tests/budget.rs (5)

24-24: LGTM! Import updated to v100.

The import statement has been correctly updated to reference v100 mock artifacts.


647-650: Rename variable to reflect v100 artifact.

The variable pool_v100_wasm is correctly named and the upgrade flow looks good.


662-665: Rename variable to reflect v100 artifact.

The variable s_token_v100_wasm is correctly named and the upgrade flow looks good.


675-681: LGTM! Debt token upgrade flow updated correctly.

The variable naming and upgrade flow are correct, using the v100 artifact.


705-734: LGTM! Budget measurement adapted to Protocol 23 API.

The measure_budget function has been correctly updated to use the new cost_estimate().budget() API:

  • Resets budget to unlimited before the callback
  • Reads CPU and memory costs from the cost estimate after callback execution
  • The approach simplifies budget tracking by removing manual delta calculations

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
integration-tests/tests/pool.sut.ts (1)

1-1: SDK bump already flagged in past review.

The import of @stellar/stellar-sdk v14.2.0 and Node ≥20 requirement was already flagged in the past review comment. Please address that concern.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9353da7 and bc4e5a2.

⛔ Files ignored due to path filters (1)
  • contracts/pool/src/tests/snapshots/budget_utilization.snap is excluded by !**/*.snap
📒 Files selected for processing (2)
  • integration-tests/tests/pool.sut.ts (17 hunks)
  • integration-tests/tests/pool/2.liquidator.spec.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
integration-tests/tests/pool.sut.ts (3)
integration-tests/tests/soroban.client.ts (1)
  • SorobanClient (19-132)
integration-tests/tests/soroban.converter.ts (7)
  • convertToScvAddress (9-12)
  • parseScvToJs (77-156)
  • convertToScvBytes (64-67)
  • convertToScvMap (18-27)
  • convertToScvU32 (52-54)
  • convertToScvU64 (56-58)
  • convertToScvI128 (38-43)
integration-tests/tests/soroban.config.ts (1)
  • adminKeys (8-8)
integration-tests/tests/pool/2.liquidator.spec.ts (2)
integration-tests/tests/pool.sut.ts (7)
  • borrow (403-420)
  • tokenBalanceOf (308-320)
  • debtTokenBalanceOf (294-306)
  • sTokenUnderlyingBalanceOf (352-364)
  • debtTokenTotalSupply (391-401)
  • accountPosition (322-333)
  • liquidate (480-495)
contracts/pool/src/lib.rs (2)
  • borrow (148-150)
  • liquidate (164-166)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (9)
integration-tests/tests/pool.sut.ts (6)

83-83: LGTM: isRelease flag correctly differentiates test vs. release configurations.

The false parameter in the standard init and true in releaseInit align with the conditional logic in initPool and initPoolCollateral, enabling separate test and release configurations.

Also applies to: 100-103, 189-189, 203-205


366-377: LGTM: protocolFee query function correctly added.

The new protocolFee function follows the existing pattern for query functions (using simulateTransaction and parseScvToJs) and correctly queries the pool's protocol_fee method.


480-495: LGTM: liquidate signature correctly simplified.

The removal of the receiveStoken parameter aligns with the updated contract API (liquidate(env: Env, liquidator: Address, who: Address) in contracts/pool/src/lib.rs:163), simplifying the liquidation interface.


554-554: LGTM: WASM target path updated for Protocol 23.

The path change from wasm32-unknown-unknown to wasm32v1-none aligns with Soroban Protocol 23's updated WASM target.


576-606: LGTM: liquidateCli signature correctly simplified.

The removal of the receiveStoken parameter from liquidateCli is consistent with the updated liquidate function and contract API.


702-702: LGTM: Budget snapshot API updated for Protocol 23.

The changes from .cost to ["cost"] and .readBytes() to .diskReadBytes() reflect updated Soroban RPC API in Protocol 23. The bracket notation suggests a schema change in the simulation response.

Also applies to: 707-707

integration-tests/tests/pool/2.liquidator.spec.ts (3)

112-113: LGTM: Test scenario borrow amount adjusted.

The borrow amount change to 89_999_000n is a test scenario adjustment, with corresponding assertion updates in lines 121-130.


121-130: LGTM: Assertions correctly updated for new borrow amount.

All balance and position assertions (XLM balance, debt balance, sXLM balance, dXLM supply, debt/npv ranges) are mathematically consistent with the updated borrow amount of 89_999_000n.


178-178: LGTM: liquidate calls correctly updated to match new signature.

The removal of the false parameter (formerly receiveStoken) aligns with the simplified liquidate function signature in pool.sut.ts:480-495.

Also applies to: 229-229

{
asset: "XLM",
asset_decimals: +process.env['XLM_DECIMALS'] ?? 7,
asset_decimals: +(process.env['XLM_DECIMALS'] ?? 7),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Verify fallback decimal values for XRP and USDC.

All three assets default to 7 decimals when environment variables are missing. However, XRP and USDC typically use 9 decimals (lines 80-81 in test init confirm this). The fallback ?? 7 may cause incorrect decimal handling in release mode if XRP_DECIMALS or USDC_DECIMALS are not set.

Apply this diff to correct the fallbacks:

         asset: "XRP",
-        asset_decimals: +(process.env['XRP_DECIMALS'] ?? 7),
+        asset_decimals: +(process.env['XRP_DECIMALS'] ?? 9),
         max_sanity_price_in_base: BigInt(+process.env['XRP_MAX_SANITY_PRICE_IN_BASE']),
         asset: "USDC",
-        asset_decimals: +(process.env['USDC_DECIMALS'] ?? 7),
+        asset_decimals: +(process.env['USDC_DECIMALS'] ?? 9),
         max_sanity_price_in_base: BigInt(+process.env['USDC_MAX_SANITY_PRICE_IN_BASE']),

Also applies to: 229-229, 244-244

🤖 Prompt for AI Agents
In integration-tests/tests/pool.sut.ts around lines 214, 229, and 244, the
decimal fallbacks incorrectly default XRP and USDC to 7; update the three places
so each asset uses the correct fallback: XLM should default to 7 and both XRP
and USDC should default to 9, and coerce the env value to a number (e.g.,
Number(process.env['XRP_DECIMALS'] ?? 9)) to ensure numeric decimals are used in
tests.

Comment on lines 838 to 902
async function initPool(
client: SorobanClient,
salt: string
salt: string,
isRelease: boolean
): Promise<void> {
await initContract<Array<any>>(
"POOL",
() =>
client.sendTransaction(
process.env.SLENDER_DEPLOYER,
"deploy_pool",
adminKeys,
3,
convertToScvBytes(salt, "hex"),
convertToScvBytes(process.env.SLENDER_POOL_HASH, "hex"),
convertToScvAddress(adminKeys.publicKey()),
convertToScvMap({
base_asset_address: convertToScvAddress(process.env[`SLENDER_TOKEN_${process.env[`BASE_ASSET`] ?? 'XLM'}`]),
base_asset_decimals: convertToScvU32(+process.env['BASE_ASSET_DECIMALS'] ?? 7),
flash_loan_fee: convertToScvU32(+process.env['FLASH_LOAN_FEE_BPS'] ?? 5),
grace_period: convertToScvU64(+process.env['GRACE_PERIOD_SEC'] ?? 1),
initial_health: convertToScvU32(+process.env['INITIAL_HEALTH_BPS'] ?? 2_500),
ir_alpha: convertToScvU32(+process.env['IR_ALPHA'] ?? 143),
ir_initial_rate: convertToScvU32(+process.env['IR_INITIAL_RATE_BPS'] ?? 200),
ir_max_rate: convertToScvU32(+process.env['IR_MAX_RATE_BPS'] ?? 50_000),
ir_scaling_coeff: convertToScvU32(+process.env['IR_SCALING_COEFF_BPS'] ?? 9_000),
liquidation_protocol_fee: convertToScvU32(+process.env['LIQUIDATION_PROTOCOL_FEE_BPS'] ?? 0),
min_collat_amount: convertToScvI128(process.env['MIN_COLLAT_AMOUNT_IN_BASE'] ? BigInt(process.env['MIN_COLLAT_AMOUNT_IN_BASE']) : 1n),
min_debt_amount: convertToScvI128(process.env['MIN_DEBT_AMOUNT_IN_BASE'] ? BigInt(process.env['MIN_DEBT_AMOUNT_IN_BASE']) : 1n),
timestamp_window: convertToScvU64(+process.env['TIMESTAMP_WINDOW_SEC'] ?? 20),
user_assets_limit: convertToScvU32(+process.env['USER_ASSET_LIMIT'] ?? 4),
})
),
() => {
if (isRelease) {
return client.sendTransaction(
process.env.SLENDER_DEPLOYER,
"deploy_pool",
adminKeys,
3,
convertToScvBytes(salt, "hex"),
convertToScvBytes(process.env.SLENDER_POOL_HASH, "hex"),
convertToScvAddress(adminKeys.publicKey()),
convertToScvMap({
base_asset_address: convertToScvAddress(process.env[`SLENDER_TOKEN_${process.env[`BASE_ASSET`]}`]),
base_asset_decimals: convertToScvU32(+(process.env['BASE_ASSET_DECIMALS'])),
flash_loan_fee: convertToScvU32(+(process.env['FLASH_LOAN_FEE_BPS'])),
grace_period: convertToScvU64(+(process.env['GRACE_PERIOD_SEC'])),
initial_health: convertToScvU32(+(process.env['INITIAL_HEALTH_BPS'])),
ir_alpha: convertToScvU32(+(process.env['IR_ALPHA'])),
ir_initial_rate: convertToScvU32(+(process.env['IR_INITIAL_RATE_BPS'])),
ir_max_rate: convertToScvU32(+(process.env['IR_MAX_RATE_BPS'])),
ir_scaling_coeff: convertToScvU32(+(process.env['IR_SCALING_COEFF_BPS'])),
liquidation_protocol_fee: convertToScvU32(+(process.env['LIQUIDATION_PROTOCOL_FEE_BPS'])),
min_collat_amount: convertToScvI128(BigInt(process.env['MIN_COLLAT_AMOUNT_IN_BASE'])),
min_debt_amount: convertToScvI128(BigInt(process.env['MIN_DEBT_AMOUNT_IN_BASE'])),
timestamp_window: convertToScvU64(+(process.env['TIMESTAMP_WINDOW_SEC'])),
user_assets_limit: convertToScvU32(+(process.env['USER_ASSET_LIMIT'])),
})
);
} else {
return client.sendTransaction(
process.env.SLENDER_DEPLOYER,
"deploy_pool",
adminKeys,
3,
convertToScvBytes(salt, "hex"),
convertToScvBytes(process.env.SLENDER_POOL_HASH, "hex"),
convertToScvAddress(adminKeys.publicKey()),
convertToScvMap({
base_asset_address: convertToScvAddress(process.env['SLENDER_TOKEN_XLM']),
base_asset_decimals: convertToScvU32(7),
flash_loan_fee: convertToScvU32(5),
grace_period: convertToScvU64(1),
initial_health: convertToScvU32(2_500),
ir_alpha: convertToScvU32(143),
ir_initial_rate: convertToScvU32(200),
ir_max_rate: convertToScvU32(50_000),
ir_scaling_coeff: convertToScvU32(9_000),
liquidation_protocol_fee: convertToScvU32(100),
min_collat_amount: convertToScvI128(1n),
min_debt_amount: convertToScvI128(1n),
timestamp_window: convertToScvU64(20),
user_assets_limit: convertToScvU32(4),
})
);
}
},
(result) => result[0]
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Validate required environment variables in release mode.

The isRelease=true branch reads 14+ environment variables (e.g., BASE_ASSET, BASE_ASSET_DECIMALS, FLASH_LOAN_FEE_BPS) without validation. Missing or invalid values will cause runtime failures. Consider adding validation or defaulting to test values if env vars are missing.

Run the following script to check which env vars are used but not documented:


🏁 Script executed:

#!/bin/bash
# Extract env var names from initPool and initPoolCollateral release branches
rg -nP "process\.env\[[\'\"]([A-Z_]+)[\'\"]" integration-tests/tests/pool.sut.ts | \
  sed -E "s/.*process\.env\[[\'\"]([A-Z_]+)['\"].*/\1/" | \
  sort -u | \
  while read var; do
    echo "Checking $var"
    rg -q "^${var}=" .env.example 2>/dev/null || echo "  ⚠️  $var not in .env.example"
  done

Length of output: 3074


Document and validate environment variables used in the release branch.
The isRelease=true branch references numerous env vars absent from .env.example (e.g. BASE_ASSET_DECIMALS, FLASH_LOAN_FEE_BPS, GRACE_PERIOD_SEC, etc.); update .env.example to include all of them and add runtime checks to fail fast on undefined or invalid values.

🤖 Prompt for AI Agents
integration-tests/tests/pool.sut.ts lines 838-902: the release branch uses many
environment variables that are missing from .env.example and are not validated
at runtime; add all referenced vars to .env.example (BASE_ASSET,
BASE_ASSET_DECIMALS, FLASH_LOAN_FEE_BPS, GRACE_PERIOD_SEC, INITIAL_HEALTH_BPS,
IR_ALPHA, IR_INITIAL_RATE_BPS, IR_MAX_RATE_BPS, IR_SCALING_COEFF_BPS,
LIQUIDATION_PROTOCOL_FEE_BPS, MIN_COLLAT_AMOUNT_IN_BASE,
MIN_DEBT_AMOUNT_IN_BASE, TIMESTAMP_WINDOW_SEC, USER_ASSET_LIMIT,
SLENDER_TOKEN_<BASE_ASSET>, SLENDER_POOL_HASH, SLENDER_DEPLOYER) and implement a
fast-fail validation helper that runs before initPool (or at function start)
which checks each required env var is defined, parses numbers/BigInt safely (use
Number(), parseInt, BigInt where appropriate), validates ranges/types and throws
a clear error if missing or invalid so deployment fails fast with actionable
messages.

Comment on lines 924 to 965
async function initPoolCollateral(
client: SorobanClient,
asset: SlenderAsset,
order: number
order: number,
isRelease: boolean
): Promise<void> {
await initContract(`POOL_${asset}_COLLATERAL_CONFIGURED`, () =>
client.sendTransaction(
process.env.SLENDER_POOL,
"configure_as_collateral",
adminKeys,
3,
convertToScvAddress(process.env[`SLENDER_TOKEN_${asset}`]),
convertToScvMap({
// todo: trim to short string
discount: convertToScvU32(+process.env[`${asset}_DISCOUNT_BPS`] ?? 6000),
liq_cap: convertToScvI128(process.env[`${asset}_LIQUIDITY_CAP`] ? BigInt(process.env[`${asset}_LIQUIDITY_CAP`]) : 1000000000000000n),
pen_order: convertToScvU32(+process.env[`${asset}_PENALTY_ORDER`] ?? order),
util_cap: convertToScvU32(+process.env[`${asset}_UTILIZATION_CAP`] ?? 9000),
})
)
await initContract(`POOL_${asset}_COLLATERAL_CONFIGURED`, () => {
if (isRelease) {
return client.sendTransaction(
process.env.SLENDER_POOL,
"configure_as_collateral",
adminKeys,
3,
convertToScvAddress(process.env[`SLENDER_TOKEN_${asset}`]),
convertToScvMap({
// todo: trim to short string
discount: convertToScvU32(+(process.env[`${asset}_DISCOUNT_BPS`])),
liq_cap: convertToScvI128(BigInt(process.env[`${asset}_LIQUIDITY_CAP`])),
pen_order: convertToScvU32(+(process.env[`${asset}_PENALTY_ORDER`])),
util_cap: convertToScvU32(+(process.env[`${asset}_UTILIZATION_CAP`])),
})
);
} else {

return client.sendTransaction(
process.env.SLENDER_POOL,
"configure_as_collateral",
adminKeys,
3,
convertToScvAddress(process.env[`SLENDER_TOKEN_${asset}`]),
convertToScvMap({
// todo: trim to short string
discount: convertToScvU32(6000),
liq_cap: convertToScvI128(1000000000000000n),
pen_order: convertToScvU32(order),
util_cap: convertToScvU32(9000),
})
);
}
}
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Validate required environment variables for collateral config in release mode.

Similar to initPool, the isRelease=true branch reads asset-specific environment variables (${asset}_DISCOUNT_BPS, ${asset}_LIQUIDITY_CAP, etc.) without validation. Missing values will cause runtime failures.

Run the following script to check which asset-specific env vars are required:


🏁 Script executed:

#!/bin/bash
# Check which assets and their env vars are used
for asset in XLM XRP USDC RWA; do
  echo "=== $asset ==="
  for suffix in DISCOUNT_BPS LIQUIDITY_CAP PENALTY_ORDER UTILIZATION_CAP; do
    var="${asset}_${suffix}"
    rg -q "^${var}=" .env.example 2>/dev/null || echo "  ⚠️  $var not in .env.example"
  done
done

Length of output: 760


Add missing env vars to .env.example and validate them in initPoolCollateral.

  • Update .env.example to include, for each asset (XLM, XRP, USDC, RWA), the four variables:
    • ${asset}_DISCOUNT_BPS
    • ${asset}_LIQUIDITY_CAP
    • ${asset}_PENALTY_ORDER
    • ${asset}_UTILIZATION_CAP
  • In the isRelease branch of initPoolCollateral (in integration-tests/tests/pool.sut.ts), assert that each process.env[...] is defined and throw a clear error if any are missing before calling sendTransaction.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc4e5a2 and c761f26.

📒 Files selected for processing (1)
  • integration-tests/tests/pool/3.liquidator.spec.ts (8 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
integration-tests/tests/pool/3.liquidator.spec.ts (2)
integration-tests/tests/pool.sut.ts (4)
  • liquidate (480-495)
  • sTokenBalanceOf (280-292)
  • accountPosition (322-333)
  • withdraw (460-478)
contracts/pool/src/methods/liquidate.rs (1)
  • liquidate (26-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (6)
integration-tests/tests/pool/3.liquidator.spec.ts (6)

193-193: Liquidate API correctly updated.

The removal of the boolean flag parameter aligns with the updated function signature in pool.sut.ts.


266-266: Liquidate API correctly updated.

Aligns with the updated function signature.


287-299: Assertions correctly reflect partial liquidation behavior.

The updated assertions properly validate:

  • USDC collateral remains untouched (line 287)
  • Liquidator receives underlying XRP, not sTokens (lines 289-290)
  • sXRP supply decreases as collateral is liquidated (line 293)
  • Borrower's position remains solvent after partial liquidation (line 299)

The logic aligns with the partial liquidation flow described in the contract code.


302-308: Test correctly validates liquidation rejection.

The test properly checks that liquidation is rejected when the borrower has no collateral remaining. The updated API call aligns with the new signature.


212-221: Verify sXrpSupply calculation logic.
Ensure 40000000000n - (borrower1SXrpBalanceBefore - borrower1SXrpBalanceAfter) correctly reflects the post‐liquidation sXRP supply, including any protocol fees or rounding adjustments.


234-240: Ensure zero-amount withdrawal still rejects when position is unhealthy.

I couldn’t locate the withdraw implementation to confirm its handling of a 0n amount; please verify that attempting to withdraw 0n when NPV ratio < 0.25 correctly triggers a rejection.


// TODO: requires optimization
it("Case 6: Liquidator liquidates Borrower's positions partialy", async function () {
it("Case 5: Liquidator liquidates Borrower's positions partialy", async function () {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in test description.

"partialy" should be "partially".

Apply this diff:

-    it("Case 5: Liquidator liquidates Borrower's positions partialy", async function () {
+    it("Case 5: Liquidator liquidates Borrower's positions partially", async function () {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("Case 5: Liquidator liquidates Borrower's positions partialy", async function () {
it("Case 5: Liquidator liquidates Borrower's positions partially", async function () {
🤖 Prompt for AI Agents
integration-tests/tests/pool/3.liquidator.spec.ts around line 183: the test
description contains a typo "partialy"; update the string to "partially" so the
it(...) reads: it("Case 5: Liquidator liquidates Borrower's positions
partially", async function () {.

});

it("Case 7: Borrower withdraw XRP partialy to NPV ~= 0", async function () {
it("Case 6: Borrower withdraw XRP partialy to NPV ~= 0", async function () {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in test description.

"partialy" should be "partially".

Apply this diff:

-    it("Case 6: Borrower withdraw XRP partialy to NPV ~= 0", async function () {
+    it("Case 6: Borrower withdraw XRP partially to NPV ~= 0", async function () {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("Case 6: Borrower withdraw XRP partialy to NPV ~= 0", async function () {
it("Case 6: Borrower withdraw XRP partially to NPV ~= 0", async function () {
🤖 Prompt for AI Agents
integration-tests/tests/pool/3.liquidator.spec.ts around line 231: the test
description string contains a typo "partialy"; update the it(...) description to
use the correct spelling "partially" so the test reads: it("Case 6: Borrower
withdraw XRP partially to NPV ~= 0", async function () { ... });

});

it("Case 9: Liquidator liquidates Borrower's position partialy 2", async function () {
it("Case 8: Liquidator liquidates Borrower's position partialy 2", async function () {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in test description.

"partialy" should be "partially".

Apply this diff:

-    it("Case 8: Liquidator liquidates Borrower's position partialy 2", async function () {
+    it("Case 8: Liquidator liquidates Borrower's position partially 2", async function () {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("Case 8: Liquidator liquidates Borrower's position partialy 2", async function () {
it("Case 8: Liquidator liquidates Borrower's position partially 2", async function () {
🤖 Prompt for AI Agents
In integration-tests/tests/pool/3.liquidator.spec.ts around line 252, the test
description contains a typo: change the string "Case 8: Liquidator liquidates
Borrower's position partialy 2" to "Case 8: Liquidator liquidates Borrower's
position partially 2" by editing the it(...) title accordingly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c761f26 and ed3fec4.

📒 Files selected for processing (1)
  • integration-tests/tests/pool/4.npv.spec.ts (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
integration-tests/tests/pool/4.npv.spec.ts (2)
integration-tests/tests/pool.sut.ts (9)
  • withdraw (460-478)
  • tokenBalanceOf (308-320)
  • sTokenBalanceOf (280-292)
  • sTokenUnderlyingBalanceOf (352-364)
  • sTokenTotalSupply (379-389)
  • accountPosition (322-333)
  • initPrice (1021-1043)
  • healthFactor (62-64)
  • deposit (422-439)
contracts/pool/src/methods/withdraw.rs (1)
  • withdraw (28-214)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (7)
integration-tests/tests/pool/4.npv.spec.ts (7)

137-154: Test recalibration for Protocol 23 looks correct.

The withdrawal amount reduction from 5 XRP to 0.0001 XRP and corresponding balance/NPV/collateral assertions are internally consistent. The smaller withdrawal correctly results in higher remaining balances (19,999,900,000n sXRP vs the previous ~15,000,000,000n) and slightly lower discounted collateral (119,999,400n).


185-187: Collateral assertion correctly reflects the lower XRP price.

The updated discounted_collateral value (83_999_580n) appropriately reflects the XRP price drop to 0.7, resulting in lower collateral value and maintaining NPV < 0 as intended for this test case.


200-209: Balance and collateral assertions are consistent.

The balance assertions correctly match the ending state from Case 4, and the discounted_collateral (83_999_580n) reflects the repriced collateral. Both properly validate that the withdrawal attempt is rejected without state changes.


225-237: Balance and position assertions correctly reflect the deposit.

The assertions properly validate the 3.5 XRP deposit:

  • sXRP balances increased by 3,500,000,000n (from 19,999,900,000n to 23,499,900,000n)
  • XRP balance decreased correspondingly (76,500,100,000n)
  • discounted_collateral increased to 98,699_580n reflecting additional collateral at the 0.7 price
  • NPV improved to the 9.6M-10M range while maintaining health < 0.25

258-261: Position assertions correctly unchanged after rejected borrow.

The discounted_collateral and NPV values properly match Case 8's ending state, confirming that the rejected borrow attempt did not modify the borrower's position.


265-289: Deposit amount increase and corresponding assertions are correct.

The doubled deposit amount (from 3.5 XRP to 7 XRP) and all corresponding assertions are internally consistent:

  • sXRP balances increased by 7,000,000,000n (from 23,499,900,000n to 30,499,900,000n)
  • XRP balance decreased correspondingly (69,500,100,000n)
  • discounted_collateral increased to 128,099,580n reflecting the substantial additional collateral
  • NPV improved to the 39M-40M range, achieving the target health >= 0.25

310-313: Position assertions are acceptable given the ranges.

The collateral correctly remains unchanged at 128,099,580n after the borrow operation. The NPV range (39M-40M) overlaps with Case 10 because the 90,000 debt increase is small relative to the 1M assertion range, which is acceptable for this integration test.

Comment on lines 158 to +159
// XRP price is set to 0.9
await initPrice(client, "XRP", 9_000_000_000_000_000n, 0);
await initPrice(client, "XRP", 7_000_000_000_000_000n, 0);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update comment to reflect actual price.

The comment states "XRP price is set to 0.9" but the code sets it to 7_000_000_000_000_000n, which represents 0.7 (not 0.9) assuming the standard precision.

Apply this diff to fix the comment:

-        // XRP price is set to 0.9
+        // XRP price is set to 0.7
         await initPrice(client, "XRP", 7_000_000_000_000_000n, 0);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// XRP price is set to 0.9
await initPrice(client, "XRP", 9_000_000_000_000_000n, 0);
await initPrice(client, "XRP", 7_000_000_000_000_000n, 0);
// XRP price is set to 0.7
await initPrice(client, "XRP", 7_000_000_000_000_000n, 0);
🤖 Prompt for AI Agents
In integration-tests/tests/pool/4.npv.spec.ts around lines 158 to 159, the
inline comment incorrectly states "XRP price is set to 0.9" while the call
initPrice(client, "XRP", 7_000_000_000_000_000n, 0) sets the price to 0.7 (given
the standard precision); update the comment to accurately read "XRP price is set
to 0.7" (or equivalent wording) so it matches the numeric value used.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
integration-tests/tests/pool/6.tx.budget.spec.ts (1)

140-147: LGTM! Liquidate signature updated correctly.

The liquidate call has been properly updated to match the new function signature (removing the asset and boolean flag parameters), consistent with the Protocol 23 migration to typed contract events shown in the relevant code snippets.

Consider removing the commented-out old code (Lines 143-146) if it's no longer needed for reference.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed3fec4 and b8825d0.

📒 Files selected for processing (1)
  • integration-tests/tests/pool/6.tx.budget.spec.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
integration-tests/tests/pool/6.tx.budget.spec.ts (1)
integration-tests/tests/pool.sut.ts (3)
  • deposit (422-439)
  • borrow (403-420)
  • liquidate (480-495)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests

Comment on lines +80 to +83
// Borrower2 deposits 20_000_000_000 USDC, borrows 60_000_000 XLM, 4_000_000_000 XRP
await deposit(client, borrower2Keys, "USDC", 20_000_000_000n);
await borrow(client, borrower2Keys, "XLM", 60_000_000n);
await borrow(client, borrower2Keys, "XRP", 5_900_000_000n);
await borrow(client, borrower2Keys, "XRP", 2_000_000_000n);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the comment to match the actual borrow amount.

The comment on Line 80 states that Borrower2 borrows 4_000_000_000 XRP, but the code on Line 83 shows 2_000_000_000n. Update the comment to reflect the correct value.

Apply this diff:

-        // Borrower2 deposits 20_000_000_000 USDC, borrows 60_000_000 XLM, 4_000_000_000 XRP
+        // Borrower2 deposits 20_000_000_000 USDC, borrows 60_000_000 XLM, 2_000_000_000 XRP
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Borrower2 deposits 20_000_000_000 USDC, borrows 60_000_000 XLM, 4_000_000_000 XRP
await deposit(client, borrower2Keys, "USDC", 20_000_000_000n);
await borrow(client, borrower2Keys, "XLM", 60_000_000n);
await borrow(client, borrower2Keys, "XRP", 5_900_000_000n);
await borrow(client, borrower2Keys, "XRP", 2_000_000_000n);
// Borrower2 deposits 20_000_000_000 USDC, borrows 60_000_000 XLM, 2_000_000_000 XRP
await deposit(client, borrower2Keys, "USDC", 20_000_000_000n);
await borrow(client, borrower2Keys, "XLM", 60_000_000n);
await borrow(client, borrower2Keys, "XRP", 2_000_000_000n);
🤖 Prompt for AI Agents
integration-tests/tests/pool/6.tx.budget.spec.ts around lines 80 to 83: the
inline comment says Borrower2 borrows 4_000_000_000 XRP but the actual call
borrows 2_000_000_000n; update the comment to state 2_000_000_000 XRP so it
matches the code (i.e., change "4_000_000_000 XRP" to "2_000_000_000 XRP").

@artur-abliazimov artur-abliazimov merged commit 2b4aa3c into master Oct 3, 2025
2 checks passed
@artur-abliazimov artur-abliazimov deleted the feature/protocol-23 branch October 3, 2025 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants