The tariff
The tariff is one unsigned integer stored in the contract: micro-USDC per Relay Unit. At launch
it is 10_000, which is $0.010 per Relay Unit.
Everything with a price is derived from it:
price(tier) = price_units(tier) × tariff
payg_price(tier) = tariff × payg_bps(tier) / 10,000
sender_fee = sender_fee_ru × tariff
Nothing else in the system carries a USDC price. Add-ons that cost something — adding a named wallet, for example — are priced in Relay Units, so the one value keeps rescaling everything at once. That is the design: one lever, publicly readable, with hard limits on how it may move.
Because there is exactly one lever, no plan's price can move on its own, and there is no negotiated rate that others cannot see: a custom plan is created on chain like any other tier. Paying up to 12 months ahead locks today's tariff for the whole prepaid block. (Credits and billing)
Who may change it
Only the owner — the deploying key, held offline. Not the operator, whose key is warm and whose job is incident response. The operator can pause things; it cannot reprice them.
What the contract will not allow
These are compiled constants of the contract, not settings. Changing one requires an upgrade, which is public and deliberate. A settable notice period could be set to zero by the very key it is meant to restrain.
| Rule | Value |
|---|---|
| Absolute floor | 1,000 micro-USDC per Relay Unit |
| Absolute ceiling | 1,000,000 micro-USDC per Relay Unit |
| Step per call | At most a doubling, at least a halving — the new value must lie in [current/2, current × 2] |
| Notice for an increase | 48 hours before it takes effect |
| Notice for a decrease | None; it is immediate |
| Granularity | A multiple of 100 |
The step limit caps the rate of increase at a doubling per 48 hours. The granularity rule exists so that every pay-as-you-go price is an exact integer and no rounding rule has to exist anywhere in the billing.
The 48 hours are real
A scheduled increase is announced the moment it is scheduled, through every channel: the pending
member of the pricing document, an account notice (in the notice feed and on the account stream),
a banner in the dashboard. A notice period that is not delivered is not a notice period.
Only one change can be pending at a time, and scheduling a new one cancels the old one. That keeps the invariant honest: a decrease that left an older, larger increase queued behind it could produce a jump bigger than the step rule allows.
What a change does to your money
Nothing, for anything already paid for. A purchase snapshots its terms into a plan block. Tariff changes do not reach into a block that has been paid for — in either direction. If the tariff halves tomorrow, what you bought today is still what you bought.
What a change touches:
| Effect of an increase | |
|---|---|
| Plans you already paid for | None. |
| Your next renewal | Priced at the new tariff — which is why auto-renew requires an explicit max_renew_price. |
| Pay-as-you-go usage after activation | Priced at the new tariff — which is why setPayg takes a max_payg_price. |
| A quote already issued | A quote whose 120-second life crosses an activation is priced at the pending, higher value and says so. It can only ever charge you less than you accepted, never more. |
Why not an oracle
Fees are paid in EGLD and EGLD has a market price, so an automatic peg is the obvious idea. It is rejected, for reasons worth stating:
- The contract would have to trust a price feed. That is a new dependency with its own failure modes and its own attack surface, inside the one component that must be simplest.
- Prices would move without notice. The 48-hour rule would be meaningless if a feed could move the number.
- It would be unreadable. "Micro-USDC per Relay Unit, currently 10,000" can be checked by anyone in one call. A formula over an oracle cannot.
The contract never reads a price. Adjusting the tariff is a human decision, made publicly, with notice — and the pricing policy behind it is documented rather than secret: it targets covering the deepest tier discount, the relayer's share of revenue and the swap cost at the prevailing EGLD price, with a small headroom.
There is also a deliberate asymmetry: the tariff is sticky downward. Credits deposited while EGLD was expensive and spent after a cut are under-hedged, which is CoRelayer's problem and nobody else's — so cuts happen for competitive reasons, not automatically.
Reading it, and its history
| Call | Gives |
|---|---|
getTariff | Current value, pending value, effective time, version. |
getEffectiveTariff | The value in force right now, applying any due activation. |
getTariffByVersion | Any historical value by version. |
getTariffHistory | The full append-only history. |
GET /v1/pricing | The same, plus prices, as a document. |
GET /v1/pricing/tariff-history | The same history over HTTP. |
The history is append-only in the contract, and the version number is simply its length. There is no separate counter that could disagree with the list.
The Relay Unit schedule changes the same way
The formula that converts a transaction into Relay Units is itself versioned, hashed into the contract, and changed under the same 48-hour notice. So neither half of "what you pay" — the price per unit, or what counts as a unit — can move without warning.