Emits a forged "transfer" ContractEvent with arbitrary topics/data. honest field: contractID == self (the deployed contract address) — NOT the SAC of the named asset.
fn fire(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
(#25) Emits a DIAGNOSTIC event via log!() containing target/amount.
Diagnostic events are a separate XDR field (diagnosticEvents) and
are retained in meta even when contract events would be rolled back.
Probes parsers that index diagnosticEvents alongside contract events.
Limitation honestly stated: log!() produces topics=[Symbol("log"), Symbol("fmt")] with a structured data payload. A parser that filters topics[0]==Symbol("transfer") won't match. The test is whether the parser indexes diagnostic events at all and what it does with them.
fn fire_log(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
(#26) SEP-0041 token-interface conformant transfer.
A parser that whitelists "anything implementing the SAC token
interface" (rather than a specific contractID) would treat this
contract's events as legitimate token transfers. The event topic
shape exactly matches SAC's transfer event.
fn transfer(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
amount: i128,
)
Emits a forged "mint" ContractEvent.
fn fake_mint(
env: soroban_sdk::Env,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
(#12) Emits N forged "transfer" events in one invocation. Probes whether the parser accumulates per-event credits or dedups.
fn fire_many(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
count: u32,
)
(#21) Inner — emits a forged transfer event, then panics. Invoked indirectly via outer_pan's try_invoke_contract.
fn inner_pan(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
(#21) Outer that invokes inner_pan via try_invoke_contract. Inner emits a forged transfer event THEN panics. The outer ignores the inner's error and returns OK.
Soroban's correctness guarantee: events from an inner frame that errors out are DISCARDED on rollback, even when the outer recovers via try_invoke_contract. If this holds, the tx-level meta should contain NO transfer event after this call.
If the host has a bug and the inner event survives → phantom credit.
fn outer_pan(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
(#13) Emits a forged "transfer" event with a NEGATIVE i128 amount. Probes whether the parser silently treats negative as a deduction, or normalises via abs(), or rejects.
fn fire_negative(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
(#22) Real-deposit + forged-event amplification.
Performs a REAL 1-stroop XLM transfer via the XLM SAC (legitimate event with contractID = XLM SAC) AND emits a FORGED transfer event for a larger fake_amount (contractID = self = fake_emitter).
Probes whether the parser aggregates events by topic shape across the tx without per-event contractID gating.
xlm_sac: Address of the XLM Stellar Asset Contract.
from: Attacker's account — must auth the real SAC transfer.
to: Target deposit address.
fake_amount: i128 used as the forged event's data (in stroops).
The REAL transfer is hard-coded to 1 stroop.
(#23) Like fire, but topic[0] is a STRING ("transfer") not a SYMBOL.
Probes parsers that compare topic[0] as decoded text without
checking the ScVal type tag.
fn fire_str_topic(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
asset: soroban_sdk::String,
amount: i128,
)
fn real_plus_fake(
env: soroban_sdk::Env,
xlm_sac: soroban_sdk::Address,
from: soroban_sdk::Address,
to: soroban_sdk::Address,
fake_amount: i128,
)