Skip to content
Protocol contracts not yet configured for this build
Enter app

Developers

Indexing revenue

The contracts store bounded arrays and expose them by index, so a full history can be read without an indexer. For a UI you will usually want one anyway.

On-chain arrays

solidity
// PloutoRevenueRouterfunction routesLength() external view returns (uint256);function getRoute(uint256 index) external view returns (RouteRecord); struct RouteRecord {    uint64  timestamp;    uint256 amount;    uint256 toBuybacks;    uint256 toStakers;    uint256 toReserve;}

Reading the most recent 50, newest first:

typescript
const count = Number(await client.readContract({  address: router, abi: ploutoRevenueRouterAbi, functionName: 'routesLength',})); const indices = Array.from({length: Math.min(count, 50)}, (_, i) => BigInt(count - 1 - i)); const routes = await client.multicall({  contracts: indices.map((i) => ({    address: router,    abi: ploutoRevenueRouterAbi,    functionName: 'getRoute',    args: [i],  })),});

This is exactly what the Core page does. No backend is involved.

From logs

For a full historical index, or to attach transaction hashes, use the events instead:

typescript
const logs = await client.getLogs({  address: router,  event: parseAbiItem(    'event RevenueRouted(uint256 amount, uint256 toBuybacks, uint256 toStakers, uint256 toReserve, uint256 totalRevenueRouted, uint256 routeIndex)'  ),  fromBlock: deploymentBlock,  toBlock: 'latest',});

routeIndex in the log corresponds exactly to the array index, so the two sources reconcile.

Reconstructing the pipeline

To rebuild the full fee picture you need three event streams:

EventGives you
PonsFeesClaimedWhen fees were claimed, the measured amount, and what the escrow reported.
RevenueRoutedEach split, with all three destinations.
DonationReceivedETH that is explicitly not revenue.

Keep donations out of any "fees earned" figure. The contract does; an indexer that sums raw ETH inflows would not.

Invariants worth asserting in an indexer

If your reconstruction ever violates one of these, the bug is in the indexer:

text
Σ RevenueRouted.amount                          == totalRevenueRoutedΣ PonsFeesClaimed.measuredDelta                 == totalRevenueClaimedtotalRevenueClaimed - totalRevenueRouted        == unallocatedRevenuetoBuybacks + toStakers + toReserve              == amount     (per event)

Suggested schema

sql
CREATE TABLE revenue_epoch (  route_index      BIGINT PRIMARY KEY,  block_number     BIGINT NOT NULL,  tx_hash          BYTEA  NOT NULL,  ts               TIMESTAMPTZ NOT NULL,  amount_wei       NUMERIC(78,0) NOT NULL,  to_buybacks_wei  NUMERIC(78,0) NOT NULL,  to_stakers_wei   NUMERIC(78,0) NOT NULL,  to_reserve_wei   NUMERIC(78,0) NOT NULL);

Store wei as exact integers. Never store ETH as a float — the values exceed float precision and rounding will silently break the reconciliation above.