Sign in

Boundary of consent

Suggest an edit

On-chain state can change between signing and execution. An exact expected result may already be stale when the transaction arrives.

The boundaries can be signed together with the intended execution data: maximum input, minimum output, limit price, maximum oracle age or deadline. Execution inside the accepted boundaries is valid, but execution outside of them fails. For example, in swaps, this boundary is slippage. It defines acceptable price movement rather than predicting it. The same pattern applies to orders, oracle reads, liquidations etc.

Boundary of consentA horizontal bar marks the range the user signed, from a minimum to a maximum. The expected result is a hollow point inside it. Two actual results inside the range are marked with checks, one outside is marked with a cross. Boundary of consent signed range min max expected result result result The user signs how far the result may move, not the result itself. Outside the range the transaction fails.

Examples

Jupiter: an expected output can be calculated right on the spot, but the user in fact signs the minimum acceptable output they can agree to. The swap executes while the result stays above that minimum, but completely fails when it is below the acceptable minimum.

In code

The boundary is an argument the user signs with the action. The program runs the action and fails if the result falls outside it.

rust
pub fn swap(ctx: Context<Swap>, amount_in: u64, min_amount_out: u64) -> Result<()> {
    let amount_out = run_swap(&ctx, amount_in)?;
    // min_amount_out is the boundary the user signed, below it the swap fails
    require!(amount_out >= min_amount_out, SwapError::SlippageExceeded);
    settle(ctx, amount_out)
}