Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Polymarket/ctf-exchange/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The CalculatorHelper library provides utility functions for calculating amounts, prices, fees, and determining whether orders can be matched. All functions are pure and do not modify state.

Constants

uint256 internal constant ONE = 10 ** 18;
uint256 internal constant BPS_DIVISOR = 10_000;
ONE
uint256
Precision constant used for price calculations (18 decimals)
BPS_DIVISOR
uint256
Divisor for basis points conversions (10,000 bps = 100%)

Functions

calculateTakingAmount

Calculates the taker amount based on the maker amount being filled.
function calculateTakingAmount(
    uint256 makingAmount,
    uint256 makerAmount,
    uint256 takerAmount
) internal pure returns (uint256)

Parameters

makingAmount
uint256
The amount of maker tokens being filled in this transaction
makerAmount
uint256
The total maker amount from the order
takerAmount
uint256
The total taker amount from the order

Returns

takingAmount
uint256
The proportional taker amount: makingAmount * takerAmount / makerAmountReturns 0 if makerAmount is 0

Example

// Order: 50 USDC for 100 tokens
// Filling: 25 USDC
uint256 tokens = CalculatorHelper.calculateTakingAmount(
    25_000_000,  // filling 25 USDC
    50_000_000,  // total order: 50 USDC
    100_000_000  // total order: 100 tokens
);
// tokens = 50_000_000 (50 tokens)

calculateFee

Calculates the fee for an order based on outcome tokens and fee rate.
function calculateFee(
    uint256 feeRateBps,
    uint256 outcomeTokens,
    uint256 makerAmount,
    uint256 takerAmount,
    Side side
) internal pure returns (uint256 fee)

Parameters

feeRateBps
uint256
Fee rate in basis points (100 bps = 1%)
outcomeTokens
uint256
The number of outcome tokens involved in the transaction
makerAmount
uint256
The maker amount of the order
takerAmount
uint256
The taker amount of the order
side
Side
The side of the order (BUY or SELL)

Returns

fee
uint256
The calculated fee amount
  • For BUY orders: Fee charged on token proceeds
    • Formula: feeRateBps * min(price, 1-price) * (outcomeTokens/price) / BPS_DIVISOR
  • For SELL orders: Fee charged on collateral proceeds
    • Formula: feeRateBps * min(price, 1-price) * outcomeTokens / (BPS_DIVISOR * ONE)
Returns 0 if feeRateBps is 0 or price is invalid (≤ 0 or > 1)

Example

// Buy order: 40 USDC for 100 tokens (price = 0.4)
// Fee rate: 1% (100 bps)
uint256 fee = CalculatorHelper.calculateFee(
    100,         // 1% fee
    100_000_000, // 100 tokens
    40_000_000,  // 40 USDC
    100_000_000, // 100 tokens
    Side.BUY
);
// fee = 1_000_000 (1 token)

calculatePrice

Calculates the price for an order.
function calculatePrice(Order memory order) internal pure returns (uint256)

Parameters

order
Order
The order to calculate the price for

Returns

price
uint256
The price as an 18-decimal fixed-point number
  • For BUY orders: makerAmount * ONE / takerAmount (price maker is willing to pay)
  • For SELL orders: takerAmount * ONE / makerAmount (price maker wants to receive)
Returns 0 if division by zero would occur

_calculatePrice

Internal price calculation function.
function _calculatePrice(
    uint256 makerAmount,
    uint256 takerAmount,
    Side side
) internal pure returns (uint256)

Parameters

makerAmount
uint256
The maker amount
takerAmount
uint256
The taker amount
side
Side
The side of the order

Returns

price
uint256
The calculated price
  • If side == BUY: Returns makerAmount * ONE / takerAmount (or 0 if takerAmount == 0)
  • If side == SELL: Returns takerAmount * ONE / makerAmount (or 0 if makerAmount == 0)

isCrossing

Determines if two orders can be matched (i.e., their prices cross).
function isCrossing(Order memory a, Order memory b) internal pure returns (bool)

Parameters

a
Order
First order
b
Order
Second order

Returns

crosses
bool
Whether the orders cross and can be matchedReturns true if either order has zero takerAmount, or if the prices satisfy the crossing condition

_isCrossing

Internal crossing calculation function.
function _isCrossing(
    uint256 priceA,
    uint256 priceB,
    Side sideA,
    Side sideB
) internal pure returns (bool)

Parameters

priceA
uint256
Price of the first order
priceB
uint256
Price of the second order
sideA
Side
Side of the first order
sideB
Side
Side of the second order

Returns

crosses
bool
Whether the prices cross based on order sidesCrossing conditions:
  • Both BUY: priceA + priceB >= ONE (bid prices sum to ≥ 1)
  • BUY vs SELL: priceA >= priceB (bid price ≥ ask price)
  • SELL vs BUY: priceB >= priceA (bid price ≥ ask price)
  • Both SELL: priceA + priceB <= ONE (ask prices sum to ≤ 1)

min

Returns the minimum of two values.
function min(uint256 a, uint256 b) internal pure returns (uint256)

Parameters

a
uint256
First value
b
uint256
Second value

Returns

minimum
uint256
The smaller of the two values

Usage Examples

Calculate Fill Amounts

import { CalculatorHelper } from "exchange/libraries/CalculatorHelper.sol";

// Order: 50 USDC for 100 tokens
uint256 makerAmount = 50_000_000;
uint256 takerAmount = 100_000_000;

// Partially fill 25 USDC
uint256 fillAmount = 25_000_000;
uint256 tokensReceived = CalculatorHelper.calculateTakingAmount(
    fillAmount,
    makerAmount,
    takerAmount
);
// tokensReceived = 50_000_000 (50 tokens)

Check Order Matching

// Check if a buy and sell order can be matched
Order memory buyOrder = /* ... */;
Order memory sellOrder = /* ... */;

bool canMatch = CalculatorHelper.isCrossing(buyOrder, sellOrder);
if (canMatch) {
    // Execute the match
}

Calculate Trading Fee

// Calculate fee for a buy order
uint256 fee = CalculatorHelper.calculateFee(
    100,         // 1% fee (100 bps)
    100_000_000, // 100 outcome tokens
    40_000_000,  // maker amount: 40 USDC
    100_000_000, // taker amount: 100 tokens  
    Side.BUY
);

Build docs developers (and LLMs) love