A smart contract for tracking flashblock ranges on Unichain, enabling smart contracts to revert if their function calls do not fall within the specified flashblock bounds.
The Flashblocks Number Contract provides a simple and onchain method for checking if your current transaction exists within a given range of flashblocks. Similar to how Solidity's block.number provides block-level granularity, this contract enables flashblock-level granularity for time-sensitive applications using the FlashblockNumber.getFlashblockNumber() function.
- Foundry installed
- Node.js 16+ (for additional tooling)
- Git
- Clone the repository:
git clone https://github.com/uniswap/flashblocks_number_contract
cd flashblocks_number_contract- Install dependencies:
forge install- Build the project:
forge build- Set up environment variables:
# fill out the .env with the intended arguments, such as whole the initial owner of the contract (i.e. who can modify the array of builders, and who can upgrade the contract) as well as the initial list of builder addresses (i.e. which addresses are allowed to call `incrementFlashblockNumber`)
cp env.sample .env- Deploy using the deployment script:
# load your environment variables
source .env
# deploy the FlashblockNumber contract using the arguments from .env. Replace the `--chain` argument with the chain id of the chain you want to deploy to; in this case we deploy to Unichain Sepolia
forge script script/FlashblockNumber.s.sol --rpc-url $RPC_URL --broadcast --verify --interactives 1 --chain 1301To integrate with the Flashblocks Number Contract:
import "./IFlashblockNumber.sol";
contract YourContract {
IFlashblockNumber public flashblockNumber;
function checkFlashblock() internal view returns (uint256) {
return flashblockNumber.getFlashblockNumber();
}
}- Flashblock Tracking: Maintains a monotonically increasing flashblock number which acts as a counter external contracts can use to track a range of flashblocks
- Builder Authorization: Only allowlisted builders can increment the flashblock counter, ensuring controlled and reliable updates from trusted builder (e.g. Flashbots)
- Builder High Availability: Multiple builder addresses are permissioned to update the onchain flashblock number, allowing multiple builders to fail and still allow for a healthy builder to update the onchain flashblock number
- Robust Against Total Remote Builder Failure: Even if all builders fail, or there is a network error between the Unichain sequencer and the remote builder, the FlashblockNumber contract will return a the latest flashblock number, which ensures that external smart contracts will still function correctly even when a block is built locally (i.e. not by a remote builder)
- UUPS Upgradeable: Implements the Universal Upgradeable Proxy Standard for future contract upgrades/improvements. Once the maintainers decide there are no need for further updates, and the contract has been battle-tested, they will transfer ownership to an address with no known private key (i.e. there will be no owner of the FlashblockNumber contract)
- EIP-712 Support: Includes meta-transaction capabilities to simplify TEE-builder gas concerns
- Event Emission: Emits events for flashblock increments and builder management for easy monitoring
- Time-Sensitive DeFi: Applications like UniswapX that use flashblock numbers for order decay calculations
- MEV Protection: Contracts that need to enforce ordering constraints within flashblocks
-
Builder Limitations
- Strict monotonic flashblock number ordering enforced
- updates to the onchain flashblock number must occur at the beginning of each flashblock
-
Invariants
- Flashblock never decreases (except from reorgs)
- Only allowlisted builders can call
incrementFlashblockNumber() - Calls must occur exactly once per flashblock
-
Security Considerations
- No external calls during state updates to prevent reentrancy
- Access control via OpenZeppelin's battle-tested libraries
- Builder Reliability: System depends on at least one active builder to maintain flashblock number liveness
- Upgrade Governance: Contract upgrades require multisig approval
Execute the full test suite:
forge testRun with verbosity for detailed output:
forge test -vvvGenerate coverage reports:
forge coverageRun fuzz tests with extended runs:
forge test --match-test testFuzz -vvv --fuzz-runs 10000This project is licensed under the MIT License - see the LICENSE file for details.
- Flashblocks specification by Flashbots