fix(creditline): propagate reputation contract call failures to enforce atomic state-reputation invariant - #104
Conversation
…ce atomic state-reputation invariant
|
Please rebase/merge the base branch into your branch and resolve the conflicts — a fresh audit will run automatically once new commits land. |
EmeditWeb
left a comment
There was a problem hiding this comment.
✅ Automated Audit: solves
@sublime247 Excellent work, thank you! 🎉
The PR genuinely fixes issue #86 by replacing fire-and-forget let _ = discards with strict result handling in both mark_defaulted() and handle_reputation_increase(). On reputation contract failure, it emits ScoreUpdateFailed event and panics with CreditLineError::ReputationCallFailed, atomicating the revert so loan state and scores never diverge. New tests (test_reputation_call_failure_reverts_repayment, test_reputation_call_failure_reverts_default) verify the revert behavior for both paths. All 389 workspace tests pass.
CI checks: ✅ PASSED: Build and Test Contracts
Merge conflicts:
Audited by stepfi-audit-bot 🤖
|
@EmeditWeb review |
Summary of Changes
Closes #86
Problem
In
contracts/creditline-contract/src/lib.rs, cross-contract calls to the reputation contract inmark_defaulted()(decrease_score) andhandle_reputation_increase()(increase_score) used fire-and-forgetlet _ = env.try_invoke_contract(...)statements. If the reputation contract reverted (e.g. revoked updater status, TTL expiry, or WASM mismatch), the loan would default or settle while the reputation score mutation silently failed, creating state-reputation divergence.Policy Decision: Option (a) — Propagate Failure
Chosen policy: Option (a) — Propagate failure to enforce atomic loan state and reputation score consistency.
vouching-contract(add_reputation_boost), both invocation and execution results oftry_invoke_contractare strictly checked.Some(reputation_contract)), the contract emits aScoreUpdateFailedevent and panics withpanic_with_error!(&env, CreditLineError::ReputationCallFailed).None), score updates are intentionally skipped with documented rationale, as the protocol is operating without on-chain reputation integration.Implementation Details
contracts/creditline-contract/src/errors.rs: AddedReputationCallFailed = 32error variant.contracts/creditline-contract/src/events.rs: Addedemit_score_update_failed(&env, borrower, is_increase, amount)helper emittingScoreUpdateFailedtopic.contracts/creditline-contract/src/lib.rs: Removed barelet _ =discards inmark_defaulted()andhandle_reputation_increase(), enforcing strict result handling, event emission, and atomic panic on failure.contracts/creditline-contract/src/tests.rs: Updatedtest_reputation_call_failure_reverts_repaymentand addedtest_reputation_call_failure_reverts_defaultsimulating reputation contract failure for both increase and decrease paths.context/progress-tracker.md: Documented security fix and Policy Option (a) decision under Recently Fixed.Verification Results
cargo test -p creditline-contract: 141 passed; 0 failedcargo test(full workspace): 389 passed; 0 failed across all 6 contracts.