Description
On Stellar, sending an asset to an account that has not established a trustline for that asset causes the transfer to fail at the network level, potentially leaving the contract in a partially-paid inconsistent state. Before activating an invoice, the contract must verify that every recipient address has a trustline for the payment token and surface the offending address if one is missing.
Technical Context
contracts/split/src/lib.rs — activate_invoice() entry point (or the final step of initialize()); trustline presence is inferred by calling soroban_sdk::token::Client::balance(recipient_address) and treating a host-trapped invocation as absent — wrap in env.try_invoke_contract or equivalent; contracts/split/src/validation.rs — add assert_recipients_have_trustlines(env: &Env, token: &Address, recipients: &[RecipientShare]); contracts/split/src/error.rs — add Error::RecipientMissingTrustline carrying the offending Address.
Acceptance Criteria
Description
On Stellar, sending an asset to an account that has not established a trustline for that asset causes the transfer to fail at the network level, potentially leaving the contract in a partially-paid inconsistent state. Before activating an invoice, the contract must verify that every recipient address has a trustline for the payment token and surface the offending address if one is missing.
Technical Context
contracts/split/src/lib.rs—activate_invoice()entry point (or the final step ofinitialize()); trustline presence is inferred by callingsoroban_sdk::token::Client::balance(recipient_address)and treating a host-trapped invocation as absent — wrap inenv.try_invoke_contractor equivalent;contracts/split/src/validation.rs— addassert_recipients_have_trustlines(env: &Env, token: &Address, recipients: &[RecipientShare]);contracts/split/src/error.rs— addError::RecipientMissingTrustlinecarrying the offendingAddress.Acceptance Criteria
activate_invoice()iterates all recipients and calls the trustline helper before changing invoice status toActivebalance()call traps or returns an error causes activation to fail withError::RecipientMissingTrustlinecontaining that recipient's addressSTROOP), which requires no trustlinecontracts/split/src/tests/trustline_tests.rssimulates a missing trustline on recipient index 2 of 4 and assertsError::RecipientMissingTrustlinewith the correct addressactivate_invoice()succeeds when all recipients return validbalance()responses