State Machine
A design pattern where a smart contract has defined stages or phases, with different functions available or different behavior in each state.
A state machine is a design pattern where a smart contract operates in distinct stages or phases, with behavior that varies depending on the current state. Functions may only be callable in certain states, parameters may have different effects, and transitions between states follow defined rules. This pattern is essential for modeling complex protocols with temporal phases like ICOs, auctions, governance proposals, and vesting schedules.
State Machine Fundamentals
In a state machine, the contract maintains an explicit state variable that determines its current phase. Functions check this state before executing, and certain actions trigger state transitions. This explicit modeling makes contract behavior predictable and easier to audit.
1enum State { Inactive, Active, Paused, Finalized }2State public currentState;34modifier inState(State required) {5 require(currentState == required, "Invalid state");6 _;7}89function deposit() external inState(State.Active) {10 // Only callable when Active11}1213function finalize() external inState(State.Active) {14 currentState = State.Finalized;15}
The pattern prevents invalid operations by making state requirements explicit. A user cannot deposit funds after finalization, and the contract cannot be finalized twice.
Common Use Cases
Token sales and ICOs: Crowdsales typically progress through stages—not yet started, active sale, soft cap reached, hard cap reached, finalized. Each stage has different rules for contributions and refunds.
Auctions: Auction contracts move from bidding phase to reveal phase (in blind auctions) to settlement phase. Bids are only accepted during bidding, reveals only during reveal, and settlement only after.
Governance proposals: Proposals transition through pending, active voting, succeeded, queued, and executed states. Each transition has time-based or vote-based requirements.
Vesting schedules: Vesting contracts track cliff periods, vesting periods, and completion. Withdrawals calculate differently based on the current vesting state.
State Transitions and Guards
Well-designed state machines enforce valid transitions. Not every state should be reachable from every other state—an auction shouldn't jump from bidding directly to settled, skipping the reveal phase.
1function startBidding() external onlyOwner inState(State.Pending) {2 currentState = State.Bidding;3 biddingEndTime = block.timestamp + BIDDING_DURATION;4}56function endBidding() external inState(State.Bidding) {7 require(block.timestamp >= biddingEndTime, "Bidding not ended");8 currentState = State.Revealing;9 revealEndTime = block.timestamp + REVEAL_DURATION;10}
Time-based transitions add complexity but are often necessary. The combination of state checks and time checks creates a robust progression model.
Security Considerations
State machines introduce specific security considerations that auditors examine closely:
Unreachable states: Can the contract get stuck in a state with no valid exit? If the only transition out of a state requires a condition that can never be met, funds may be locked forever.
State manipulation: Can attackers force the contract into an unintended state? State transitions should be protected by appropriate access controls and conditions.
Timing attacks: For time-based transitions, can attackers manipulate timing to their advantage? Consider block timestamp manipulation limits and ensure timing windows are appropriate.
Reentrancy across states: If a function changes state and makes external calls, can reentrancy allow operations in an inconsistent state? Apply the checks-effects-interactions pattern carefully.
Missing transitions: Are all necessary transitions implemented? A governance system that can create proposals but lacks a way to execute them has a critical missing transition.
State Machine Testing
Testing state machines requires covering:
All valid transitions: Test each legitimate path through the state graph.
Invalid transition attempts: Verify that prohibited transitions revert with appropriate errors.
Boundary conditions: Test transitions at exactly the right time, just before, and just after time boundaries.
State-specific behavior: Verify that functions behave correctly (or revert) in each possible state.
State persistence: Confirm that state survives across transactions and doesn't reset unexpectedly.
State Machines and Upgradeability
When combining state machines with upgradeable contracts via the proxy pattern, ensure that:
- State variables maintain consistent storage layout across upgrades
- New states can be added without breaking existing state encoding
- Migration functions exist if state representation needs to change
- State transitions work correctly across upgrade boundaries
Documentation Best Practices
State machines benefit greatly from visual documentation. Include state diagrams showing all states and valid transitions in your documentation. For each state, document which functions are available, what conditions enable transitions, and any time-based constraints.
This documentation helps both developers implementing the contract and auditors reviewing it. Clear state machine diagrams often reveal missing transitions or unreachable states that might otherwise be overlooked.
Articles Using This Term
Learn more about State Machine in these articles:
Related Terms
Checks-Effects-Interactions
Solidity security pattern ordering operations to validate inputs, update state, then make external calls preventing reentrancy vulnerabilities.
Timelock
Smart contract mechanism enforcing mandatory delay between initiating and executing critical protocol changes for transparency.
Proxy Pattern
Smart contract design separating storage and logic, enabling upgrades by changing implementation while preserving state.
Need expert guidance on State Machine?
Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.
Get a Quote

