-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
What? Why? Who?
Implement an API endpoint that returns the history of reward distributions for a specific smart contract address, paginated.
The main consumer right now is the Qubic Explorer.
This is needed for the Smart Contract page (address page), where users can see all the reward (dividend) distributions that a given contract has made over time, across all epochs.
Acceptance Criteria
- The endpoint returns paginated reward distributions for the given contract address
- Results are ordered by most recent first
- Response includes pagination metadata
- Response includes
totalAllTimeDistributed— the total amount distributed by this contract across all available epochs (not just the current page) and as we do not have all epochs data, we should receive also which is the start epoch where data is available. - Response includes total number of distributions
- Each distribution item contains: epoch, contractAddress, tickNumber, totalAmount, amountPerShare, transferCount, timestamp
- Returns an error if the given address is not a valid contract address.
Out of Scope
- Epoch-level rewards endpoint (separate issue)
- Individual transfer-level detail (we only return aggregated summaries per distribution)
Technical Sketch (How?)
How to identify reward distributions in Bob log events
Bob emits log events per tick. Each event has these relevant fields:
| Field | Description |
|---|---|
tick |
Tick number where the event occurred |
epoch |
Epoch number |
logId |
Sequential ID within the tick (determines ordering) |
type |
Log type: 0 = QU_TRANSFER, 255 = CUSTOM_MESSAGE |
body.from |
Source address (on QU_TRANSFER events) |
body.to |
Destination address (on QU_TRANSFER events) |
body.amount |
Amount transferred (on QU_TRANSFER events) |
body.customMessage |
Operation code (on CUSTOM_MESSAGE events only) |
A reward distribution appears as a group of consecutive events within a single tick, wrapped by two markers:
logId 100: type=255, body.customMessage=6217575821008262227 ← START marker
logId 101: type=0, body.from=CONTRACT_X, body.to=ADDR_1, body.amount=1000 ← payment
logId 102: type=0, body.from=CONTRACT_X, body.to=ADDR_2, body.amount=1000 ← payment
...
logId 777: type=255, body.customMessage=6217575821008457285 ← END marker
All QU_TRANSFER events (type=0) with a logId between the START and END markers belong to that distribution. They all share the same body.from (the contract address).
Step-by-step logic
- Find all START markers: events where
type = 255ANDbody.customMessage = 6217575821008262227 - Find all END markers: events where
type = 255ANDbody.customMessage = 6217575821008457285 - Pair each START with its END: for each START, find the END in the same tick with the smallest
logIdgreater than the START'slogId - Collect reward transfers: for each START/END pair, get all events where
type = 0AND sametickANDlogIdis between START and END — then filter only those wherebody.from = {input address} - Aggregate per distribution:
totalAmount= sum of allbody.amounttransferCount= count of transfersamountPerShare=totalAmount / 676(676 = fixed number of computors)contractAddress=body.fromfrom any transfertickNumber= the tick of the START markertimestamp= timestamp of the tickepoch= epoch of the tick
- Order by
tickNumberdescending (most recent first) - Paginate: apply
offsetandsizeto the ordered results - Calculate totals across all pages:
totalAllTimeDistributed= sum oftotalAmountfrom ALL distributions (not just the current page),totalCount= total number of distributions
Expected input
- Smart contract address
- Pagination parameters
Expected output
{
"contractAddress": "BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"distributions": [
{
"epoch": 152,
"contractAddress": "BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"tickNumber": 42187300,
"totalAmount": 676000,
"amountPerShare": 1000.0,
"transferCount": 451,
"timestamp": "2024-12-17T10:00:00Z"
},
{
"epoch": 151,
"contractAddress": "BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"tickNumber": 42100500,
"totalAmount": 338000,
"amountPerShare": 500.0,
"transferCount": 423,
"timestamp": "2024-12-12T08:30:00Z"
}
...
],
"totalAllTimeDistributed": 1014000,
"hits": {
"total": 10000,
"from": 0,
"size": 50
},
}References
- Reference frontend implementation:
http://149.50.116.131/address/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARMID?tab=rewards
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
🔖 Ready