Flap Candy Box
Overview
Flap Candy Box is an on-chain data oracle that delivers paginated, addressable lists to consumer contracts via a request-response callback pattern. It serves as an infrastructure layer for programmable, transparent, and automated reward distribution β vaults and other smart contracts can access dynamic CandyBox lists on-chain and act on them automatically, without maintaining the lists themselves.
Each subscription ID represents a list β it could be a static snapshot, a dynamically refreshed dataset, or any curated set of addresses. The first subscription is provided by Flap and refreshed every 24 hours, featuring the most active users from the previous day's trading activity on Flap. More subscriptions will be added over time.
Want to build your own custom list? Reach out to us β we'd love to explore it with you.
Deployed addresses:
BSC Mainnet
0x6255fbd731272a517022e99f6CaCf6A5De9414Ee
2,000,000
BSC Testnet
0x8e6C16Bf07022a7Da9398B543f38846E9355Bd70
2,000,000
Max Callback Gas: The maximum gas limit supported for an onDataReceived callback.
How it works
Step by step:
The consumer contract calls
requestData(), paying the subscription fee and specifying the page (offset,limit) to fetch.The oracle records the request and emits
FlapDataRequested.The backend queries the previous day's trade data and encodes it as a
ResponseDatastruct.The backend calls
fulfillData(requestId, encodedData)on the oracle.The oracle forwards the data to the consumer via
onDataReceived()with a bounded gas limit.The oracle emits
FlapDataFulfilledwith the callback outcome.
Request status lifecycle
If the consumer's onDataReceived() reverts, the request status is set to FAILED. The oracle operator can retry delivery via retryFulfillData() once the consumer issue is resolved.
Subscriptions
Each subscription defines a dataset, its pricing, and the maximum page size.
subscriptionId
bytes32
Pass to requestData()
description
string
Human-readable rule
responseStruct
string
Struct name for decoding data in onDataReceived()
fee
uint256
Required msg.value per request (wei)
maxLimit
uint32
Maximum records per page
Current limit cap:
maxLimitis 145 per request. This accounts for consumer contracts that store the returned records on-chain β larger payloads may exceed the callback gas budget. Use pagination for more records.
Available subscriptions
Constant
subscriptionId
Description
responseStruct
FLAP_TRADE_BNB_24H
keccak256("FLAP_TRADE_BNB_24H")
Addresses based on their trading activity in the previous 24 hours β across both Bonding Curve and DEX β on tokens launched from Flap
ResponseData
Fees may change. Always call getFee(subscriptionId) on-chain immediately before sending requestData().
How to integrate
Step 1 β Query the fee
Step 2 β Call requestData()
requestData()Pass
block.timestampdirectly β do not manually computestartTime/endTime. The backend derives the previous UTC day window from the request timestamp.
Pagination example β fetching 3000 addresses in pages of 145:
Step 3 β Implement the consumer
The recommended approach is to inherit FlapCandyBoxConsumerBase, which provides the onlyFlapCandyBox modifier and hardcoded address resolution automatically.
Alternatively, implement IFlapCandyBoxConsumer directly and validate msg.sender yourself:
ResponseData struct
The data payload in onDataReceived() is ABI-encoded as ResponseData. Use getSubscription(subscriptionId).responseStruct to confirm the struct name for each subscription.
Use
totalSize(notreturnedCount) for proportional distribution calculations across pages.
Security checklist
Validate msg.sender
Use FlapCandyBoxConsumerBase (recommended) or require(msg.sender == address(oracle))
Guard double-delivery
Track a fulfilled flag per requestId and revert on repeat
Reentrancy
Mark fulfilled before any external calls or token transfers
Callback gas
Keep onDataReceived() within getMaxCallbackGas(); check with oracle.getMaxCallbackGas()
Fee freshness
Call getFee() immediately before sending requestData() β fees may change
Page size
Use getMaxLimit(subscriptionId) to check the current cap before submitting
Reference
Full interface
Last updated