Skip to content

feat(precompiles): storage delta helpers#5605

Draft
shekhirin wants to merge 1 commit into
mainfrom
alexey/sinc-sdec-main
Draft

feat(precompiles): storage delta helpers#5605
shekhirin wants to merge 1 commit into
mainfrom
alexey/sinc-sdec-main

Conversation

@shekhirin

@shekhirin shekhirin commented Jun 10, 2026

Copy link
Copy Markdown
Member

Adds semantic sinc/sdec storage helpers and uses them for TIP-20 balance deltas and fee-manager accruals. The helpers intentionally return no post-delta value so callers cannot branch on intermediate delta results.

They will be used for parallel execution in builder prewarming that outputs storage actions which can then be applied in serial builder loop.

@shekhirin shekhirin changed the title feat(precompiles): add storage delta helpers feat(precompiles): storage delta helpers Jun 10, 2026
@shekhirin shekhirin added C-enhancement New feature or request A-precompile Related to precompiles labels Jun 10, 2026
@shekhirin shekhirin force-pushed the alexey/sinc-sdec-main branch from 497d547 to 4f5da22 Compare June 10, 2026 15:16
@shekhirin shekhirin added the cyclops Trigger Cyclops PR audit label Jun 10, 2026
@codspeed-hq

codspeed-hq Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 18 untouched benchmarks
⏩ 9 skipped benchmarks1


Comparing alexey/sinc-sdec-main (4f5da22) with main (3aab3a6)

Open in CodSpeed

Footnotes

  1. 9 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@shekhirin shekhirin force-pushed the alexey/sinc-sdec-main branch from 4f5da22 to 92759de Compare June 10, 2026 15:32
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

📊 Tempo Precompiles Coverage

precompiles

Coverage: 5820/9099 lines (63.96%)

File details
File Lines Coverage
src/account_keychain/dispatch.rs 36/103 34.95%
src/account_keychain/mod.rs 300/855 35.09%
src/address_registry/dispatch.rs 31/36 86.11%
src/address_registry/mod.rs 50/60 83.33%
src/error.rs 48/148 32.43%
src/ip_validation.rs 10/10 100.00%
src/lib.rs 183/233 78.54%
src/nonce/dispatch.rs 9/10 90.00%
src/nonce/mod.rs 42/57 73.68%
src/receive_policy_guard/dispatch.rs 0/21 0.00%
src/receive_policy_guard/mod.rs 0/139 0.00%
src/signature_verifier/dispatch.rs 21/30 70.00%
src/signature_verifier/mod.rs 13/55 23.64%
src/stablecoin_dex/dispatch.rs 92/93 98.92%
src/stablecoin_dex/mod.rs 879/946 92.92%
src/stablecoin_dex/order.rs 120/154 77.92%
src/stablecoin_dex/orderbook.rs 157/216 72.69%
src/storage/evm.rs 192/221 86.88%
src/storage/hashmap.rs 0/158 0.00%
src/storage/mod.rs 42/57 73.68%
src/storage/packing.rs 68/93 73.12%
src/storage/thread_local.rs 173/235 73.62%
src/storage/types/array.rs 0/72 0.00%
src/storage/types/bytes_like.rs 139/183 75.96%
src/storage/types/cache.rs 65/122 53.28%
src/storage/types/mapping.rs 36/48 75.00%
src/storage/types/mod.rs 47/71 66.20%
src/storage/types/primitives.rs 21/24 87.50%
src/storage/types/set.rs 28/192 14.58%
src/storage/types/slot.rs 63/89 70.79%
src/storage/types/vec.rs 103/261 39.46%
src/tip20/dispatch.rs 159/175 90.86%
src/tip20/mod.rs 624/778 80.21%
src/tip20/rewards.rs 231/246 93.90%
src/tip20/roles.rs 85/88 96.59%
src/tip20_channel_reserve/dispatch.rs 0/51 0.00%
src/tip20_channel_reserve/mod.rs 3/478 0.63%
src/tip20_factory/dispatch.rs 20/21 95.24%
src/tip20_factory/mod.rs 117/140 83.57%
src/tip403_registry/dispatch.rs 58/75 77.33%
src/tip403_registry/mod.rs 330/493 66.94%
src/tip_fee_manager/amm.rs 284/392 72.45%
src/tip_fee_manager/dispatch.rs 81/83 97.59%
src/tip_fee_manager/mod.rs 57/154 37.01%
src/validator_config/dispatch.rs 38/52 73.08%
src/validator_config/mod.rs 171/227 75.33%
src/validator_config_v2/dispatch.rs 71/73 97.26%
src/validator_config_v2/mod.rs 523/581 90.02%

contracts

Coverage: 1/168 lines (0.60%)

File details
File Lines Coverage
src/lib.rs 1/1 100.00%
src/precompiles/receive_policy_guard.rs 0/78 0.00%
src/precompiles/tip20.rs 0/50 0.00%
src/precompiles/tip20_channel_reserve.rs 0/27 0.00%
src/precompiles/tip403_registry.rs 0/9 0.00%
src/precompiles/validator_config_v2.rs 0/3 0.00%

Total: 5821/9267 lines (62.81%)

📦 Download full HTML report

@shekhirin shekhirin force-pushed the alexey/sinc-sdec-main branch from 92759de to 918cf68 Compare June 10, 2026 16:11
@shekhirin shekhirin force-pushed the alexey/sinc-sdec-main branch from 918cf68 to b9a6ddf Compare June 10, 2026 16:16
@shekhirin shekhirin added cyclops Trigger Cyclops PR audit and removed cyclops Trigger Cyclops PR audit labels Jun 10, 2026
@tempoxyz-bot

tempoxyz-bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

👁️ Cyclops Security Review

b9a6ddf

🧭 Audit failed · mode=normal · workers 2/3 done (0 left, 1 failed) · verify pending 0

Worker Engine Latest Status Status
pr-5605-w1 claude-opus-4-8 🚨 Iteration 3 · Verify Done
pr-5605-w2 gpt-5.5 ✅ Iteration 3 · Audit Done
pr-5605-w3 claude-fable-5 ❌ Iteration 3 · Audit Failed

Findings

# Finding Severity Status
1 _transfer balance pre-check removal lets handle_rewards_on_transfer reclassify insufficient-balance as a Panic system error for opted-in senders Low Iteration 3 · Verify
⚙️ Controls
  • 🚀 Keep only 1 remaining iteration per worker after the current work finishes.
  • 👀 Keep only 2 remaining iterations per worker after the current work finishes.
  • ❤️ Let only worker 1 continue; other workers skip queued iterations.
  • 😄 Let only worker 2 continue; other workers skip queued iterations.
  • 🎉 End faster by skipping queued iterations and moving toward consolidation.
  • 😕 Stop active workers/verifiers now and start consolidation immediately.

📜 24 events

🔍 pr-5605-w1 iter 1/3 [audit-general.md]
🔍 pr-5605-w2 iter 1/3 [audit-focused.md]
🔍 pr-5605-w3 iter 1/3 [audit-ripple.md]
pr-5605-w3 iter 1 — failed
🔍 pr-5605-w3 iter 2/3 [audit-invariants.md]
pr-5605-w3 iter 2 — failed
🔍 pr-5605-w3 iter 3/3 [audit-general.md]
pr-5605-w3 iter 3 — failed
pr-5605-w3 failed — one or more audit iterations failed
pr-5605-w1 iter 1 — clear
🔍 pr-5605-w1 iter 2/3 [audit-focused.md]
pr-5605-w1 iter 2 — clear
🔍 pr-5605-w1 iter 3/3 [audit-ripple.md]
pr-5605-w2 iter 1 — clear
🔍 pr-5605-w2 iter 2/3 [audit-ripple.md]
🚨 pr-5605-w1 iter 3 — finding
🚨 Finding: _transfer balance pre-check removal lets handle_rewards_on_transfer reclassify insufficient-balance as a Panic system error for opted-in senders (Low)
🔬 Verifying: _transfer balance pre-check removal lets handle_rewards_on_transfer reclassify insufficient-balance as a Panic system error for opted-in senders
📋 Verify: _transfer balance pre-check removal lets handle_rewards_on_transfer reclassify insufficient-balance as a Panic system error for opted-in senders → ✅ Verified
🏁 pr-5605-w1 done
pr-5605-w2 iter 2 — clear
🔍 pr-5605-w2 iter 3/3 [audit-invariants.md]
pr-5605-w2 iter 3 — clear
🏁 pr-5605-w2 done

@shekhirin shekhirin marked this pull request as ready for review June 10, 2026 16:40
@shekhirin shekhirin marked this pull request as draft June 10, 2026 16:46
Comment on lines +278 to +280
let collected_fees = self.collected_fees.at_mut(&validator).at_mut(&token);
let slot = collected_fees.slot();
collected_fees.sinc(slot, amount)?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we maybe have a helper on Slot<U256> for this? i do like the collected_fees[validator][token] API

Comment on lines +1002 to +1010
let balance = self.balances.at_mut(&account);
let slot = balance.slot();
balance.sinc(slot, amount).map_err(|err| {
if err == TempoPrecompileError::under_overflow() {
TIP20Error::supply_cap_exceeded().into()
} else {
err
}
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@legion2002 legion2002 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️ Cyclops Review

Manual consolidation for the failed Cyclops workflows on PR #5605. I only reposted the latest verified finding that still applies to current head b9a6ddf; no older 4f5da225 findings were reposted.

.ok_or(TempoPrecompileError::under_overflow())?;

self.set_balance(from, new_from_balance)?;
self.decrement_balance(from, amount)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [LOW] _transfer balance pre-check removal lets rewards accounting turn insufficient balance into a Panic

The PR removes the up-front from balance check and now relies on decrement_balance to map storage underflow back into TIP20Error::insufficient_balance. That mapping happens only here, after handle_rewards_on_transfer(from, to.target, amount) has already run. For an opted-in sender that transfers more than its balance to a non-opted-in recipient, rewards accounting can subtract amount from opted_in_supply first; when amount exceeds the opted-in supply, that path returns TempoPrecompileError::under_overflow(), which is encoded as Solidity Panic(0x11) and treated as a system error instead of the expected TIP20 insufficient-balance error.

Recommended Fix:
Restore an explicit balance check before handle_rewards_on_transfer, or make handle_rewards_on_transfer receive the already-validated sender balance / post-debit amount so insufficient-balance transfers fail with TIP20Error::insufficient_balance before reward accounting can underflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-precompile Related to precompiles C-enhancement New feature or request cyclops Trigger Cyclops PR audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants