Labels: Official Campaign | FWC26 GrantFox OSS Maybe Rewarded contract soroban storage reliability bug
This is a smart-contract issue for the GrantFox FWC26 campaign. Include airdrop and yield-escrow records in the TTL sweep so long-lived user funds are never archived.
Requirements and Context
contracts/finchippay-contract/src/storage.rs — ttl_class_at maps sweep indices to TtlClass:
0 => TtlClass::Config,
1 => TtlClass::Receipts,
2 => TtlClass::Escrows,
3 => TtlClass::Streams,
4 => TtlClass::MultiSig,
5 => TtlClass::Vesting,
6 => TtlClass::YieldEscrow,
_ => TtlClass::Emergency,
Airdrop(u32) / AirdropCount / AirdropClaimed(u32, Address) are not in any TTL class — bump_all_ttls never touches them. claim_airdrop/create_airdrop do call storage::bump on the record in the read path, but an unclaimed airdrop that sits idle for ~31 days (MIN_TTL_LEDGERS = 535,680 ledgers) can have its Airdrop(id) entry archived, after which claim_airdrop panics "Airdrop not found" and the funder's tokens are stuck.
YieldEscrow records are swept, but TtlClass::YieldEscrow is not included in bump_ttl_class_item — check the match arms: TtlClass::YieldEscrow falls through to the _ arm of ttl_class_len? No — ttl_class_len has a YieldEscrow arm, but bump_ttl_class_item's match arms end at TtlClass::Emergency with no YieldEscrow arm, so a sweep over class index 6 (YieldEscrow) returns 0 for every item — yield escrows are never actually extended by the sweep.
Verify with cargo test --test integration after patching; the fix is to add the missing bump_ttl_class_item arm and a dedicated airdrop class.
Objectives
- Add a
TtlClass::Airdrop variant (or fold airdrop keys into an existing class) and bump them in bump_all_ttls.
- Implement the missing
TtlClass::YieldEscrow arm in bump_ttl_class_item so the sweep actually extends those keys.
- Add tests asserting that after a sweep, airdrop and yield-escrow records are bumped (using a probe counter or a
get_min_ttl assertion).
Suggested Execution
- Fork and branch:
git checkout -b fix/ttl-sweep-coverage.
- Patch
storage.rs (TtlClass, ttl_class_at, ttl_class_len, bump_ttl_class_item).
- Add sweep-coverage tests.
- Run
cargo fmt --check && cargo clippy -- -D warnings && cargo test.
Acceptance Criteria
Guidelines
- Keep
MAX_TTL_BUMP_KEYS bounds; add the new class to TTL_CLASS_COUNT and get_min_ttl output.
Timeframe: 48 hours
Labels:
Official Campaign | FWC26GrantFox OSSMaybe RewardedcontractsorobanstoragereliabilitybugRequirements and Context
contracts/finchippay-contract/src/storage.rs—ttl_class_atmaps sweep indices toTtlClass:Airdrop(u32)/AirdropCount/AirdropClaimed(u32, Address)are not in any TTL class —bump_all_ttlsnever touches them.claim_airdrop/create_airdropdo callstorage::bumpon the record in the read path, but an unclaimed airdrop that sits idle for ~31 days (MIN_TTL_LEDGERS= 535,680 ledgers) can have itsAirdrop(id)entry archived, after whichclaim_airdroppanics "Airdrop not found" and the funder's tokens are stuck.YieldEscrowrecords are swept, butTtlClass::YieldEscrowis not included inbump_ttl_class_item— check the match arms:TtlClass::YieldEscrowfalls through to the_arm ofttl_class_len? No —ttl_class_lenhas aYieldEscrowarm, butbump_ttl_class_item's match arms end atTtlClass::Emergencywith noYieldEscrowarm, so a sweep over class index 6 (YieldEscrow) returns0for every item — yield escrows are never actually extended by the sweep.Verify with
cargo test --test integrationafter patching; the fix is to add the missingbump_ttl_class_itemarm and a dedicated airdrop class.Objectives
TtlClass::Airdropvariant (or fold airdrop keys into an existing class) and bump them inbump_all_ttls.TtlClass::YieldEscrowarm inbump_ttl_class_itemso the sweep actually extends those keys.get_min_ttlassertion).Suggested Execution
git checkout -b fix/ttl-sweep-coverage.storage.rs(TtlClass,ttl_class_at,ttl_class_len,bump_ttl_class_item).cargo fmt --check && cargo clippy -- -D warnings && cargo test.Acceptance Criteria
bump_all_ttls.bump_all_ttls(previously skipped).cargo test+wasm32v1-nonebuild pass.Guidelines
MAX_TTL_BUMP_KEYSbounds; add the new class toTTL_CLASS_COUNTandget_min_ttloutput.Timeframe: 48 hours