Flap Trigger Service

Overview

FlapTriggerService is a decentralized on-chain scheduler that allows smart contracts to request delayed or immediate function callbacks executed by a trusted backend. It bridges on-chain logic with off-chain coordination, enabling complex time-sensitive operations without requiring the caller to manage execution timing directly.

Deployed addresses:

Network
Address

BSC Mainnet

0xcf4EE25035CF883895110f367F5BA8172416a7F9

BSC Testnet

0x560E9830926C9e0EB98a59c6b9902383Fc0D9Eb2

Primary use cases:

  • Time-delayed operations (vesting unlocks, periodic distributions, deferred settlements)

  • Backend-coordinated operations requiring MEV protection

  • Operations that need external computation before on-chain execution

How it works

Step by step:

  1. The requester contract calls requestTrigger(), paying the required gas fee and specifying an executeAfter timestamp (or 0 for immediate execution).

  2. The service records the request and emits a FlapTriggerRequested event.

  3. The off-chain backend monitors for these events and indexes all pending requests.

  4. When the scheduled time arrives, the backend submits a trigger(requestId) transaction via an MEV-protected RPC (e.g., Flashbots, BloXroute).

  5. FlapTriggerService calls back requester.trigger(requestId) with a bounded gas limit.

  6. The requester's callback uses the requestId to identify and execute the intended operation.

Timing guarantees

circle-exclamation

Integrators must assume there can be an unpredictable delay due to:

  • Network congestion

  • Backend processing latency

  • Block inclusion delays

  • MEV protection overhead

Requester contracts must be designed to handle late execution gracefully and must not rely on execution at a precise time.


Trigger pricing

A fixed native-currency fee (BNB on BSC) is charged per trigger request. The current price is 0.0002 BNB per request.

This fee covers:

  • Gas costs for the backend's trigger() transaction

  • Gas costs for the callback to the requester contract

  • A small service fee

Getting the current fee:

The fee is paid upfront when calling requestTrigger() as msg.value. Excess payment above the required fee is accumulated as protocol fees β€” there is no refund for overpayment.

Callback gas limit:

Each trigger callback is forwarded at most getMaxCallbackGas() gas. Requester contracts must ensure their trigger() callback completes within this limit. Exceeding the limit will cause the callback to fail (status becomes FAILED).

Failed callbacks and retry:

If a callback fails (e.g., out of gas or revert), the request status is set to FAILED. Anyone can retry a failed request by calling retryTrigger(requestId) β€” this forwards all available gas to the callback, allowing the caller to supply sufficient gas. The fee stored in the request is transferred to the fee receiver on successful retry.


How to integrate

Step 1 β€” Import the interfaces

Step 2 β€” Implement ITriggerReceiver

Your contract must implement the trigger(uint256 requestId) callback. This function is called by FlapTriggerService when the scheduled time has passed.

Security requirements for the callback:

  • Must validate msg.sender == address(triggerService)

  • Should implement a reentrancy guard if performing external calls or state changes

  • Must complete within getMaxCallbackGas() gas

  • Must not assume execution happens exactly at executeAfter β€” always assume potential delay

Step 3 β€” Schedule a trigger

Call requestTrigger() with the desired executeAfter timestamp. Store the returned requestId to map it back to the intended operation in your callback.

Pseudo-code example

Scheduling for immediate execution

Pass 0 as executeAfter to request execution as soon as the backend processes the event:

Querying request status

Retrying a failed trigger

If a callback fails (e.g., the callback used more gas than the limit), anyone can retry:


Reference

Full interface

Last updated