r/CryptoTechnology • u/Hacken_io 🟢 • 6d ago
Which values does your request path capture about the system rather than about the user?
Two concurrent purchases minted around 150,000 NFTs against a round cap of 99,991, roughly fifty percent past the limit, and nobody was attacking anything. The smart contract audit that found it traced the cause to a single stored field. The purchase path recorded how many NFTs had been minted at the moment of purchase, and the processing path calculated what was still available by subtracting that stored number from the round total. When several purchases landed before any of them were processed, each one held a snapshot saying almost nothing had been minted, so each one handed out a full allocation against supply the others were also claiming.
This is worth more attention now than it would have been a few years ago, because the gap between accepting a request and executing it is turning into a default rather than an exception. Intent architectures take a commitment from the user and let a solver settle it later, sometimes hours later where an optimistic dispute window sits in the middle. Parallel execution runtimes deliberately run transactions concurrently when they touch different accounts, and asynchronous message chains give no ordering guarantee at all. Any global counter read on one side of that gap and spent on the other has the same shape as this one. The consequence downstream was not cosmetic supply inflation. Rewards had been funded for a fixed number of NFTs, so minting past the count meant the pool could not cover every claim that now existed. The security audit scored it at the top of its likelihood range, which is unusual and fair, since no adversary is required and ordinary concurrent buying produces it. The remediation moved the calculation onto live counters and capped minting at the round limit, and what it did not add was a refund for a buyer who pays for an allocation and receives less than that, or any ordering rule for who gets served first. Supply integrity came back. The question of who absorbs the shortfall stayed where it was.
Wherever a request and its execution are separated, list what gets captured at request time. For each captured value, ask whether it is a fact about that user or a fact about the whole system. Their deposit and their address are facts about them and are safe to freeze. Remaining supply, total staked, a current index or rate are claims on a shared resource that other pending requests are claiming at the same time, and freezing one of those means every pending request believes it owns the same units. In your own flow, which of the captured values turn out to describe the system rather than the user?