Skip to main content

Pair Smart Contract (1.0.0)

Download OpenAPI specification:Download

The Pair Contract in the Bitcoin.me DeFi system manages liquidity pools for token pairs. It facilitates operations such as adding and removing liquidity, performing token swaps, and managing fees.

Overview

The Pair Contract is essential for decentralized exchanges and liquidity provision, enabling efficient and secure token trading and liquidity management. Key features include:

  • Liquidity Management: Allows users to add or remove liquidity from the pool, issuing and burning LP tokens as needed.
  • Token Swaps: Supports swapping between token pairs with various methods to ensure price stability and minimal fees.
  • Fee Management: Configures and collects transaction fees, forwarding them to designated addresses.
  • Whitelisting: Controls access to certain functions, ensuring only authorized addresses can perform specific operations.
  • Price Stability: Implements mechanisms to calculate and maintain a safe price for tokens within the pool, preventing manipulation and volatility.

Liquidity Pool Calculations

The pools operate based on the constant product formula:

ReserveA × ReserveB = k (constant)

When adding liquidity, the proportional amount is calculated as:

ΔTokenB = ΔTokenA × ReserveB / ReserveA

Precision Conversion

Since each token can have different precision (e.g., TokenA with precision 3 and TokenB with precision 6), values need to be converted:

Convert user input to raw format (blockchain):

AmountRaw = AmountUser × 10^Precision

Convert back to user-friendly format:

AmountUser = AmountRaw / 10^Precision

Endpoints

Write operations that modify contract state

Add Initial Liquidity

Adds the initial liquidity to a trading pair. This is used to provide the initial tokens needed to start the operation of the pair.

Prerequisites:

  • The caller must have adequate permissions to add liquidity to the pair
  • Minimum liquidity of 1,000 units is required
  • The LP token must be identified through the setLpTokenIdentifier endpoint
  • The Pair contract must have the mint role for the LP token

Important Notes:

  • The initial value will define the token ratio for the pool
  • The contract mints the LP_TOKEN and retains 1,000 units in the contract itself (minimum liquidity)

Example - Grant mint role to contract:

go run ./cmd/operator/ --key-file=./localWalletKey.pem kda trigger 6 --kdaID KFIKLVLP-2GC1 --addRolesMint klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu
Request Body schema: application/json
required
scAddress
required
string

Pair contract address

funcName
required
string
Value: "addInitialLiquidity"
value
required
string

Token payments in format TOKEN_A=amount,TOKEN_B=amount

Responses

Request samples

Content type
application/json
{
  • "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
  • "funcName": "addInitialLiquidity",
  • "value": "KFI=10000000,KLV=10000000"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": "string",
  • "code": "string"
}

Add Liquidity

Allows users to add liquidity to a trading pair. Adding liquidity is a single transaction process that involves sending both tokens and calling the endpoint.

Important Observations:

  • The function ensures that the amount of each token added maintains the correct proportion in the pool
  • If the provided amount of one token is greater than needed to maintain the proportion, the excess will be returned
  • The minimum amounts defined ensure that the user does not add fewer tokens than desired, allowing slippage tolerance to be set

Parameters:

  • first_token_amount_min: Minimum acceptable amount of first token (for slippage protection)
  • second_token_amount_min: Minimum acceptable amount of second token (for slippage protection)
Request Body schema: application/json
required
scAddress
required
string

Pair contract address

funcName
required
string
Value: "addLiquidity"
args
required
Array of strings

Arguments:

  • first_token_amount_min (BigUint): Minimum amount of first token
  • second_token_amount_min (BigUint): Minimum amount of second token
value
required
string

Token payments

Responses

Request samples

Content type
application/json
{
  • "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
  • "funcName": "addLiquidity",
  • "args": [
    ],
  • "value": "KFI=50000000,KLV=50000000"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": "string",
  • "code": "string"
}

Remove Liquidity

Removes liquidity from the trading pair, returning the originally provided tokens according to the proportion of the removed liquidity.

Prerequisites:

  • The caller must have sufficient liquidity tokens (LP tokens) to remove

Parameters:

  • first_token_amount_min: Minimum acceptable amount of first token to receive
  • second_token_amount_min: Minimum acceptable amount of second token to receive
Request Body schema: application/json
required
scAddress
required
string
funcName
required
string
Value: "removeLiquidity"
args
required
Array of strings

Arguments:

  • first_token_amount_min (BigUint): Minimum first token to receive
  • second_token_amount_min (BigUint): Minimum second token to receive
value
required
string

LP tokens to burn

Responses

Request samples

Content type
application/json
{
  • "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
  • "funcName": "removeLiquidity",
  • "args": [
    ],
  • "value": "KFIKLVLP-3O1A=10000000"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": "string",
  • "code": "string"
}

Swap Tokens (Fixed Input)

Swaps a fixed amount of one token for a variable amount of another token according to the current exchange rate.

Behavior:

  • The user pays the exact amount of the input token
  • The user receives at least the minimum amount of the output token specified
  • If the amount received is less than the minimum specified, returns a Slippage Error
  • If the amount received exceeds the minimum, the user receives the larger amount

Prerequisites:

  • The pair must be active for swap (use resume endpoint to activate)

Note: If the contract is configured with simple-lock settings (setLockingScAddress, setLockingDeadlineEpoch, setUnlockEpoch), the user will receive a locked token (SFT) instead of the desired token. The user can exchange this for the actual token once the unlock epoch is reached.

Example - Activate pair for swaps:

go run ./cmd/operator/ --key-file=./localWalletKey.pem sc invoke klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu resume --await
Request Body schema: application/json
required
scAddress
required
string
funcName
required
string
Value: "swapTokensFixedInput"
args
required
Array of strings

Arguments:

  • token_out (TokenIdentifier): Output token identifier
  • amount_out_min (BigUint): Minimum output amount (slippage protection)
value
required
string

Input token payment

Responses

Request samples

Content type
application/json
{
  • "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
  • "funcName": "swapTokensFixedInput",
  • "args": [
    ],
  • "value": "KFI=20000000"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": "string",
  • "code": "string"
}

Swap Tokens (Fixed Output)

Swaps a variable amount of one token for a fixed amount of another token.

Behavior:

  • The user specifies the exact amount of the output token they wish to receive
  • The user pays the required amount of the input token based on the current exchange rate
  • If the amount provided is insufficient, returns a Slippage Error
  • If there is excess payment, the excess input tokens will be returned

Prerequisites:

  • The pair must be active for swap (use resume endpoint to activate)

Note: If the contract is configured with simple-lock settings (setLockingScAddress, setLockingDeadlineEpoch, setUnlockEpoch), the user will receive a locked token (SFT) instead of the desired token. The user can exchange this for the actual token once the unlock epoch is reached.

Request Body schema: application/json
required
scAddress
required
string
funcName
required
string
Value: "swapTokensFixedOutput"
args
required
Array of strings

Arguments:

  • token_out (TokenIdentifier): Output token identifier
  • amount_out (BigUint): Exact output amount desired
value
required
string

Input token payment (may be partially returned)

Responses

Request samples

Content type
application/json
{
  • "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
  • "funcName": "swapTokensFixedOutput",
  • "args": [
    ],
  • "value": "KLV=20000000"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": "string",
  • "code": "string"
}