StrataSolidity

Fundamentals

Frame Conditions (modifies)#

A modifies clause declares which state variables a function is allowed to change. Anything not listed must remain unchanged. This is called a frame condition — it frames what can change and, by exclusion, what cannot.

Declaring modifies#

/// @custom:strata modifies totalSupply, balances[to]
function mint(address to, uint256 amount) external {
    totalSupply += amount;
    balances[to] += amount;
}

StrataSolidity checks two things: 1. The function only writes to totalSupply and balances[to]. 2. All other state variables (and all other mapping keys) remain unchanged.

Key-scoped modifies#

For mappings, you can scope modifies to specific keys:

/// @custom:strata modifies balances[msg.sender], balances[to]
function transfer(address to, uint256 amount) external {
    balances[msg.sender] -= amount;
    balances[to] += amount;
}

This proves that transfer only modifies the balances of the sender and receiver. The balance of every other address is guaranteed unchanged — without needing an explicit forall postcondition.

modifies vs. forall postconditions#

Key-scoped modifies and forall postconditions can express similar properties:

// These two are equivalent:

// Option 1: modifies clause
/// @custom:strata modifies balances[msg.sender], balances[to]

// Option 2: explicit forall postcondition
/// @custom:strata ensures forall a : address :: (a != msg.sender && a != to) ==> balances[a] == old(balances[a])

The modifies clause is more concise and is checked automatically. Use forall postconditions when you need to express more complex frame properties that modifies cannot capture.

Multiple state variables#

List all modified state variables, separated by commas:

/// @custom:strata modifies owner, totalSupply, balances[to]
function mintAndTransferOwnership(address to, uint256 amount, address newOwner) external {
    owner = newOwner;
    totalSupply += amount;
    balances[to] += amount;
}

What happens without modifies?#

If you omit the modifies clause, StrataSolidity does not check frame conditions for that function. Adding modifies is optional but strongly recommended — it catches unintended state mutations that postconditions alone might miss.

View this page’s source on GitHub