Skip to content

security: HIGH-1 — defer commit_pool_ordinal allocation to threshold-… - #147

Merged
Bluechip23 merged 1 commit into
mainfrom
claude/bluechip-security-audit-dbsuW
May 19, 2026
Merged

security: HIGH-1 — defer commit_pool_ordinal allocation to threshold-…#147
Bluechip23 merged 1 commit into
mainfrom
claude/bluechip-security-audit-dbsuW

Conversation

@Bluechip23

Copy link
Copy Markdown
Owner

…cross

COMMIT_POOL_COUNTER was bumped inside execute_create_creator_pool and the resulting ordinal pinned onto PoolDetails.commit_pool_ordinal at create time. The bluechip mint-decay formula in
calculate_and_mint_bluechip then read this ordinal as its x input.

Effect: paid commit-pool creation spam (junk pools that never cross threshold) permanently inflates x for every future legitimate threshold-crossing pool, decaying the protocol's bluechip mint schedule toward zero without the attacker ever crossing a threshold themselves. At a $1 launch creation fee, ~$33k in fees + gas (plus rotation across ~33k addresses to bypass the 1h per-address rate limit) suppresses the mint to zero permanently.

Fix: allocate the ordinal at threshold-cross time inside execute_notify_threshold_crossed, immediately after the POOL_THRESHOLD_MINTED idempotency gate. Junk pools that never cross no longer consume an ordinal slot, so the decay input tracks real protocol activity (threshold crossings) instead of paid creation volume.

Atomicity is preserved across failure paths: POOL_THRESHOLD_MINTED flips, COMMIT_POOL_COUNTER bumps, and POOLS_BY_ID updates ride in the same tx as the mint dispatch. A failed mint reverts all three; RetryFactoryNotify then re-allocates from the same prior counter value, so no slot is ever consumed by a failed cross. The existing zero-guard at the consumer in calculate_and_mint_bluechip becomes load-bearing — any future path that bypasses the new allocation site fails closed instead of inflating the mint to the base 500e6 amount.

Migration: not required for fresh launch. If any deployment already has commit pools with non-zero commit_pool_ordinal from the pre-fix code, the notify handler will overwrite the field with the freshly allocated value at threshold-cross — since POOL_THRESHOLD_MINTED gates uncrossed pools, the overwrite is correct.

https://claude.ai/code/session_019mxdB2vwswjgipCUq2x4Fu

…cross

`COMMIT_POOL_COUNTER` was bumped inside `execute_create_creator_pool` and
the resulting ordinal pinned onto `PoolDetails.commit_pool_ordinal` at
create time. The bluechip mint-decay formula in
`calculate_and_mint_bluechip` then read this ordinal as its `x` input.

Effect: paid commit-pool creation spam (junk pools that never cross
threshold) permanently inflates `x` for every future legitimate
threshold-crossing pool, decaying the protocol's bluechip mint
schedule toward zero without the attacker ever crossing a threshold
themselves. At a $1 launch creation fee, ~$33k in fees + gas (plus
rotation across ~33k addresses to bypass the 1h per-address rate
limit) suppresses the mint to zero permanently.

Fix: allocate the ordinal at threshold-cross time inside
`execute_notify_threshold_crossed`, immediately after the
`POOL_THRESHOLD_MINTED` idempotency gate. Junk pools that never cross
no longer consume an ordinal slot, so the decay input tracks real
protocol activity (threshold crossings) instead of paid creation
volume.

Atomicity is preserved across failure paths: `POOL_THRESHOLD_MINTED`
flips, `COMMIT_POOL_COUNTER` bumps, and `POOLS_BY_ID` updates ride in
the same tx as the mint dispatch. A failed mint reverts all three;
`RetryFactoryNotify` then re-allocates from the same prior counter
value, so no slot is ever consumed by a failed cross. The existing
zero-guard at the consumer in `calculate_and_mint_bluechip` becomes
load-bearing — any future path that bypasses the new allocation site
fails closed instead of inflating the mint to the base 500e6 amount.

Migration: not required for fresh launch. If any deployment already
has commit pools with non-zero `commit_pool_ordinal` from the pre-fix
code, the notify handler will overwrite the field with the freshly
allocated value at threshold-cross — since `POOL_THRESHOLD_MINTED`
gates uncrossed pools, the overwrite is correct.

https://claude.ai/code/session_019mxdB2vwswjgipCUq2x4Fu
@Bluechip23
Bluechip23 merged commit 9731eb7 into main May 19, 2026
1 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants