fix(atomic_swap): pay insurance claims from per-policy reservations - #936
Merged
fejilaup-cloud merged 1 commit intoAug 28, 2026
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Summary
Pay insurance claims from per-policy reservations
Problem
claim_insurancecomputedactual_payout = if pool >= payout { payout } else { pool }, paying every policy from one fungibleInsurancePool(token)balance. Two valid policies on the same token could be claimed in sequence, and the second claimant silently got a partial payout or zero, with no error separating "your claim is invalid" from "someone drained the pool first".Fix
InsuranceReserved(swap_id)andInsuranceReservedTotal(token), kept asDataKeyvariants rather thanSwapRecordfields so existing test literals compile untouched.accept_swapandbatch_accept_swaps.claim_insurancepays that policy's own reservation or panics. It never transfers a reduced amount.save_swapinstead of duplicated across ~20 status transitions, and is skipped while a swap is still flaggedInsuranceClaimable.New errors
InsuranceNotReservedInsufficientInsuranceReserveNew API
get_insurance_pool_status(token)returnsInsurancePoolStatus { token, balance, reserved, collateralized, shortfall }, so under-collateralization is observable before it causes a failed payout.get_insurance_reservation(swap_id).fund_insurance_pool(funder, token, amount). Not in the original scope but load-bearing: a policy contributes 2% of price and reserves 100% of it, so a premium-only pool is under-collateralized by construction and every claim would panic#67.Tests
Five tests in
insurance_reserve_tests, all issuing policies through the realinitiate_swapthenaccept_swappath:AthenBandBthenA.#67.#66.get_insurance_pool_statusbefore any claim.cargo build --workspaceandcargo test --workspaceare green, including the Redis-gatedapi-servertests.Unchanged
Premium calculation, risk-factor, and tiering logic are untouched. The premium stays 2% of price in both
initiate_swapandbatch_initiate_with_insurance.Known issue not fixed here
reveal_keysetsInsuranceClaimable(swap_id)and then callspanic_with_error(InvalidKey), which reverts the write, so the flag cannot persist andclaim_insuranceis unreachable through that path. Pre-existing, and fixing it changesreveal_key's revert semantics. Tests seed the flag directly.Closes
Closes #789