CIP: 0104
Layer: Canton, Daml
Title: Traffic-Based App Rewards
Author:
Simon Meier
License: CC0-1.0
Status: Approved
Approved: 2026-02-12
Type: Tokenomics
Created: 2026-01-29
Approved:
Post-History: https://lists.sync.global/g/cip-discuss/message/511
This CIP proposes to improve the quality of the app reward incentives by removing featured app markers and instead basing an app’s rewards on the actual traffic spent on (sub-)transactions that change the state managed by the app.
This is achieved by measuring traffic spent directly on the Global Synchronizer using only sequencer and mediator data.
This removes the need for app builders to create FeaturedAppActivityMarkers in all the right places, and instead measures the actual burn contributed by all activity of an app provider party by default.
To enable validator operators to manage the traffic costs incurred by validating (as opposed to submitting) transactions and to foster decentralization of apps and wallets, this CIP also proposes to make protocol-conformant confirmation responses free. Thus validator nodes only pay for the submission of transactions by their users, which is an action that validators can explicitly gate, and charge for, if required.
This CIP further proposes to implement these changes in a way that improves the throughput of the Global Synchronizer, and reduces the transaction cost of app transactions.
Concretely it proposes to avoid using the DSO party in app transactions for the sole purpose of recording app activity, thereby reducing the size of app transactions, and avoiding the need for the SV nodes to validate and confirm extra sub-transactions concerning the DSO party.
Note that the confirmers of a view are the parties whose validator nodes must validate the view and send a positive confirmation response for the (sub-)transaction contained in the view to be committed.
This CIP proposes to
change the app activity recording such that the traffic cost of a successful confirmation request is granted to the app provider parties proportional to the envelope sizes of the envelopes on which they appear as confirmers.
The app provider parties are computed deterministically by reading FeaturedAppRights as-of the time that the mining round opens.
These records are ingested by the SV app based on the mediator verdicts from the mediator scan API, and from the sequencer using a new sequencer traffic scan API.
They replace the use of FeaturedAppActivityMarkers and AppRewardCoupons as activity records.
The Daml code for splice-amulet is changed such that neither FeaturedAppActivityMarker nor AppRewardCoupon contracts are created anymore.
Recall that mining rounds are preannounced and there are always at least two rounds that are open for activity recording, as shown in the following diagram copied from Page 19 of the Canton Coin whitepaper.
This CIP proposes to assign the activity records resulting from a confirmation request to the earliest round that is open at the time the confirmation request was sequenced. That round is always guaranteed to be open for activity recording, and closes the soonest.
The activity record computation is structured such that for a confirmation request that involves only a single app, all traffic spent for that request is attributed to that one app. For confirmation requests involving multiple apps, the computation shares the credit in equal amounts per envelope. This is done as follows:
-
Compute the confirmers of an envelope as the union of the confirmers of the views in that envelope. Use the view hashes visible to the sequencer on the confirmation request to determine the views contained in the envelope.
-
Determine the app confirmers as the parties for which a
FeaturedAppRightis active at round start time. -
Determine
total_app_envelopes_trafficas the total amount of traffic of envelopes that have at least one app confirmer. -
Let
total_confirmation_request_trafficdenote the total traffic cost of the confirmation request. -
For every envelope with
num_app_confirmers > 0, computeper_app_traffic_weight = (envelope_traffic_cost * total_confirmation_request_traffic) / (total_app_envelopes_traffic * num_app_confirmers)using integer arithmetic, and attribute
per_app_traffic_weightto every app confirmer of the envelope.
Note that the computation in Item 5 takes care of distributing the traffic cost not attributed to app envelopes in a weighted fashion among the app envelopes.
When all envelopes have an app confirmer, it becomes per_app_traffic_weight = envelope_traffic_cost / num_app_confirmers, as expected.
See the Example: Views and Envelopes for DvP settlement section for concrete calculation examples.
The computations are performed using integer arithmetic for efficiency and determinism reasons. For confirmation requests whose traffic size is below 100 MB, they can be performed with 64-bit signed integers without risk of overflow.
This CIP proposes to change the accounting of the minting allowance of app provider parties away from using many FeaturedAppActivityMarker and AppRewardCoupon contracts per party per round, and instead have the DSO create exactly one coupon per round for every party whose app rewards for the round surpass the appRewardCouponThreshold (new Amulet config parameter; default, $0.5).
The coupons are valid for appRewardCouponLifetime (new Amulet config parameter; default, 24h) measured from the time they are created.
This allows app providers to batch their minting across multiple rounds and thus lower their traffic cost, and the load on the DSO party.
The coupon amounts are computed as follows:
- All SV apps ingest the app activity records using the data from their associated mediator and sequencer to compute the activity records.
- All SV apps compute the per-party app rewards for the round as described in the “App Reward Computation Details” section below.
- All SV apps agree on them with a super-majority of the other SV apps, using an on-ledger workflow.
- All SV apps run decentralized automation that creates exactly one app reward coupon for every party with a non-zero minting allowance.
App rewards for parties below the threshold are burned.
Note that the minting workflows for SV rewards, validator rewards, and the ecosystem development fund from CIP-82 remain unchanged as part of this CIP. Only the workflow for app rewards is changed.
The overall design proposed by this CIP is compatible with creating activity records for both unfeatured and featured apps, thereby keeping it compatible with the reward computation from the Canton Coin whitepaper, which assigns different caps to unfeatured and featured apps. The implementation proposed by this CIP only supports rewarding featured apps for the reasons given in the rationale section on Rewards for Unfeatured Apps.
The CIP proposes to use the following computation to compute the minting allowances for app provider parties in a round:
- Compute the
total_featured_app_trafficby summing up all activity record weights for the round. - Determine the
traffic_price_in_CC_per_MBusing theAmuletRulescontract at round start time. - Compute
total_featured_app_burn_CC = (total_featured_app_traffic / 1e6) * traffic_price_in_CC_per_MB. - Compute the
issuance_per_featured_app_weightusing the issuance computation from the whitepaper withtotal_unfeatured_app_burn_CC = 0andtotal_featured_app_burn_CCas computed above. - Read the
appRewardCouponThresholdfrom theAmuletConfigread from theAmuletRulescontract at round start time, and computeapp_reward_coupon_threshold_CC = appRewardCouponThreshold / CC_conversion_rate_of_round. - Compute the
per_app_minting_allowancefor every party, by computing thetotal_app_trafficas the sum of the app provider’s activity record weights for the round, and settingper_app_minting_allowance0 = (total_app_traffic / 1e6) * traffic_price_in_CC_per_MB * issuance_per_featured_app_weight per_app_minting_allowance = if per_app_minting_allowance0 >= app_reward_coupon_threshold_CC then per_app_minting_allowance0 else 0
All computations that involve CC are performed using decimals with the same precision and rounding mode as Daml Decimals.
The implementation of featured app activity markers supports fine grained, per-transaction activity attribution to multiple beneficiary parties. For scalability reasons, this CIP proposes to replace per-transaction attribution of beneficiary parties with the same construction that is used to manage beneficiaries of SV rewards: as part of minting, the app provider party can specify a list of beneficiaries and the amount of CC they should receive out of the minted allowance.
The MintingDelegations introduced in CIP-73 will support minting app reward coupons from the adjusted workflow for the app provider.
Automating the specification of beneficiaries and their amounts is however out of scope for the MintingDelegations from CIP-73. We expect such automation to be built as part of the apps themselves.
The CIP proposes to extend the Scan API to make both the data used by the app activity record computation and the activity records themselves available. Concretely:
- Add an endpoint to the Scan API that serves a stream of summaries of the traffic spent on confirmation requests. These summaries contain the per-envelope traffic costs, the total traffic cost, and the hashes of the views contained in an envelope. The stream is served in sequencing time order.
- Add an endpoint to the Scan API that serves the stream of app activity records created for successful confirmation requests.
- Extend the
/v2/eventsendpoint so that the views in the mediator verdicts are annotated with their view hash.
This data enables network explorers to provide both details and summaries of app activity on the network.
Note that the CIP proposes introducing extra endpoints instead of extending the data returned in /v2/events, so that:
- Traffic summaries can be read by clients as soon as the corresponding message has been sequenced, and not only once the confirmation request has been completed, which may be up to 30s later.
- The
/v2/eventsstream is not held up by a potentially delayed app activity record computation.
The Canton Protocol is changed so that the confirmation responses expected to be sent by a confirming participant node become de-facto free. The mechanism works as follows:
- The sequencer continues to charge the traffic cost of a submission to the submitting validator node. This ensures that traffic cost continues to serve as an effective Denial-of-Service (DoS) protection measure.
- The mediator keeps track of the traffic cost spent by validator nodes on protocol-conformant confirmation responses, i.e., responses that match in-flight confirmation requests.
- The mediator regularly reimburses the validator nodes for the traffic spent on protocol-conformant confirmation responses.
For scalability, the reimbursements may be batched, but they happen at most after
maxConfirmationResponseReimbursementDelay(new Amulet config parameter; default, 1h).
Thus validator nodes no longer pay for confirmation responses during normal operations. They only need to hold enough traffic to pay for the in-flight responses that have not yet been reimbursed. In case of network errors, validator nodes retry sending confirmation responses, which may lead to extra traffic costs in case the retry resulted in a duplicate confirmation response.
In Version 34 of the Canton Protocol, which is the version used on MainNet at the time of writing, the confirmation responses are the only messages that are addressed to exactly one mediator group. This CIP proposes to exploit this fact to expedite the change to make confirmation responses free as follows:
- Add a boolean dynamic synchronizer flag to the topology state.
- Change the traffic accounting in sequencers such that no traffic is deducted for messages that have only a single mediator group as their recipients.
- Have the SV apps set the flag once all of the SV nodes have upgraded their sequencer to support the flag.
The drawback of the heuristic implementation is that it opens up a DoS attack vector: a validator node could send lots of messages to mediators without paying traffic for them. The proper implementation avoids that problem. When using the heuristic implementation, the SV nodes can detect this DoS vector using the existing sequencer metrics on SV nodes, and handle abuse using IP blacklisting.
This CIP proposes to roll-out the changes in multiple increments:
- Make confirmation responses free using the heuristic implementation
- Make per-envelope traffic cost observable on Scan
- Make traffic-based app activity records observable on Scan
- Switch to traffic-based app reward computation
- Switch to only making protocol-conformant confirmation responses free.
Increments 2 and 3 serve to give the community a preview on the actual switch happening in the Increment 4. In particular, they allow network explorers to build support for as-if analyses for app providers. The caveat being that the view structure of an app's Daml transactions will change once the app no longer creates featured app markers. App providers can use LocalNet, DevNet or TestNet to preview the impact of adjusting their Daml models.
The difference between Increment 2 and Increment 3 is that the first one allows for an approximate computation of the traffic-based app rewards in network explorers using the featured app status at the time of ingestion. Increment 3 implements the precise activity record logic described in this CIP directly in Scan, and thus ensures that all network explorers use the same data.
The minimal delay between Increment 2 and Increment 4 landing on MainNet must be at least 30 days.
The Global Synchronizer for Canton Network incentivizes app builders via an app reward denominated in Canton Coin. This reward was initially granted only to applications that transferred Canton Coin as part of their activity, but this was found to be too limiting: the Super Validators wanted to also incentivize applications that moved assets other than Canton Coin. As a result the Super Validators introduced featured application activity markers (“featured app markers”) in CIP-47, which allowed a featured application to receive rewards for any economically meaningful activity.
This approach also had shortcomings, however: the reward weight generated was not directly correlated to the amount of traffic burned. At the time of writing, roughly 150% of weight is claimed via markers compared to actual traffic burned. The work to assess and govern these markers has become complex and time-consuming, and produces pressure to centralize governance of application behavior.
App markers are also computationally expensive for the Super Validators, decreasing the amount of throughput that can be devoted to economically useful activity. We need a better method for incentivizing app builders that incentivizes economically useful behavior, and improves governance decentralization while decreasing the requirement for human oversight, so that applications are economically motivated to add the highest possible value in each transaction.
This CIP improves the quality of the app reward incentives using the following two changes:
- Measuring the actual traffic burn contributed by an app.
- Enabling validator operators to charge their users for the cost of accessing the network.
These two changes ensure that, in BME, the app rewards received by an app are de-facto paid by the traffic spent by the app’s users. This incentivizes apps to build workflows whose traffic costs are below the value gained by the app’s users, while at the same time encouraging those apps to have their users submit a large number of transactions.
Furthermore, this CIP removes the need to govern the creation of app markers, by replacing them with a uniform mechanism that always records all featured app activity. Doing this uniformly using traffic-weighted app activity records ensures a level playing field among apps, and removes the need to optimize the amount of traffic spent per marker created.
This CIP proposes to distribute app activity weights only among the confirming app providers of a view instead of sharing them among all featured app providers that are informees of the view. Practically, the main difference is that only the signatories of a contract creation node and the input contract signatories and actors of an exercise node receive app rewards. Parties that are only contract observers or choice observers do not receive app rewards.
The rationale for this is two-fold:
- The confirming app providers are the ones that actively participate in the validation and thus increase the integrity of the network.
- Not considering contract observers and choice observers allows more flexibility for apps to optimize their Daml workflows without impacting their app rewards. For example, the ability to add extra choice observers is important to avoid creating one view per item in a batch of actions, and thus reduce traffic cost.
Instead of attributing the traffic spend of each envelope to the app confirmers of the envelope, one could consider attributing the traffic spend of the whole confirmation request in equal shares across all confirmers of the whole transaction.
We propose not to do so, as that would not work well with composed transactions. The goal is that app providers get the same rewards for the composed transaction as they would get if the user acted on each of the apps individually. This ensures that the users’ “vote of app value” is independent of how their use of the app came about.
The Canton Coin whitepaper supports both unfeatured and featured applications. The difference between them being the amount of rewards they are allowed to earn per dollar of fees spent by their users. The mechanisms introduced by this CIP are compatible with supporting both featured and unfeatured applications provided there is a scalable means to identify app provider parties ahead of activity record creation.
Thus what is missing to support unfeatured applications is the design and implementation for identifying unfeatured apps. A strawman candidate is to compute the set of unfeatured app providers daily, and require that an unfeatured app provider was involved in sub-transactions costing more than a threshold amount of traffic on the previous day. Designing and implementing a scalable implementation of this idea would however significantly delay the delivery of this CIP, which is why it is not included. However adding support for rewarding unfeatured apps in a future CIP is very much in line with the spirit of this CIP.
One additional proposal for app rewards is to allow an app provider to specify per-transaction weights for how to split the app’s activity record among a set of beneficiaries, who would then ultimately be able tomint Canton Coin rewards for this activity.
The current proposal does not address this feature. The main motivation for not supporting per-transaction beneficiaries is to avoid scalability issues. In particular the following two issues seem important to avoid:
-
Avoid tracking minting allowances for millions of parties at the DSO level: unnetted, direct reward sharing with app users would encourage apps to share rewards in fine-grained increments, which in turn creates unwanted scalability pressure on the SV app’s implementation of the minting allowance accounting that must run for every round.
-
Avoid involving the DSO party in most transactions: transactions involving the DSO party are validated and confirmed by all SV validator nodes. They thus carry a high cost, and should be used sparingly.
Supporting per-transaction beneficiaries would require communicating information about different sub-transactions to the SV nodes at scale at the Daml-level. Thus creating a scalability issue by making the DSO party a confirmer of almost every transaction on the Global Synchronizer.
App providers are however free to perform their own accounting to determine how to split the rewards they receive among their beneficiaries. They can retrieve the necessary data from Scan and they can communicate the the minting allowances of their beneficiaries to the DSO on-ledger. They may either perform the accounting themselves or use a third-party data provider that performs the accounting on their behalf.
A given transaction might compose activity from multiple applications. In some cases, a given app provider could argue that their application provides a larger fraction of the overall value generated by that transaction, and therefore their application should receive a larger share of the total rewards generated by that transaction, even if the provider party for that application is not included in a comparable portion of the sub-transactions within the overall transaction. In this conceptual approach, the Daml model defining the app’s behavior would also dictate the weighting to be assigned to that app’s participation in any composed transaction involving that Daml model.
However due to Canton’s privacy, there is no way for the sequencer and mediator to know which Daml models are used in which (sub-)transactions, so value splits defined in a Daml model and cannot be evaluated by the DSO. It may be possible to control the split of rewards within a given sub-transaction, but that would introduce significant complexity to the scope of this proposal.
As a result, this CIP does not address weighting beneficiaries via Daml models, due to the significant increase in complexity this would introduce. We leave it to the community to consider this as a future enhancement.
The certainty about the app rewards gained on traffic spent changes over the duration of a round. It is lowest at its start and highest towards the end of the round. Thus one can expect that rounds with low traffic will see a peak of transactions from elastic demand towards the end of the round. The exact height of these peaks is unclear.
If these load peaks become a problem, then a future CIP can propose adopting an idea like the following deterministically randomized round assignment to smoothen them:
- Round start and end times are assigned such that at any point in time exactly two rounds overlap; and thus there are two candidate rounds for every activity record.
- Every activity record is assigned to one of the candidate rounds in a deterministically randomized fashion using the hash of their record time.
- The probability of the assignment to the later round is managed such that it linearly increases from zero at the round start time to one at the round end time of the prior round.
Thus the later an activity is recorded in a round the more likely it is for that activity to be attributed to the next round, for which the expected reward is more uncertain. Thereby lowering the fluctuation of reward certainty over the duration of a round, which in turn lowers the peaks from elastic demand.
See the Canton Network whitepaper and the Canton Blockchain Protocol whitepaper for more information about confirmation requests, views, and responses.
Canton protocol messages are distributed via the sequencer as a batch of envelopes (proto). An envelope consists of a list of recipients, a list of signatures, and a payload (proto). The envelope payload used to distribute views is called an EncryptedViewMessage (proto). The view itself is only stored in encrypted form, but the view hash is available in plaintext for the sequencer.
We use the DvP example from the Canton ledger model documentation on privacy. See that documentation for diagram notation, context on the example, and formal definitions of concepts like action, transaction, node, informees, and witnesses.
The diagram shows the confirmers of an action in green.
As explained in the Canton docs here, Canton 3.4 creates a view for every action node in the transaction tree if the validator nodes that host their informees are not a subset of their parent view’s informees' validators.
Assuming that all parties in the example are hosted on their own validator nodes, the example DvP transaction results in five views, which are each encoded in their own envelope. For efficiency, envelopes only encode the root node of the view, as the subtree below the root node can be recomputed using its associated Daml code.
Below we show three calculation examples to illustrate the activity record computation. The all assume the following envelope sizes for the envelopes containing the node’s views:
- Node 1: 12 kB
- Node 2: 4 kB
- Node 3: 2 kB
- Node 4: 5 kB
- Node 5: 2 kB
total_confirmation_request_traffic: 25 kB
Note that we set total_confirmation_request_traffic to the sum of all envelopes for the sake of this example.
In practice, a confirmation request always contains two envelopes without associated views (one for the mediator view tree, and one or the root view hashes).
Note that Bank1 is an confirmer of Node 2 and 3. Thus
total_app_envelopes_traffic= 6 kB- Bank1 gets the following
per_app_traffic_weightfor Node 2:per_app_traffic_weight = (4 * 25) / (6 * 1) = 16.666 kB - Bank1 gets the following
per_app_traffic_weightfor Node 3:per_app_traffic_weight = (2 * 25) / (6 * 1) = 8.333 kB
Thus Bank1 total activity record for this confirmation request is 24.999 kB, which is equal to total confirmation request traffic of 25 kB when ignoring rounding errors.
No other party gets credit for the traffic spent on this confirmation request.
Note that Bank1 is an confirmer of Node 2 and 3; and Bank2 is an confirmer of Node 4 and 5. Thus
total_app_envelopes_traffic= 13 kB- Bank1 gets the following
per_app_traffic_weightfor Node 2:per_app_traffic_weight = (4 * 25) / (13 * 1) = 7.692 kB - Bank1 gets the following
per_app_traffic_weightfor Node 3:per_app_traffic_weight = (2 * 25) / (13 * 1) = 3.846 kB - Bank2 gets the following
per_app_traffic_weightfor Node 4:per_app_traffic_weight = (5 * 25) / (13 * 1) = 9.615 kB - Bank2 gets the following
per_app_traffic_weightfor Node 5:per_app_traffic_weight = (2 * 25) / (13 * 1) = 3.846 kB
Thus Bank1’s total activity record for this confirmation request is 11.538 kB and Bank2’s total is 13.461 kB. They sum up to 24.999 kB, and their ratio is 13.461 / 11.538 = 1.166, which matches the ratio of the size of their envelopes 7 / 6.
Note that both Bank1 and Bank2 still got full attribution for the envelopes involving only themselves. The difference to the first example is that Bank1 no longer gets any extra credit for the traffic spent by their users on the envelopes for nodes 1, 4, and 5.
Intuition: Alice is a featured app because they act as an automated market maker.
Note that Bank1 is an confirmer of Node 2 and 3; Bank2 is an confirmer of Node 4 and 5; and Alice is an confirmer of Node 1 and 2. Thus
total_app_envelopes_traffic= 25 kB- Alice gets the following
per_app_traffic_weightfor Node 1:per_app_traffic_weight = (12 * 25) / (25 * 1) = 12 kB - Bank1 and Alice each get the following
per_app_traffic_weightfor Node 2:per_app_traffic_weight = (4 * 25) / (25 * 2) = 2 kBThat is they share the credit for Node 2 in equal shares. - Bank1 gets the following
per_app_traffic_weightfor Node 3:per_app_traffic_weight = (2 * 25) / (25 * 1) = 2 kB - Bank2 gets the following
per_app_traffic_weightfor Node 4:per_app_traffic_weight = (5 * 25) / (25 * 1) = 5 kB - Bank2 gets the following
per_app_traffic_weightfor Node 5:per_app_traffic_weight = (2 * 25) / (25 * 1) = 2 kB
Thus the totals are as follows:
- Alice: 14 kB
- Bank1: 4 kB
- Bank2: 7 kB
Note that the actual view decomposition of an app very much depends on their Daml models, and is best observed in production.
For example the SimpleAsset contract used in this example does not make the owner a signatory.
If the owner were a signatory, then the new owner would be an confirmer on the Transfer choice, and thus a corresponding DvP settlement transaction would only contain three views: one for the settlement choice, and one for each transfer.
For this reason, this CIP proposes an Incremental Roll-Out, whose first increment makes the view decomposition and traffic costs observable on Scan. Using a LocalNet deployment of this increment, app providers may experiment with their Daml models and observe the view decomposition and envelope sizes. They can also use Daml Studio to observe the full transaction trees from their Daml models, which can be used with enough experience to predict the view decomposition.
TODO: build and reference here
This CIP is licensed under CC0-1.0: Creative Commons CC0 1.0 Universal
- 2026-02-12: CIP Approved.
- 2026-01-29: draft published
- 2026-01-10: change to share app rewards among confirmers instead of informees

