Skip to main content

Points Tokenization

The points tokenization system transforms your offchain loyalty points into real, tradeable onchain assets.

The Deposit Process

Dual-Token Model

When you deposit points, you receive a deposit receipt that represents your points. Later, when your offer is filled on the market, ERC20 tokens are minted. This two-stage design creates security and efficiency:

1. Deposit Receipt (chXXX-R tokens)

Minted immediately at deposit. A non-transferable receipt that proves you deposited X amount of points and tracks changes to your points amount over time. This receipt is your proof of deposit and is required to create offers on the market. Referenced as the DepositReceipt contract. onchain points data: Point balance changes are tracked onchain via the Oracle, which internally uses OpenZeppelin’s Checkpoints library to maintain an immutable record of all balance updates. This data is queryable onchain via the deposit receipt.
function getAccountData(bytes calldata account)
    external
    view
    returns (
        uint256 depositedAmount,
        uint256 heldAmount,
        uint256 latestPointsAmount,
        uint48 latestClaimTime,
        address operator,
        bytes memory account
    );

2. Escrow Token (chXXX tokens)

Minted when someone fills your offer on Market. There are two minting paths:
  • Custodied or escrowable markets: buyers mint chXXX 1:1 against the filled points amount
  • Non-custodial markets: buyers mint chXXX using collateral-weighted minting to account for seller default risk when the protocol cannot directly escrow the underlying points
For the collateral-weighted path, each market can define an ideal USDC collateral per point target. When an offer is filled, the protocol compares the seller’s posted collateral against that market target and derives a collateral weight. That weight then feeds the escrow token mint curve:
  • below the ideal collateral target, buyers mint fewer chXXX than raw points filled
  • at the ideal collateral target, buyers mint at the default/neutral rate
  • above the ideal collateral target, buyers can mint more chXXX, up to the escrow token’s max weight cap
This means two offers for the same number of points can mint different amounts of chXXX on non-custodial markets depending on how much collateral backs each offer. As a result this promotes sellers to back the offers with more collateral, win-win. Referenced as the EscrowToken contract. Fill extra On every fill, the market can also mint an extra amount of escrow tokens to the protocol treasury using the fillExtra config. This is a small inflationary escrow-side fee, not an additional USDC charge taken from the buyer or the seller and is used for seeding escrow token liquidity.

Weighted Mint Curve

On non-custodial markets, the weighted mint path uses the WeightedCurve library to convert a collateral weight into a mint multiplier. The curve constants are:
  • C_MIN = 0.05
  • ALPHA = 0.7
  • R_MAX = 0.5
  • K = 1.8
  • IDEAL_WEIGHT_BPS = 10_000 (100%)
  • MAX_WEIGHT_BPS = 30_000 (300%)
First, the market derives a normalized collateral ratio: weight=min(weightBps,maxWeightBps)weight = \min(\text{weightBps}, \text{maxWeightBps}) c=weightidealWeightBpsc = \frac{weight}{\text{idealWeightBps}} Then the mint multiplier mm is computed piecewise: m(c)={0,cCMIN(cCMIN1CMIN)α,CMIN<c11+RMAX(1eK(c1)),c>1m(c) = \begin{cases} 0, & c \le C_{MIN} \\ \left(\frac{c - C_{MIN}}{1 - C_{MIN}}\right)^{\alpha}, & C_{MIN} < c \le 1 \\ 1 + R_{MAX}\left(1 - e^{-K(c - 1)}\right), & c > 1 \end{cases} So the weighted escrow token mint amount is: mintedAmount=pointsAmount×m(c)\text{mintedAmount} = \left\lfloor \text{pointsAmount} \times m(c) \right\rfloor This gives the curve three useful regions:
  • Below 5% of ideal collateral: minting is zero
  • From 5% to 100% of ideal collateral: minting increases with a concave penalty curve
  • Above 100% of ideal collateral: minting receives a bonus that saturates toward the max weight

Example Curve

Assume a market sets the ideal collateral per point to $0.01 USDC. That means: weightBps=collateralPerPoint0.01×10,000\text{weightBps} = \frac{\text{collateralPerPoint}}{0.01} \times 10{,}000 with IDEAL_WEIGHT_BPS = 10_000 and MAX_WEIGHT_BPS = 30_000. On Protocol Token Generation Event (TGE):
  • The escrow tokens are redeemable for the real tokens at a given ratio determined by Settlement
The redemption ratio is calculated as: tokenRatio=totalTokenAmount×RATIO_PRECISIONtotalEscrowSupply\text{tokenRatio} = \left\lfloor \frac{\text{totalTokenAmount} \times \text{RATIO\_PRECISION}}{\text{totalEscrowSupply}} \right\rfloor Where:
  • totalTokenAmount => ERC20(TGEToken).balanceOf(address(settlement))
  • RATIO_PRECISION => 10**18
  • totalEscrowSupply => ERC20(escrowToken).totalSupply()
Final settlement is based on your share of the total escrow supply for that points program, not on a fixed points-to-token conversion that is pre-determined.

Hold System

When you create an offer to sell points in the Market, your points are “held” temporarily and are freed when the offer is cancelled.
  • Held points: Reserved for your pending trade
  • Available points: Free to use or trade elsewhere
  • Total points: Held + Available = Your complete balance